namespace Palete {
public class LanguageClientVala : LanguageClient {
- int countdown = 0;
protected bool initialized = false;
bool sent_shutdown = false;
uint change_queue_id = 0;
private IOStream? subprocess_stream = null;
public Jsonrpc.Client? jsonrpc_client = null;
+ int countdown = 0;
Gee.ArrayList<JsRender.JsRender> 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 {
return this._change_queue_file;
}
}
+
+
+
void startServer()
{
var exe = GLib.Environment.find_program_in_path( "vala-language-server");
// 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();
this.initialize_server ();
}
-
}
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
}
- public bool isReady()
+ public override bool isReady()
{
if (this.closed) {
this.log(LanguageClientAction.RESTART,"closed is set - restarting");
});
}
- this.countdown = 3;
+ this.countdown = 2;
this.change_queue_file = file;
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)) {
}
+
+
+
+ static int hover_call_count = 1;
+ bool getting_hover = false;
+
//CompletionListInfo.itmems.parse_varient or CompletionListInfo.parsevarient
- public override async Gee.ArrayList<Lsp.DocumentSymbol> 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<Lsp.DocumentSymbol> 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<Lsp.DocumentSymbol>();
//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<Lsp.SignatureInformation> 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<Lsp.SignatureInformation>();
+ //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,
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<Lsp.SymbolInformation> 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<Lsp.SymbolInformation>();
+ //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