godo.js/src-js/godo-additional-keymap.mjs

99 lines
3.3 KiB
JavaScript

import {wrapIn, setBlockType, chainCommands, toggleMark, exitCode,
joinUp, joinDown, lift, selectParentNode} from "prosemirror-commands"
import {undo, redo} from "prosemirror-history"
const mac = typeof navigator != "undefined" ? /Mac/.test(navigator.platform) : false
// :: (Schema, ?Object) → Object
// Inspect the given schema looking for marks and nodes from the
// basic schema, and if found, add key bindings related to them.
// This will add:
//
// * **Mod-b** for toggling [strong](#schema-basic.StrongMark)
// * **Mod-i** for toggling [emphasis](#schema-basic.EmMark)
// * **Mod-`** for toggling [code font](#schema-basic.CodeMark)
// * **Ctrl-Shift-0** for making the current textblock a paragraph
// * **Ctrl-Shift-1** to **Ctrl-Shift-Digit6** for making the current
// textblock a heading of the corresponding level
// * **Ctrl-Shift-Backslash** to make the current textblock a code block
// * **Ctrl-Shift-8** to wrap the selection in an ordered list
// * **Ctrl-Shift-9** to wrap the selection in a bullet list
// * **Ctrl->** to wrap the selection in a block quote
// * **Enter** to split a non-empty textblock in a list item while at
// the same time splitting the list item
// * **Mod-Enter** to insert a hard break
// * **Mod-_** to insert a horizontal rule
// * **Backspace** to undo an input rule
// * **Alt-ArrowUp** to `joinUp`
// * **Alt-ArrowDown** to `joinDown`
// * **Mod-BracketLeft** to `lift`
// * **Escape** to `selectParentNode`
//
// You can suppress or map these bindings by passing a `mapKeys`
// argument, which maps key names (say `"Mod-B"` to either `false`, to
// remove the binding, or a new key name string.
export function buildKeymap(schema, mapKeys, options) {
let keys = {}, type;
function bind(key, cmd) {
if (mapKeys) {
let mapped = mapKeys[key]
if (mapped === false) return
if (mapped) key = mapped
}
keys[key] = cmd
}
bind("Mod-z", undo)
bind("Shift-Mod-z", redo)
if (!mac) bind("Mod-y", redo)
bind("Alt-ArrowUp", joinUp)
bind("Alt-ArrowDown", joinDown)
bind("Mod-BracketLeft", lift)
bind("Escape", selectParentNode)
if (type = schema.marks.strong) {
bind("Mod-b", toggleMark(type))
bind("Mod-B", toggleMark(type))
}
if (type = schema.marks.em) {
bind("Mod-i", toggleMark(type))
bind("Mod-I", toggleMark(type))
}
if (type = schema.marks.code)
bind("Mod-`", toggleMark(type))
if (type = schema.nodes.blockquote)
bind("Ctrl->", wrapIn(type))
if (type = schema.nodes.hard_break) {
let br = type, cmd = chainCommands(exitCode, (state, dispatch) => {
dispatch(state.tr.replaceSelectionWith(br.create()).scrollIntoView())
return true
})
bind("Mod-Enter", cmd)
bind("Shift-Enter", cmd)
if (mac) bind("Ctrl-Enter", cmd)
}
if (type = schema.nodes.paragraph)
bind("Shift-Ctrl-0", setBlockType(type))
if (type = schema.nodes.code_block)
bind("Shift-Ctrl-\\", setBlockType(type))
if (type = schema.nodes.heading) {
options.heading_levels.forEach( (level, index) => {
bind(`Shift-Ctrl-${index+1}`, setBlockType(type, {level: level}))
});
}
if (type = schema.nodes.horizontal_rule) {
let hr = type
bind("Mod-_", (state, dispatch) => {
dispatch(state.tr.replaceSelectionWith(hr.create()).scrollIntoView())
return true
})
}
return keys
}