Fix diagnostic propagation
This commit is contained in:
parent
0e70335791
commit
db5f33e961
|
|
@ -8,6 +8,7 @@ import {
|
|||
ChangeSet,
|
||||
} from "@codemirror/state";
|
||||
import { history } from "@codemirror/commands";
|
||||
import { Diagnostic, setDiagnostics } from "@codemirror/lint";
|
||||
import { Editor } from "./editor";
|
||||
import van, { State } from "vanjs-core";
|
||||
import { WorkspaceFile } from "@codemirror/lsp-client";
|
||||
|
|
@ -104,6 +105,11 @@ export class OpenFile implements WorkspaceFile {
|
|||
createEditor(): Editor {
|
||||
const editor = new Editor(this);
|
||||
this.editors.push(editor);
|
||||
editor.dispatch(
|
||||
editor.view.state.update(
|
||||
setDiagnostics(editor.view.state, this.diagnostics || []),
|
||||
),
|
||||
);
|
||||
return editor;
|
||||
}
|
||||
|
||||
|
|
@ -172,12 +178,7 @@ export class OpenFile implements WorkspaceFile {
|
|||
es.forEach((e) => e.dispatch(e.view.state.update(trs), true));
|
||||
} else {
|
||||
this.editors.forEach((e) => {
|
||||
const changes = transaction.changes;
|
||||
const userEvent = transaction.annotation(Transaction.userEvent);
|
||||
const annotations = userEvent
|
||||
? [Transaction.userEvent.of(userEvent)]
|
||||
: [];
|
||||
e.dispatch(e.view.state.update({ changes, annotations }), true);
|
||||
e.dispatch(e.view.state.update(trs), true);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -215,4 +216,14 @@ export class OpenFile implements WorkspaceFile {
|
|||
if (this.editors.length > 0) return this.editors[0].view;
|
||||
return null;
|
||||
}
|
||||
|
||||
private diagnostics: Diagnostic[];
|
||||
setDiagnostics(diagnostics: Diagnostic[]) {
|
||||
this.diagnostics = diagnostics;
|
||||
for (const editor of this.editors) {
|
||||
editor.view.dispatch(
|
||||
setDiagnostics(editor.view.state, diagnostics),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,11 +7,14 @@ import { EditorView } from "@codemirror/view";
|
|||
import {
|
||||
LSPClient,
|
||||
LSPPlugin,
|
||||
languageServerExtensions,
|
||||
Workspace,
|
||||
serverCompletion,
|
||||
hoverTooltips,
|
||||
signatureHelp,
|
||||
} from "@codemirror/lsp-client";
|
||||
|
||||
import { OpenFile } from "./filestate";
|
||||
import { serverDiagnostics } from "./lsp/diagnostics";
|
||||
|
||||
// Create a very small MessagePort-based transport implementation
|
||||
// compatible with @codemirror/lsp-client's expected Transport interface.
|
||||
|
|
@ -108,9 +111,9 @@ class OpenFileWorkspace extends Workspace {
|
|||
file.version = this.nextFileVersion(file.uri);
|
||||
file.changes = ChangeSet.empty(file.doc.length);
|
||||
}
|
||||
for(const e of file.editors) {
|
||||
for (const e of file.editors) {
|
||||
const plugin = LSPPlugin.get(e.view);
|
||||
if(plugin) {
|
||||
if (plugin) {
|
||||
plugin.clear();
|
||||
}
|
||||
}
|
||||
|
|
@ -257,7 +260,12 @@ export async function createLspExtension(
|
|||
|
||||
try {
|
||||
const client = new LSPClient({
|
||||
extensions: languageServerExtensions(),
|
||||
extensions: [
|
||||
serverDiagnostics(),
|
||||
serverCompletion(),
|
||||
hoverTooltips(),
|
||||
signatureHelp(),
|
||||
],
|
||||
rootUri: rootUri,
|
||||
workspace: (c) => new OpenFileWorkspace(c),
|
||||
});
|
||||
|
|
|
|||
|
|
@ -0,0 +1,55 @@
|
|||
import type * as lsp from "vscode-languageserver-protocol"
|
||||
import {setDiagnostics} from "@codemirror/lint"
|
||||
import {ViewPlugin, ViewUpdate} from "@codemirror/view"
|
||||
import {LSPPlugin, LSPClientExtension} from "@codemirror/lsp-client"
|
||||
import {OpenFile} from "../filestate"
|
||||
import { Text } from "@codemirror/state"
|
||||
|
||||
function toSeverity(sev: lsp.DiagnosticSeverity) {
|
||||
return sev == 1 ? "error" : sev == 2 ? "warning" : sev == 3 ? "info" : "hint"
|
||||
}
|
||||
|
||||
const autoSync = ViewPlugin.fromClass(class {
|
||||
pending: any | null = null
|
||||
update(update: ViewUpdate) {
|
||||
if (update.docChanged) {
|
||||
if (this.pending != null) clearTimeout(this.pending)
|
||||
this.pending = setTimeout(() => {
|
||||
this.pending = null
|
||||
let plugin = LSPPlugin.get(update.view)
|
||||
if (plugin) plugin.client.sync()
|
||||
}, 500)
|
||||
}
|
||||
}
|
||||
destroy() {
|
||||
if (this.pending != null) clearTimeout(this.pending)
|
||||
}
|
||||
})
|
||||
|
||||
function fromPosition(doc: Text, pos: lsp.Position): number {
|
||||
let line = doc.line(pos.line + 1)
|
||||
return line.from + pos.character
|
||||
}
|
||||
|
||||
export function serverDiagnostics(): LSPClientExtension {
|
||||
return {
|
||||
clientCapabilities: {textDocument: {publishDiagnostics: {versionSupport: true}}},
|
||||
notificationHandlers: {
|
||||
"textDocument/publishDiagnostics": (client, params: lsp.PublishDiagnosticsParams) => {
|
||||
let file = client.workspace.getFile(params.uri) as OpenFile;
|
||||
if (!file || params.version != null && params.version != file.version) return false;
|
||||
for(const view of file.editors.map(e => e.view)) {
|
||||
const mapPos = (p: number) => file.changes ? file.changes.mapPos(p) : p;
|
||||
file.setDiagnostics(params.diagnostics.map(item => ({
|
||||
from: mapPos(fromPosition(file.doc, item.range.start)),
|
||||
to: mapPos(fromPosition(file.doc, item.range.end)),
|
||||
severity: toSeverity(item.severity ?? 1),
|
||||
message: item.message,
|
||||
})));
|
||||
}
|
||||
return true
|
||||
}
|
||||
},
|
||||
editorExtension: autoSync
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue