X-Git-Url: http://git.roojs.org/?a=blobdiff_plain;f=src%2FPalete%2FLanguageClientVala.vala;h=f49bbd8b28fbd4803741f348844417eb5f176b5a;hb=HEAD;hp=e0156aacb88a2bd91d387726aece52339ca679ee;hpb=191b1d687de60c24bb8124978ad4ec5a239b0c7a;p=roobuilder diff --git a/src/Palete/LanguageClientVala.vala b/src/Palete/LanguageClientVala.vala index e0156aacb..f49bbd8b2 100644 --- a/src/Palete/LanguageClientVala.vala +++ b/src/Palete/LanguageClientVala.vala @@ -1,7 +1,6 @@ namespace Palete { public class LanguageClientVala : LanguageClient { - int countdown = 0; protected bool initialized = false; bool sent_shutdown = false; uint change_queue_id = 0; @@ -20,9 +19,13 @@ namespace Palete { private IOStream? subprocess_stream = null; public Jsonrpc.Client? jsonrpc_client = null; + int countdown = 0; Gee.ArrayList open_files; private JsRender.JsRender? _change_queue_file = null; + int doc_countdown = 0; private string change_queue_file_source = ""; + private JsRender.JsRender? doc_queue_file = null; + JsRender.JsRender? change_queue_file { set { @@ -33,6 +36,9 @@ namespace Palete { return this._change_queue_file; } } + + + void startServer() { var exe = GLib.Environment.find_program_in_path( "vala-language-server"); @@ -50,30 +56,59 @@ namespace Palete { // extend versions will proably call initialize to start and connect to server. base(project); - this.change_queue_id = GLib.Timeout.add_seconds(1, () => { - if (this.change_queue_file == null) { - return true; - } - if (this.getting_diagnostics) { - return true; - } - this.countdown--; - + if (this.change_queue_id == 0 ) { + this.change_queue_id = GLib.Timeout.add(500, () => { + this.run_change_queue(); + return true; + }); + } - if (this.countdown < 0){ - this.document_change_force.begin(this.change_queue_file, this.change_queue_file_source, (o, res) => { - this.document_change_force.end(res); - }); - this.change_queue_file = null; - - } - return true; - }); this.startServer(); } + void run_change_queue() + { + + if (this.change_queue_file == null) { + return ; + } + if (this.countdown < -1) { + return; + } + if (this.getting_diagnostics) { + return; + } + this.countdown--; + + + if (this.countdown < 0){ + this.document_change_force.begin(this.change_queue_file, this.change_queue_file_source, (o, res) => { + this.document_change_force.end(res); + }); + this.change_queue_file = null; + + } + return ; + } + async int queuer(int cnt) + { + SourceFunc cb = this.queuer.callback; + + GLib.Timeout.add(500, () => { + GLib.Idle.add((owned) cb); + return false; + }); + + yield; + return cnt; + } + static int doc_queue_id = 0; + + + + public bool initProcess(string process_path) { this.onClose(); @@ -160,7 +195,6 @@ namespace Palete { this.initialize_server (); } - } @@ -173,7 +207,14 @@ namespace Palete { this.buildDict ( processId: new Variant.int32 ((int32) Posix.getpid ()), rootPath: new Variant.string (this.project.path), - rootUri: new Variant.string (File.new_for_path (this.project.path).get_uri ()) + rootUri: new Variant.string (File.new_for_path (this.project.path).get_uri ()), + capabilities : this.buildDict ( + textDocument: this.buildDict ( + documentSymbol : this.buildDict ( + hierarchicalDocumentSymbolSupport : new Variant.boolean (true) + ) + ) + ) ), null, out return_value @@ -237,7 +278,7 @@ namespace Palete { } - public bool isReady() + public override bool isReady() { if (this.closed) { this.log(LanguageClientAction.RESTART,"closed is set - restarting"); @@ -429,7 +470,7 @@ namespace Palete { }); } - this.countdown = 3; + this.countdown = 2; this.change_queue_file = file; @@ -444,7 +485,7 @@ namespace Palete { if (!this.isReady()) { return; } - this.countdown = 9; // not really relivant.. + this.countdown = -2; // not really relivant.. this.change_queue_file = null; // this is more important.. if (!this.open_files.contains(file)) { @@ -597,25 +638,182 @@ namespace Palete { } + + + + static int hover_call_count = 1; + bool getting_hover = false; + //CompletionListInfo.itmems.parse_varient or CompletionListInfo.parsevarient - public override async Gee.ArrayList syntax (JsRender.JsRender file) throws GLib.Error + public override async Lsp.Hover hover (JsRender.JsRender file, int line, int offset) throws GLib.Error { /* partial_result_token , work_done_token context = null) */ - GLib.debug("get syntax %s", file.relpath); + //GLib.debug("get hover %s %d %d", file.relpath, (int)line, (int)offset); + var ret = new Lsp.Hover(); + //ret = null; + if (!this.isReady()) { + return ret; + } + if (this.getting_hover) { + return ret; + } + + hover_call_count++; + var call_id = yield this.queuer(hover_call_count); + + //GLib.debug("end hover call=%d count=%d", call_id, hover_call_count); + if (call_id != hover_call_count) { + //GLib.debug("get hover CANCELLED %s %d %d", file.relpath, (int)line, (int)offset); + return ret; + } + + //GLib.debug("get hover RUN %s %d %d", file.relpath, (int)line, (int)offset); + + this.getting_hover = true; + + Variant? return_value; + try { + yield this.jsonrpc_client.call_async ( + "textDocument/hover", + this.buildDict ( + + 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))) + ) + + ), + null, + out return_value + ); + } catch(GLib.Error e) { + this.getting_hover = false; + throw e; + } + this.getting_hover = false; + GLib.debug ("LS hover replied with %s", Json.to_string (Json.gvariant_serialize (return_value), true)); + if (return_value == null) { + return ret; + } + + var json = Json.gvariant_serialize (return_value); + if (json.get_node_type() != Json.NodeType.OBJECT) { + return ret; + } + + + ret = Json.gobject_deserialize ( typeof (Lsp.Hover), json) as Lsp.Hover; + + return ret; + + + + } + + + static int doc_symbol_queue_call_count = 1; + + + + public override void queueDocumentSymbols (JsRender.JsRender file) + { + + this.documentSymbols.begin(file, (o, res) => { + var ret = documentSymbols.end(res); + file.navigation_tree_updated(ret); + }); + + + } + + bool getting_symbols = false; + + public override async Gee.ArrayList documentSymbols (JsRender.JsRender file) throws GLib.Error + { + /* partial_result_token , work_done_token context = null) */ + GLib.debug("get documentSymbols %s", file.relpath); var ret = new Gee.ArrayList(); //ret = null; if (!this.isReady()) { + GLib.debug("docsymbols not ready"); return ret; } + if (this.getting_symbols) { + GLib.debug("docsymbols currently getting symbols"); + return ret; + } + + + doc_symbol_queue_call_count++; + var call_id = yield this.queuer(doc_symbol_queue_call_count); + if (call_id != doc_symbol_queue_call_count) { + GLib.debug("docsymbols call id does not match %d %d" ,call_id , doc_symbol_queue_call_count); + return ret; + } + this.getting_symbols = true; + Variant? return_value; - yield this.jsonrpc_client.call_async ( - "textDocument/documentSymbol", + try { + 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 + ); + } catch(Error e) { + this.getting_symbols = false; + throw e; + } + this.getting_symbols = false; + + 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(); + GLib.debug ("LS replied with %D items", ar.get_length()); + 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 ; + + + } + // cant seem to get this to show anything!! + public override async Gee.ArrayList signatureHelp (JsRender.JsRender file, int line, int offset) throws GLib.Error { + /* partial_result_token , work_done_token context = null) */ + GLib.debug("get signatureHelp %s, %d, %d", file.relpath, line, offset); + var ret = new Gee.ArrayList(); + //ret = null; + if (!this.isReady()) { + return ret; + } + Variant? return_value; + yield this.jsonrpc_client.call_async ( + "textDocument/signatureHelp", this.buildDict ( textDocument : this.buildDict ( ///TextDocumentItem; - uri: new GLib.Variant.string (file.to_url()), - version : new GLib.Variant.uint64 ( (uint64) file.version) - ) + uri: new GLib.Variant.string (file.to_url()) + ), + position : this.buildDict ( + line : new GLib.Variant.uint64 ( (uint) line) , + character : new GLib.Variant.uint64 ( uint.max(0, (offset -1))) + ) ), null, @@ -625,21 +823,54 @@ namespace Palete { 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.ARRAY) { + return ret; + } + var ar = json.get_array(); + GLib.debug ("LS replied with %D items", ar.get_length()); for(var i = 0; i < ar.get_length(); i++ ) { - var add= Json.gobject_deserialize ( typeof (Lsp.DocumentSymbol), ar.get_element(i)) as Lsp.DocumentSymbol; + var add= Json.gobject_deserialize ( typeof (Lsp.SignatureInformation), ar.get_element(i)) as Lsp.SignatureInformation; ret.add( add); } - return ret ; + return ret ; - + } + // ok for general symbol search, not much details though. + public override async Gee.ArrayList symbol (string sym) throws GLib.Error + { + /* partial_result_token , work_done_token context = null) */ + GLib.debug("get symbol %s,", sym); + var ret = new Gee.ArrayList(); + //ret = null; + if (!this.isReady()) { + return ret; + } + Variant? return_value; + yield this.jsonrpc_client.call_async ( + "workspace/symbol", + this.buildDict ( + query : new GLib.Variant.string (sym) + ), + null, + out return_value + ); + +GLib.debug ("LS replied with %s", Json.to_string (Json.gvariant_serialize (return_value), true)); + return ret; } } + + + + + + + } \ No newline at end of file