+ public void onNotification(string method, Variant? return_value)
+ {
+ switch (method) {
+ case "textDocument/publishDiagnostics":
+ this.onDiagnostic(return_value);
+ return;
+ default:
+ break;
+
+ }
+ GLib.debug("got notification %s : %s", method , Json.to_string (Json.gvariant_serialize (return_value), true));
+
+ }
+
+ /***
+
+ */
+ public void onDiagnostic(Variant? return_value)
+ {
+
+ var dg = Json.gobject_deserialize (typeof (Lsp.Diagnostics), Json.gvariant_serialize (return_value)) as Lsp.Diagnostics;
+ this.log(LanguageClientAction.DIAG, dg.filename);
+ var f = this.project.getByPath(dg.filename);
+ if (f == null) {
+ //GLib.debug("no file %s", dg.uri);
+ this.project.updateErrorsforFile(null);
+ return;
+ }
+ foreach(var v in f.errorsByType.values) {
+ v.remove_all();
+ }
+ foreach(var diag in dg.diagnostics) {
+ var ce = new CompileError.new_from_diagnostic(f, diag);
+ if (!f.errorsByType.has_key(ce.category)) {
+ f.errorsByType.set(ce.category, new GLib.ListStore(typeof(CompileError)));
+ }
+ f.errorsByType.get(ce.category).append(ce);
+ }
+ f.project.updateErrorsforFile(f);
+
+ }
+
+ public override void document_open (JsRender.JsRender file)
+ {
+ if (!this.isReady()) {
+ return;
+ }
+ if (!this.open_files.contains(file)) {
+ this.open_files.add(file);
+ }
+
+ GLib.debug ("LS sent open");
+ try {
+ this.jsonrpc_client.send_notification (
+ "textDocument/didOpen",
+ this.buildDict (
+ textDocument : this.buildDict (
+ uri: new Variant.string (file.to_url()),
+ languageId : new Variant.string (file.language_id()),
+ version : new GLib.Variant.uint64 ( (uint64) file.version),
+ text : new Variant.string (file.toSource())
+ )
+ ),
+ null
+ );
+ this.log(LanguageClientAction.OPEN, file.path);
+ } catch( GLib.Error e) {
+ this.log(LanguageClientAction.ERROR_RPC, e.message);
+ this.onClose();
+ GLib.debug ("LS sent open err %s", e.message);
+ }
+
+ }
+
+ public override void document_save (JsRender.JsRender file)
+ {
+ if (!this.isReady()) {
+ return;
+ }
+ this.change_queue_file = null;
+ GLib.debug ("LS send save");
+ try {
+ this.jsonrpc_client.send_notification (
+ "textDocument/didChange",
+ this.buildDict (
+ textDocument : this.buildDict ( ///TextDocumentItem;
+ uri: new GLib.Variant.string (file.to_url()),
+ version : new GLib.Variant.uint64 ( (uint64) file.version)
+ )
+ ),
+ null
+ );
+ this.log(LanguageClientAction.SAVE, file.path);
+ } catch( GLib.Error e) {
+ this.log(LanguageClientAction.ERROR_RPC, e.message);
+ GLib.debug ("LS save err %s", e.message);
+ this.onClose();
+ }
+
+
+ }
+ public override void document_close (JsRender.JsRender file)
+ {
+ if (!this.isReady()) {
+ return;
+ }
+ this.change_queue_file = null;
+
+ if (this.open_files.contains(file)) {
+ this.open_files.remove(file);
+ }
+ this.log(LanguageClientAction.CLOSE, file.path);
+ GLib.debug ("LS send close");
+ try {
+ this.jsonrpc_client.send_notification (
+ "textDocument/didChange",
+ this.buildDict (
+ textDocument : this.buildDict ( ///TextDocumentItem;
+ uri: new GLib.Variant.string (file.to_url())
+
+ )
+ ),
+ null
+ );
+ } catch( GLib.Error e) {
+ this.log(LanguageClientAction.ERROR_RPC, e.message);
+ GLib.debug ("LS close err %s", e.message);
+ this.onClose();
+ }
+
+
+ }
+
+
+ public override void document_change (JsRender.JsRender file )
+ {
+ if (this.change_queue_file != null && this.change_queue_file.path != file.path) {
+ this.document_change_force(this.change_queue_file, this.change_queue_file_source);
+ }
+
+ this.countdown = 3;
+ this.change_queue_file = file;
+
+
+
+ }
+
+
+ public override void document_change_force (JsRender.JsRender file, string contents)
+ {
+ if (!this.isReady()) {
+ return;
+ }
+
+
+ GLib.debug ("LS send change");
+ var ar = new Json.Array();
+ var obj = new Json.Object();
+ obj.set_string_member("text", contents);
+ ar.add_object_element(obj);
+ var node = new Json.Node(Json.NodeType.ARRAY);
+ node.set_array(ar);
+ this.log(LanguageClientAction.CHANGE, file.path);
+ try {
+ this.jsonrpc_client.send_notification (
+ "textDocument/didChange",
+ this.buildDict (
+ textDocument : this.buildDict ( ///TextDocumentItem;
+ uri: new GLib.Variant.string (file.to_url()),
+ version : new GLib.Variant.uint64 ( (uint64) file.version)
+ ),
+ contentChanges : Json.gvariant_deserialize (node, null)
+
+ ),
+ null
+ );
+ } catch( GLib.Error e) {
+ this.log(LanguageClientAction.ERROR_RPC, e.message);
+ GLib.debug ("LS change err %s", e.message);
+ this.onClose();
+ }
+
+
+ }
+ // called by close window (on last window)...
+ public override void exit () throws GLib.Error
+ {
+ if (!this.isReady()) {
+
+ return;
+ }
+ this.log(LanguageClientAction.TERM, "SEND exit");
+
+ this.jsonrpc_client.send_notification (
+ "exit",
+ null,
+ null
+ );
+ this.onClose();
+
+ }
+ // not used currently..
+ public override async void shutdown () throws GLib.Error
+ {
+ if (!this.isReady()) {
+ return;
+ }
+ this.log(LanguageClientAction.TERM, "SEND shutodwn");
+ this.sent_shutdown = true;
+ Variant? return_value;
+ yield this.jsonrpc_client.call_async (
+ "shutdown",
+ null,
+ null,
+ out return_value
+ );
+ GLib.debug ("LS replied with %s", Json.to_string (Json.gvariant_serialize (return_value), true));
+ }
+ //public async ??/symbol (string symbol) throws GLib.Error {
+
+ // and now for the important styff..
+
+ /*
+
+ @triggerType 1 = typing or ctl-spac, 2 = tiggercharactres? 3= inside completion?
+ */
+ public override async Lsp.CompletionList? completion(JsRender.JsRender file, int line, int offset , int triggerType = 1) throws GLib.Error
+ {
+ /* partial_result_token , work_done_token context = null) */
+ GLib.debug("%s get completion %s @ %d:%d", this.get_type().name(), file.relpath, line, offset);
+
+ var ret = new Lsp.CompletionList();
+
+ if (!this.isReady()) {
+ GLib.debug("completion - language server not ready");
+ return ret;
+ }
+ // make sure completion has the latest info..
+ //if (this.change_queue_file != null && this.change_queue_file.path != file.path) {
+ // this.document_change_real(this.change_queue_file, this.change_queue_file_source);
+ // this.change_queue_file != null;
+ //}
+ this.log(LanguageClientAction.COMPLETE, "SEND complete %s @ %d:%d".printf(file.relpath, line, offset) );
+
+ Variant? return_value;
+
+ var args = this.buildDict (
+ context : this.buildDict ( ///CompletionContext;
+ triggerKind: new GLib.Variant.int32 (triggerType)
+ // triggerCharacter : new GLib.Variant.string ("")
+ ),
+ textDocument : this.buildDict ( ///TextDocumentItem;
+ uri: new GLib.Variant.string (file.to_url()),
+ version : new GLib.Variant.uint64 ( (uint64) file.version)
+ ),
+ position : this.buildDict (
+ line : new GLib.Variant.uint64 ( (uint) line) ,
+ character : new GLib.Variant.uint64 ( uint.max(0, (offset -1)))
+ )
+ );
+
+ GLib.debug ("textDocument/completion send with %s", Json.to_string (Json.gvariant_serialize (args), true));
+
+ yield this.jsonrpc_client.call_async (
+ "textDocument/completion",
+ args,
+ null,
+ out return_value
+ );
+
+
+ //GLib.debug ("LS replied with %s", Json.to_string (Json.gvariant_serialize (return_value), true));
+ var json = Json.gvariant_serialize (return_value);
+
+
+ if (json.get_node_type() == Json.NodeType.OBJECT) {
+ ret = Json.gobject_deserialize (typeof (Lsp.CompletionList), json) as Lsp.CompletionList;
+ this.log(LanguageClientAction.COMPLETE_REPLY, "GOT complete %d items".printf(ret.items.size) );
+ GLib.debug ("LS replied with Object");
+ return ret;
+ }
+
+ if (json.get_node_type() != Json.NodeType.ARRAY) {
+ GLib.debug ("LS replied with %s", Json.to_string (Json.gvariant_serialize (return_value), true));
+ this.log(LanguageClientAction.ERROR_REPLY, "GOT something else??");
+ return ret;
+
+ }
+ var ar = json.get_array();
+
+ for(var i = 0; i < ar.get_length(); i++ ) {
+ var add= Json.gobject_deserialize ( typeof (Lsp.CompletionItem), ar.get_element(i)) as Lsp.CompletionItem;
+ ret.items.add( add);
+
+ }
+ this.log(LanguageClientAction.COMPLETE_REPLY, "GOT array %d items".printf(ret.items.size) );
+ GLib.debug ("LS replied with Array");
+ return ret;
+
+
+ }
+ //CompletionListInfo.itmems.parse_varient or CompletionListInfo.parsevarient
+ public override async Gee.ArrayList<Lsp.DocumentSymbol> syntax (JsRender.JsRender file) throws GLib.Error
+ {
+ /* partial_result_token , work_done_token context = null) */
+ GLib.debug("get syntax %s", file.relpath);
+ var ret = new Gee.ArrayList<Lsp.DocumentSymbol>();
+ //ret = null;
+ if (!this.isReady()) {
+ return ret;
+ }
+ Variant? return_value;
+ yield this.jsonrpc_client.call_async (
+ "textDocument/documentSymbol",
+ this.buildDict (
+
+ textDocument : this.buildDict ( ///TextDocumentItem;
+ uri: new GLib.Variant.string (file.to_url()),
+ version : new GLib.Variant.uint64 ( (uint64) file.version)
+ )
+
+ ),
+ null,
+ out return_value
+ );
+
+
+ GLib.debug ("LS replied with %s", Json.to_string (Json.gvariant_serialize (return_value), true));
+ var json = Json.gvariant_serialize (return_value);
+
+
+
+ var ar = json.get_array();
+ for(var i = 0; i < ar.get_length(); i++ ) {
+ var add= Json.gobject_deserialize ( typeof (Lsp.DocumentSymbol), ar.get_element(i)) as Lsp.DocumentSymbol;
+ ret.add( add);
+
+ }
+ return ret ;
+
+
+
+ }
+