From 73191f56e1833494896a62417a4a662bb4451c4f Mon Sep 17 00:00:00 2001 From: Mathias Jakobsen Date: Fri, 14 Apr 2023 09:58:37 +0100 Subject: [PATCH] [cm6+rt] Make formatting commands work after UnknownCommands without arguments (#12625) GitOrigin-RevId: 0eb59e6580d6f217c46424ede0fa6f79c8786940 --- .../features/source-editor/commands/ranges.ts | 26 +++++++++++++++---- .../source-editor/commands/ranges.test.ts | 18 +++++++++++++ 2 files changed, 39 insertions(+), 5 deletions(-) diff --git a/services/web/frontend/js/features/source-editor/commands/ranges.ts b/services/web/frontend/js/features/source-editor/commands/ranges.ts index bc2f354579..5c5318c017 100644 --- a/services/web/frontend/js/features/source-editor/commands/ranges.ts +++ b/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 || '' diff --git a/services/web/test/frontend/features/source-editor/commands/ranges.test.ts b/services/web/test/frontend/features/source-editor/commands/ranges.test.ts index 88029a1b83..9a847e7a99 100644 --- a/services/web/test/frontend/features/source-editor/commands/ranges.test.ts +++ b/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 ') }) }) + + describe('when range is after a command', function () { + it('still formats list items', function () { + const cm = new CodemirrorTestSession([ + '\\begin{itemize}', + ' \\item ', + '\\end{itemize}', + ]) + cm.applyCommand(BOLD_COMMAND) + expect(cm).line(2).to.equal(' \\item \\textbf{}') + }) + + it('still formats after command', function () { + const cm = new CodemirrorTestSession(['\\noindent ']) + cm.applyCommand(BOLD_COMMAND) + expect(cm).line(1).to.equal('\\noindent \\textbf{}') + }) + }) }) })