@@ -30,7 +30,7 @@ import {
3030 adaptedHighlightSpecialChars ,
3131 adaptedLineNumbers ,
3232 adaptedLintGutter ,
33- adaptedPlaceholder ,
33+ adaptedPlaceholder , compartment ,
3434} from "./tests/codemirrorTestHelper" ;
3535import { ExtensionCreator } from "./types" ;
3636
@@ -226,7 +226,19 @@ export const CodeEditor = ({
226226 const currentReadOnly = React . useRef ( readOnly )
227227 currentReadOnly . current = readOnly
228228 const [ showPreview , setShowPreview ] = React . useState < boolean > ( false ) ;
229- const readOnlyCompartment = React . useRef < Compartment > ( new Compartment ( ) )
229+ // CodeMirror Compartments in order to allow for re-configuration after initialization
230+ const readOnlyCompartment = React . useRef < Compartment > ( compartment ( ) )
231+ const wrapLinesCompartment = React . useRef < Compartment > ( compartment ( ) )
232+ const preventLineNumbersCompartment = React . useRef < Compartment > ( compartment ( ) )
233+ const shouldHaveMinimalSetupCompartment = React . useRef < Compartment > ( compartment ( ) )
234+ const placeholderCompartment = React . useRef < Compartment > ( compartment ( ) )
235+ const modeCompartment = React . useRef < Compartment > ( compartment ( ) )
236+ const keyMapConfigsCompartment = React . useRef < Compartment > ( compartment ( ) )
237+ const tabIntentSizeCompartment = React . useRef < Compartment > ( compartment ( ) )
238+ const disabledCompartment = React . useRef < Compartment > ( compartment ( ) )
239+ const supportCodeFoldingCompartment = React . useRef < Compartment > ( compartment ( ) )
240+ const useLintingCompartment = React . useRef < Compartment > ( compartment ( ) )
241+ const shouldHighlightActiveLineCompartment = React . useRef < Compartment > ( compartment ( ) )
230242
231243 const linters = useMemo ( ( ) => {
232244 if ( ! mode ) {
@@ -270,14 +282,17 @@ export const CodeEditor = ({
270282 return false ;
271283 } ;
272284
273- React . useEffect ( ( ) => {
285+ const createKeyMapConfigs = ( ) => {
274286 const tabIndent =
275287 ! ! ( tabIntentStyle === "tab" && mode && ! ( tabForceSpaceForModes ?? [ ] ) . includes ( mode ) ) || enableTab ;
276- const keyMapConfigs = [
288+ return [
277289 defaultKeymap as KeyBinding ,
278290 ...addToKeyMapConfigFor ( supportCodeFolding , foldKeymap ) ,
279291 ...addToKeyMapConfigFor ( tabIndent , indentWithTab ) ,
280292 ] ;
293+ }
294+
295+ React . useEffect ( ( ) => {
281296 const domEventHandlers = {
282297 ...addHandlersFor ( ! ! onScroll , "scroll" , onScroll ) ,
283298 ...addHandlersFor (
@@ -291,13 +306,13 @@ export const CodeEditor = ({
291306 } as DOMEventHandlers < any > ;
292307 const extensions = [
293308 markField ,
294- adaptedPlaceholder ( placeholder ) ,
309+ placeholderCompartment . current . of ( adaptedPlaceholder ( placeholder ) ) ,
295310 adaptedHighlightSpecialChars ( ) ,
296- useCodeMirrorModeExtension ( mode ) ,
297- keymap ?. of ( keyMapConfigs ) ,
298- EditorState ?. tabSize . of ( tabIntentSize ) ,
311+ modeCompartment . current . of ( useCodeMirrorModeExtension ( mode ) ) ,
312+ keyMapConfigsCompartment . current . of ( keymap ?. of ( createKeyMapConfigs ( ) ) ) ,
313+ tabIntentSizeCompartment . current . of ( EditorState ?. tabSize . of ( tabIntentSize ) ) ,
299314 readOnlyCompartment . current . of ( EditorState ?. readOnly . of ( readOnly ) ) ,
300- EditorView ?. editable . of ( ! disabled ) ,
315+ disabledCompartment . current . of ( EditorView ?. editable . of ( ! disabled ) ) ,
301316 AdaptedEditorViewDomEventHandlers ( domEventHandlers ) as Extension ,
302317 EditorView ?. updateListener . of ( ( v : ViewUpdate ) => {
303318 if ( disabled ) return ;
@@ -333,12 +348,12 @@ export const CodeEditor = ({
333348 }
334349 }
335350 } ) ,
336- addExtensionsFor ( shouldHaveMinimalSetup , minimalSetup ) ,
337- addExtensionsFor ( ! preventLineNumbers , adaptedLineNumbers ( ) ) ,
338- addExtensionsFor ( shouldHighlightActiveLine , adaptedHighlightActiveLine ( ) ) ,
339- addExtensionsFor ( wrapLines , EditorView ?. lineWrapping ) ,
340- addExtensionsFor ( supportCodeFolding , adaptedFoldGutter ( ) , adaptedCodeFolding ( ) ) ,
341- addExtensionsFor ( useLinting , ...linters ) ,
351+ shouldHaveMinimalSetupCompartment . current . of ( addExtensionsFor ( shouldHaveMinimalSetup , minimalSetup ) ) ,
352+ preventLineNumbersCompartment . current . of ( addExtensionsFor ( ! preventLineNumbers , adaptedLineNumbers ( ) ) ) ,
353+ shouldHighlightActiveLineCompartment . current . of ( addExtensionsFor ( shouldHighlightActiveLine , adaptedHighlightActiveLine ( ) ) ) ,
354+ wrapLinesCompartment . current . of ( addExtensionsFor ( wrapLines , EditorView ?. lineWrapping ) ) ,
355+ supportCodeFoldingCompartment . current . of ( addExtensionsFor ( supportCodeFolding , adaptedFoldGutter ( ) , adaptedCodeFolding ( ) ) ) ,
356+ useLintingCompartment . current . of ( addExtensionsFor ( useLinting , ...linters ) ) ,
342357 additionalExtensions ,
343358 ] ;
344359
@@ -380,16 +395,65 @@ export const CodeEditor = ({
380395 setView ( undefined ) ;
381396 }
382397 } ;
383- } , [ parent . current , mode , preventLineNumbers , wrapLines ] ) ;
398+ } , [ parent . current ] ) ;
399+
400+ // Updates an extension for a specific parameter that has changed after the initialization
401+ const updateExtension = ( extension : Extension | undefined , parameterCompartment : Compartment ) : void => {
402+ if ( extension ) {
403+ currentView . current ?. dispatch ( {
404+ effects : readOnlyCompartment . current . reconfigure ( extension )
405+ } )
406+ }
407+ }
384408
385409 React . useEffect ( ( ) => {
386- const v = EditorState ?. readOnly . of ( readOnly ! )
387-
388- currentView . current ?. dispatch ( {
389- effects : readOnlyCompartment . current . reconfigure ( v )
390- } )
410+ updateExtension ( EditorState ?. readOnly . of ( readOnly ! ) , readOnlyCompartment . current )
391411 } , [ readOnly ] )
392412
413+ React . useEffect ( ( ) => {
414+ updateExtension ( adaptedPlaceholder ( placeholder ) , placeholderCompartment . current )
415+ } , [ placeholder ] )
416+
417+ React . useEffect ( ( ) => {
418+ updateExtension ( useCodeMirrorModeExtension ( mode ) , modeCompartment . current )
419+ } , [ mode ] )
420+
421+ React . useEffect ( ( ) => {
422+ updateExtension ( keymap ?. of ( createKeyMapConfigs ( ) ) , keyMapConfigsCompartment . current )
423+ } , [ supportCodeFolding , mode , tabIntentStyle , ( tabForceSpaceForModes ?? [ ] ) . join ( ", " ) , enableTab ] )
424+
425+ React . useEffect ( ( ) => {
426+ updateExtension ( EditorState ?. tabSize . of ( tabIntentSize ?? 2 ) , tabIntentSizeCompartment . current )
427+ } , [ tabIntentSize ] )
428+
429+ React . useEffect ( ( ) => {
430+ updateExtension ( EditorView ?. editable . of ( ! disabled ) , disabledCompartment . current )
431+ } , [ disabled ] )
432+
433+ React . useEffect ( ( ) => {
434+ updateExtension ( addExtensionsFor ( shouldHaveMinimalSetup ?? true , minimalSetup ) , shouldHaveMinimalSetupCompartment . current )
435+ } , [ shouldHaveMinimalSetup ] )
436+
437+ React . useEffect ( ( ) => {
438+ updateExtension ( addExtensionsFor ( ! preventLineNumbers , adaptedLineNumbers ( ) ) , preventLineNumbersCompartment . current )
439+ } , [ preventLineNumbers ] )
440+
441+ React . useEffect ( ( ) => {
442+ updateExtension ( addExtensionsFor ( shouldHighlightActiveLine ?? false , adaptedHighlightActiveLine ( ) ) , shouldHighlightActiveLineCompartment . current )
443+ } , [ shouldHighlightActiveLine ] )
444+
445+ React . useEffect ( ( ) => {
446+ updateExtension ( addExtensionsFor ( wrapLines ?? false , EditorView ?. lineWrapping ) , wrapLinesCompartment . current )
447+ } , [ wrapLines ] )
448+
449+ React . useEffect ( ( ) => {
450+ updateExtension ( addExtensionsFor ( supportCodeFolding ?? false , adaptedFoldGutter ( ) , adaptedCodeFolding ( ) ) , supportCodeFoldingCompartment . current )
451+ } , [ supportCodeFolding ] )
452+
453+ React . useEffect ( ( ) => {
454+ updateExtension ( addExtensionsFor ( useLinting ?? false , ...linters ) , useLintingCompartment . current )
455+ } , [ mode , useLinting ] )
456+
393457 const hasToolbarSupport = mode && ModeToolbarSupport . indexOf ( mode ) > - 1 && useToolbar ;
394458
395459 const editorToolbar = ( mode ?: SupportedCodeEditorModes ) : JSX . Element => {
0 commit comments