[gnome-builder/wip/chergert/completion] ctags: make ctags search more lazy



commit 6129ba3610eb01645769b3ff6c886d52a2af14c6
Author: Christian Hergert <chergert redhat com>
Date:   Thu May 10 14:31:36 2018 -0700

    ctags: make ctags search more lazy
    
    This now performs the search in a thread and avoids creating an GObjects
    until they've been requested by the GListModel interface. That means our
    dynamic allocations are now just an array to point to the index entry (and
    it's priority for sorting). The objects can now be discarded at will when
    they are no longer visible.

 src/plugins/ctags/ide-ctags-completion-item.c     |  22 +-
 src/plugins/ctags/ide-ctags-completion-item.h     |  12 +-
 src/plugins/ctags/ide-ctags-completion-provider.c | 109 +++-----
 src/plugins/ctags/ide-ctags-index.c               |   4 +
 src/plugins/ctags/ide-ctags-index.h               |   4 +
 src/plugins/ctags/ide-ctags-results.c             | 317 ++++++++++++++++++++++
 src/plugins/ctags/ide-ctags-results.h             |  46 ++++
 src/plugins/ctags/meson.build                     |  10 +-
 8 files changed, 426 insertions(+), 98 deletions(-)
---
diff --git a/src/plugins/ctags/ide-ctags-completion-item.c b/src/plugins/ctags/ide-ctags-completion-item.c
index 74e078a5a..8254fdaf0 100644
--- a/src/plugins/ctags/ide-ctags-completion-item.c
+++ b/src/plugins/ctags/ide-ctags-completion-item.c
@@ -22,16 +22,8 @@
 #include <glib/gi18n.h>
 
 #include "ide-ctags-completion-item.h"
-#include "ide-ctags-completion-provider.h"
-#include "ide-ctags-completion-provider-private.h"
 #include "ide-ctags-index.h"
-
-struct _IdeCtagsCompletionItem
-{
-  GObject parent_instance;
-  const IdeCtagsIndexEntry *entry;
-  IdeCtagsCompletionProvider *provider;
-};
+#include "ide-ctags-results.h"
 
 static void proposal_iface_init (IdeCompletionProposalInterface *iface);
 
@@ -44,15 +36,19 @@ G_DEFINE_DYNAMIC_TYPE_EXTENDED (IdeCtagsCompletionItem,
 DZL_DEFINE_COUNTER (instances, "IdeCtagsCompletionItem", "Instances", "Number of IdeCtagsCompletionItems")
 
 IdeCtagsCompletionItem *
-ide_ctags_completion_item_new (IdeCtagsCompletionProvider *provider,
-                               const IdeCtagsIndexEntry   *entry)
+ide_ctags_completion_item_new (IdeCtagsResults          *results,
+                               const IdeCtagsIndexEntry *entry)
 {
   IdeCtagsCompletionItem *self;
 
-  g_return_val_if_fail (entry != NULL, NULL);
+  /*
+   * we hold a reference to results so that we can ensure that
+   * a reference to the index that contains @entry is maintained.
+   * (as indexes are never unref'd from @results until finalized).
+   */
 
   self = g_object_new (IDE_TYPE_CTAGS_COMPLETION_ITEM, NULL);
-  self->provider = provider;
+  self->results = g_object_ref (results);
   self->entry = entry;
 
   return self;
diff --git a/src/plugins/ctags/ide-ctags-completion-item.h b/src/plugins/ctags/ide-ctags-completion-item.h
index 3598faaab..f9c714ebf 100644
--- a/src/plugins/ctags/ide-ctags-completion-item.h
+++ b/src/plugins/ctags/ide-ctags-completion-item.h
@@ -18,11 +18,10 @@
 
 #pragma once
 
-#include <gtksourceview/gtksource.h>
 #include <ide.h>
 
 #include "ide-ctags-index.h"
-#include "ide-ctags-completion-provider.h"
+#include "ide-ctags-results.h"
 
 G_BEGIN_DECLS
 
@@ -30,7 +29,14 @@ G_BEGIN_DECLS
 
 G_DECLARE_FINAL_TYPE (IdeCtagsCompletionItem, ide_ctags_completion_item, IDE, CTAGS_COMPLETION_ITEM, GObject)
 
-IdeCtagsCompletionItem *ide_ctags_completion_item_new         (IdeCtagsCompletionProvider *provider,
+struct _IdeCtagsCompletionItem
+{
+  GObject parent_instance;
+  const IdeCtagsIndexEntry *entry;
+  IdeCtagsResults *results;
+};
+
+IdeCtagsCompletionItem *ide_ctags_completion_item_new         (IdeCtagsResults            *results,
                                                                const IdeCtagsIndexEntry   *entry);
 gboolean                ide_ctags_completion_item_is_function (IdeCtagsCompletionItem     *self);
 IdeSourceSnippet       *ide_ctags_completion_item_get_snippet (IdeCtagsCompletionItem     *self,
diff --git a/src/plugins/ctags/ide-ctags-completion-provider.c 
b/src/plugins/ctags/ide-ctags-completion-provider.c
index 78168aea8..2214801fb 100644
--- a/src/plugins/ctags/ide-ctags-completion-provider.c
+++ b/src/plugins/ctags/ide-ctags-completion-provider.c
@@ -25,6 +25,7 @@
 #include "ide-ctags-completion-item.h"
 #include "ide-ctags-completion-provider.h"
 #include "ide-ctags-completion-provider-private.h"
+#include "ide-ctags-results.h"
 #include "ide-ctags-service.h"
 #include "ide-ctags-util.h"
 
@@ -182,6 +183,23 @@ get_allowed_suffixes (IdeCompletionContext *context)
   return ide_ctags_get_allowed_suffixes (lang_id);
 }
 
+static void
+ide_ctags_completion_provider_populate_cb (GObject      *object,
+                                           GAsyncResult *result,
+                                           gpointer      user_data)
+{
+  IdeCtagsResults *results = (IdeCtagsResults *)object;
+  g_autoptr(IdeTask) task = user_data;
+  g_autoptr(GError) error = NULL;
+
+  g_assert (IDE_IS_CTAGS_RESULTS (results));
+
+  if (!ide_ctags_results_populate_finish (results, result, &error))
+    ide_task_return_error (task, g_steal_pointer (&error));
+  else
+    ide_task_return_object (task, g_object_ref (results));
+}
+
 static void
 ide_ctags_completion_provider_populate_async (IdeCompletionProvider  *provider,
                                               IdeCompletionContext   *context,
@@ -191,12 +209,9 @@ ide_ctags_completion_provider_populate_async (IdeCompletionProvider  *provider,
                                               gpointer                user_data)
 {
   IdeCtagsCompletionProvider *self = (IdeCtagsCompletionProvider *)provider;
-  const gchar * const *allowed;
-  g_autofree gchar *casefold = NULL;
-  g_autofree gchar *word = NULL;
-  g_autoptr(GHashTable) completions = NULL;
+  g_autoptr(IdeCtagsResults) model = NULL;
   g_autoptr(IdeTask) task = NULL;
-  g_autoptr(GListStore) store = NULL;
+  g_autofree gchar *word = NULL;
   GtkTextIter begin, end;
   gint word_len;
 
@@ -215,78 +230,26 @@ ide_ctags_completion_provider_populate_async (IdeCompletionProvider  *provider,
       !(word = gtk_text_iter_get_slice (&begin, &end)) ||
       !(word_len = strlen (word)) ||
       strlen (word) < self->minimum_word_size)
-    goto word_too_small;
-
-  allowed = get_allowed_suffixes (context);
-  casefold = g_utf8_casefold (word, -1);
-  store = g_list_store_new (IDE_TYPE_COMPLETION_PROPOSAL);
-  completions = g_hash_table_new (g_str_hash, g_str_equal);
-
-  for (guint i = 0; i < self->indexes->len; i++)
     {
-      g_autofree gchar *copy = g_strdup (word);
-      IdeCtagsIndex *index = g_ptr_array_index (self->indexes, i);
-      const IdeCtagsIndexEntry *entries = NULL;
-      guint tmp_len = word_len;
-      gsize n_entries = 0;
-      gchar gdata_key[64];
-
-      /* NOTE: "ctags-%d" is turned into a GQuark and therefore lives the
-       *       length of the process. But it's generally under 1000 so not a
-       *       really big deal for now.
-       */
-
-      /*
-       * Make sure we hold a reference to the index for the lifetime of the results.
-       * When the results are released, so could our indexes.
-       */
-      g_snprintf (gdata_key, sizeof gdata_key, "ctags-%d", i);
-      g_object_set_data_full (G_OBJECT (store), gdata_key,
-                              g_object_ref (index), g_object_unref);
-
-      while (entries == NULL && copy[0])
-        {
-          if (!(entries = ide_ctags_index_lookup_prefix (index, copy, &n_entries)))
-            copy [--tmp_len] = '\0';
-        }
-
-      if ((entries == NULL) || (n_entries == 0))
-        continue;
-
-      for (guint j = 0; j < n_entries; j++)
-        {
-          const IdeCtagsIndexEntry *entry = &entries [j];
-          guint priority;
-
-          if (g_hash_table_contains (completions, entry->name))
-            continue;
-
-          g_hash_table_add (completions, (gchar *)entry->name);
-
-          if (!ide_ctags_is_allowed (entry, allowed))
-            continue;
-
-          if (ide_completion_item_fuzzy_match (entry->name, casefold, &priority))
-            {
-              g_autoptr(IdeCtagsCompletionItem) item = NULL;
-
-              item = ide_ctags_completion_item_new (self, entry);
-              g_list_store_append (store, item);
-            }
-        }
+      ide_task_return_new_error (task,
+                                 G_IO_ERROR,
+                                 G_IO_ERROR_NOT_SUPPORTED,
+                                 "Word too short to query ctags");
+      return;
     }
 
-  *results = g_object_ref (G_LIST_MODEL (store));
+  model = ide_ctags_results_new ();
+  ide_ctags_results_set_suffixes (model, get_allowed_suffixes (context));
+  ide_ctags_results_set_word (model, word);
+  for (guint i = 0; i < self->indexes->len; i++)
+    ide_ctags_results_add_index (model, g_ptr_array_index (self->indexes, i));
 
-  ide_task_return_pointer (task, g_steal_pointer (&store), g_object_unref);
-  return;
+  ide_ctags_results_populate_async (model,
+                                    cancellable,
+                                    ide_ctags_completion_provider_populate_cb,
+                                    g_steal_pointer (&task));
 
-word_too_small:
-  ide_task_return_new_error (task,
-                             G_IO_ERROR,
-                             G_IO_ERROR_NOT_SUPPORTED,
-                             "Word too small to query ctags");
-  return;
+  *results = G_LIST_MODEL (g_steal_pointer (&model));
 }
 
 static GListModel *
@@ -297,7 +260,7 @@ ide_ctags_completion_provider_populate_finish (IdeCompletionProvider  *provider,
   g_return_val_if_fail (IDE_IS_CTAGS_COMPLETION_PROVIDER (provider), NULL);
   g_return_val_if_fail (IDE_IS_TASK (result), NULL);
 
-  return ide_task_propagate_pointer (IDE_TASK (result), error);
+  return ide_task_propagate_object (IDE_TASK (result), error);
 }
 
 static gint
diff --git a/src/plugins/ctags/ide-ctags-index.c b/src/plugins/ctags/ide-ctags-index.c
index 31ec2a71e..ce34b3570 100644
--- a/src/plugins/ctags/ide-ctags-index.c
+++ b/src/plugins/ctags/ide-ctags-index.c
@@ -26,6 +26,10 @@
 
 #include "ide-ctags-index.h"
 
+/* This object is meant to be immutable after loading so that
+ * it can be used from threads safely.
+ */
+
 struct _IdeCtagsIndex
 {
   IdeObject  parent_instance;
diff --git a/src/plugins/ctags/ide-ctags-index.h b/src/plugins/ctags/ide-ctags-index.h
index c2cbadc56..d88d54665 100644
--- a/src/plugins/ctags/ide-ctags-index.h
+++ b/src/plugins/ctags/ide-ctags-index.h
@@ -55,6 +55,10 @@ typedef struct
   guint8                  padding[3];
 } IdeCtagsIndexEntry;
 
+/* This object is meant to be immutable after loading so that
+ * it can be used from threads safely.
+ */
+
 IdeCtagsIndex            *ide_ctags_index_new           (GFile                    *file,
                                                          const gchar              *path_root,
                                                          guint64                   mtime);
diff --git a/src/plugins/ctags/ide-ctags-results.c b/src/plugins/ctags/ide-ctags-results.c
new file mode 100644
index 000000000..19f85e95b
--- /dev/null
+++ b/src/plugins/ctags/ide-ctags-results.c
@@ -0,0 +1,317 @@
+/* ide-ctags-results.c
+ *
+ * Copyright 2018 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#define G_LOG_DOMAIN "ide-ctags-results"
+
+#include "ide-ctags-completion-item.h"
+#include "ide-ctags-results.h"
+#include "ide-ctags-util.h"
+
+struct _IdeCtagsResults
+{
+  GObject parent_instance;
+  const gchar * const *suffixes;
+  gchar *word;
+  GPtrArray *indexes;
+  GArray *items;
+};
+
+typedef struct
+{
+  const IdeCtagsIndexEntry *entry;
+  guint priority;
+} Item;
+
+typedef struct
+{
+  const gchar * const *suffixes;
+  gchar *word;
+  gchar *casefold;
+  GPtrArray *indexes;
+  GArray *items;
+} Populate;
+
+static void
+populate_free (Populate *state)
+{
+  g_clear_pointer (&state->word, g_free);
+  g_clear_pointer (&state->casefold, g_free);
+  g_clear_pointer (&state->indexes, g_ptr_array_unref);
+  g_clear_pointer (&state->items, g_array_unref);
+  g_slice_free (Populate, state);
+}
+
+static GType
+ide_ctags_results_get_item_type (GListModel *model)
+{
+  return IDE_TYPE_COMPLETION_PROPOSAL;
+}
+
+static gpointer
+ide_ctags_results_get_item (GListModel *model,
+                            guint       position)
+{
+  IdeCtagsResults *self = (IdeCtagsResults *)model;
+  const Item *item;
+
+  g_assert (IDE_IS_CTAGS_RESULTS (self));
+  g_assert (position < self->items->len);
+
+  item = &g_array_index (self->items, Item, position);
+
+  return ide_ctags_completion_item_new (self, item->entry);
+}
+
+static guint
+ide_ctags_results_get_n_items (GListModel *model)
+{
+  g_assert (IDE_IS_CTAGS_RESULTS (model));
+
+  return IDE_CTAGS_RESULTS (model)->items->len;
+}
+
+static void
+list_model_iface_init (GListModelInterface *iface)
+{
+  iface->get_item_type = ide_ctags_results_get_item_type;
+  iface->get_n_items = ide_ctags_results_get_n_items;
+  iface->get_item = ide_ctags_results_get_item;
+}
+
+G_DEFINE_TYPE_WITH_CODE (IdeCtagsResults, ide_ctags_results, G_TYPE_OBJECT,
+                         G_IMPLEMENT_INTERFACE (G_TYPE_LIST_MODEL, list_model_iface_init))
+
+static void
+ide_ctags_results_finalize (GObject *object)
+{
+  IdeCtagsResults *self = (IdeCtagsResults *)object;
+
+  g_clear_pointer (&self->items, g_array_unref);
+  g_clear_pointer (&self->indexes, g_ptr_array_unref);
+  g_clear_pointer (&self->word, g_free);
+
+  G_OBJECT_CLASS (ide_ctags_results_parent_class)->finalize (object);
+}
+
+static void
+ide_ctags_results_class_init (IdeCtagsResultsClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  object_class->finalize = ide_ctags_results_finalize;
+}
+
+static void
+ide_ctags_results_init (IdeCtagsResults *self)
+{
+  self->indexes = g_ptr_array_new_with_free_func (g_object_unref);
+  self->items = g_array_new (FALSE, FALSE, sizeof (Item));
+}
+
+static gint
+sort_by_priority (gconstpointer a,
+                  gconstpointer b)
+{
+  return (gint)((const Item *)a)->priority -
+         (gint)((const Item *)b)->priority;
+}
+
+static void
+ide_ctags_results_populate_worker (IdeTask      *task,
+                                   gpointer      source_object,
+                                   gpointer      task_data,
+                                   GCancellable *cancellable)
+{
+  Populate *p = task_data;
+  g_autoptr(GHashTable) completions = NULL;
+  guint word_len;
+
+  g_assert (IDE_IS_TASK (task));
+  g_assert (IDE_IS_CTAGS_RESULTS (source_object));
+  g_assert (p != NULL);
+  g_assert (p->word != NULL);
+  g_assert (p->casefold != NULL);
+  g_assert (p->indexes != NULL);
+  g_assert (p->items != NULL);
+  g_assert (!cancellable || G_IS_CANCELLABLE (cancellable));
+
+  completions = g_hash_table_new (g_str_hash, g_str_equal);
+  word_len = strlen (p->word);
+
+  for (guint i = 0; i < p->indexes->len; i++)
+    {
+      g_autofree gchar *copy = g_strdup (p->word);
+      IdeCtagsIndex *index = g_ptr_array_index (p->indexes, i);
+      const IdeCtagsIndexEntry *entries = NULL;
+      guint tmp_len = word_len;
+      gsize n_entries = 0;
+
+      while (!entries && *copy)
+        {
+          if (!(entries = ide_ctags_index_lookup_prefix (index, copy, &n_entries)))
+            copy [--tmp_len] = '\0';
+        }
+
+      if (!entries || !n_entries)
+        continue;
+
+      for (guint j = 0; j < n_entries; j++)
+        {
+          const IdeCtagsIndexEntry *entry = &entries [j];
+          guint priority;
+
+          if (g_hash_table_contains (completions, entry->name))
+            continue;
+
+          g_hash_table_add (completions, (gchar *)entry->name);
+
+          if (!ide_ctags_is_allowed (entry, p->suffixes))
+            continue;
+
+          if (ide_completion_item_fuzzy_match (entry->name, p->casefold, &priority))
+            {
+              Item item;
+
+              item.entry = entry;
+              item.priority = priority;
+
+              g_array_append_val (p->items, item);
+            }
+        }
+    }
+
+  g_array_sort (p->items, sort_by_priority);
+
+  ide_task_return_pointer (task,
+                           g_array_ref (p->items),
+                           (GDestroyNotify)g_array_unref);
+}
+
+#if 0
+
+  casefold = g_utf8_casefold (word, -1);
+  store = g_list_store_new (IDE_TYPE_COMPLETION_PROPOSAL);
+
+  *results = g_object_ref (G_LIST_MODEL (store));
+
+  ide_task_return_pointer (task, g_steal_pointer (&store), g_object_unref);
+
+#endif
+
+void
+ide_ctags_results_populate_async (IdeCtagsResults     *self,
+                                  GCancellable        *cancellable,
+                                  GAsyncReadyCallback  callback,
+                                  gpointer             user_data)
+{
+  g_autoptr(IdeTask) task = NULL;
+  Populate *p;
+
+  g_return_if_fail (IDE_IS_CTAGS_RESULTS (self));
+  g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
+
+
+  task = ide_task_new (self, cancellable, callback, user_data);
+  ide_task_set_source_tag (task, ide_ctags_results_populate_async);
+  ide_task_set_priority (task, G_PRIORITY_HIGH);
+
+  if (self->word == NULL)
+    {
+      ide_task_return_new_error (task,
+                                 G_IO_ERROR,
+                                 G_IO_ERROR_INVAL,
+                                 "No word set to query");
+      return;
+    }
+
+  p = g_slice_new (Populate);
+  p->word = g_strdup (self->word);
+  p->casefold = g_utf8_casefold (self->word, -1);
+  p->indexes = g_ptr_array_new_full (self->indexes->len, g_object_unref);
+  p->items = g_array_new (FALSE, FALSE, sizeof (GArray));
+  p->suffixes = self->suffixes;
+
+  for (guint i = 0; i < self->indexes->len; i++)
+    g_ptr_array_add (p->indexes, g_object_ref (g_ptr_array_index (self->indexes, i)));
+
+  ide_task_set_task_data (task, p, (GDestroyNotify)populate_free);
+  ide_task_run_in_thread (task, ide_ctags_results_populate_worker);
+}
+
+gboolean
+ide_ctags_results_populate_finish (IdeCtagsResults  *self,
+                                   GAsyncResult     *result,
+                                   GError          **error)
+{
+  GArray *items;
+
+  g_return_val_if_fail (IDE_IS_CTAGS_RESULTS (self), FALSE);
+  g_return_val_if_fail (IDE_IS_TASK (result), FALSE);
+
+  if ((items = ide_task_propagate_pointer (IDE_TASK (result), error)))
+    {
+      guint old_len = self->items->len;
+      guint new_len = items->len;
+
+      g_array_unref (self->items);
+      self->items = g_steal_pointer (&items);
+
+      g_list_model_items_changed (G_LIST_MODEL (self), 0, old_len, new_len);
+
+      return TRUE;
+    }
+
+  return FALSE;
+}
+
+void
+ide_ctags_results_set_suffixes (IdeCtagsResults     *self,
+                                const gchar * const *suffixes)
+{
+  /* @suffixes is an interned string array */
+  self->suffixes = suffixes;
+}
+
+void
+ide_ctags_results_set_word (IdeCtagsResults *self,
+                            const gchar     *word)
+{
+  g_assert (IDE_IS_CTAGS_RESULTS (self));
+
+  if (word != self->word)
+    {
+      g_free (self->word);
+      self->word = g_strdup (word);
+    }
+}
+
+IdeCtagsResults *
+ide_ctags_results_new (void)
+{
+  return g_object_new (IDE_TYPE_CTAGS_RESULTS, NULL);
+}
+
+void
+ide_ctags_results_add_index (IdeCtagsResults *self,
+                             IdeCtagsIndex   *index)
+{
+  g_assert (IDE_IS_CTAGS_RESULTS (self));
+  g_assert (IDE_IS_CTAGS_INDEX (index));
+
+  g_ptr_array_add (self->indexes, g_object_ref (index));
+}
diff --git a/src/plugins/ctags/ide-ctags-results.h b/src/plugins/ctags/ide-ctags-results.h
new file mode 100644
index 000000000..b20edb1fe
--- /dev/null
+++ b/src/plugins/ctags/ide-ctags-results.h
@@ -0,0 +1,46 @@
+/* ide-ctags-results.h
+ *
+ * Copyright 2018 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include <ide.h>
+
+#include "ide-ctags-index.h"
+
+G_BEGIN_DECLS
+
+#define IDE_TYPE_CTAGS_RESULTS (ide_ctags_results_get_type())
+
+G_DECLARE_FINAL_TYPE (IdeCtagsResults, ide_ctags_results, IDE, CTAGS_RESULTS, GObject)
+
+IdeCtagsResults *ide_ctags_results_new             (void);
+void             ide_ctags_results_set_suffixes    (IdeCtagsResults      *self,
+                                                    const gchar * const  *suffixes);
+void             ide_ctags_results_add_index       (IdeCtagsResults      *self,
+                                                    IdeCtagsIndex        *index);
+void             ide_ctags_results_set_word        (IdeCtagsResults      *self,
+                                                    const gchar          *word);
+void             ide_ctags_results_populate_async  (IdeCtagsResults      *self,
+                                                    GCancellable         *cancellable,
+                                                    GAsyncReadyCallback   callback,
+                                                    gpointer              user_data);
+gboolean         ide_ctags_results_populate_finish (IdeCtagsResults      *self,
+                                                    GAsyncResult         *result,
+                                                    GError              **error);
+
+G_END_DECLS
diff --git a/src/plugins/ctags/meson.build b/src/plugins/ctags/meson.build
index 20d1f2737..d4ee889fc 100644
--- a/src/plugins/ctags/meson.build
+++ b/src/plugins/ctags/meson.build
@@ -8,24 +8,16 @@ ctags_resources = gnome.compile_resources(
 
 ctags_sources = [
   'ide-ctags-builder.c',
-  'ide-ctags-builder.h',
   'ide-ctags-completion-item.c',
-  'ide-ctags-completion-item.h',
   'ide-ctags-completion-provider.c',
-  'ide-ctags-completion-provider.h',
-  'ide-ctags-completion-provider-private.h',
   'ide-ctags-highlighter.c',
-  'ide-ctags-highlighter.h',
   'ide-ctags-index.c',
-  'ide-ctags-index.h',
   'ide-ctags-service.c',
-  'ide-ctags-service.h',
+  'ide-ctags-results.c',
   'ide-ctags-symbol-node.c',
   'ide-ctags-symbol-resolver.c',
-  'ide-ctags-symbol-resolver.h',
   'ide-ctags-symbol-tree.c',
   'ide-ctags-util.c',
-  'ide-ctags-util.h',
   'ctags-plugin.c',
 ]
 


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