From 9b12d486f546b5879fb9390a6b46edde6bde8361 Mon Sep 17 00:00:00 2001 From: Tom Moor Date: Tue, 23 Apr 2024 22:30:52 -0400 Subject: [PATCH] fix: Disable smart text replacements in code mark (#6839) --- app/editor/extensions/SmartText.ts | 3 ++- shared/editor/lib/InputRule.ts | 38 ++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 shared/editor/lib/InputRule.ts diff --git a/app/editor/extensions/SmartText.ts b/app/editor/extensions/SmartText.ts index e45e0f230..3ddaa4970 100644 --- a/app/editor/extensions/SmartText.ts +++ b/app/editor/extensions/SmartText.ts @@ -1,5 +1,6 @@ -import { ellipsis, smartQuotes, InputRule } from "prosemirror-inputrules"; +import { ellipsis, smartQuotes } from "prosemirror-inputrules"; import Extension from "@shared/editor/lib/Extension"; +import { InputRule } from "@shared/editor/lib/InputRule"; const rightArrow = new InputRule(/->$/, "→"); const emdash = new InputRule(/--$/, "—"); diff --git a/shared/editor/lib/InputRule.ts b/shared/editor/lib/InputRule.ts new file mode 100644 index 000000000..fb1f472df --- /dev/null +++ b/shared/editor/lib/InputRule.ts @@ -0,0 +1,38 @@ +import { InputRule as ProsemirrorInputRule } from "prosemirror-inputrules"; +import { EditorState } from "prosemirror-state"; +import isInCode from "../queries/isInCode"; + +/** + * A factory function for creating Prosemirror input rules that automatically insert text + * that matches a given regular expression unless the selection is inside a code block or code mark. + */ +export class InputRule extends ProsemirrorInputRule { + constructor(rule: RegExp, insert: string) { + super( + rule, + ( + state: EditorState, + match: RegExpMatchArray, + start: number, + end: number + ) => { + if (isInCode(state)) { + return null; + } + + if (match[1]) { + const offset = match[0].lastIndexOf(match[1]); + insert += match[0].slice(offset + match[1].length); + start += offset; + const cutOff = start - end; + if (cutOff > 0) { + insert = match[0].slice(offset - cutOff, offset) + insert; + start = end; + } + } + + return state.tr.insertText(insert, start, end); + } + ); + } +}