2022-10-10 12:50:21 +00:00
|
|
|
|
import { KeyBinding } from "./deps.ts";
|
|
|
|
|
import { syntaxTree } from "../common/deps.ts";
|
2022-04-24 16:06:34 +00:00
|
|
|
|
|
2022-10-17 13:48:21 +00:00
|
|
|
|
const straightQuoteContexts = [
|
|
|
|
|
"CommentBlock",
|
|
|
|
|
"FencedCode",
|
|
|
|
|
"InlineCode",
|
|
|
|
|
"FrontMatterCode",
|
|
|
|
|
];
|
2022-03-20 08:56:28 +00:00
|
|
|
|
|
|
|
|
|
// TODO: Add support for selection (put quotes around or create blockquote block?)
|
|
|
|
|
function keyBindingForQuote(
|
|
|
|
|
quote: string,
|
|
|
|
|
left: string,
|
2022-10-10 12:50:21 +00:00
|
|
|
|
right: string,
|
2022-03-20 08:56:28 +00:00
|
|
|
|
): KeyBinding {
|
|
|
|
|
return {
|
2022-11-09 08:35:26 +00:00
|
|
|
|
any: (target, event): boolean => {
|
|
|
|
|
// Moving this check here rather than using the regular "key" property because
|
|
|
|
|
// for some reason the "ä" key is not recognized as a quote key by CodeMirror.
|
|
|
|
|
if (event.key !== quote) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2022-10-17 13:48:21 +00:00
|
|
|
|
const cursorPos = target.state.selection.main.from;
|
|
|
|
|
const chBefore = target.state.sliceDoc(cursorPos - 1, cursorPos);
|
2022-04-24 16:06:34 +00:00
|
|
|
|
|
|
|
|
|
// Figure out the context, if in some sort of code/comment fragment don't be smart
|
|
|
|
|
let node = syntaxTree(target.state).resolveInner(cursorPos);
|
|
|
|
|
while (node) {
|
|
|
|
|
if (straightQuoteContexts.includes(node.type.name)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
if (node.parent) {
|
|
|
|
|
node = node.parent;
|
|
|
|
|
} else {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Ok, still here, let's use a smart quote
|
2022-11-09 08:35:26 +00:00
|
|
|
|
let q = right;
|
2022-03-20 08:56:28 +00:00
|
|
|
|
if (/\W/.exec(chBefore) && !/[!\?,\.\-=“]/.exec(chBefore)) {
|
2022-11-09 08:35:26 +00:00
|
|
|
|
q = left;
|
2022-03-20 08:56:28 +00:00
|
|
|
|
}
|
|
|
|
|
target.dispatch({
|
|
|
|
|
changes: {
|
2022-11-09 08:35:26 +00:00
|
|
|
|
insert: q,
|
2022-03-20 08:56:28 +00:00
|
|
|
|
from: cursorPos,
|
|
|
|
|
},
|
|
|
|
|
selection: {
|
|
|
|
|
anchor: cursorPos + 1,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
return true;
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export const smartQuoteKeymap: KeyBinding[] = [
|
|
|
|
|
keyBindingForQuote('"', "“", "”"),
|
|
|
|
|
keyBindingForQuote("'", "‘", "’"),
|
|
|
|
|
];
|