| 1 | // The markdown editing keymap shared by every preset: fence-aware Enter (auto-close, newline |
| 2 | // inside code), Tab list indentation, and the inline-mark toggles. Hosts layer their own bindings |
| 3 | // (submit, pickers) at higher precedence; the composer factory does exactly that. |
| 4 | import { defaultKeymap, historyKeymap } from "@codemirror/commands"; |
| 5 | import { type Extension, Prec } from "@codemirror/state"; |
| 6 | import { keymap } from "@codemirror/view"; |
| 7 | |
| 8 | import { |
| 9 | codeBlockEnter, |
| 10 | continueList, |
| 11 | cycleEmphasis, |
| 12 | dedentListItem, |
| 13 | indentListItem, |
| 14 | surroundSelection, |
| 15 | toggleInlineMark, |
| 16 | } from "./commands.ts"; |
| 17 | |
| 18 | /** Fence/list-aware Enter, Tab list indent/dedent, Mod-b/Mod-i, and selection surrounds. */ |
| 19 | export function markdownKeymap(): Extension { |
| 20 | return Prec.high( |
| 21 | keymap.of([ |
| 22 | { key: "Enter", run: (target) => codeBlockEnter(target) || continueList(target) }, |
| 23 | { key: "Tab", run: indentListItem }, |
| 24 | { key: "Shift-Tab", run: dedentListItem }, |
| 25 | { key: "Mod-b", run: toggleInlineMark("**") }, |
| 26 | { key: "Mod-i", run: toggleInlineMark("*") }, |
| 27 | { key: "`", run: surroundSelection("`") }, |
| 28 | { key: "*", run: cycleEmphasis }, |
| 29 | ]), |
| 30 | ); |
| 31 | } |
| 32 | |
| 33 | /** |
| 34 | * History plus the CodeMirror defaults, minus bindings that make no sense in markdown: Mod-/ |
| 35 | * toggles an HTML comment (markdown's only comment syntax), which no markdown editor wants. |
| 36 | */ |
| 37 | export function baseKeymap(): Extension { |
| 38 | return keymap.of([...historyKeymap, ...defaultKeymap.filter((b) => b.key !== "Mod-/")]); |
| 39 | } |