|
@@ -2,6 +2,7 @@ import { useCallback } from 'react';
|
|
|
|
|
|
|
|
import type { EditorView } from '@codemirror/view';
|
|
import type { EditorView } from '@codemirror/view';
|
|
|
|
|
|
|
|
|
|
+
|
|
|
export type InsertMarkdownElements = (
|
|
export type InsertMarkdownElements = (
|
|
|
prefix: string,
|
|
prefix: string,
|
|
|
suffix: string,
|
|
suffix: string,
|
|
@@ -24,27 +25,32 @@ const removeSymbol = (text: string, prefix: string, suffix: string): string => {
|
|
|
export const useInsertMarkdownElements = (view?: EditorView): InsertMarkdownElements => {
|
|
export const useInsertMarkdownElements = (view?: EditorView): InsertMarkdownElements => {
|
|
|
|
|
|
|
|
return useCallback((prefix, suffix) => {
|
|
return useCallback((prefix, suffix) => {
|
|
|
- const selection = view?.state.sliceDoc(
|
|
|
|
|
- view?.state.selection.main.from,
|
|
|
|
|
- view?.state.selection.main.to,
|
|
|
|
|
- );
|
|
|
|
|
|
|
+ if (view == null) return;
|
|
|
|
|
+
|
|
|
|
|
+ const from = view?.state.selection.main.from;
|
|
|
|
|
+ const to = view?.state.selection.main.to;
|
|
|
|
|
+
|
|
|
|
|
+ const selectedText = view?.state.sliceDoc(from, to);
|
|
|
const cursorPos = view?.state.selection.main.head;
|
|
const cursorPos = view?.state.selection.main.head;
|
|
|
|
|
|
|
|
- let insertText;
|
|
|
|
|
|
|
+ let insertText: string;
|
|
|
|
|
|
|
|
- if (selection?.startsWith(prefix) && selection?.endsWith(suffix)) {
|
|
|
|
|
- const result = removeSymbol(selection, prefix, suffix);
|
|
|
|
|
- insertText = view?.state.replaceSelection(result);
|
|
|
|
|
|
|
+ if (selectedText?.startsWith(prefix) && selectedText?.endsWith(suffix)) {
|
|
|
|
|
+ insertText = removeSymbol(selectedText, prefix, suffix);
|
|
|
}
|
|
}
|
|
|
else {
|
|
else {
|
|
|
- insertText = view?.state.replaceSelection(prefix + selection + suffix);
|
|
|
|
|
|
|
+ insertText = prefix + selectedText + suffix;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- if (insertText == null || cursorPos == null) {
|
|
|
|
|
|
|
+ const selection = (from === to) ? { anchor: from + prefix.length } : { anchor: from, head: from + insertText.length };
|
|
|
|
|
+
|
|
|
|
|
+ const transaction = view?.state.replaceSelection(insertText);
|
|
|
|
|
+
|
|
|
|
|
+ if (transaction == null || cursorPos == null) {
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
- view?.dispatch(insertText);
|
|
|
|
|
- view?.dispatch({ selection: { anchor: cursorPos + prefix.length } });
|
|
|
|
|
|
|
+ view?.dispatch(transaction);
|
|
|
|
|
+ view?.dispatch({ selection });
|
|
|
view?.focus();
|
|
view?.focus();
|
|
|
}, [view]);
|
|
}, [view]);
|
|
|
};
|
|
};
|