Explorar o código

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

[web] Load Write and Cite with AutoComplete

GitOrigin-RevId: b496874447b00723410df01a96ea66aa8ec4da3c
Mathias Jakobsen hai 1 ano
pai
achega
58b52db56d

+ 1 - 0
services/web/config/settings.defaults.js

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

+ 27 - 6
services/web/frontend/js/features/source-editor/extensions/auto-complete.ts

@@ -7,20 +7,40 @@ import {
   Completion,
 } from '@codemirror/autocomplete'
 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()
 
-export const autoComplete = ({ autoComplete }: { autoComplete: boolean }) =>
-  autoCompleteConf.of(createAutoComplete(autoComplete))
+type AutoCompleteOptions = {
+  enabled: boolean
+} & Record<string, any>
+
+export const autoComplete = ({ enabled, ...rest }: AutoCompleteOptions) =>
+  autoCompleteConf.of(createAutoComplete({ enabled, ...rest }))
 
-export const setAutoComplete = (autoComplete: boolean): TransactionSpec => {
+export const setAutoComplete = ({
+  enabled,
+  ...rest
+}: AutoCompleteOptions): TransactionSpec => {
   return {
-    effects: autoCompleteConf.reconfigure(createAutoComplete(autoComplete)),
+    effects: autoCompleteConf.reconfigure(
+      createAutoComplete({ enabled, ...rest })
+    ),
   }
 }
 
-const createAutoComplete = (enabled: boolean) => {
+const createAutoComplete = ({ enabled, ...rest }: AutoCompleteOptions) => {
   if (!enabled) {
     return []
   }
@@ -79,6 +99,7 @@ const createAutoComplete = (enabled: boolean) => {
         ])
       ),
     ],
+    moduleExtensions.map(extension => extension({ ...rest })),
   ]
 }
 

+ 4 - 1
services/web/frontend/js/features/source-editor/extensions/index.ts

@@ -102,7 +102,10 @@ export const createExtensions = (options: Record<string, any>): Extension[] => [
 
   // NOTE: `autoComplete` needs to be before `keybindings` so that arrow key handling
   // 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
   // precedence over language-specific keyboard shortcuts

+ 10 - 2
services/web/frontend/js/features/source-editor/hooks/use-codemirror-scope.ts

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