[gnome-builder/wip/chergert/completion] completion: allow tweaking priority for completion



commit 9bbf47fc1bedc1f06b04898906f1de798d922438
Author: Christian Hergert <chergert redhat com>
Date:   Wed Jun 6 21:40:01 2018 -0700

    completion: allow tweaking priority for completion
    
    Based on the completion location, we may want to alter the priority of the
    group of completion items. This allows the snippet provider to be lower
    priority when it isn't at the beginning of a line, so that more interesting
    results are at the top.
    
    Another thing we can do, is to create a special internal list model that
    is used for very likely results and let providers register them with the
    context.

 src/libide/completion/ide-completion-context.c           | 16 ++++++++++++----
 src/libide/completion/ide-completion-provider.c          | 10 ++++++++--
 src/libide/completion/ide-completion-provider.h          |  6 ++++--
 src/libide/langserv/ide-langserv-completion-provider.c   |  3 ++-
 src/plugins/clang/ide-clang-completion-provider.c        |  3 ++-
 src/plugins/ctags/ide-ctags-completion-provider.c        |  3 ++-
 .../html-completion/ide-html-completion-provider.c       |  3 ++-
 src/plugins/jedi/jedi_plugin.py                          |  5 +----
 .../python_gi_imports_completion.py                      |  2 +-
 src/plugins/snippets/ide-snippet-completion-provider.c   | 16 +++++++++++++++-
 src/plugins/vala-pack/ide-vala-completion-provider.vala  |  2 +-
 11 files changed, 50 insertions(+), 19 deletions(-)
---
diff --git a/src/libide/completion/ide-completion-context.c b/src/libide/completion/ide-completion-context.c
index 27c2bc485..d58453765 100644
--- a/src/libide/completion/ide-completion-context.c
+++ b/src/libide/completion/ide-completion-context.c
@@ -95,13 +95,15 @@ clear_provider_info (gpointer data)
 
 static gint
 compare_provider_info (gconstpointer a,
-                       gconstpointer b)
+                       gconstpointer b,
+                       gpointer      user_data)
 {
+  IdeCompletionContext *self = user_data;
   const ProviderInfo *info_a = a;
   const ProviderInfo *info_b = b;
 
-  return ide_completion_provider_get_priority (info_a->provider) -
-         ide_completion_provider_get_priority (info_b->provider);
+  return ide_completion_provider_get_priority (info_a->provider, self) -
+         ide_completion_provider_get_priority (info_b->provider, self);
 }
 
 static void
@@ -319,7 +321,7 @@ _ide_completion_context_add_provider (IdeCompletionContext  *self,
   info.results = NULL;
 
   g_array_append_val (self->providers, info);
-  g_array_sort (self->providers, compare_provider_info);
+  g_array_sort_with_data (self->providers, compare_provider_info, self);
 }
 
 void
@@ -508,6 +510,7 @@ _ide_completion_context_complete_async (IdeCompletionContext *self,
   g_autoptr(IdeTask) task = NULL;
   CompleteTaskData *task_data;
   GtkTextBuffer *buffer;
+  guint n_items;
 
   g_return_if_fail (IDE_IS_COMPLETION_CONTEXT (self));
   g_return_if_fail (self->has_populated == FALSE);
@@ -555,6 +558,11 @@ _ide_completion_context_complete_async (IdeCompletionContext *self,
                                               g_object_ref (task));
     }
 
+  /* Providers may adjust their position based on our new marks */
+  n_items = g_list_model_get_n_items (G_LIST_MODEL (self));
+  g_array_sort_with_data (self->providers, compare_provider_info, self);
+  g_list_model_items_changed (G_LIST_MODEL (self), 0, n_items, n_items);
+
   if (task_data->n_active == 0)
       ide_task_return_boolean (task, TRUE);
 
diff --git a/src/libide/completion/ide-completion-provider.c b/src/libide/completion/ide-completion-provider.c
index fe96368e6..15490ac2f 100644
--- a/src/libide/completion/ide-completion-provider.c
+++ b/src/libide/completion/ide-completion-provider.c
@@ -56,23 +56,29 @@ ide_completion_provider_get_icon (IdeCompletionProvider *self)
 /**
  * ide_completion_provider_get_priority:
  * @self: an #IdeCompletionProvider
+ * @context: an #IdeCompletionContext
  *
  * Gets the priority for the completion provider.
  *
  * This value is used to group all of the providers proposals together
  * when displayed, with relation to other providers.
  *
+ * The @context is provided as some providers may want to lower their
+ * priority based on the position of the completion.
+ *
  * Returns: an integer specific to the provider
  *
  * Since: 3.28
  */
 gint
-ide_completion_provider_get_priority (IdeCompletionProvider *self)
+ide_completion_provider_get_priority (IdeCompletionProvider *self,
+                                      IdeCompletionContext  *context)
 {
   g_return_val_if_fail (IDE_IS_COMPLETION_PROVIDER (self), 0);
+  g_return_val_if_fail (IDE_IS_COMPLETION_CONTEXT (context), 0);
 
   if (IDE_COMPLETION_PROVIDER_GET_IFACE (self)->get_priority)
-    return IDE_COMPLETION_PROVIDER_GET_IFACE (self)->get_priority (self);
+    return IDE_COMPLETION_PROVIDER_GET_IFACE (self)->get_priority (self, context);
 
   return 0;
 }
diff --git a/src/libide/completion/ide-completion-provider.h b/src/libide/completion/ide-completion-provider.h
index 94a9b8f33..706d6c3fa 100644
--- a/src/libide/completion/ide-completion-provider.h
+++ b/src/libide/completion/ide-completion-provider.h
@@ -39,7 +39,8 @@ struct _IdeCompletionProviderInterface
   void        (*load)              (IdeCompletionProvider    *self,
                                     IdeContext               *context);
   GIcon      *(*get_icon)          (IdeCompletionProvider    *self);
-  gint        (*get_priority)      (IdeCompletionProvider    *self);
+  gint        (*get_priority)      (IdeCompletionProvider    *self,
+                                    IdeCompletionContext     *context);
   gchar      *(*get_title)         (IdeCompletionProvider    *self);
   void        (*populate_async)    (IdeCompletionProvider    *self,
                                     IdeCompletionContext     *context,
@@ -74,7 +75,8 @@ struct _IdeCompletionProviderInterface
 IDE_AVAILABLE_IN_3_30
 GIcon      *ide_completion_provider_get_icon         (IdeCompletionProvider    *self);
 IDE_AVAILABLE_IN_3_30
-gint        ide_completion_provider_get_priority     (IdeCompletionProvider    *self);
+gint        ide_completion_provider_get_priority     (IdeCompletionProvider    *self,
+                                                      IdeCompletionContext     *context);
 IDE_AVAILABLE_IN_3_30
 gchar      *ide_completion_provider_get_title        (IdeCompletionProvider    *self);
 IDE_AVAILABLE_IN_3_30
diff --git a/src/libide/langserv/ide-langserv-completion-provider.c 
b/src/libide/langserv/ide-langserv-completion-provider.c
index 5f29cd66b..26c62ea73 100644
--- a/src/libide/langserv/ide-langserv-completion-provider.c
+++ b/src/libide/langserv/ide-langserv-completion-provider.c
@@ -163,7 +163,8 @@ ide_langserv_completion_provider_set_client (IdeLangservCompletionProvider *self
 }
 
 static gint
-ide_langserv_completion_provider_get_priority (IdeCompletionProvider *provider)
+ide_langserv_completion_provider_get_priority (IdeCompletionProvider *provider,
+                                               IdeCompletionContext  *context)
 {
   return IDE_LANGSERV_COMPLETION_PROVIDER_PRIORITY;
 }
diff --git a/src/plugins/clang/ide-clang-completion-provider.c 
b/src/plugins/clang/ide-clang-completion-provider.c
index fa9b73999..74dfa5652 100644
--- a/src/plugins/clang/ide-clang-completion-provider.c
+++ b/src/plugins/clang/ide-clang-completion-provider.c
@@ -31,7 +31,8 @@ struct _IdeClangCompletionProvider
 };
 
 static gint
-ide_clang_completion_provider_get_priority (IdeCompletionProvider *provider)
+ide_clang_completion_provider_get_priority (IdeCompletionProvider *provider,
+                                            IdeCompletionContext  *context)
 {
   return 100;
 }
diff --git a/src/plugins/ctags/ide-ctags-completion-provider.c 
b/src/plugins/ctags/ide-ctags-completion-provider.c
index 1ba07d4c0..4943bf5df 100644
--- a/src/plugins/ctags/ide-ctags-completion-provider.c
+++ b/src/plugins/ctags/ide-ctags-completion-provider.c
@@ -323,7 +323,8 @@ ide_ctags_completion_provider_populate_finish (IdeCompletionProvider  *provider,
 }
 
 static gint
-ide_ctags_completion_provider_get_priority (IdeCompletionProvider *provider)
+ide_ctags_completion_provider_get_priority (IdeCompletionProvider *provider,
+                                            IdeCompletionContext  *context)
 {
   return IDE_CTAGS_COMPLETION_PROVIDER_PRIORITY;
 }
diff --git a/src/plugins/html-completion/ide-html-completion-provider.c 
b/src/plugins/html-completion/ide-html-completion-provider.c
index dd97069fc..2c029fd8e 100644
--- a/src/plugins/html-completion/ide-html-completion-provider.c
+++ b/src/plugins/html-completion/ide-html-completion-provider.c
@@ -448,7 +448,8 @@ ide_html_completion_provider_display_proposal (IdeCompletionProvider   *provider
 }
 
 static gint
-ide_html_completion_provider_get_priority (IdeCompletionProvider *provider)
+ide_html_completion_provider_get_priority (IdeCompletionProvider *provider,
+                                           IdeCompletionContext  *context)
 {
   return 200;
 }
diff --git a/src/plugins/jedi/jedi_plugin.py b/src/plugins/jedi/jedi_plugin.py
index 540ab2300..3eed9ce81 100644
--- a/src/plugins/jedi/jedi_plugin.py
+++ b/src/plugins/jedi/jedi_plugin.py
@@ -432,7 +432,7 @@ class JediCompletionProvider(Ide.Object, Ide.CompletionProvider):
     def do_get_icon(self):
         return None
 
-    def do_get_priority(self):
+    def do_get_priority(self, context):
         return 200
 
     def do_load(self, context):
@@ -510,9 +510,6 @@ class JediCompletionProvider(Ide.Object, Ide.CompletionProvider):
     def do_populate_finish(self, result):
         return result.propagate_object()
 
-    def do_get_priority(self):
-        return 200
-
     def do_refilter(self, context, model):
         word = context.get_word().lower()
         model.refilter(word)
diff --git a/src/plugins/python-gi-imports-completion/python_gi_imports_completion.py 
b/src/plugins/python-gi-imports-completion/python_gi_imports_completion.py
index 16f2e5b7d..3a61ebc14 100644
--- a/src/plugins/python-gi-imports-completion/python_gi_imports_completion.py
+++ b/src/plugins/python-gi-imports-completion/python_gi_imports_completion.py
@@ -82,7 +82,7 @@ class CompletionProvider(Ide.Object, Ide.CompletionProvider):
         buffer.insert(begin, proposal.completion, -1)
         buffer.end_user_action()
 
-    def do_get_priority(self):
+    def do_get_priority(self, context):
         # This provider only activates when it is very likely that we
         # want the results. So use high priority (negative is better).
         return -1000
diff --git a/src/plugins/snippets/ide-snippet-completion-provider.c 
b/src/plugins/snippets/ide-snippet-completion-provider.c
index 31d1aa9dd..7c4319075 100644
--- a/src/plugins/snippets/ide-snippet-completion-provider.c
+++ b/src/plugins/snippets/ide-snippet-completion-provider.c
@@ -75,8 +75,22 @@ ide_snippet_completion_provider_load (IdeCompletionProvider *provider,
 }
 
 static gint
-ide_snippet_completion_provider_get_priority (IdeCompletionProvider *provider)
+ide_snippet_completion_provider_get_priority (IdeCompletionProvider *provider,
+                                              IdeCompletionContext  *context)
 {
+  GtkTextIter begin, end;
+
+  if (ide_completion_context_get_bounds (context, &begin, &end))
+    {
+      while (!gtk_text_iter_starts_line (&begin) &&
+             gtk_text_iter_backward_char (&begin))
+        {
+          /* Penalize the priority if we aren't at the beginning of the line */
+          if (!g_unichar_isspace (gtk_text_iter_get_char (&begin)))
+            return 500;
+        }
+    }
+
   return -100;
 }
 
diff --git a/src/plugins/vala-pack/ide-vala-completion-provider.vala 
b/src/plugins/vala-pack/ide-vala-completion-provider.vala
index 93f48dd93..2174f0306 100644
--- a/src/plugins/vala-pack/ide-vala-completion-provider.vala
+++ b/src/plugins/vala-pack/ide-vala-completion-provider.vala
@@ -108,7 +108,7 @@ namespace Ide
                        return "Vala";
                }
 
-               public int get_priority ()
+               public int get_priority (Ide.CompletionContext context)
                {
                        return 200;
                }


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