Merge pull request #20903 from overleaf/mj-load-write-and-cite-with-autocomplete

[web] Load Write and Cite with AutoComplete

GitOrigin-RevId: b496874447b00723410df01a96ea66aa8ec4da3c
This commit is contained in:
Mathias Jakobsen 2024-10-08 13:18:49 +01:00 committed by Copybot
parent 16d3d59bc1
commit 58b52db56d
4 changed files with 42 additions and 9 deletions

View file

@ -962,6 +962,7 @@ module.exports = {
usGovBanner: [], usGovBanner: [],
offlineModeToolbarButtons: [], offlineModeToolbarButtons: [],
settingsEntries: [], settingsEntries: [],
autoCompleteExtensions: [],
}, },
moduleImportSequence: [ moduleImportSequence: [

View file

@ -7,20 +7,40 @@ import {
Completion, Completion,
} from '@codemirror/autocomplete' } from '@codemirror/autocomplete'
import { EditorView, keymap } from '@codemirror/view' import { EditorView, keymap } from '@codemirror/view'
import { Compartment, Prec, TransactionSpec } from '@codemirror/state' import {
Compartment,
Extension,
Prec,
TransactionSpec,
} from '@codemirror/state'
import importOverleafModules from '../../../../macros/import-overleaf-module.macro'
const moduleExtensions: Array<(options: Record<string, any>) => Extension> =
importOverleafModules('autoCompleteExtensions').map(
(item: { import: { extension: Extension } }) => item.import.extension
)
const autoCompleteConf = new Compartment() const autoCompleteConf = new Compartment()
export const autoComplete = ({ autoComplete }: { autoComplete: boolean }) => type AutoCompleteOptions = {
autoCompleteConf.of(createAutoComplete(autoComplete)) enabled: boolean
} & Record<string, any>
export const setAutoComplete = (autoComplete: boolean): TransactionSpec => { export const autoComplete = ({ enabled, ...rest }: AutoCompleteOptions) =>
autoCompleteConf.of(createAutoComplete({ enabled, ...rest }))
export const setAutoComplete = ({
enabled,
...rest
}: AutoCompleteOptions): TransactionSpec => {
return { return {
effects: autoCompleteConf.reconfigure(createAutoComplete(autoComplete)), effects: autoCompleteConf.reconfigure(
createAutoComplete({ enabled, ...rest })
),
} }
} }
const createAutoComplete = (enabled: boolean) => { const createAutoComplete = ({ enabled, ...rest }: AutoCompleteOptions) => {
if (!enabled) { if (!enabled) {
return [] return []
} }
@ -79,6 +99,7 @@ const createAutoComplete = (enabled: boolean) => {
]) ])
), ),
], ],
moduleExtensions.map(extension => extension({ ...rest })),
] ]
} }

View file

@ -102,7 +102,10 @@ export const createExtensions = (options: Record<string, any>): Extension[] => [
// NOTE: `autoComplete` needs to be before `keybindings` so that arrow key handling // NOTE: `autoComplete` needs to be before `keybindings` so that arrow key handling
// in the autocomplete pop-up takes precedence over Vim/Emacs key bindings // in the autocomplete pop-up takes precedence over Vim/Emacs key bindings
autoComplete(options.settings), autoComplete({
enabled: options.settings.autoComplete,
projectFeatures: options.projectFeatures,
}),
// NOTE: `keybindings` needs to be before `language` so that Vim/Emacs bindings take // NOTE: `keybindings` needs to be before `language` so that Vim/Emacs bindings take
// precedence over language-specific keyboard shortcuts // precedence over language-specific keyboard shortcuts

View file

@ -111,7 +111,10 @@ function useCodeMirrorScope(view: EditorView) {
const [spellCheckLanguage] = useScopeValue<string>( const [spellCheckLanguage] = useScopeValue<string>(
'project.spellCheckLanguage' 'project.spellCheckLanguage'
) )
const [projectFeatures] = useScopeValue<boolean>('project.features') const [projectFeatures] =
useScopeValue<Record<string, boolean | string | number | undefined>>(
'project.features'
)
const hunspellManager = useHunspell(spellCheckLanguage) const hunspellManager = useHunspell(spellCheckLanguage)
@ -408,7 +411,12 @@ function useCodeMirrorScope(view: EditorView) {
useEffect(() => { useEffect(() => {
settingsRef.current.autoComplete = autoComplete settingsRef.current.autoComplete = autoComplete
view.dispatch(setAutoComplete(autoComplete)) view.dispatch(
setAutoComplete({
enabled: autoComplete,
projectFeatures: projectFeaturesRef.current,
})
)
}, [view, autoComplete]) }, [view, autoComplete])
useEffect(() => { useEffect(() => {