online editor: Have LSP trigger updates in the Properties View

We still get some updates from the editor that we do not really need
anymore, but we also get updtaes from the LSP now.

This fixes e.g. the property value being out of sync right after you
changed it in the property editor.
This commit is contained in:
Tobias Hunger 2022-12-02 21:36:16 +01:00 committed by Tobias Hunger
parent 9cd6c60000
commit 71199fbb16
2 changed files with 82 additions and 9 deletions

View file

@ -12,7 +12,20 @@ import { change_property, query_properties } from "./properties_client";
import { Message } from "@lumino/messaging";
import { Widget } from "@lumino/widgets";
import { BaseLanguageClient } from "vscode-languageclient";
import {
BaseLanguageClient,
HandleWorkDoneProgressSignature,
ProgressToken,
WorkDoneProgressBegin,
WorkDoneProgressEnd,
WorkDoneProgressReport,
} from "vscode-languageclient";
function extract_uri_from_progress_message(input: string): string {
const start = input.indexOf(": ");
const end = input.lastIndexOf("@");
return input.slice(start + 2, end);
}
export class PropertiesWidget extends Widget {
#language_client: BaseLanguageClient | null = null;
@ -21,6 +34,7 @@ export class PropertiesWidget extends Widget {
return;
};
#propertiesView: PropertiesView;
#current_position: LspPosition | null = null;
constructor() {
const node = PropertiesView.createNode();
@ -53,21 +67,70 @@ export class PropertiesWidget extends Widget {
};
}
set_language_client(client: BaseLanguageClient | null) {
this.#language_client = client ?? this.#language_client;
dispose(): void {
super.dispose();
}
position_changed(uri: LspURI, version: number, position: LspPosition) {
set_language_client(client: BaseLanguageClient | null) {
if (client != null) {
this.#language_client = client;
const work = client.middleware.handleWorkDoneProgress;
const new_work = (
token: ProgressToken,
params:
| WorkDoneProgressBegin
| WorkDoneProgressReport
| WorkDoneProgressEnd,
next: HandleWorkDoneProgressSignature,
) => {
if (params.kind === "begin") {
this.data_stale(
extract_uri_from_progress_message(params.message || ""),
);
} else if (params.kind === "end") {
this.data_valid(
extract_uri_from_progress_message(params.message || ""),
);
}
if (work != null) {
work(token, params, next);
}
};
this.#language_client.middleware.handleWorkDoneProgress = new_work;
}
}
data_stale(uri: string) {
if (uri == this.#propertiesView.current_data_uri) {
this.#propertiesView.show_welcome("Refreshing data");
}
}
data_valid(uri: string) {
if (
uri == this.#propertiesView.current_data_uri &&
this.#current_position
) {
query_properties(this.#language_client, uri, this.#current_position)
.then((r: PropertyQuery) => {
this.#propertiesView.set_properties(r);
})
.catch(() => {
this.#propertiesView.current_data_uri = uri.toString();
this.#propertiesView.show_welcome("loading...");
});
}
}
position_changed(uri: LspURI, _: number, position: LspPosition) {
this.#current_position = position;
query_properties(this.#language_client, uri, position)
.then((r: PropertyQuery) => {
this.#propertiesView.set_properties(r);
})
.catch(() => {
// Document has not loaded yet!
setTimeout(
() => this.position_changed(uri, version, position),
1000,
);
this.#propertiesView.current_data_uri = uri.toString();
this.#propertiesView.show_welcome("Data not yet available.");
});
}

View file

@ -88,6 +88,16 @@ export class PropertiesView {
#current_element_range: LspRange | null = null;
#binding_editor: BindingEditor;
get current_data_uri() {
return this.#current_data_uri;
}
set current_data_uri(uri: string) {
this.#current_data_uri = uri;
}
get current_data_version() {
return this.#current_data_version;
}
static createNode(): HTMLElement {
const node = document.createElement("div");
const content = document.createElement("div");