Просмотр исходного кода

[cm6] Move cursor over existing closing brace when inserting a required parameter (#13494)

* Move cursor over existing closing brace

* Update package-lock.json

* Update tests

GitOrigin-RevId: dd729e41c2174d9f4563f2f47efcc075c7453ced
Alf Eaton 3 лет назад
Родитель
Сommit
adbccde085

+ 6 - 8
package-lock.json

@@ -3280,9 +3280,8 @@
       "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw=="
     },
     "node_modules/@codemirror/autocomplete": {
-      "version": "6.6.1",
-      "resolved": "git+ssh://git@github.com/overleaf/codemirror-autocomplete.git#4514fd21c6c9219f5c23a6a675ad843bb7a5b2bd",
-      "integrity": "sha512-3xD9M0e5cw0XsC7mMfRy+vKcOup7Nno4J3r0aTvwWqsUlQYBzT0R3sBEn6y+gHdpIpuSEx+jKIGKiqBsWI8czg==",
+      "version": "6.8.0",
+      "resolved": "git+ssh://git@github.com/overleaf/codemirror-autocomplete.git#03ea9e4565635c9bc005c9b809713d1897aabc59",
       "license": "MIT",
       "dependencies": {
         "@codemirror/language": "^6.0.0",
@@ -41256,7 +41255,7 @@
         "@babel/preset-env": "^7.21.5",
         "@babel/preset-react": "^7.18.6",
         "@babel/preset-typescript": "^7.21.5",
-        "@codemirror/autocomplete": "github:overleaf/codemirror-autocomplete#4514fd21c6c9219f5c23a6a675ad843bb7a5b2bd",
+        "@codemirror/autocomplete": "github:overleaf/codemirror-autocomplete#v6.8.0-overleaf-1",
         "@codemirror/commands": "^6.2.3",
         "@codemirror/lang-markdown": "^6.1.1",
         "@codemirror/language": "^6.6.0",
@@ -44935,9 +44934,8 @@
       "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw=="
     },
     "@codemirror/autocomplete": {
-      "version": "git+ssh://git@github.com/overleaf/codemirror-autocomplete.git#4514fd21c6c9219f5c23a6a675ad843bb7a5b2bd",
-      "integrity": "sha512-3xD9M0e5cw0XsC7mMfRy+vKcOup7Nno4J3r0aTvwWqsUlQYBzT0R3sBEn6y+gHdpIpuSEx+jKIGKiqBsWI8czg==",
-      "from": "@codemirror/autocomplete@github:overleaf/codemirror-autocomplete#4514fd21c6c9219f5c23a6a675ad843bb7a5b2bd",
+      "version": "git+ssh://git@github.com/overleaf/codemirror-autocomplete.git#03ea9e4565635c9bc005c9b809713d1897aabc59",
+      "from": "@codemirror/autocomplete@github:overleaf/codemirror-autocomplete#v6.8.0-overleaf-1",
       "requires": {
         "@codemirror/language": "^6.0.0",
         "@codemirror/state": "^6.0.0",
@@ -50239,7 +50237,7 @@
         "@babel/preset-react": "^7.18.6",
         "@babel/preset-typescript": "^7.21.5",
         "@babel/register": "^7.21.0",
-        "@codemirror/autocomplete": "github:overleaf/codemirror-autocomplete#4514fd21c6c9219f5c23a6a675ad843bb7a5b2bd",
+        "@codemirror/autocomplete": "github:overleaf/codemirror-autocomplete#v6.8.0-overleaf-1",
         "@codemirror/commands": "^6.2.3",
         "@codemirror/lang-markdown": "^6.1.1",
         "@codemirror/language": "^6.6.0",

+ 6 - 2
services/web/frontend/js/features/source-editor/languages/latex/completions/apply.ts

@@ -57,8 +57,12 @@ export const extendRequiredParameter = (
     argumentNode.getChild('OpenBrace') &&
     argumentNode.getChild('CloseBrace')
 
-  // add a closing brace if needed
-  if (nextChar(state.doc, change.to) !== '}') {
+  if (nextChar(state.doc, change.to) === '}') {
+    // include an existing closing brace, so the cursor moves after it
+    change.insert += '}'
+    change.to++
+  } else {
+    // add a closing brace if needed
     if (countUnclosedBraces(state.doc, change.from, change.to) > 0) {
       change.insert += '}'
     }

+ 1 - 1
services/web/package.json

@@ -71,7 +71,7 @@
     "@babel/preset-env": "^7.21.5",
     "@babel/preset-react": "^7.18.6",
     "@babel/preset-typescript": "^7.21.5",
-    "@codemirror/autocomplete": "github:overleaf/codemirror-autocomplete#4514fd21c6c9219f5c23a6a675ad843bb7a5b2bd",
+    "@codemirror/autocomplete": "github:overleaf/codemirror-autocomplete#v6.8.0-overleaf-1",
     "@codemirror/commands": "^6.2.3",
     "@codemirror/lang-markdown": "^6.1.1",
     "@codemirror/language": "^6.6.0",

+ 9 - 9
services/web/test/frontend/features/source-editor/components/codemirror-editor-autocomplete.spec.tsx

@@ -177,7 +177,7 @@ describe('autocomplete', { scrollBehavior: false }, function () {
     cy.contains('\\includegraphics[width=0.3\\textwidth]{frog.jpg}')
 
     // start a new line and select an "includegraphics" command completion
-    cy.get('@line').type('{rightArrow}{Enter}')
+    cy.get('@line').type('{Enter}')
     activeEditorLine().type('\\includegr')
     cy.contains('\\includegraphics[]{}').click()
 
@@ -191,7 +191,7 @@ describe('autocomplete', { scrollBehavior: false }, function () {
     cy.contains('\\includegraphics[]{test-folder/example.png}')
 
     activeEditorLine()
-      .type(`${'{leftArrow}'.repeat('test-folder/example.png'.length)}fr`)
+      .type(`${'{leftArrow}'.repeat('test-folder/example.png}'.length)}fr`)
       .type('{ctrl+ }')
 
     cy.findAllByRole('listbox').should('have.length', 1)
@@ -492,7 +492,7 @@ describe('autocomplete', { scrollBehavior: false }, function () {
     cy.get('@line').contains('\\cite{ref-2}')
 
     // start typing another reference
-    cy.get('@line').type(', re')
+    cy.get('@line').type('{leftArrow}, re')
 
     // autocomplete open again
     cy.findAllByRole('listbox').contains('ref-3').click()
@@ -1031,37 +1031,37 @@ describe('autocomplete', { scrollBehavior: false }, function () {
     activeEditorLine().type('\\include{s', { delay: 100 })
     cy.findAllByRole('option').contains('sometext.txt').click()
     activeEditorLine().should('have.text', '\\include{sometext.txt}')
-    activeEditorLine().type('{rightArrow}{Enter}')
+    activeEditorLine().type('{Enter}')
 
     activeEditorLine().type('\\inclu', { delay: 100 })
     cy.contains('\\include{}').click()
     cy.contains('example.tex').click()
     activeEditorLine().should('have.text', '\\include{example}')
-    activeEditorLine().type('{rightArrow}{Enter}')
+    activeEditorLine().type('{Enter}')
 
     activeEditorLine().type('\\inclu', { delay: 100 })
     cy.findAllByRole('option').contains('\\include{}').click()
     cy.findAllByRole('option').contains('sometext.txt').click()
     activeEditorLine().should('have.text', '\\include{sometext.txt}')
-    activeEditorLine().type('{rightArrow}{Enter}')
+    activeEditorLine().type('{Enter}')
 
     activeEditorLine().click().as('line')
     activeEditorLine().type('\\input{e', { delay: 100 })
     cy.findAllByRole('option').contains('example.tex').click()
     activeEditorLine().should('have.text', '\\input{example}')
-    activeEditorLine().type('{rightArrow}{Enter}')
+    activeEditorLine().type('{Enter}')
 
     activeEditorLine().click().as('line')
     activeEditorLine().type('\\input{s', { delay: 100 })
     cy.findAllByRole('option').contains('sometext.txt').click()
     activeEditorLine().should('have.text', '\\input{sometext.txt}')
-    activeEditorLine().type('{rightArrow}{Enter}')
+    activeEditorLine().type('{Enter}')
 
     activeEditorLine().type('\\inpu', { delay: 100 })
     cy.findAllByRole('option').contains('\\input{}').click()
     cy.findAllByRole('option').contains('example.tex').click()
     activeEditorLine().should('have.text', '\\input{example}')
-    activeEditorLine().type('{rightArrow}{Enter}')
+    activeEditorLine().type('{Enter}')
 
     activeEditorLine().type('\\inpu', { delay: 100 })
     cy.findAllByRole('option').contains('\\input{}').click()