fix missing ref on property objects, and skip _ as a suggestion
[roobuilder] / src / Palete / CompletionProvider.vala
index 74cca1f..5e1a307 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,10 +33,26 @@ namespace Palete {
                  return 200;
                }
                
+               
+               public bool is_trigger(global::Gtk.TextIter  iter, unichar ch)
+               {
+                       if (this.in_populate || ch == 32) {
+                               return false;
+                       }
+                       GLib.debug("should trigger? %c", (int) ch);
+                       
+                       
+                       return true;
+               }
+               
                public  void activate (GtkSource.CompletionContext context, GtkSource.CompletionProposal proposal)
                {
                        GLib.debug("compelte activate");
+                       
                        var  p = (CompletionProposal) proposal;
+                       GLib.debug("lsp says use %s", p.ci.insertText);
+                       
+                       
                        global::Gtk.TextMark end_mark = null;
                        global::Gtk.TextIter begin, end;
 
@@ -47,6 +62,26 @@ namespace Palete {
                        var buffer = begin.get_buffer();
                
                        var  word = p.label;
+                       if (p.ci.kind == Lsp.CompletionItemKind.Method || p.ci.kind == Lsp.CompletionItemKind.Function) {
+                               var bits = p.text.split("(");
+                               var abits = bits[1].split(")");
+                               var args = abits[0].split(",");
+                               
+                               word += "(";
+                               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..?
+                               }
+                               word += args.length > 0 ? " )" : ")";
+                       }
+                       
                        var len = -1;
                        
 
@@ -91,7 +126,7 @@ namespace Palete {
 
                public  void display (GtkSource.CompletionContext context, GtkSource.CompletionProposal proposal, GtkSource.CompletionCell cell)
                {
-                       GLib.debug("compelte display");
+                       //GLib.debug("compelte display");
                        var col = cell.get_column();
                        
                        var p = (CompletionProposal) proposal;
@@ -100,12 +135,57 @@ namespace Palete {
                                        cell.set_text(p.label);
                                        break;
                                case GtkSource.CompletionColumn.ICON:
-                                       cell.set_icon_name("completion-snippet-symbolic");
-                                       break;
+//cell.set_icon_name("lang-define-symbolic");return;
+//cell.set_icon_name("lang-include-symbolic");return;
+//cell.set_icon_name("lang-typedef-symbolic");return;
+//cell.set_icon_name("lang-union-symbolic");return;                     
+                                       switch (p.ci.kind) {
+                                       
+                                               case    Lsp.CompletionItemKind.Text: cell.set_icon_name("completion-snippet-symbolic");return;
+                                               case    Lsp.CompletionItemKind.Method: cell.set_icon_name("lang-method-symbolic");return;
+                                               case    Lsp.CompletionItemKind.Function: cell.set_icon_name("lang-function-symbolic");return;
+                                               case    Lsp.CompletionItemKind.Constructor: cell.set_icon_name("lang-method-symbolic");return;
+                                               case    Lsp.CompletionItemKind.Field: cell.set_icon_name("lang-struct-field-symbolic");return;
+                                               case    Lsp.CompletionItemKind.Variable: cell.set_icon_name("lang-variable-symbolic");return;
+                                               case    Lsp.CompletionItemKind.Class: cell.set_icon_name("lang-class-symbolic");return;
+                                               case    Lsp.CompletionItemKind.Interface: cell.set_icon_name("lang-class-symbolic");return;
+                                               case    Lsp.CompletionItemKind.Module: cell.set_icon_name("lang-namespace-symbolic");return;
+                                               case    Lsp.CompletionItemKind.Property:cell.set_icon_name("lang-struct-field-symbolic");return;
+                                               case    Lsp.CompletionItemKind.Unit: cell.set_icon_name("lang-variable-symbolic");return;
+                                               case    Lsp.CompletionItemKind.Value: cell.set_icon_name("lang-variable-symbolic");return;
+                                               case    Lsp.CompletionItemKind.Enum: cell.set_icon_name("lang-enum-symbolic");return;
+                                               case    Lsp.CompletionItemKind.Keyword: cell.set_icon_name("completion-word-symbolic");return;
+                                               case    Lsp.CompletionItemKind.Snippet: cell.set_icon_name("completion-snippet-symbolic");return;
+
+                                               case    Lsp.CompletionItemKind.Color: cell.set_icon_name("lang-typedef-symbolic");return;
+                                               case    Lsp.CompletionItemKind.File:cell.set_icon_name("lang-typedef-symbolic");return;
+                                               case    Lsp.CompletionItemKind.Reference: cell.set_icon_name("lang-typedef-symbolic");return;
+                                               case    Lsp.CompletionItemKind.Folder:cell.set_icon_name("lang-typedef-symbolic");return;
+                                               case    Lsp.CompletionItemKind.EnumMember: cell.set_icon_name("lang-typedef-symbolic");return;
+                                               case    Lsp.CompletionItemKind.Constant:cell.set_icon_name("lang-typedef-symbolic");return;
+                                               case    Lsp.CompletionItemKind.Struct: cell.set_icon_name("lang-struct-symbolic");return;
+                                               case    Lsp.CompletionItemKind.Event:cell.set_icon_name("lang-typedef-symbolic");return;
+                                               case    Lsp.CompletionItemKind.Operator:cell.set_icon_name("lang-typedef-symbolic");return;
+                                               case    Lsp.CompletionItemKind.TypeParameter:cell.set_icon_name("lang-typedef-symbolic");return;
+                                               default:
+
+
+
+                                       
+                                                       cell.set_icon_name("completion-snippet-symbolic");
+                                                       return;
+                                               }
+                                               
+                                       
                                case  GtkSource.CompletionColumn.COMMENT:
-                                       cell.set_text(p.info);
+                                       cell.set_text(p.text);
                                        break;
                                case GtkSource.CompletionColumn.DETAILS:
+                                       if (p.ci.documentation != null) {
+                                               cell.set_text(p.ci.documentation.value);
+                                               return;
+                                       }
+                               
                                        cell.set_text(p.text);
                                        break;
                                default:
@@ -114,19 +194,54 @@ namespace Palete {
                        }       
                }
 
-               
+               bool in_populate = false;
         
-               internal  async GLib.ListModel populate_async (GtkSource.CompletionContext context, GLib.Cancellable? cancellable)
+               internal  async GLib.ListModel populate_async (GtkSource.CompletionContext context, GLib.Cancellable? cancellable) 
                {
                        GLib.debug("pupoulate async");
+                       var ret = new GLib.ListStore(typeof(CompletionProposal));
+                       
+                       if (this.in_populate) {
+                               GLib.debug("pupoulate async  - skipped waiting for reply");
+                               return ret;
+                       }
+                       this.in_populate = true;
 
                        global::Gtk.TextIter begin, end;
                        Lsp.CompletionList res;
                        if (context.get_bounds (out begin, out end)) {
-                               yield this.file.getLanguageServer().completion(this.file, end.get_line(), end.get_line_offset(), 1, out res);
+                               var line = end.get_line();
+                               var offset =  end.get_line_offset();
+                               if (this.editor.prop != null) {
+                               //      tried line -1 (does not work)
+                                       GLib.debug("node pad = '%s' %d", this.editor.node.node_pad, this.editor.node.node_pad.length);
+                                       
+                                       line += this.editor.prop.start_line ; 
+                                       // this is based on Gtk using tabs (hence 1/2 chars);
+                                       offset += this.editor.node.node_pad.length;
+                                       // javascript listeners are indented 2 more spaces.
+                                       if (this.editor.prop.ptype == JsRender.NodePropType.LISTENER) {
+                                               offset += 2;
+                                       }
+                               } 
+                               //  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);
+                                       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();
                        
@@ -137,6 +252,7 @@ namespace Palete {
                        var  filter_model = new global::Gtk.FilterListModel(this.model, this.filter); 
                        filter.match_mode = global::Gtk.StringFilterMatchMode.PREFIX;
                        filter_model.set_incremental(true);
+                       this.in_populate = false;
                        return filter_model; 
                        
                         
@@ -146,8 +262,10 @@ namespace Palete {
                internal  void refilter (GtkSource.CompletionContext context, GLib.ListModel in_model)
                {
  
-                       GLib.debug("pupoulate refilter");
-        
+                       //GLib.debug("pupoulate refilter");
+                       if (this.filter == null) {
+                               return;
+                       }
 
                        var word = context.get_word();
                        this.filter.set_search(word);
@@ -200,7 +318,9 @@ namespace Palete {
                        this.search = word;
                        if (res != null) {
                                foreach(var comp in res.items) {
-                                        
+                                        if (comp.label == "_") { // skip '_'
+                                               continue;
+                                       }
                                        this.items.add(new CompletionProposal(comp));   
                                        
                                }
@@ -212,7 +332,7 @@ namespace Palete {
                    }
                
                    items.sort((a, b) => {
-                           return ((string)(a.text)).collate((string)(b.text));
+                           return ((string)(a.label)).collate((string)(b.label));
                    });
                
                }
@@ -264,14 +384,17 @@ namespace Palete {
                
                public string text  { get; set; default = ""; }
                public string info  { get; set; default = ""; }
+               
+               public Lsp.CompletionItem ci;
+               
                public CompletionProposal(Lsp.CompletionItem ci) //string label, string text, string info)
                {
                        
-                       
+                       this.ci = ci;
                        this.text = ci.detail == null ? "" : ci.detail ;
                        this.label = ci.label;
                        this.info = ci.documentation == null ? "": ci.documentation.value;
-                       GLib.debug("SET: text=%s, label = %s; info =%s", ci.detail, ci.label, "to long..");
+                       //GLib.debug("SET: detail =%s, label = %s; info =%s", ci.detail, ci.label, "to long..");
                }
                
        }