|
1 | 1 | import React, { useMemo, useRef } from "react"; |
2 | | -import { defaultKeymap, indentWithTab } from "@codemirror/commands"; |
| 2 | +import { defaultKeymap, history, historyKeymap, indentWithTab } from "@codemirror/commands"; |
3 | 3 | import { defaultHighlightStyle, foldKeymap } from "@codemirror/language"; |
4 | 4 | import { Compartment, EditorState, Extension } from "@codemirror/state"; |
5 | 5 | import { DOMEventHandlers, EditorView, KeyBinding, keymap, Rect, ViewUpdate } from "@codemirror/view"; |
@@ -141,7 +141,8 @@ export interface CodeEditorProps |
141 | 141 | */ |
142 | 142 | additionalExtensions?: Extension[]; |
143 | 143 | /** |
144 | | - * codemirror minimal setup flag |
| 144 | + * CodeMirror minimal setup flag. If disabled, the rest of CodeMirror's minimal setup stays off, |
| 145 | + * but editor history remains enabled explicitly. |
145 | 146 | */ |
146 | 147 | shouldHaveMinimalSetup?: boolean; |
147 | 148 | /** |
@@ -265,6 +266,7 @@ export const CodeEditor = ({ |
265 | 266 | const wrapLinesCompartment = React.useRef<Compartment>(compartment()); |
266 | 267 | const preventLineNumbersCompartment = React.useRef<Compartment>(compartment()); |
267 | 268 | const shouldHaveMinimalSetupCompartment = React.useRef<Compartment>(compartment()); |
| 269 | + const historyCompartment = React.useRef<Compartment>(compartment()); |
268 | 270 | const placeholderCompartment = React.useRef<Compartment>(compartment()); |
269 | 271 | const modeCompartment = React.useRef<Compartment>(compartment()); |
270 | 272 | const keyMapConfigsCompartment = React.useRef<Compartment>(compartment()); |
@@ -319,6 +321,7 @@ export const CodeEditor = ({ |
319 | 321 | !!(tabIntentStyle === "tab" && mode && !(tabForceSpaceForModes ?? []).includes(mode)) || enableTab; |
320 | 322 | return [ |
321 | 323 | defaultKeymap as KeyBinding, |
| 324 | + ...addToKeyMapConfigFor(!shouldHaveMinimalSetup, ...historyKeymap), |
322 | 325 | ...addToKeyMapConfigFor(supportCodeFolding, ...foldKeymap), |
323 | 326 | ...addToKeyMapConfigFor(tabIndent, indentWithTab), |
324 | 327 | ]; |
@@ -354,6 +357,7 @@ export const CodeEditor = ({ |
354 | 357 | ...addHandlersFor(!!onKeyDown, "keydown", onKeyDownHandler), |
355 | 358 | } as DOMEventHandlers<any>; |
356 | 359 | const extensions = [ |
| 360 | + historyCompartment.current.of(addExtensionsFor(!shouldHaveMinimalSetup, history())), |
357 | 361 | markField, |
358 | 362 | placeholderCompartment.current.of(adaptedPlaceholder(placeholder)), |
359 | 363 | adaptedHighlightSpecialChars(), |
@@ -478,7 +482,7 @@ export const CodeEditor = ({ |
478 | 482 |
|
479 | 483 | React.useEffect(() => { |
480 | 484 | updateExtension(keymap?.of(createKeyMapConfigs()), keyMapConfigsCompartment.current); |
481 | | - }, [supportCodeFolding, mode, tabIntentStyle, (tabForceSpaceForModes ?? []).join(", "), enableTab]); |
| 485 | + }, [supportCodeFolding, mode, tabIntentStyle, (tabForceSpaceForModes ?? []).join(", "), enableTab, shouldHaveMinimalSetup]); |
482 | 486 |
|
483 | 487 | React.useEffect(() => { |
484 | 488 | updateExtension(EditorState?.tabSize.of(tabIntentSize ?? 2), tabIntentSizeCompartment.current); |
@@ -526,6 +530,7 @@ export const CodeEditor = ({ |
526 | 530 | addExtensionsFor(shouldHaveMinimalSetup ?? true, minimalSetup), |
527 | 531 | shouldHaveMinimalSetupCompartment.current, |
528 | 532 | ); |
| 533 | + updateExtension(addExtensionsFor(!shouldHaveMinimalSetup, history()), historyCompartment.current); |
529 | 534 | }, [shouldHaveMinimalSetup]); |
530 | 535 |
|
531 | 536 | React.useEffect(() => { |
|
0 commit comments