[gnome-builder/gnome-builder-3-18] vala: port completions to new API



commit 4e7bfa901c940384bc2c1f365770386733a19a79
Author: Ben Iofel <iofelben gmail com>
Date:   Thu Oct 1 20:33:26 2015 -0400

    vala: port completions to new API

 plugins/vala-pack/ide-vala-completion-item.vala    |   56 ++++------
 .../vala-pack/ide-vala-completion-provider.vala    |  117 ++++----------------
 plugins/vala-pack/ide-vala-index.vala              |   33 +++---
 3 files changed, 60 insertions(+), 146 deletions(-)
---
diff --git a/plugins/vala-pack/ide-vala-completion-item.vala b/plugins/vala-pack/ide-vala-completion-item.vala
index 32c9559..c5339d9 100644
--- a/plugins/vala-pack/ide-vala-completion-item.vala
+++ b/plugins/vala-pack/ide-vala-completion-item.vala
@@ -27,16 +27,17 @@ namespace Ide
                static uint hash_seed;
 
                internal Vala.Symbol symbol;
-               weak Ide.ValaCompletionProvider? provider;
+               weak Ide.ValaCompletionProvider provider;
                string label;
 
                static construct {
                        hash_seed = "IdeValaCompletionItem".hash ();
                }
 
-               public ValaCompletionItem (Vala.Symbol symbol)
+               public ValaCompletionItem (Vala.Symbol symbol, Ide.ValaCompletionProvider provider)
                {
                        this.symbol = symbol;
+                       this.provider = provider;
 
                        /* Unfortunate we have to do this here, because it would
                         * be better to do this lazy. But that would require access to
@@ -45,11 +46,6 @@ namespace Ide
                        this.build_label ();
                }
 
-               internal void set_provider (Ide.ValaCompletionProvider? provider)
-               {
-                       this.provider = provider;
-               }
-
                public unowned string? get_icon_name ()
                {
                        if (symbol is Vala.LocalVariable)
@@ -78,23 +74,12 @@ namespace Ide
                        return null;
                }
 
-               public bool matches (string? prefix_lower)
-               {
-                       uint priority;
-                       bool ret;
-
-                       if (prefix_lower == null || prefix_lower [0] == '\0')
-                               return true;
-
-                       ret = Ide.CompletionItem.fuzzy_match (this.symbol.name, prefix_lower, out priority);
-                       /* TODO: Save priority to use for sorting. */
-
-                       return ret;
-               }
-
-               public string get_label ()
+               public override bool match (string query, string casefold)
                {
-                       return this.symbol.name;
+                       uint priority = 0;
+                       bool result = Ide.CompletionItem.fuzzy_match (this.symbol.name, casefold, out 
priority);
+                       this.set_priority (priority);
+                       return result;
                }
 
                public void build_label ()
@@ -142,10 +127,13 @@ namespace Ide
                        this.label = (owned)str.str;
                }
 
-               public string get_markup ()
-               {
-                       if (this.provider != null)
-                               return highlight_full (this.label, this.provider.last_prefix, true, 1);
+               public string get_markup () {
+                       if (this.provider.query != null)
+                               return highlight_full (this.label, this.provider.query, true, 1 /* 
GB_HIGHLIGHT_BOLD */);
+                       return "";
+               }
+
+               public string get_label () {
                        return this.label;
                }
 
@@ -154,16 +142,20 @@ namespace Ide
                        return this.symbol.name;
                }
 
+               public string? get_info () {
+                       return null;
+               }
+
+               public unowned GLib.Icon? get_gicon () {
+                       return null;
+               }
+
                public uint hash ()
                {
                        return this.symbol.name.hash () ^ hash_seed;
                }
-
-               public unowned GLib.Icon? get_gicon () { return null; }
-               public unowned Gdk.Pixbuf? get_icon () { return null; }
-               public string? get_info () { return null; }
        }
 
        [CCode (cheader_filename = "gb-string.h", cname = "gb_str_highlight_full")]
-       extern string? highlight_full (string haystack, string needle, bool insensitive, int type);
+       extern unowned string? highlight_full (string haystack, string needle, bool insensitive, int type);
 }
diff --git a/plugins/vala-pack/ide-vala-completion-provider.vala 
b/plugins/vala-pack/ide-vala-completion-provider.vala
index 6061695..69a285f 100644
--- a/plugins/vala-pack/ide-vala-completion-provider.vala
+++ b/plugins/vala-pack/ide-vala-completion-provider.vala
@@ -22,39 +22,14 @@ using Vala;
 
 namespace Ide
 {
-       /*
-        * TODO:
-        *
-        *   There is some fun optimization work we can do here to work around the
-        *   list interface of GtkSourceCompletionContext. However, I'm not yet
-        *   sure how to do this in Vala. In C, of course, it's trivial.
-        *
-        *   The goal here is to reduce the overhead of sorting the GList of items
-        *   that needs to be sent to GtkSourceCompletionContext. We may want to
-        *   reorder them based on the input text or another better sorting
-        *   heuristic. But doing that on a malloc'd list is expensive and
-        *   annoying.
-        *
-        *   We could solve this by having an array of GList,pointer fields and
-        *   update the GList items after sorting. We could also just embed the
-        *   GList in the Ide.ValaCompletionitem (but I don't know how to do this
-        *   in Vala. I guess we could make a subclass for this too.
-        *
-        *   This way, when looking at our previous items, we sort using a
-        *   cacheline efficient array of items, and just update the pointers
-        *   at the same time or at the end.
-        *
-        *   For now, we'll do the dumb stupid slow thing.
-        */
        public class ValaCompletionProvider: Ide.Object,
                                             Gtk.SourceCompletionProvider,
                                             Ide.CompletionProvider
        {
-               internal string? last_prefix;
-               GenericArray<Ide.ValaCompletionItem>? last_results;
-               string? last_line;
+               internal string? query;
                int line = -1;
                int column = -1;
+               Ide.CompletionResults? results;
 
                public void populate (Gtk.SourceCompletionContext context)
                {
@@ -66,41 +41,22 @@ namespace Ide
                                return;
                        }
 
-                       var prefix = CompletionProvider.context_current_word (context);
+                       this.query = CompletionProvider.context_current_word (context);
 
                        begin = iter;
                        begin.set_line_offset (0);
                        var line = begin.get_slice (iter);
 
-                       /*
-                        * We might be able to reuse the results from our previous query if
-                        * the buffer is sufficiently similar. If so, possibly just
-                        * rearrange some things and redisplay those results.
-                        */
-                       if (can_replay (line)) {
-                               HashTable<void*,bool> dedup = new HashTable<void*,bool> (GLib.direct_hash, 
GLib.direct_equal);
-
-                               var downcase = prefix.down ();
-                               var results = new GLib.List<Gtk.SourceCompletionProposal> ();
-
-                               /* See the comment above about optimizing this. */
-                               for (int i = 0; i < this.last_results.length; i++) {
-                                       var result = this.last_results.get (i);
-                                       if (result.matches (downcase)) {
-                                               var hash = (void*)result.hash ();
-                                               if (dedup.contains ((void*)hash))
-                                                       continue;
-                                               results.prepend (result);
-                                               dedup.insert (hash, true);
-                                       }
+                       if (this.results != null) {
+                               if (this.results.replay (this.query)) {
+                                       this.results.present (this, context);
+                                       return;
                                }
+                               this.results = null;
+                       }
 
-                               this.last_prefix = prefix;
-
-                               results.reverse ();
-
-                               context.add_proposals (this, results, true);
-
+                       if (this.query.length < 3) {
+                               context.add_proposals (this, null, true);
                                return;
                        }
 
@@ -117,8 +73,7 @@ namespace Ide
 
                        buffer.sync_to_unsaved_files ();
 
-                       var service = (this.get_context ()
-                                          .get_service_typed (typeof (Ide.ValaService)) as Ide.ValaService);
+                       var service = (this.get_context ().get_service_typed (typeof (Ide.ValaService)) as 
Ide.ValaService);
                        var index = service.index;
                        var unsaved_files = this.get_context ().get_unsaved_files ();
 
@@ -132,35 +87,22 @@ namespace Ide
                                                   iter.get_line_offset () + 1,
                                                   line,
                                                   unsaved_files,
+                                                  this,
                                                   null,
                                                   (obj,res) => {
                                int res_line = -1;
                                int res_column = -1;
 
-                               var results = index.code_complete.end (res, out res_line , out res_column);
+                               this.results = index.code_complete.end (res, out res_line, out res_column);
 
                                if (res_line > 0 && res_column > 0) {
                                        this.line = res_line - 1;
                                        this.column = res_column - 1;
                                }
 
-                               results.sort ((a,b) => {
-                                       return -GLib.strcmp (a.symbol.name, b.symbol.name);
-                               });
-
                                if (!cancellable.is_cancelled ()) {
-                                       /* TODO: fix more brain dead slow list conversion stuff */
-                                       var list = new GLib.List<Ide.ValaCompletionItem> ();
-                                       for (int i = 0; i < results.length; i++) {
-                                               var item = results.get (i);
-                                               list.prepend (item);
-                                               item.set_provider (this);
-                                       }
-                                       context.add_proposals (this, list, true);
+                                       this.results.present (this, context);
                                }
-
-                               this.last_results = results;
-                               this.last_line = line;
                        });
                }
 
@@ -186,35 +128,16 @@ namespace Ide
                                        return false;
                        }
 
-                       return true;
-               }
-
-               /*
-                * Check to see if this line can be replayed using the results from
-                * the previous query. We can do that if the characters that have
-                * changed are simply alphanumeric or _ (function or symbol name
-                * characters). We just need to massage the results appropriately.
-                */
-               bool can_replay (string? line)
-               {
-                       if (line == null || this.last_line == null)
+                       if (Ide.CompletionProvider.context_in_comment (context))
                                return false;
 
-                       if (!line.has_prefix (this.last_line))
-                               return false;
-
-                       var suffix = line.offset (this.last_line.length);
-
-                       while (suffix[0] != '\0') {
-                               var ch = suffix.get_char ();
-                               if (!ch.isalnum() && ch != '_')
-                                       return false;
-                               suffix = suffix.next_char ();
-                       }
-
                        return true;
                }
 
+               public string get_name () {
+                       return "Vala";
+               }
+
                public int get_priority ()
                {
                        return 200;
diff --git a/plugins/vala-pack/ide-vala-index.vala b/plugins/vala-pack/ide-vala-index.vala
index 88a5a81..56f9b34 100644
--- a/plugins/vala-pack/ide-vala-index.vala
+++ b/plugins/vala-pack/ide-vala-index.vala
@@ -114,7 +114,7 @@ namespace Ide
 
                void add_file (GLib.File file)
                {
-                       var path  =file.get_path ();
+                       var path = file.get_path ();
                        if (path == null)
                                return;
 
@@ -175,17 +175,18 @@ namespace Ide
                        return true;
                }
 
-               public async GenericArray<Ide.ValaCompletionItem> code_complete (GLib.File file,
-                                                                                int line,
-                                                                                int column,
-                                                                                string? line_text,
-                                                                                Ide.UnsavedFiles? 
unsaved_files,
-                                                                                out int result_line,
-                                                                                out int result_column,
-                                                                                GLib.Cancellable? 
cancellable)
+               public async Ide.CompletionResults code_complete (GLib.File file,
+                                                                 int line,
+                                                                 int column,
+                                                                 string? line_text,
+                                                                 Ide.UnsavedFiles? unsaved_files,
+                                                                 Ide.ValaCompletionProvider provider,
+                                                                 GLib.Cancellable? cancellable,
+                                                                 out int result_line,
+                                                                 out int result_column)
                {
                        var unsaved_files_copy = unsaved_files.to_array ();
-                       var result = new GenericArray<Ide.ValaCompletionItem> ();
+                       var result = new Ide.CompletionResults (provider.query);
 
                        Ide.ThreadPool.push (Ide.ThreadPoolKind.COMPILER, () => {
                                if ((cancellable == null) || !cancellable.is_cancelled ()) {
@@ -202,7 +203,7 @@ namespace Ide
                                                        var locator = new Ide.ValaLocator ();
                                                        var nearest = locator.locate (source_file, line, 
column);
 
-                                                       this.add_completions (source_file, ref line, ref 
column, text, nearest, result);
+                                                       this.add_completions (source_file, ref line, ref 
column, text, nearest, result, provider);
                                                }
 
                                                Vala.CodeContext.pop ();
@@ -274,12 +275,10 @@ namespace Ide
                                      ref int column,
                                      string line_text,
                                      Vala.Symbol? nearest,
-                                     GenericArray<Ide.ValaCompletionItem> results)
+                                     Ide.CompletionResults results,
+                                     Ide.ValaCompletionProvider provider)
                {
-                       if (!(nearest is Vala.Block))
-                               nearest = null;
-
-                       var block = (Vala.Block)nearest;
+                       var block = nearest as Vala.Block;
                        Vala.SourceLocation cursor = Vala.SourceLocation (null, line, column);
 
                        // TODO: our list building could use a lot of low-hanging optimizations.
@@ -291,7 +290,7 @@ namespace Ide
 
                        foreach (var symbol in list) {
                                if (symbol.name != null && symbol.name[0] != '\0')
-                                       results.add (new Ide.ValaCompletionItem (symbol));
+                                       results.take_proposal (new Ide.ValaCompletionItem (symbol, provider));
                        }
 
                        line = cursor.line;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]