Sfoglia il codice sorgente

[cm6] Add beginEnvironmentCompletionSource (#12913)

GitOrigin-RevId: eb4582606103268f1f2c90da7d372a0a33926e36
Alf Eaton 3 anni fa
parent
commit
f2f7f6b7d6

+ 57 - 0
services/web/frontend/js/features/source-editor/languages/latex/complete.ts

@@ -20,6 +20,12 @@ import {
   cursorIsAtBeginEnvironment,
   cursorIsAtEndEnvironment,
 } from '../../utils/tree-query'
+import {
+  applySnippet,
+  extendOverUnpairedClosingBrace,
+} from './completions/apply'
+import { snippet } from './completions/data/environments'
+import { syntaxTree } from '@codemirror/language'
 
 function blankCompletions(): Completions {
   return {
@@ -373,3 +379,54 @@ export const inCommandCompletionSource: CompletionSource = ifInType(
 export const explicitCommandCompletionSource: CompletionSource = context => {
   return context.explicit ? commandCompletionSource(context) : null
 }
+
+/**
+ * An additional completion source that handles two situations:
+ *
+ * 1. Typing the environment name within an already-complete `\begin{…}` command.
+ * 2. After typing the closing brace of a complete `\begin{foo}` command, where the environment
+ * isn't previously known, leaving the cursor after the closing brace.
+ */
+export const beginEnvironmentCompletionSource: CompletionSource = context => {
+  const beginEnvToken = context.tokenBefore(['BeginEnv'])
+  if (!beginEnvToken) {
+    return null
+  }
+
+  const beginEnv = syntaxTree(context.state).resolveInner(
+    beginEnvToken.from,
+    1
+  ).parent
+  if (!beginEnv?.type.is('BeginEnv')) {
+    return null
+  }
+
+  const envNameGroup = beginEnv.getChild('EnvNameGroup')
+  if (!envNameGroup) {
+    return null
+  }
+
+  // this completion source must only be active when the \begin command has a closing brace
+  const closeBrace = envNameGroup.getChild('CloseBrace')
+  if (!closeBrace) {
+    return null
+  }
+
+  const envName = envNameGroup.getChild('$EnvName')
+  if (!envName) {
+    return null
+  }
+
+  const name = context.state.sliceDoc(envName.from, envName.to)
+
+  const completion = {
+    label: `\\begin{${name}} …`,
+    apply: applySnippet(snippet(name)),
+    extend: extendOverUnpairedClosingBrace,
+  }
+
+  return {
+    from: beginEnvToken.from,
+    options: [completion],
+  }
+}

+ 2 - 0
services/web/frontend/js/features/source-editor/languages/latex/index.ts

@@ -9,6 +9,7 @@ import {
   argumentCompletionSources,
   explicitCommandCompletionSource,
   inCommandCompletionSource,
+  beginEnvironmentCompletionSource,
 } from './complete'
 import { documentCommands } from './document-commands'
 import importOverleafModules from '../../../../../macros/import-overleaf-module.macro'
@@ -20,6 +21,7 @@ const completionSources: CompletionSource[] = [
   ...argumentCompletionSources,
   inCommandCompletionSource,
   explicitCommandCompletionSource,
+  beginEnvironmentCompletionSource,
   ...importOverleafModules('sourceEditorCompletionSources').map(
     (item: any) => item.import.default
   ),