[gnome-builder/wip/chergert/completion] completion: allow delivering results early



commit 4ce50dd2fad92d249206fe23dc56f59327de1228
Author: Christian Hergert <chergert redhat com>
Date:   Wed Jun 6 23:30:24 2018 -0700

    completion: allow delivering results early
    
    Since we lost our out parameter, we need another way to deliver
    results early. This is arguably a better design since it doesn't
    hit the corner cases of G-I bindings.

 src/libide/completion/ide-completion-context.c    | 26 ++++++++++----
 src/libide/completion/ide-completion-context.h    | 42 +++++++++++++----------
 src/libide/completion/ide-completion-provider.c   |  4 +++
 src/plugins/clang/ide-clang-completion-provider.c |  8 +++++
 4 files changed, 55 insertions(+), 25 deletions(-)
---
diff --git a/src/libide/completion/ide-completion-context.c b/src/libide/completion/ide-completion-context.c
index d58453765..dab4bc4bc 100644
--- a/src/libide/completion/ide-completion-context.c
+++ b/src/libide/completion/ide-completion-context.c
@@ -382,10 +382,24 @@ ide_completion_context_items_changed_cb (IdeCompletionContext  *self,
   ide_completion_context_update_empty (self);
 }
 
-static void
-ide_completion_context_set_results_for_provider (IdeCompletionContext  *self,
-                                                 IdeCompletionProvider *provider,
-                                                 GListModel            *results)
+/**
+ * ide_completion_context_set_proposals_for_provider:
+ * @self: an #IdeCompletionContext
+ * @provider: an #IdeCompletionProvider
+ * @results: (nullable): a #GListModel or %NULL
+ *
+ * This function allows providers to update their results for a context
+ * outside of a call to ide_completion_provider_populate_async(). This
+ * can be used to immediately return results for a provider while it does
+ * additional asynchronous work. Doing so will allow the completions to
+ * update while the operation is in progress.
+ *
+ * Since: 3.30
+ */
+void
+ide_completion_context_set_proposals_for_provider (IdeCompletionContext  *self,
+                                                   IdeCompletionProvider *provider,
+                                                   GListModel            *results)
 {
   guint position = 0;
 
@@ -403,7 +417,7 @@ ide_completion_context_set_results_for_provider (IdeCompletionContext  *self,
           guint n_added = 0;
 
           if (info->results == results)
-            break;
+            return;
 
           if (info->results != NULL)
             n_removed = g_list_model_get_n_items (info->results);
@@ -464,7 +478,7 @@ ide_completion_context_populate_cb (GObject      *object,
   if (!(results = ide_completion_provider_populate_finish (provider, result, &error)))
     ide_completion_context_mark_failed (self, provider, error);
   else
-    ide_completion_context_set_results_for_provider (self, provider, results);
+    ide_completion_context_set_proposals_for_provider (self, provider, results);
 
   task_data->n_active--;
 
diff --git a/src/libide/completion/ide-completion-context.h b/src/libide/completion/ide-completion-context.h
index 5780f2a03..9e368cd2d 100644
--- a/src/libide/completion/ide-completion-context.h
+++ b/src/libide/completion/ide-completion-context.h
@@ -29,35 +29,39 @@ IDE_AVAILABLE_IN_3_30
 G_DECLARE_FINAL_TYPE (IdeCompletionContext, ide_completion_context, IDE, COMPLETION_CONTEXT, GObject)
 
 IDE_AVAILABLE_IN_3_30
-const gchar   *ide_completion_context_get_language    (IdeCompletionContext   *self);
+const gchar   *ide_completion_context_get_language               (IdeCompletionContext   *self);
 IDE_AVAILABLE_IN_3_30
-gboolean       ide_completion_context_is_language     (IdeCompletionContext   *self,
-                                                       const gchar            *language);
+gboolean       ide_completion_context_is_language                (IdeCompletionContext   *self,
+                                                                  const gchar            *language);
 IDE_AVAILABLE_IN_3_30
-GtkTextBuffer *ide_completion_context_get_buffer      (IdeCompletionContext   *self);
+GtkTextBuffer *ide_completion_context_get_buffer                 (IdeCompletionContext   *self);
 IDE_AVAILABLE_IN_3_30
-GtkTextView   *ide_completion_context_get_view        (IdeCompletionContext   *self);
+GtkTextView   *ide_completion_context_get_view                   (IdeCompletionContext   *self);
 IDE_AVAILABLE_IN_3_30
-gboolean       ide_completion_context_get_busy        (IdeCompletionContext   *self);
+gboolean       ide_completion_context_get_busy                   (IdeCompletionContext   *self);
 IDE_AVAILABLE_IN_3_30
-gboolean       ide_completion_context_is_empty        (IdeCompletionContext   *self);
+gboolean       ide_completion_context_is_empty                   (IdeCompletionContext   *self);
 IDE_AVAILABLE_IN_3_30
-IdeCompletion *ide_completion_context_get_completion  (IdeCompletionContext   *self);
+void           ide_completion_context_set_proposals_for_provider (IdeCompletionContext  *self,
+                                                                  IdeCompletionProvider *provider,
+                                                                  GListModel            *model);
 IDE_AVAILABLE_IN_3_30
-gboolean       ide_completion_context_get_bounds      (IdeCompletionContext   *self,
-                                                       GtkTextIter            *begin,
-                                                       GtkTextIter            *end);
+IdeCompletion *ide_completion_context_get_completion             (IdeCompletionContext   *self);
 IDE_AVAILABLE_IN_3_30
-gboolean       ide_completion_context_get_start_iter  (IdeCompletionContext   *self,
-                                                       GtkTextIter            *iter);
+gboolean       ide_completion_context_get_bounds                 (IdeCompletionContext   *self,
+                                                                  GtkTextIter            *begin,
+                                                                  GtkTextIter            *end);
 IDE_AVAILABLE_IN_3_30
-gchar         *ide_completion_context_get_word        (IdeCompletionContext   *self);
+gboolean       ide_completion_context_get_start_iter             (IdeCompletionContext   *self,
+                                                                  GtkTextIter            *iter);
 IDE_AVAILABLE_IN_3_30
-gchar         *ide_completion_context_get_line_text   (IdeCompletionContext   *self);
+gchar         *ide_completion_context_get_word                   (IdeCompletionContext   *self);
 IDE_AVAILABLE_IN_3_30
-gboolean       ide_completion_context_get_item_full   (IdeCompletionContext   *self,
-                                                       guint                   position,
-                                                       IdeCompletionProvider **provider,
-                                                       IdeCompletionProposal **proposal);
+gchar         *ide_completion_context_get_line_text              (IdeCompletionContext   *self);
+IDE_AVAILABLE_IN_3_30
+gboolean       ide_completion_context_get_item_full              (IdeCompletionContext   *self,
+                                                                  guint                   position,
+                                                                  IdeCompletionProvider **provider,
+                                                                  IdeCompletionProposal **proposal);
 
 G_END_DECLS
diff --git a/src/libide/completion/ide-completion-provider.c b/src/libide/completion/ide-completion-provider.c
index 15490ac2f..c426efc0f 100644
--- a/src/libide/completion/ide-completion-provider.c
+++ b/src/libide/completion/ide-completion-provider.c
@@ -114,6 +114,10 @@ ide_completion_provider_get_title (IdeCompletionProvider *self)
  *
  * Asynchronously requests the provider populate the contents.
  *
+ * For completion providers that can provide intermediate results immediately,
+ * use ide_completion_context_set_proposals_for_provider() to notify of results
+ * while the async operation is in progress.
+ *
  * Since: 3.28
  */
 void
diff --git a/src/plugins/clang/ide-clang-completion-provider.c 
b/src/plugins/clang/ide-clang-completion-provider.c
index 74dfa5652..65d404abd 100644
--- a/src/plugins/clang/ide-clang-completion-provider.c
+++ b/src/plugins/clang/ide-clang-completion-provider.c
@@ -232,6 +232,14 @@ ide_clang_completion_provider_populate_async (IdeCompletionProvider  *provider,
   if (self->proposals == NULL)
     self->proposals = ide_clang_proposals_new (self->client);
 
+  /* Deliver results immediately until our updated results come in. Often what
+   * the user wants will be in the previous list too, and that can drop the
+   * latency a bit.
+   */
+  ide_completion_context_set_proposals_for_provider (context,
+                                                     provider,
+                                                     G_LIST_MODEL (self->proposals));
+
   ide_clang_proposals_populate_async (self->proposals,
                                       &begin,
                                       word,


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