more codemirror enhancements (#2912)

Signed-off-by: Jess Frazelle <github@jessfraz.com>
This commit is contained in:
Jess Frazelle
2024-07-03 22:06:52 -07:00
committed by GitHub
parent 7cec1d45fe
commit 08e9fe2e52
5 changed files with 113 additions and 116 deletions

View File

@ -1455,8 +1455,6 @@ test.describe('Can create sketches on all planes and their back sides', () => {
}) })
test.describe('Copilot ghost text', () => { test.describe('Copilot ghost text', () => {
test.skip(true, 'temporarily disabled')
test('completes code in empty file', async ({ page }) => { test('completes code in empty file', async ({ page }) => {
const u = await getUtils(page) const u = await getUtils(page)
// const PUR = 400 / 37.5 //pixeltoUnitRatio // const PUR = 400 / 37.5 //pixeltoUnitRatio
@ -3715,9 +3713,7 @@ test.describe('Regression tests', () => {
// Make sure it's not a link // Make sure it's not a link
await expect(zooLogo).not.toHaveAttribute('href') await expect(zooLogo).not.toHaveAttribute('href')
}) })
test.fixme( test('Position _ Is Out Of Range... regression test', async ({ page }) => {
'Position _ Is Out Of Range... regression test',
async ({ page }) => {
const u = await getUtils(page) const u = await getUtils(page)
// const PUR = 400 / 37.5 //pixeltoUnitRatio // const PUR = 400 / 37.5 //pixeltoUnitRatio
await page.setViewportSize({ width: 1200, height: 500 }) await page.setViewportSize({ width: 1200, height: 500 })
@ -3757,6 +3753,7 @@ test.describe('Regression tests', () => {
await page.keyboard.press('ArrowUp') await page.keyboard.press('ArrowUp')
await page.keyboard.press('ArrowUp') await page.keyboard.press('ArrowUp')
await page.keyboard.press('ArrowUp') await page.keyboard.press('ArrowUp')
await page.keyboard.press('ArrowUp')
await page.keyboard.up('Shift') await page.keyboard.up('Shift')
await page.keyboard.press('Backspace') await page.keyboard.press('Backspace')
await expect(page.locator('.cm-lint-marker-error')).not.toBeVisible() await expect(page.locator('.cm-lint-marker-error')).not.toBeVisible()
@ -3767,17 +3764,16 @@ test.describe('Regression tests', () => {
await page.keyboard.press('Enter') await page.keyboard.press('Enter')
await expect(page.locator('.cm-content')) await expect(page.locator('.cm-content'))
.toHaveText(`const exampleSketch = startSketchOn("XZ") .toContainText(`const exampleSketch = startSketchOn("XZ")
|> startProfileAt([0, 0], %) |> startProfileAt([0, 0], %)
|> angledLine({ angle: 50, length: 45 }, %) |> angledLine({ angle: 50, length: 45 }, %)
|> yLineTo(0, %) |> yLineTo(0, %)
|> close(%) |> close(%
thing: "blah"`) thing: "blah"`)
await expect(page.locator('.cm-lint-marker-error')).toBeVisible() await expect(page.locator('.cm-lint-marker-error')).toBeVisible()
} })
)
}) })
test.describe('Sketch tests', () => { test.describe('Sketch tests', () => {

View File

@ -1,10 +1,7 @@
import { autocompletion } from '@codemirror/autocomplete' import { foldService } from '@codemirror/language'
import { foldService, syntaxTree } from '@codemirror/language'
import { Extension, EditorState } from '@codemirror/state' import { Extension, EditorState } from '@codemirror/state'
import { ViewPlugin } from '@codemirror/view' import { ViewPlugin } from '@codemirror/view'
import { CompletionTriggerKind } from 'vscode-languageserver-protocol'
import { import {
docPathFacet, docPathFacet,
LanguageServerPlugin, LanguageServerPlugin,
@ -13,7 +10,6 @@ import {
workspaceFolders, workspaceFolders,
LanguageServerOptions, LanguageServerOptions,
} from './plugin/lsp' } from './plugin/lsp'
import { offsetToPos } from './plugin/util'
export type { LanguageServerClientOptions } from './client' export type { LanguageServerClientOptions } from './client'
export { LanguageServerClient } from './client' export { LanguageServerClient } from './client'
@ -57,59 +53,5 @@ export function lspPlugin(options: LanguageServerOptions): Extension {
}), }),
] ]
if (options.client.getServerCapabilities().completionProvider) {
ext.push(
autocompletion({
defaultKeymap: false,
override: [
async (context) => {
if (plugin === null) {
return null
}
const { state, pos, explicit } = context
let nodeBefore = syntaxTree(state).resolveInner(pos, -1)
if (
nodeBefore.name === 'BlockComment' ||
nodeBefore.name === 'LineComment'
)
return null
const line = state.doc.lineAt(pos)
let trigKind: CompletionTriggerKind = CompletionTriggerKind.Invoked
let trigChar: string | undefined
if (
!explicit &&
plugin.client
.getServerCapabilities()
.completionProvider?.triggerCharacters?.includes(
line.text[pos - line.from - 1]
)
) {
trigKind = CompletionTriggerKind.TriggerCharacter
trigChar = line.text[pos - line.from - 1]
}
if (
trigKind === CompletionTriggerKind.Invoked &&
!context.matchBefore(/\w+$/)
) {
return null
}
return await plugin.requestCompletion(
context,
offsetToPos(state.doc, pos),
{
triggerKind: trigKind,
triggerCharacter: trigChar,
}
)
},
],
})
)
}
return ext return ext
} }

View File

@ -1,5 +1,6 @@
import { import {
acceptCompletion, acceptCompletion,
autocompletion,
clearSnippet, clearSnippet,
closeCompletion, closeCompletion,
hasNextSnippetField, hasNextSnippetField,
@ -8,10 +9,17 @@ import {
prevSnippetField, prevSnippetField,
startCompletion, startCompletion,
} from '@codemirror/autocomplete' } from '@codemirror/autocomplete'
import { Prec } from '@codemirror/state' import { Prec, Extension } from '@codemirror/state'
import { EditorView, keymap, KeyBinding } from '@codemirror/view' import { EditorView, keymap, KeyBinding, ViewPlugin } from '@codemirror/view'
import { CompletionItemKind } from 'vscode-languageserver-protocol' import {
CompletionItemKind,
CompletionTriggerKind,
} from 'vscode-languageserver-protocol'
import { LanguageServerPlugin } from './lsp'
import { offsetToPos } from './util'
import { syntaxTree } from '@codemirror/language'
export const CompletionItemKindMap = Object.fromEntries( export const CompletionItemKindMap = Object.fromEntries(
Object.entries(CompletionItemKind).map(([key, value]) => [value, key]) Object.entries(CompletionItemKind).map(([key, value]) => [value, key])
@ -46,6 +54,59 @@ const lspAutocompleteKeymap: readonly KeyBinding[] = [
}, },
] ]
export const lspAutocompleteKeymapExt = Prec.highest( const lspAutocompleteKeymapExt = Prec.highest(keymap.of(lspAutocompleteKeymap))
keymap.of(lspAutocompleteKeymap)
export default function lspAutocompleteExt(
plugin: ViewPlugin<LanguageServerPlugin>
): Extension {
return [
lspAutocompleteKeymapExt,
autocompletion({
defaultKeymap: false,
override: [
async (context) => {
const { state, pos, explicit, view } = context
let value = view?.plugin(plugin)
if (!value) return null
let nodeBefore = syntaxTree(state).resolveInner(pos, -1)
if (
nodeBefore.name === 'BlockComment' ||
nodeBefore.name === 'LineComment'
) )
return null
const line = state.doc.lineAt(pos)
let trigKind: CompletionTriggerKind = CompletionTriggerKind.Invoked
let trigChar: string | undefined
if (
!explicit &&
value.client
.getServerCapabilities()
.completionProvider?.triggerCharacters?.includes(
line.text[pos - line.from - 1]
)
) {
trigKind = CompletionTriggerKind.TriggerCharacter
trigChar = line.text[pos - line.from - 1]
}
if (
trigKind === CompletionTriggerKind.Invoked &&
!context.matchBefore(/\w+$/)
) {
return null
}
return await value.requestCompletion(
context,
offsetToPos(state.doc, pos),
{
triggerKind: trigKind,
triggerCharacter: trigChar,
}
)
},
],
}),
]
}

View File

@ -31,7 +31,7 @@ import { LanguageServerClient } from '../client'
import { CompletionItemKindMap } from './autocomplete' import { CompletionItemKindMap } from './autocomplete'
import { addToken, SemanticToken } from './semantic-tokens' import { addToken, SemanticToken } from './semantic-tokens'
import { deferExecution, posToOffset, formatMarkdownContents } from './util' import { deferExecution, posToOffset, formatMarkdownContents } from './util'
import { lspAutocompleteKeymapExt } from './autocomplete' import lspAutocompleteExt from './autocomplete'
import lspHoverExt from './hover' import lspHoverExt from './hover'
import lspFormatExt from './format' import lspFormatExt from './format'
import lspIndentExt from './indent' import lspIndentExt from './indent'
@ -556,7 +556,7 @@ export class LanguageServerPluginSpec
{ {
provide(plugin: ViewPlugin<LanguageServerPlugin>): Extension { provide(plugin: ViewPlugin<LanguageServerPlugin>): Extension {
return [ return [
lspAutocompleteKeymapExt, lspAutocompleteExt(plugin),
lspFormatExt(plugin), lspFormatExt(plugin),
lspHoverExt(plugin), lspHoverExt(plugin),
lspIndentExt(), lspIndentExt(),

View File

@ -29,7 +29,6 @@ import {
LanguageServerClient, LanguageServerClient,
docPathFacet, docPathFacet,
languageId, languageId,
lspPlugin,
} from '@kittycad/codemirror-lsp-client' } from '@kittycad/codemirror-lsp-client'
import { deferExecution } from 'lib/utils' import { deferExecution } from 'lib/utils'
import { CopilotLspCompletionParams } from 'wasm-lib/kcl/bindings/CopilotLspCompletionParams' import { CopilotLspCompletionParams } from 'wasm-lib/kcl/bindings/CopilotLspCompletionParams'
@ -621,7 +620,6 @@ export const copilotPlugin = (options: LanguageServerOptions): Extension => {
) )
return [ return [
/*lspPlugin(options),
completionPlugin, completionPlugin,
copilotAutocompleteKeymapExt, copilotAutocompleteKeymapExt,
domHandlers, domHandlers,
@ -632,6 +630,6 @@ export const copilotPlugin = (options: LanguageServerOptions): Extension => {
plugin.rejectSuggestionCommand() plugin.rejectSuggestionCommand()
return null return null
}),*/ }),
] ]
} }