Fix #8047 - debugging language server and fix completion handling
[roobuilder] / src / Palete / CompletionProvider.vala
index 06259d4..5f5e527 100644 (file)
@@ -6,7 +6,6 @@ namespace Palete {
 
     public class CompletionProvider : Object, GtkSource.CompletionProvider
     {
-
                public JsRender.JsRender file {
                        get { return this.editor.file; }
                        private set {}
@@ -14,7 +13,7 @@ namespace Palete {
                public Editor editor; 
                //public WindowState windowstate;
                public CompletionModel model;
-               global::Gtk.StringFilter filter;
+               global::Gtk.StringFilter? filter = null;
 
                public CompletionProvider(Editor editor)
                {
@@ -34,6 +33,29 @@ namespace Palete {
                  return 200;
                }
                
+               
+               public bool is_trigger(global::Gtk.TextIter  iter, unichar ch)
+               {
+                       if (this.in_populate || ch == 32 || ch == 10) {
+                               return false;
+                       }
+                       if (this.editor.buffer.el.iter_has_context_class(iter, "comment") ||
+                               this.editor.buffer.el.iter_has_context_class(iter, "string")
+                       ) { 
+                               return false;
+                       }
+                       var back = iter.copy();
+                       back.backward_char();
+                       
+                       // what's the character at the iter?
+                       var str = back.get_text(iter);
+                       
+                       GLib.debug("Previos char to trigger is '%s;", str);
+                       
+                       
+                       return true;
+               }
+               
                public  void activate (GtkSource.CompletionContext context, GtkSource.CompletionProposal proposal)
                {
                        GLib.debug("compelte activate");
@@ -60,6 +82,10 @@ namespace Palete {
                                for(var i = 0 ; i < args.length; i++) {
                                        word += i > 0 ? ", " : " ";
                                        var wbit = args[i].strip().split(" ");
+                                       if (wbit.length < 2) {
+                                               word += wbit[0];
+                                               continue;
+                                       }
                                        var ty = wbit[wbit.length - 2];
                                        ty = ty.has_suffix("?") ? "?" : "";  
                                        word += ty + wbit[wbit.length-1]; // property type..?
@@ -184,12 +210,14 @@ namespace Palete {
                internal  async GLib.ListModel populate_async (GtkSource.CompletionContext context, GLib.Cancellable? cancellable) 
                {
                        GLib.debug("pupoulate async");
-                       /*if (!this.in_populate) {
+                       var ret = new GLib.ListStore(typeof(CompletionProposal));
+                       
+                       if (this.in_populate) {
                                GLib.debug("pupoulate async  - skipped waiting for reply");
-                               return null;
+                               return ret;
                        }
                        this.in_populate = true;
-*/
+
                        global::Gtk.TextIter begin, end;
                        Lsp.CompletionList res;
                        if (context.get_bounds (out begin, out end)) {
@@ -207,25 +235,36 @@ namespace Palete {
                                                offset += 2;
                                        }
                                } 
-                               
-                               this.file.getLanguageServer().document_change_force(this.file, this.editor.tempFileContents());                         
+                               //  this should not really be slow, as it's a quick repsonse
+                               yield this.file.getLanguageServer().document_change_force(this.file, this.editor.tempFileContents());                           
                                try {
                                        GLib.debug("sending request to language server %s", this.file.getLanguageServer().get_type().name());
                                        
                                        res = yield this.file.getLanguageServer().completion(this.file, line, offset, 1);
                                } catch (GLib.Error e) {
                                        GLib.debug("got error %s", e.message);
-                                       res = null;
+                                       this.in_populate = false;
+                                       return ret;
                                }
                                
                        } else {
-                               res = null;
+                               this.in_populate = false;
+                               return ret;
                        }
                        
                        GLib.debug("pupoulate async  - got reply");
                        this.model = new CompletionModel(this, context, res, cancellable); 
                        var word = context.get_word();
                        
+                       var lc = end.copy();
+                       lc.backward_char();
+                       var lchar = lc.get_text(end);
+                       
+                       
+                       GLib.debug("Context word is %s / '%s' , %d", word, lchar, (int)word.length);
+                       if (word.length < 1 && lchar != ".") {
+                               word = " "; // this should filter out everything, and prevent it displaying 
+                       }
                        
                        var expression = new global::Gtk.PropertyExpression(typeof(CompletionProposal), null, "label");
                        this.filter = new global::Gtk.StringFilter(expression);
@@ -244,7 +283,9 @@ namespace Palete {
                {
  
                        //GLib.debug("pupoulate refilter");
-        
+                       if (this.filter == null) {
+                               return;
+                       }
 
                        var word = context.get_word();
                        this.filter.set_search(word);
@@ -297,12 +338,15 @@ namespace Palete {
                        this.search = word;
                        if (res != null) {
                                foreach(var comp in res.items) {
-                                        
+                                        if (comp.label == "_") { // skip '_'
+                                               continue;
+                                       }
+                                       GLib.debug("got suggestion %s", comp.label);
                                        this.items.add(new CompletionProposal(comp));   
                                        
                                }
                        }
-                   print("GOT %d results\n", (int) items.size); 
+                   GLib.debug("GOT %d results\n", (int) items.size); 
                        // WHY TWICE?
                    if (this.items.size < this.minimum_word_size) {
                                return;