Skip to content

Commit

Permalink
sv
Browse files Browse the repository at this point in the history
  • Loading branch information
nighca committed Dec 27, 2024
1 parent a6b1cef commit 5712aae
Show file tree
Hide file tree
Showing 7 changed files with 71 additions and 19 deletions.
21 changes: 19 additions & 2 deletions spx-gui/src/components/editor/code-editor/code-editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import type { Runtime } from '@/models/runtime'
import type { Project } from '@/models/project'
import { Copilot } from './copilot'
import { DocumentBase } from './document-base'
import { SpxLSPClient } from './lsp'
import { SpxLSPClient, semanticTokenLegend } from './lsp'
import {
type ICodeEditorUI,
type DiagnosticsContext,
Expand Down Expand Up @@ -55,7 +55,8 @@ import {
type CommandArgs,
getTextDocumentId,
containsPosition,
makeBasicMarkdownString
makeBasicMarkdownString,
fromMonacoUri
} from './common'
import { TextDocument, createTextDocument } from './text-document'
import { type Monaco } from './monaco'
Expand Down Expand Up @@ -542,6 +543,22 @@ export class CodeEditor extends Disposable {

init() {
this.lspClient.init()

this.addDisposable(
this.monaco.languages.registerDocumentSemanticTokensProvider('spx', {
getLegend: () => semanticTokenLegend,
provideDocumentSemanticTokens: async (model) => {
const tokens = await this.lspClient.textDocumentSemanticTokens({
textDocument: fromMonacoUri(model.uri)
})
if (tokens == null) return { data: new Uint32Array(0) }
return { data: new Uint32Array(tokens.data) } // TODO: pass data with array buffer instead of number array
},
releaseDocumentSemanticTokens() {
// do nothing
}
})
)
}

dispose(): void {
Expand Down
9 changes: 9 additions & 0 deletions spx-gui/src/components/editor/code-editor/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { Costume } from '@/models/costume'
import { Animation } from '@/models/animation'
import { isWidget } from '@/models/widget'
import { stageCodeFilePaths } from '@/models/stage'
import type { Monaco, monaco } from './monaco'

export type Position = {
line: number
Expand Down Expand Up @@ -562,3 +563,11 @@ export function textDocumentId2CodeFileName(id: TextDocumentIdentifier) {
return { en: spriteName, zh: spriteName }
}
}

export function fromMonacoUri(uri: monaco.Uri): TextDocumentIdentifier {
return { uri: uri.toString() }
}

export function toMonacoUri(id: TextDocumentIdentifier, monaco: Monaco): monaco.Uri {
return monaco.Uri.parse(id.uri)
}
32 changes: 32 additions & 0 deletions spx-gui/src/components/editor/code-editor/lsp/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,11 @@ export class SpxLSPClient extends Disposable {
return spxlc.request<lsp.TextEdit[] | null>(lsp.DocumentFormattingRequest.method, params)
}

async textDocumentSemanticTokens(params: lsp.SemanticTokensParams): Promise<lsp.SemanticTokens | null> {
const spxlc = await this.prepareRequest()
return spxlc.request<lsp.SemanticTokens | null>(lsp.SemanticTokensRequest.method, params)
}

// Higher-level APIs

async getResourceReferences(textDocument: TextDocumentIdentifier): Promise<ResourceReference[]> {
Expand Down Expand Up @@ -200,3 +205,30 @@ export class SpxLSPClient extends Disposable {
return completionResult as CompletionItem[]
}
}

// Keep in sync with `tools/spxls/internal/server/semantic_token.go`
export const semanticTokenLegend = {
tokenTypes: [
lsp.SemanticTokenTypes.namespace,
lsp.SemanticTokenTypes.type,
lsp.SemanticTokenTypes.interface,
lsp.SemanticTokenTypes.struct,
lsp.SemanticTokenTypes.parameter,
lsp.SemanticTokenTypes.variable,
lsp.SemanticTokenTypes.property,
lsp.SemanticTokenTypes.function,
lsp.SemanticTokenTypes.method,
lsp.SemanticTokenTypes.keyword,
lsp.SemanticTokenTypes.comment,
lsp.SemanticTokenTypes.string,
lsp.SemanticTokenTypes.number,
lsp.SemanticTokenTypes.operator,
'label' // since LSP 3.18.0, Not supported by `vscode-languageserver-protocol` yet
],
tokenModifiers: [
lsp.SemanticTokenModifiers.declaration,
lsp.SemanticTokenModifiers.readonly,
lsp.SemanticTokenModifiers.static,
lsp.SemanticTokenModifiers.defaultLibrary
]
}
9 changes: 7 additions & 2 deletions spx-gui/src/components/editor/code-editor/text-document.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ import {
type TextDocumentIdentifier,
type WordAtPosition,
type TextEdit,
getTextDocumentId
getTextDocumentId,
toMonacoUri
} from './common'
import { toMonacoPosition, toMonacoRange, fromMonacoPosition } from './ui/common'
import type { Monaco, monaco } from './monaco'
Expand Down Expand Up @@ -114,7 +115,11 @@ export class TextDocument
) {
super()

this.monacoTextModel = monaco.editor.createModel(codeOwner.getCode() ?? '', 'spx')
this.monacoTextModel = monaco.editor.createModel(
codeOwner.getCode() ?? '',
'spx',
toMonacoUri(this.codeOwner.getTextDocumentId(), monaco)
)

this.addDisposer(
watch(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,9 @@ const monacoEditorOptions = computed<monaco.editor.IStandaloneEditorConstruction
tabSize,
insertSpaces,
fontSize: fontSize.value,
contextmenu: false
contextmenu: false,
// TODO: preserve `semanticHighlighting` of theme (in `@shikijs/monaco`), then remove this line
'semanticHighlighting.enabled': true
}))
const monacEditorInitDataRef = shallowRef<MonacoEditorInitData | null>(null)
Expand Down
12 changes: 1 addition & 11 deletions spx-gui/src/components/editor/code-editor/ui/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@ import type { ResourceModel } from '@/models/common/resource-model'
import { Sprite } from '@/models/sprite'
import { Sound } from '@/models/sound'
import { isWidget } from '@/models/widget'
import { type Range, type Position, type TextDocumentIdentifier, type Selection } from '../common'
import type { Monaco } from '../monaco'
import { type Range, type Position, type Selection } from '../common'

export function token2Signal(token: monaco.CancellationToken): AbortSignal {
const ctrl = new AbortController()
Expand Down Expand Up @@ -60,15 +59,6 @@ export function toMonacoSelection(selection: Selection): monaco.ISelection {
}
}

export function fromMonacoUri(uri: monaco.Uri): TextDocumentIdentifier {
// TODO: check if this is correct
return { uri: uri.toString() }
}

export function toMonacoUri(id: TextDocumentIdentifier, monaco: Monaco): monaco.Uri {
return monaco.Uri.parse(id.uri)
}

export function supportGoTo(resourceModel: ResourceModel): boolean {
// Currently, we do not support "go to detail" for other types of resources due to two reasons:
// 1. The "selected" state of certain resource types, such as animations, is still managed within the Component, making it difficult to control from here.
Expand Down
3 changes: 0 additions & 3 deletions spx-gui/src/utils/spx/gop-tm-language.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,6 @@
"name": "GoPlus",
"scopeName": "source.gop",
"patterns": [
{
"include": "#statements"
}
],
"repository": {
"statements": {
Expand Down

0 comments on commit 5712aae

Please sign in to comment.