Desktop: Fixes #14584: Fix changes to editor settings not applied until editor reloads (#14586)

This commit is contained in:
Henry Heino
2026-03-08 14:11:54 -07:00
committed by GitHub
parent fd3b133b16
commit 5fd0dc23da
4 changed files with 90 additions and 45 deletions

View File

@@ -271,6 +271,7 @@ packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v6/Editor.js
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v6/useEditorCommands.js
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v6/utils/localisation.js
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v6/utils/useContentScriptRegistration.js
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v6/utils/useEditorSettings.js
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v6/utils/useKeymap.js
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v6/utils/useRefocusOnVisiblePaneChange.js
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v6/utils/useSyncEditorValue.js

1
.gitignore vendored
View File

@@ -244,6 +244,7 @@ packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v6/Editor.js
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v6/useEditorCommands.js
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v6/utils/localisation.js
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v6/utils/useContentScriptRegistration.js
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v6/utils/useEditorSettings.js
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v6/utils/useKeymap.js
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v6/utils/useRefocusOnVisiblePaneChange.js
packages/app-desktop/gui/NoteEditor/NoteBody/CodeMirror/v6/utils/useSyncEditorValue.js

View File

@@ -1,5 +1,5 @@
import * as React from 'react';
import { useState, useEffect, useRef, forwardRef, useCallback, useImperativeHandle, useMemo, ForwardedRef, useContext } from 'react';
import { useState, useEffect, useRef, forwardRef, useCallback, useImperativeHandle, ForwardedRef, useContext } from 'react';
import { EditorCommand, MarkupToHtmlOptions, NoteBodyEditorProps, NoteBodyEditorRef, OnChangeEvent } from '../../../utils/types';
import { getResourcesFromPasteEvent } from '../../../utils/resourceHandling';
@@ -12,11 +12,10 @@ import Note from '@joplin/lib/models/Note';
import { _ } from '@joplin/lib/locale';
import bridge from '../../../../../services/bridge';
import shim from '@joplin/lib/shim';
import { MarkupToHtml } from '@joplin/renderer';
import { clipboard } from 'electron';
import { reg } from '@joplin/lib/registry';
import ErrorBoundary from '../../../../ErrorBoundary';
import { EditorKeymap, EditorLanguageType, EditorSettings, SearchState, UserEventSource } from '@joplin/editor/types';
import { SearchState, UserEventSource } from '@joplin/editor/types';
import useStyles from '../utils/useStyles';
import { EditorEvent, EditorEventType } from '@joplin/editor/events';
import useScrollHandler from '../utils/useScrollHandler';
@@ -33,6 +32,7 @@ import { WindowIdContext } from '../../../../NewWindowOrIFrame';
import eventManager, { EventName, ResourceChangeEvent } from '@joplin/lib/eventManager';
import useSyncEditorValue from './utils/useSyncEditorValue';
import { getGlobalSettings } from '@joplin/renderer/types';
import useEditorSettings from './utils/useEditorSettings';
const logger = Logger.create('CodeMirror6');
const logDebug = (message: string) => logger.debug(message);
@@ -338,47 +338,6 @@ const CodeMirror = (props: NoteBodyEditorProps, ref: ForwardedRef<NoteBodyEditor
void CommandService.instance().execute('focusElement', 'noteTitle');
}, []);
const editorSettings = useMemo((): EditorSettings => {
const isHTMLNote = props.contentMarkupLanguage === MarkupToHtml.MARKUP_LANGUAGE_HTML;
let keyboardMode = EditorKeymap.Default;
if (props.keyboardMode === 'vim') {
keyboardMode = EditorKeymap.Vim;
} else if (props.keyboardMode === 'emacs') {
keyboardMode = EditorKeymap.Emacs;
}
return {
language: isHTMLNote ? EditorLanguageType.Html : EditorLanguageType.Markdown,
readOnly: props.disabled,
markdownMarkEnabled: Setting.value('markdown.plugin.mark'),
markdownInsertEnabled: Setting.value('markdown.plugin.insert'),
katexEnabled: Setting.value('markdown.plugin.katex'),
inlineRenderingEnabled: Setting.value('editor.inlineRendering'),
imageRenderingEnabled: Setting.value('editor.imageRendering'),
highlightActiveLine: Setting.value('editor.highlightActiveLine'),
themeData: {
...styles.globalTheme,
marginLeft: 0,
marginRight: 0,
monospaceFont: Setting.value('style.editor.monospaceFontFamily'),
},
automatchBraces: Setting.value('editor.autoMatchingBraces'),
autocompleteMarkup: Setting.value('editor.autocompleteMarkup'),
useExternalSearch: false,
ignoreModifiers: true,
spellcheckEnabled: Setting.value('editor.spellcheckBeta'),
keymap: keyboardMode,
preferMacShortcuts: shim.isMac(),
indentWithTabs: true,
tabMovesFocus: props.tabMovesFocus,
editorLabel: _('Markdown editor'),
};
}, [
props.contentMarkupLanguage, props.disabled, props.keyboardMode, styles.globalTheme,
props.tabMovesFocus,
]);
const initialCursorLocationRef = useRef(0);
initialCursorLocationRef.current = props.initialCursorLocation.markdown ?? 0;
@@ -391,6 +350,14 @@ const CodeMirror = (props: NoteBodyEditorProps, ref: ForwardedRef<NoteBodyEditor
initialCursorLocationRef,
});
const settings = useEditorSettings({
baseTheme: styles.globalTheme,
contentMarkupLanguage: props.contentMarkupLanguage,
disabled: props.disabled,
keyboardMode: props.keyboardMode,
tabMovesFocus: props.tabMovesFocus,
});
const renderEditor = () => {
return (
<div className='editor'>
@@ -400,7 +367,7 @@ const CodeMirror = (props: NoteBodyEditorProps, ref: ForwardedRef<NoteBodyEditor
initialSelectionRef={initialCursorLocationRef}
initialNoteId={props.noteId}
ref={editorRef}
settings={editorSettings}
settings={settings}
pluginStates={props.plugins}
onPasteFile={null}
onEvent={onEditorEvent}

View File

@@ -0,0 +1,76 @@
import { EditorKeymap, EditorLanguageType, EditorSettings, EditorTheme } from '@joplin/editor/types';
import shim from '@joplin/lib/shim';
import { MarkupLanguage, MarkupToHtml } from '@joplin/renderer';
import { useMemo } from 'react';
import { useSelector } from 'react-redux';
import { AppState } from '../../../../../../app.reducer';
import { _ } from '@joplin/lib/locale';
import { isDeepStrictEqual } from 'node:util';
interface EditorSettingsProps {
contentMarkupLanguage: MarkupLanguage;
keyboardMode: string;
disabled: boolean;
tabMovesFocus: boolean;
baseTheme: EditorTheme;
}
const useEditorSettings = (props: EditorSettingsProps) => {
const stateToSettings = (state: AppState) => ({
markdownMark: state.settings['markdown.plugin.mark'],
markdownInsert: state.settings['markdown.plugin.insert'],
katex: state.settings['markdown.plugin.katex'],
inlineRendering: state.settings['editor.inlineRendering'],
imageRendering: state.settings['editor.imageRendering'],
highlightActiveLine: state.settings['editor.highlightActiveLine'],
monospaceFont: state.settings['style.editor.monospaceFontFamily'],
automatchBraces: state.settings['editor.autoMatchingBraces'],
autocompleteMarkup: state.settings['editor.autocompleteMarkup'],
spellcheckEnabled: state.settings['editor.spellcheckBeta'],
});
type SelectedSettings = ReturnType<typeof stateToSettings>;
const settings = useSelector<AppState, SelectedSettings>(stateToSettings, isDeepStrictEqual);
return useMemo((): EditorSettings => {
const isHTMLNote = props.contentMarkupLanguage === MarkupToHtml.MARKUP_LANGUAGE_HTML;
let keyboardMode = EditorKeymap.Default;
if (props.keyboardMode === 'vim') {
keyboardMode = EditorKeymap.Vim;
} else if (props.keyboardMode === 'emacs') {
keyboardMode = EditorKeymap.Emacs;
}
return {
language: isHTMLNote ? EditorLanguageType.Html : EditorLanguageType.Markdown,
readOnly: props.disabled,
markdownMarkEnabled: settings.markdownMark,
markdownInsertEnabled: settings.markdownInsert,
katexEnabled: settings.katex,
inlineRenderingEnabled: settings.inlineRendering,
imageRenderingEnabled: settings.imageRendering,
highlightActiveLine: settings.highlightActiveLine,
themeData: {
...props.baseTheme,
marginLeft: 0,
marginRight: 0,
monospaceFont: settings.monospaceFont,
},
automatchBraces: settings.automatchBraces,
autocompleteMarkup: settings.autocompleteMarkup,
useExternalSearch: false,
ignoreModifiers: true,
spellcheckEnabled: settings.spellcheckEnabled,
keymap: keyboardMode,
preferMacShortcuts: shim.isMac(),
indentWithTabs: true,
tabMovesFocus: props.tabMovesFocus,
editorLabel: _('Markdown editor'),
};
}, [
props.contentMarkupLanguage, props.disabled, props.keyboardMode, props.baseTheme,
props.tabMovesFocus, settings,
]);
};
export default useEditorSettings;