mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-21 20:47:08 -05:00
[cm6] Improve begin environment autocompletion (#12982)
GitOrigin-RevId: 42731e6f2261f7ed9b85523a550c636968698fc3
This commit is contained in:
parent
a248da99c1
commit
ea996582bf
5 changed files with 39 additions and 41 deletions
|
@ -1,9 +1,5 @@
|
|||
import { EditorState, SelectionRange, Text } from '@codemirror/state'
|
||||
import {
|
||||
CloseBracketConfig,
|
||||
completionStatus,
|
||||
prevChar,
|
||||
} from '@codemirror/autocomplete'
|
||||
import { CloseBracketConfig, prevChar } from '@codemirror/autocomplete'
|
||||
|
||||
export const closeBracketConfig: CloseBracketConfig = {
|
||||
brackets: ['$', '$$', '[', '{', '('],
|
||||
|
@ -74,10 +70,6 @@ export const closeBracketConfig: CloseBracketConfig = {
|
|||
// don't auto-close \{
|
||||
return open
|
||||
}
|
||||
// avoid auto-closing curly brackets when autocomplete is open
|
||||
if (completionStatus(state)) {
|
||||
return open
|
||||
}
|
||||
return open + close
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,10 @@ import {
|
|||
} from '@codemirror/autocomplete'
|
||||
import { customEndCompletions } from './completions/environments'
|
||||
import { customCommandCompletions } from './completions/doc-commands'
|
||||
import { customEnvironmentCompletions } from './completions/doc-environments'
|
||||
import {
|
||||
customEnvironmentCompletions,
|
||||
findEnvironmentsInDoc,
|
||||
} from './completions/doc-environments'
|
||||
import { Completions } from './completions/types'
|
||||
import { buildReferenceCompletions } from './completions/references'
|
||||
import { buildPackageCompletions } from './completions/packages'
|
||||
|
@ -406,12 +409,6 @@ export const beginEnvironmentCompletionSource: CompletionSource = context => {
|
|||
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
|
||||
|
@ -419,10 +416,19 @@ export const beginEnvironmentCompletionSource: CompletionSource = context => {
|
|||
|
||||
const name = context.state.sliceDoc(envName.from, envName.to)
|
||||
|
||||
// if not directly after `\begin{…}`, exclude known environments
|
||||
if (context.pos !== envNameGroup.to) {
|
||||
const existingEnvironmentNames = findEnvironmentsInDoc(context)
|
||||
if (existingEnvironmentNames.has(name)) {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
const completion = {
|
||||
label: `\\begin{${name}} …`,
|
||||
apply: applySnippet(snippet(name)),
|
||||
extend: extendOverUnpairedClosingBrace,
|
||||
boost: -99,
|
||||
}
|
||||
|
||||
return {
|
||||
|
|
|
@ -22,7 +22,7 @@ export function customEnvironmentCompletions(context: CompletionContext) {
|
|||
return completions
|
||||
}
|
||||
|
||||
const findEnvironmentsInDoc = (context: CompletionContext) => {
|
||||
export const findEnvironmentsInDoc = (context: CompletionContext) => {
|
||||
const result = new Set<string>()
|
||||
|
||||
const environmentNamesProjection: ProjectionResult<EnvironmentName> =
|
||||
|
|
|
@ -321,10 +321,10 @@ describe('autocomplete', { scrollBehavior: false }, function () {
|
|||
cy.get('.cm-line').eq(28).click().as('line')
|
||||
cy.get('@line').type('\\begin{{}ab')
|
||||
cy.findAllByRole('option').as('options')
|
||||
cy.get('@options').should('have.length', 4)
|
||||
cy.get('@options').should('have.length', 5)
|
||||
|
||||
// ---- The environment being typed should not appear in the list
|
||||
cy.get('@options').contains('\\begin{ab}').should('not.exist')
|
||||
// ---- The environment being typed should appear in the list
|
||||
cy.get('@options').contains('\\begin{ab}').should('exist')
|
||||
|
||||
// ---- A new environment used elsewhere in the doc should appear next
|
||||
cy.get('@options')
|
||||
|
|
|
@ -126,8 +126,8 @@ describe('<CodeMirrorEditor/> in Rich Text mode', function () {
|
|||
function (command) {
|
||||
cy.get('@first-line')
|
||||
.type(`\\${command}{`)
|
||||
.should('have.text', `\\${command}{`)
|
||||
.type('} ') // Should still show braces for empty commands
|
||||
.should('have.text', `{}`)
|
||||
.type('{rightArrow} ')
|
||||
.should('have.text', '{} ')
|
||||
.type('{Backspace}{leftArrow}test text')
|
||||
.should('have.text', '{test text}')
|
||||
|
@ -148,10 +148,8 @@ describe('<CodeMirrorEditor/> in Rich Text mode', function () {
|
|||
]).it('handles \\%s sectioning command', function (command) {
|
||||
cy.get('@first-line')
|
||||
.type(`\\${command}{`)
|
||||
.should('have.text', `\\${command}{`)
|
||||
.type(`}`)
|
||||
.should('have.text', `\\${command}{}`)
|
||||
.type(' ')
|
||||
.type('{rightArrow} ')
|
||||
.should('have.text', `\\${command}{} `)
|
||||
// Press enter before closing brace
|
||||
.type('{Backspace}{leftArrow}title{leftArrow}{Enter}')
|
||||
|
@ -160,24 +158,14 @@ describe('<CodeMirrorEditor/> in Rich Text mode', function () {
|
|||
.should('exist')
|
||||
})
|
||||
|
||||
forEach([
|
||||
'textsc',
|
||||
'texttt',
|
||||
'sout',
|
||||
'emph',
|
||||
['verb', '|', '|'],
|
||||
'url',
|
||||
'caption',
|
||||
]).it(
|
||||
forEach(['textsc', 'texttt', 'sout', 'emph', 'url', 'caption']).it(
|
||||
'handles \\%s text',
|
||||
function (command, openingBrace = '{', closingBrace = '}') {
|
||||
function (command) {
|
||||
cy.get('@first-line')
|
||||
.type(`\\${command}${openingBrace}`)
|
||||
.should('have.text', `\\${command}${openingBrace}`)
|
||||
.type(`${closingBrace}`)
|
||||
.should('have.text', `\\${command}${openingBrace}${closingBrace}`)
|
||||
.type(' ')
|
||||
.should('have.text', `\\${command}${openingBrace}${closingBrace} `)
|
||||
.type(`\\${command}{`)
|
||||
.should('have.text', `\\${command}{}`)
|
||||
.type('{rightArrow} ')
|
||||
.should('have.text', `\\${command}{} `)
|
||||
.type('{Backspace}{leftArrow}test text{rightArrow} ')
|
||||
.should('have.text', 'test text ')
|
||||
.find(`.ol-cm-command-${command}`)
|
||||
|
@ -185,6 +173,18 @@ describe('<CodeMirrorEditor/> in Rich Text mode', function () {
|
|||
}
|
||||
)
|
||||
|
||||
it('handles \\verb text', function () {
|
||||
cy.get('@first-line')
|
||||
.type(`\\verb|`)
|
||||
.should('have.text', `\\verb|`)
|
||||
.type('| ')
|
||||
.should('have.text', `\\verb|| `)
|
||||
.type('{Backspace}{leftArrow}test text{rightArrow} ')
|
||||
.should('have.text', 'test text ')
|
||||
.find(`.ol-cm-command-verb`)
|
||||
.should('exist')
|
||||
})
|
||||
|
||||
forEach([
|
||||
['ref', '🏷'],
|
||||
['label', '🏷'],
|
||||
|
|
Loading…
Reference in a new issue