Przeglądaj źródła

[cm6+rt] Make formatting commands work after UnknownCommands without arguments (#12625)

GitOrigin-RevId: 0eb59e6580d6f217c46424ede0fa6f79c8786940
Mathias Jakobsen 3 lat temu
rodzic
commit
73191f56e1

+ 21 - 5
services/web/frontend/js/features/source-editor/commands/ranges.ts

@@ -212,11 +212,27 @@ function getParentNode(
   assoc: 0 | 1 | -1 = 1
 ): SyntaxNode | undefined {
   const tree = ensureSyntaxTree(state, 1000)
-  let node: SyntaxNode | undefined | null =
-    typeof position === 'number'
-      ? tree?.resolveInner(position, assoc)
-      : position
-  node = node?.parent
+  let node: SyntaxNode | undefined | null = null
+  if (typeof position === 'number') {
+    node = tree?.resolveInner(position, assoc)?.parent
+    // HACK: Spaces after UnknownCommands (and other commands without arguments)
+    // are included in the Command node. So we have to adjust for that here.
+    const preceedingCharacter = state.sliceDoc(
+      Math.max(0, position - 1),
+      position
+    )
+    if (
+      preceedingCharacter === ' ' &&
+      ['UnknownCommand', 'Item', 'Left', 'Right'].some(name =>
+        node?.type.is(name)
+      )
+    ) {
+      node = ancestorOfNodeWithType(node, 'Command')?.parent
+    }
+  } else {
+    node = position?.parent
+  }
+
   while (
     ['LongArg', 'TextArgument', 'OpenBrace', 'CloseBrace'].includes(
       node?.type.name || ''

+ 18 - 0
services/web/test/frontend/features/source-editor/commands/ranges.test.ts

@@ -161,5 +161,23 @@ describe('toggleRanges', function () {
         expect(cm).line(1).to.equal('\\textbf{\\textit{this <is} my} range>')
       })
     })
+
+    describe('when range is after a command', function () {
+      it('still formats list items', function () {
+        const cm = new CodemirrorTestSession([
+          '\\begin{itemize}',
+          '    \\item <My item>',
+          '\\end{itemize}',
+        ])
+        cm.applyCommand(BOLD_COMMAND)
+        expect(cm).line(2).to.equal('    \\item \\textbf{<My item>}')
+      })
+
+      it('still formats after command', function () {
+        const cm = new CodemirrorTestSession(['\\noindent <My paragraph>'])
+        cm.applyCommand(BOLD_COMMAND)
+        expect(cm).line(1).to.equal('\\noindent \\textbf{<My paragraph>}')
+      })
+    })
   })
 })