[gnome-builder] plugins/clang: port to GTK 4



commit c2bfc86e2ce7841d55e20f16f02c894921e9131e
Author: Christian Hergert <chergert redhat com>
Date:   Mon Jul 11 22:18:26 2022 -0700

    plugins/clang: port to GTK 4
    
     - Port to newer GSV API
     - Port to new preferences design
     - Improve symbol resolving
     - Remove unused Since:

 src/plugins/clang/clang-plugin.c                  |   4 +-
 src/plugins/clang/clang.plugin                    |   3 +-
 src/plugins/clang/ide-clang-client.c              |   8 +-
 src/plugins/clang/ide-clang-completion-item.c     | 147 +++++++++----
 src/plugins/clang/ide-clang-completion-item.h     |  13 +-
 src/plugins/clang/ide-clang-completion-provider.c | 253 ++++++++++++----------
 src/plugins/clang/ide-clang-diagnostic-provider.c | 129 +++++++++--
 src/plugins/clang/ide-clang-highlighter.c         |  23 +-
 src/plugins/clang/ide-clang-preferences-addin.c   | 141 ++++++------
 src/plugins/clang/ide-clang-proposals.c           |   7 +-
 src/plugins/clang/ide-clang-symbol-resolver.c     | 174 ++++++++++++---
 src/plugins/clang/ide-clang-symbol-tree.c         |   2 -
 src/plugins/clang/ide-clang.c                     |  12 -
 13 files changed, 595 insertions(+), 321 deletions(-)
---
diff --git a/src/plugins/clang/clang-plugin.c b/src/plugins/clang/clang-plugin.c
index c8cac1bba..da43703fd 100644
--- a/src/plugins/clang/clang-plugin.c
+++ b/src/plugins/clang/clang-plugin.c
@@ -23,9 +23,11 @@
 #include "config.h"
 
 #include <libpeas/peas.h>
+
 #include <libide-code.h>
 #include <libide-foundry.h>
 #include <libide-gui.h>
+#include <libide-sourceview.h>
 
 #include "ide-clang-client.h"
 #include "ide-clang-code-indexer.h"
@@ -55,7 +57,7 @@ _ide_clang_register_types (PeasObjectModule *module)
                                               IDE_TYPE_DIAGNOSTIC_PROVIDER,
                                               IDE_TYPE_CLANG_DIAGNOSTIC_PROVIDER);
   peas_object_module_register_extension_type (module,
-                                              IDE_TYPE_COMPLETION_PROVIDER,
+                                              GTK_SOURCE_TYPE_COMPLETION_PROVIDER,
                                               IDE_TYPE_CLANG_COMPLETION_PROVIDER);
   peas_object_module_register_extension_type (module,
                                               IDE_TYPE_PREFERENCES_ADDIN,
diff --git a/src/plugins/clang/clang.plugin b/src/plugins/clang/clang.plugin
index 1a8ebfecd..c21f74810 100644
--- a/src/plugins/clang/clang.plugin
+++ b/src/plugins/clang/clang.plugin
@@ -3,10 +3,10 @@ Authors=Christian Hergert <christian hergert me>
 Builtin=true
 Copyright=Copyright © 2015 Christian Hergert
 Description=Provides integration with Clang
-Depends=editor;
 Embedded=_ide_clang_register_types
 Module=clang
 Name=Clang
+X-Category=compilers
 X-Code-Indexer-Languages-Priority=100
 X-Code-Indexer-Languages=c,chdr,cpp,cpphdr,objc
 X-Completion-Provider-Languages=c,chdr,cpp,cpphdr,objc
@@ -17,3 +17,4 @@ X-Highlighter-Languages=c,chdr,cpp,cpphdr,objc
 X-Rename-Provider-Languages=c,chdr,cpp,cpphdr,objc
 X-Symbol-Resolver-Languages-Priority=100
 X-Symbol-Resolver-Languages=c,chdr,cpp,cpphdr,objc
+X-Preferences-Kind=application
diff --git a/src/plugins/clang/ide-clang-client.c b/src/plugins/clang/ide-clang-client.c
index 1252ab4f0..a1bebfe9d 100644
--- a/src/plugins/clang/ide-clang-client.c
+++ b/src/plugins/clang/ide-clang-client.c
@@ -90,6 +90,11 @@ ide_clang_client_sync_buffers (IdeClangClient *self)
 
   g_assert (IDE_IS_CLANG_CLIENT (self));
 
+  /* Bail if we're in destruction */
+  if (self->state == STATE_SHUTDOWN ||
+      !(context = ide_object_get_context (IDE_OBJECT (self))))
+    return;
+
   /*
    * We need to sync buffers to the subprocess, but only those that are of any
    * consequence to us. So that means C, C++, or Obj-C files and headers.
@@ -103,7 +108,6 @@ ide_clang_client_sync_buffers (IdeClangClient *self)
    * be used on subsequence commands).
    */
 
-  context = ide_object_get_context (IDE_OBJECT (self));
   ufs = ide_unsaved_files_from_context (context);
   ar = ide_unsaved_files_to_array (ufs);
   IDE_PTR_ARRAY_SET_FREE_FUNC (ar, ide_unsaved_file_unref);
@@ -687,8 +691,6 @@ ide_clang_client_index_file_async (IdeClangClient      *self,
  *
  * Returns: (transfer full): a #GVariant containing the indexed data
  *   or %NULL in case of failure.
- *
- * Since: 3.32
  */
 GVariant *
 ide_clang_client_index_file_finish (IdeClangClient  *self,
diff --git a/src/plugins/clang/ide-clang-completion-item.c b/src/plugins/clang/ide-clang-completion-item.c
index 025b62b53..31aaed836 100644
--- a/src/plugins/clang/ide-clang-completion-item.c
+++ b/src/plugins/clang/ide-clang-completion-item.c
@@ -22,12 +22,13 @@
 
 #include <clang-c/Index.h>
 #include <glib/gi18n.h>
+
 #include <libide-foundry.h>
 
 #include "ide-clang-completion-item.h"
 
 G_DEFINE_FINAL_TYPE_WITH_CODE (IdeClangCompletionItem, ide_clang_completion_item, G_TYPE_OBJECT,
-                         G_IMPLEMENT_INTERFACE (IDE_TYPE_COMPLETION_PROPOSAL, NULL))
+                               G_IMPLEMENT_INTERFACE (GTK_SOURCE_TYPE_COMPLETION_PROPOSAL, NULL))
 
 static void
 ide_clang_completion_item_do_init (IdeClangCompletionItem *self)
@@ -253,11 +254,11 @@ get_space_before_mask (enum CXCompletionChunkKind kind)
     }
 }
 
-static IdeSnippet *
+static GtkSourceSnippet *
 ide_clang_completion_item_create_snippet (IdeClangCompletionItem *self,
                                           IdeFileSettings        *file_settings)
 {
-  g_autoptr(IdeSnippet) snippet = NULL;
+  g_autoptr(GtkSourceSnippet) snippet = NULL;
   g_autoptr(GVariant) result = NULL;
   g_autoptr(GVariant) chunks = NULL;
   g_autoptr(GSettings) settings = NULL;
@@ -272,7 +273,7 @@ ide_clang_completion_item_create_snippet (IdeClangCompletionItem *self,
   settings = g_settings_new ("org.gnome.builder.clang");
 
   result = ide_clang_completion_item_get_result (self);
-  snippet = ide_snippet_new (NULL, NULL);
+  snippet = gtk_source_snippet_new (NULL, NULL);
 
   if (file_settings != NULL)
     spaces = ide_file_settings_get_spaces_style (file_settings);
@@ -285,7 +286,7 @@ ide_clang_completion_item_create_snippet (IdeClangCompletionItem *self,
   while ((vchunk = g_variant_iter_next_value (&iter)))
     {
       enum CXCompletionChunkKind kind;
-      IdeSnippetChunk *chunk;
+      GtkSourceSnippetChunk *chunk;
       const gchar *text;
 
       if (!g_variant_lookup (vchunk, "kind", "u", &kind))
@@ -310,9 +311,9 @@ ide_clang_completion_item_create_snippet (IdeClangCompletionItem *self,
               /* Insert | cursor right before right paren if we aren't
                * adding params but parents is enabled.
                */
-              chunk = ide_snippet_chunk_new ();
-              ide_snippet_chunk_set_tab_stop (chunk, 0);
-              ide_snippet_add_chunk (snippet, chunk);
+              chunk = gtk_source_snippet_chunk_new ();
+              gtk_source_snippet_chunk_set_focus_position (chunk, 0);
+              gtk_source_snippet_add_chunk (snippet, chunk);
               g_clear_object (&chunk);
             }
         }
@@ -320,27 +321,27 @@ ide_clang_completion_item_create_snippet (IdeClangCompletionItem *self,
       switch (kind)
         {
         case CXCompletionChunk_TypedText:
-          chunk = ide_snippet_chunk_new ();
-          ide_snippet_chunk_set_text (chunk, text);
-          ide_snippet_chunk_set_text_set (chunk, TRUE);
-          ide_snippet_add_chunk (snippet, chunk);
+          chunk = gtk_source_snippet_chunk_new ();
+          gtk_source_snippet_chunk_set_text (chunk, text);
+          gtk_source_snippet_chunk_set_text_set (chunk, TRUE);
+          gtk_source_snippet_add_chunk (snippet, chunk);
           g_clear_object (&chunk);
           break;
 
         case CXCompletionChunk_Text:
-          chunk = ide_snippet_chunk_new ();
-          ide_snippet_chunk_set_text (chunk, text);
-          ide_snippet_chunk_set_text_set (chunk, TRUE);
-          ide_snippet_add_chunk (snippet, chunk);
+          chunk = gtk_source_snippet_chunk_new ();
+          gtk_source_snippet_chunk_set_text (chunk, text);
+          gtk_source_snippet_chunk_set_text_set (chunk, TRUE);
+          gtk_source_snippet_add_chunk (snippet, chunk);
           g_clear_object (&chunk);
           break;
 
         case CXCompletionChunk_Placeholder:
-          chunk = ide_snippet_chunk_new ();
-          ide_snippet_chunk_set_text (chunk, text);
-          ide_snippet_chunk_set_text_set (chunk, TRUE);
-          ide_snippet_chunk_set_tab_stop (chunk, ++tab_stop);
-          ide_snippet_add_chunk (snippet, chunk);
+          chunk = gtk_source_snippet_chunk_new ();
+          gtk_source_snippet_chunk_set_text (chunk, text);
+          gtk_source_snippet_chunk_set_text_set (chunk, TRUE);
+          gtk_source_snippet_chunk_set_focus_position (chunk, ++tab_stop);
+          gtk_source_snippet_add_chunk (snippet, chunk);
           g_clear_object (&chunk);
           break;
 
@@ -362,31 +363,31 @@ ide_clang_completion_item_create_snippet (IdeClangCompletionItem *self,
         case CXCompletionChunk_HorizontalSpace:
           if (spaces & get_space_before_mask (kind))
             {
-              chunk = ide_snippet_chunk_new ();
-              ide_snippet_chunk_set_text (chunk, " ");
-              ide_snippet_chunk_set_text_set (chunk, TRUE);
-              ide_snippet_add_chunk (snippet, chunk);
+              chunk = gtk_source_snippet_chunk_new ();
+              gtk_source_snippet_chunk_set_text (chunk, " ");
+              gtk_source_snippet_chunk_set_text_set (chunk, TRUE);
+              gtk_source_snippet_add_chunk (snippet, chunk);
               g_clear_object (&chunk);
             }
-          chunk = ide_snippet_chunk_new ();
-          ide_snippet_chunk_set_text (chunk, text);
-          ide_snippet_chunk_set_text_set (chunk, TRUE);
-          ide_snippet_add_chunk (snippet, chunk);
+          chunk = gtk_source_snippet_chunk_new ();
+          gtk_source_snippet_chunk_set_text (chunk, text);
+          gtk_source_snippet_chunk_set_text_set (chunk, TRUE);
+          gtk_source_snippet_add_chunk (snippet, chunk);
           g_clear_object (&chunk);
           break;
 
         case CXCompletionChunk_VerticalSpace:
           /* insert the vertical space */
-          chunk = ide_snippet_chunk_new ();
-          ide_snippet_chunk_set_text (chunk, text);
-          ide_snippet_chunk_set_text_set (chunk, TRUE);
-          ide_snippet_add_chunk (snippet, chunk);
+          chunk = gtk_source_snippet_chunk_new ();
+          gtk_source_snippet_chunk_set_text (chunk, text);
+          gtk_source_snippet_chunk_set_text_set (chunk, TRUE);
+          gtk_source_snippet_add_chunk (snippet, chunk);
           g_clear_object (&chunk);
           /* now perform indentation */
-          chunk = ide_snippet_chunk_new ();
-          ide_snippet_chunk_set_text (chunk, "\t");
-          ide_snippet_chunk_set_text_set (chunk, TRUE);
-          ide_snippet_add_chunk (snippet, chunk);
+          chunk = gtk_source_snippet_chunk_new ();
+          gtk_source_snippet_chunk_set_text (chunk, "\t");
+          gtk_source_snippet_chunk_set_text_set (chunk, TRUE);
+          gtk_source_snippet_add_chunk (snippet, chunk);
           g_clear_object (&chunk);
           break;
 
@@ -434,13 +435,11 @@ ide_clang_completion_item_init (IdeClangCompletionItem *self)
  * @self: an #IdeClangCompletionItem.
  * @file_settings: (nullable): an #IdeFileSettings or %NULL
  *
- * Gets the #IdeSnippet to be inserted when expanding this completion item.
- *
- * Returns: (transfer full): An #IdeSnippet.
+ * Gets the #GtkSourceSnippet to be inserted when expanding this completion item.
  *
- * Since: 3.32
+ * Returns: (transfer full): An #GtkSourceSnippet.
  */
-IdeSnippet *
+GtkSourceSnippet *
 ide_clang_completion_item_get_snippet (IdeClangCompletionItem *self,
                                        IdeFileSettings        *file_settings)
 {
@@ -459,8 +458,6 @@ ide_clang_completion_item_get_snippet (IdeClangCompletionItem *self,
  * The @keyword parameter is not copied, it is expected to be valid
  * string found within @variant (and therefore associated with its
  * life-cycle).
- *
- * Since: 3.32
  */
 IdeClangCompletionItem *
 ide_clang_completion_item_new (GVariant    *variant,
@@ -481,3 +478,65 @@ ide_clang_completion_item_new (GVariant    *variant,
 
   return ret;
 }
+
+void
+ide_clang_completion_item_display (IdeClangCompletionItem  *self,
+                                   GtkSourceCompletionCell *cell,
+                                   const char              *typed_text)
+{
+  GtkSourceCompletionColumn column;
+
+  g_return_if_fail (IDE_IS_CLANG_COMPLETION_ITEM (self));
+  g_return_if_fail (GTK_SOURCE_IS_COMPLETION_CELL (cell));
+
+  column = gtk_source_completion_cell_get_column (cell);
+
+  switch (column)
+    {
+    case GTK_SOURCE_COMPLETION_COLUMN_ICON:
+      gtk_source_completion_cell_set_icon_name (cell, self->icon_name);
+      break;
+
+    case GTK_SOURCE_COMPLETION_COLUMN_TYPED_TEXT:
+      {
+        g_autofree char *with_params = NULL;
+        const char *text = self->typed_text;
+        PangoAttrList *attrs;
+
+        if (text != NULL && self->params != NULL)
+          text = with_params = g_strdup_printf ("%s %s", text, self->params);
+
+        attrs = gtk_source_completion_fuzzy_highlight (self->typed_text, typed_text);
+        gtk_source_completion_cell_set_text_with_attributes (cell, text, attrs);
+        pango_attr_list_unref (attrs);
+
+        break;
+      }
+
+    case GTK_SOURCE_COMPLETION_COLUMN_COMMENT:
+      {
+        g_autoptr(GVariant) result = ide_clang_completion_item_get_result (self);
+        const char *comment;
+
+        if (g_variant_lookup (result, "command", "&s", &comment))
+          gtk_source_completion_cell_set_text (cell, comment);
+
+        break;
+      }
+
+    case GTK_SOURCE_COMPLETION_COLUMN_DETAILS:
+      gtk_source_completion_cell_set_text (cell, NULL);
+      break;
+
+    case GTK_SOURCE_COMPLETION_COLUMN_BEFORE:
+      gtk_source_completion_cell_set_text (cell, self->return_type);
+      break;
+
+    case GTK_SOURCE_COMPLETION_COLUMN_AFTER:
+      gtk_source_completion_cell_set_text (cell, NULL);
+      break;
+
+    default:
+      break;
+    }
+}
diff --git a/src/plugins/clang/ide-clang-completion-item.h b/src/plugins/clang/ide-clang-completion-item.h
index 4b32a9667..6cc239e1c 100644
--- a/src/plugins/clang/ide-clang-completion-item.h
+++ b/src/plugins/clang/ide-clang-completion-item.h
@@ -59,10 +59,13 @@ ide_clang_completion_item_get_result (const IdeClangCompletionItem *self)
   return g_steal_pointer (&child);
 }
 
-IdeClangCompletionItem *ide_clang_completion_item_new         (GVariant               *results,
-                                                               guint                   index,
-                                                               const gchar            *keyword);
-IdeSnippet             *ide_clang_completion_item_get_snippet (IdeClangCompletionItem *self,
-                                                               IdeFileSettings        *file_settings);
+IdeClangCompletionItem *ide_clang_completion_item_new         (GVariant                *results,
+                                                               guint                    index,
+                                                               const gchar             *keyword);
+GtkSourceSnippet       *ide_clang_completion_item_get_snippet (IdeClangCompletionItem  *self,
+                                                               IdeFileSettings         *file_settings);
+void                    ide_clang_completion_item_display     (IdeClangCompletionItem  *self,
+                                                               GtkSourceCompletionCell *cell,
+                                                               const char              *typed_text);
 
 G_END_DECLS
diff --git a/src/plugins/clang/ide-clang-completion-provider.c 
b/src/plugins/clang/ide-clang-completion-provider.c
index dfff821ed..24c4b4baa 100644
--- a/src/plugins/clang/ide-clang-completion-provider.c
+++ b/src/plugins/clang/ide-clang-completion-provider.c
@@ -20,6 +20,8 @@
 
 #define G_LOG_DOMAIN "ide-clang-completion-provider"
 
+#include <libide-sourceview.h>
+
 #include "ide-clang-client.h"
 #include "ide-clang-completion-item.h"
 #include "ide-clang-completion-provider.h"
@@ -28,18 +30,27 @@
 struct _IdeClangCompletionProvider
 {
   IdeObject          parent_instance;
+
   IdeClangClient    *client;
   IdeClangProposals *proposals;
+
+  char              *word;
+  char              *refilter_word;
+
+  guint              activation_keyval;
+  GdkModifierType    activation_state;
+
+  guint              loaded : 1;
 };
 
 static gboolean
-is_field_access (IdeCompletionContext *context)
+is_field_access (GtkSourceCompletionContext *context)
 {
   GtkTextIter begin, end;
 
-  g_assert (IDE_IS_COMPLETION_CONTEXT (context));
+  g_assert (GTK_SOURCE_IS_COMPLETION_CONTEXT (context));
 
-  ide_completion_context_get_bounds (context, &begin, &end);
+  gtk_source_completion_context_get_bounds (context, &begin, &end);
 
   if (gtk_text_iter_backward_char (&begin))
     {
@@ -60,8 +71,8 @@ is_field_access (IdeCompletionContext *context)
 }
 
 static gint
-ide_clang_completion_provider_get_priority (IdeCompletionProvider *provider,
-                                            IdeCompletionContext  *context)
+ide_clang_completion_provider_get_priority (GtkSourceCompletionProvider *provider,
+                                            GtkSourceCompletionContext  *context)
 {
   /* Place results before snippets */
   if (is_field_access (context))
@@ -71,7 +82,7 @@ ide_clang_completion_provider_get_priority (IdeCompletionProvider *provider,
 }
 
 static gboolean
-ide_clang_completion_provider_is_trigger (IdeCompletionProvider *provider,
+ide_clang_completion_provider_is_trigger (GtkSourceCompletionProvider *provider,
                                           const GtkTextIter     *iter,
                                           gunichar               ch)
 {
@@ -104,50 +115,74 @@ ide_clang_completion_provider_is_trigger (IdeCompletionProvider *provider,
 }
 
 static gboolean
-ide_clang_completion_provider_key_activates (IdeCompletionProvider *provider,
-                                             IdeCompletionProposal *proposal,
-                                             const GdkEventKey     *key)
+ide_clang_completion_provider_key_activates (GtkSourceCompletionProvider *provider,
+                                             GtkSourceCompletionContext  *context,
+                                             GtkSourceCompletionProposal *proposal,
+                                             guint                        keyval,
+                                             GdkModifierType              state)
 {
+  IdeClangCompletionProvider *self = (IdeClangCompletionProvider *)provider;
   IdeClangCompletionItem *item = IDE_CLANG_COMPLETION_ITEM (proposal);
 
+  g_assert (IDE_IS_CLANG_COMPLETION_PROVIDER (self));
+  g_assert (IDE_IS_CLANG_COMPLETION_ITEM (item));
+
+  if ((state & (GDK_SHIFT_MASK|GDK_CONTROL_MASK)) == 0)
+    {
+      if (keyval == GDK_KEY_Return || keyval == GDK_KEY_KP_Enter)
+        goto store_and_activate;
+    }
+
   /* Try to dereference field/variable */
   if (item->kind == IDE_SYMBOL_KIND_FIELD || item->kind == IDE_SYMBOL_KIND_VARIABLE)
-    return key->keyval == GDK_KEY_period;
+    {
+      if (keyval == GDK_KEY_period || keyval == GDK_KEY_minus)
+        goto store_and_activate;
+    }
 
-#if 0
   /* We add suffix ; if pressed */
-  if (key->keyval == GDK_KEY_semicolon)
-    return TRUE;
+  if (keyval == GDK_KEY_semicolon)
+    goto store_and_activate;
 
+#if 0
   /* Open parens for function */
   if (item->kind == IDE_SYMBOL_FUNCTION)
-    return key->keyval == GDK_KEY_parenleft;
+    return keyval == GDK_KEY_parenleft;
 #endif
 
+  self->activation_keyval = 0;
+  self->activation_state = 0;
+
   return FALSE;
 
+store_and_activate:
+  self->activation_keyval = keyval;
+  self->activation_state = state;
+
+  return TRUE;
 }
 
 static void
-ide_clang_completion_provider_activate_proposal (IdeCompletionProvider *provider,
-                                                 IdeCompletionContext  *context,
-                                                 IdeCompletionProposal *proposal,
-                                                 const GdkEventKey     *key)
+ide_clang_completion_provider_activate (GtkSourceCompletionProvider *provider,
+                                        GtkSourceCompletionContext  *context,
+                                        GtkSourceCompletionProposal *proposal)
 {
+  IdeClangCompletionProvider *self = (IdeClangCompletionProvider *)provider;
   IdeClangCompletionItem *item = (IdeClangCompletionItem *)proposal;
   g_autofree gchar *word = NULL;
-  g_autoptr(IdeSnippet) snippet = NULL;
+  g_autoptr(GtkSourceSnippet) snippet = NULL;
   IdeFileSettings *file_settings;
-  GtkTextBuffer *buffer;
-  GtkTextView *view;
+  GtkSourceBuffer *buffer;
+  GtkSourceView *view;
   GtkTextIter begin, end;
+  guint n_chunks;
 
-  g_assert (IDE_IS_CLANG_COMPLETION_PROVIDER (provider));
-  g_assert (IDE_IS_COMPLETION_CONTEXT (context));
+  g_assert (IDE_IS_CLANG_COMPLETION_PROVIDER (self));
+  g_assert (GTK_SOURCE_IS_COMPLETION_CONTEXT (context));
   g_assert (IDE_IS_CLANG_COMPLETION_ITEM (item));
 
-  buffer = ide_completion_context_get_buffer (context);
-  view = ide_completion_context_get_view (context);
+  buffer = gtk_source_completion_context_get_buffer (context);
+  view = gtk_source_completion_context_get_view (context);
 
   g_assert (IDE_IS_BUFFER (buffer));
   g_assert (IDE_IS_SOURCE_VIEW (view));
@@ -158,38 +193,40 @@ ide_clang_completion_provider_activate_proposal (IdeCompletionProvider *provider
    * If the typed text matches the typed text of the item, and the user
    * it enter, then just skip the result and instead insert a newline.
    */
-  if (key->keyval == GDK_KEY_Return || key->keyval == GDK_KEY_KP_Enter)
+  if (self->activation_keyval == GDK_KEY_Return ||
+      self->activation_keyval == GDK_KEY_KP_Enter)
     {
-      if ((word = ide_completion_context_get_word (context)))
+      if ((word = gtk_source_completion_context_get_word (context)))
         {
           if (ide_str_equal0 (word, item->typed_text))
             {
-              ide_completion_context_get_bounds (context, &begin, &end);
-              gtk_text_buffer_insert (buffer, &end, "\n", -1);
+              gtk_source_completion_context_get_bounds (context, &begin, &end);
+              gtk_text_buffer_insert (GTK_TEXT_BUFFER (buffer), &end, "\n", -1);
 
               return;
             }
         }
     }
 
-  gtk_text_buffer_begin_user_action (buffer);
+  gtk_text_buffer_begin_user_action (GTK_TEXT_BUFFER (buffer));
 
-  if (ide_completion_context_get_bounds (context, &begin, &end))
-    gtk_text_buffer_delete (buffer, &begin, &end);
+  if (gtk_source_completion_context_get_bounds (context, &begin, &end))
+    gtk_text_buffer_delete (GTK_TEXT_BUFFER (buffer), &begin, &end);
 
   snippet = ide_clang_completion_item_get_snippet (item, file_settings);
+  n_chunks = gtk_source_snippet_get_n_chunks (snippet);
 
   /* Check the last snippet chunk and see if it matches our current
    * position so we can omit it.
    */
-  if (ide_snippet_get_n_chunks (snippet) > 0)
+  if (n_chunks > 0)
     {
-      IdeSnippetChunk *chunk;
+      GtkSourceSnippetChunk *chunk;
       const gchar *text;
       GtkTextIter limit;
 
-      chunk = ide_snippet_get_nth_chunk (snippet, ide_snippet_get_n_chunks (snippet) - 1);
-      text = ide_snippet_chunk_get_text (chunk);
+      chunk = gtk_source_snippet_get_nth_chunk (snippet, n_chunks-1);
+      text = gtk_source_snippet_chunk_get_text (chunk);
       limit = end;
 
       if (text != NULL)
@@ -203,7 +240,7 @@ ide_clang_completion_provider_activate_proposal (IdeCompletionProvider *provider
                 gtk_text_iter_forward_to_line_end (&limit);
             }
 
-          ide_completion_remove_common_suffix (ide_completion_context_get_completion (context), &end, text);
+          ide_text_util_remove_common_prefix (&end, text);
           begin = end;
         }
     }
@@ -214,72 +251,73 @@ ide_clang_completion_provider_activate_proposal (IdeCompletionProvider *provider
    */
   if (item->kind == IDE_SYMBOL_KIND_FIELD || item->kind == IDE_SYMBOL_KIND_VARIABLE)
     {
-      if (key->keyval == GDK_KEY_period || key->keyval == GDK_KEY_minus)
+      if (self->activation_keyval == GDK_KEY_period ||
+          self->activation_keyval == GDK_KEY_minus)
         {
-          g_autoptr(IdeSnippetChunk) chunk = ide_snippet_chunk_new ();
+          g_autoptr(GtkSourceSnippetChunk) chunk = gtk_source_snippet_chunk_new ();
           if (strchr (item->return_type, '*'))
-            ide_snippet_chunk_set_spec (chunk, "->");
+            gtk_source_snippet_chunk_set_spec (chunk, "->");
           else
-            ide_snippet_chunk_set_spec (chunk, ".");
-          ide_snippet_add_chunk (snippet, chunk);
+            gtk_source_snippet_chunk_set_spec (chunk, ".");
+          gtk_source_snippet_add_chunk (snippet, chunk);
         }
     }
 
-  if (key->keyval == GDK_KEY_semicolon)
+  if (self->activation_keyval == GDK_KEY_semicolon)
     {
-      g_autoptr(IdeSnippetChunk) chunk = ide_snippet_chunk_new ();
-      ide_snippet_chunk_set_spec (chunk, ";");
-      ide_snippet_add_chunk (snippet, chunk);
+      g_autoptr(GtkSourceSnippetChunk) chunk = gtk_source_snippet_chunk_new ();
+      gtk_source_snippet_chunk_set_spec (chunk, ";");
+      gtk_source_snippet_add_chunk (snippet, chunk);
     }
 
-  ide_source_view_push_snippet (IDE_SOURCE_VIEW (view), snippet, &begin);
+  gtk_source_view_push_snippet (view, snippet, &begin);
 
-  gtk_text_buffer_end_user_action (buffer);
+  gtk_text_buffer_end_user_action (GTK_TEXT_BUFFER (buffer));
 }
 
-static gboolean
-ide_clang_completion_provider_refilter (IdeCompletionProvider *provider,
-                                        IdeCompletionContext  *context,
+static void
+ide_clang_completion_provider_refilter (GtkSourceCompletionProvider *provider,
+                                        GtkSourceCompletionContext  *context,
                                         GListModel            *proposals)
 {
   IdeClangCompletionProvider *self = (IdeClangCompletionProvider *)provider;
 
   g_assert (IDE_IS_CLANG_COMPLETION_PROVIDER (self));
-  g_assert (IDE_IS_COMPLETION_CONTEXT (context));
+  g_assert (GTK_SOURCE_IS_COMPLETION_CONTEXT (context));
   g_assert (G_IS_LIST_MODEL (proposals));
 
   if (self->proposals != NULL)
     {
-      g_autofree gchar *word = NULL;
       GtkTextIter begin, end;
 
-      ide_completion_context_get_bounds (context, &begin, &end);
-      word = gtk_text_iter_get_slice (&begin, &end);
-      ide_clang_proposals_refilter (self->proposals, word);
+      g_clear_pointer (&self->refilter_word, g_free);
 
-      return TRUE;
+      gtk_source_completion_context_get_bounds (context, &begin, &end);
+      self->refilter_word = gtk_text_iter_get_slice (&begin, &end);
+      ide_clang_proposals_refilter (self->proposals, self->refilter_word);
     }
-
-  return FALSE;
 }
 
 static gchar *
-ide_clang_completion_provider_get_title (IdeCompletionProvider *provider)
+ide_clang_completion_provider_get_title (GtkSourceCompletionProvider *provider)
 {
   return g_strdup ("Clang");
 }
 
 static void
-ide_clang_completion_provider_load (IdeCompletionProvider *provider,
-                                    IdeContext            *context)
+ide_clang_completion_provider_load (IdeClangCompletionProvider *self)
 {
-  IdeClangCompletionProvider *self = (IdeClangCompletionProvider *)provider;
   g_autoptr(IdeClangClient) client = NULL;
+  g_autoptr(IdeContext) context = NULL;
 
   g_assert (IDE_IS_CLANG_COMPLETION_PROVIDER (self));
-  g_assert (IDE_IS_CONTEXT (context));
+  g_assert (self->loaded == FALSE);
+
+  self->loaded = TRUE;
 
+  context = ide_object_ref_context (IDE_OBJECT (self));
   client = ide_object_ensure_child_typed (IDE_OBJECT (context), IDE_TYPE_CLANG_CLIENT);
+
   g_set_object (&self->client, client);
 }
 
@@ -303,25 +341,30 @@ ide_clang_completion_provider_populate_cb (GObject      *object,
 }
 
 static void
-ide_clang_completion_provider_populate_async (IdeCompletionProvider  *provider,
-                                              IdeCompletionContext   *context,
+ide_clang_completion_provider_populate_async (GtkSourceCompletionProvider  *provider,
+                                              GtkSourceCompletionContext   *context,
                                               GCancellable           *cancellable,
                                               GAsyncReadyCallback     callback,
                                               gpointer                user_data)
 {
   IdeClangCompletionProvider *self = (IdeClangCompletionProvider *)provider;
   g_autoptr(IdeTask) task = NULL;
-  g_autofree gchar *word = NULL;
   GtkTextIter begin, end;
 
   g_assert (IDE_IS_CLANG_COMPLETION_PROVIDER (self));
   g_assert (!cancellable || G_IS_CANCELLABLE (cancellable));
 
+  if (!self->loaded)
+    ide_clang_completion_provider_load (self);
+
   task = ide_task_new (self, cancellable, callback, user_data);
   ide_task_set_source_tag (task, ide_clang_completion_provider_populate_async);
 
-  if (ide_completion_context_get_bounds (context, &begin, &end))
-    word = gtk_text_iter_get_slice (&begin, &end);
+  g_clear_pointer (&self->refilter_word, g_free);
+  g_clear_pointer (&self->word, g_free);
+
+  if (gtk_source_completion_context_get_bounds (context, &begin, &end))
+    self->word = gtk_text_iter_get_slice (&begin, &end);
 
   if (self->proposals == NULL)
     self->proposals = ide_clang_proposals_new (self->client);
@@ -331,20 +374,20 @@ ide_clang_completion_provider_populate_async (IdeCompletionProvider  *provider,
    * latency a bit.
    */
   if (!is_field_access (context))
-    ide_completion_context_set_proposals_for_provider (context,
-                                                       provider,
-                                                       G_LIST_MODEL (self->proposals));
+    gtk_source_completion_context_set_proposals_for_provider (context,
+                                                              provider,
+                                                              G_LIST_MODEL (self->proposals));
 
   ide_clang_proposals_populate_async (self->proposals,
                                       &begin,
-                                      word,
+                                      self->word,
                                       cancellable,
                                       ide_clang_completion_provider_populate_cb,
                                       g_steal_pointer (&task));
 }
 
 static GListModel *
-ide_clang_completion_provider_populate_finish (IdeCompletionProvider  *provider,
+ide_clang_completion_provider_populate_finish (GtkSourceCompletionProvider  *provider,
                                                GAsyncResult           *result,
                                                GError                **error)
 {
@@ -355,67 +398,44 @@ ide_clang_completion_provider_populate_finish (IdeCompletionProvider  *provider,
 }
 
 static void
-ide_clang_completion_provider_display_proposal (IdeCompletionProvider   *provider,
-                                                IdeCompletionListBoxRow *row,
-                                                IdeCompletionContext    *context,
-                                                const gchar             *typed_text,
-                                                IdeCompletionProposal   *proposal)
+ide_clang_completion_provider_display (GtkSourceCompletionProvider   *provider,
+                                       GtkSourceCompletionContext    *context,
+                                       GtkSourceCompletionProposal   *proposal,
+                                       GtkSourceCompletionCell       *cell)
 {
+  IdeClangCompletionProvider *self = (IdeClangCompletionProvider *)provider;
   IdeClangCompletionItem *item = IDE_CLANG_COMPLETION_ITEM (proposal);
-  g_autofree gchar *escaped = NULL;
-  g_autofree gchar *markup = NULL;
-  g_autofree gchar *highlight = NULL;
-  g_autofree gchar *params_escaped = NULL;
+  const char *typed_text;
 
-  g_assert (IDE_IS_CLANG_COMPLETION_PROVIDER (provider));
-  g_assert (IDE_IS_COMPLETION_LIST_BOX_ROW (row));
-  g_assert (IDE_IS_COMPLETION_CONTEXT (context));
+  g_assert (IDE_IS_CLANG_COMPLETION_PROVIDER (self));
+  g_assert (GTK_SOURCE_IS_COMPLETION_CONTEXT (context));
   g_assert (IDE_IS_CLANG_COMPLETION_ITEM (item));
+  g_assert (GTK_SOURCE_IS_COMPLETION_CELL (cell));
 
-  escaped = g_markup_escape_text (item->typed_text, -1);
-  if (item->params != NULL)
-    params_escaped = g_markup_escape_text (item->params, -1);
-  highlight = ide_completion_fuzzy_highlight (escaped, typed_text);
-  ide_completion_list_box_row_set_icon_name (row, item->icon_name);
-  ide_completion_list_box_row_set_left (row, item->return_type);
-  markup = g_strdup_printf ("%s%s<span fgalpha='32767'>%s</span>",
-                            highlight,
-                            item->params ? " " : "",
-                            params_escaped ?: "");
-  ide_completion_list_box_row_set_center_markup (row, markup);
-}
-
-static gchar *
-ide_clang_completion_provider_get_comment (IdeCompletionProvider *provider,
-                                           IdeCompletionProposal *proposal)
-{
-  IdeClangCompletionItem *item = IDE_CLANG_COMPLETION_ITEM (proposal);
-  g_autoptr(GVariant) result = ide_clang_completion_item_get_result (item);
-  gchar *str = NULL;
-
-  g_variant_lookup (result, "comment", "s", &str);
+  if (self->refilter_word)
+    typed_text = self->refilter_word;
+  else
+    typed_text = self->word;
 
-  return str;
+  ide_clang_completion_item_display (item, cell, typed_text);
 }
 
 static void
-provider_iface_init (IdeCompletionProviderInterface *iface)
+provider_iface_init (GtkSourceCompletionProviderInterface *iface)
 {
-  iface->load = ide_clang_completion_provider_load;
   iface->get_priority = ide_clang_completion_provider_get_priority;
   iface->is_trigger = ide_clang_completion_provider_is_trigger;
   iface->key_activates = ide_clang_completion_provider_key_activates;
-  iface->activate_proposal = ide_clang_completion_provider_activate_proposal;
+  iface->activate = ide_clang_completion_provider_activate;
   iface->refilter = ide_clang_completion_provider_refilter;
   iface->get_title = ide_clang_completion_provider_get_title;
   iface->populate_async = ide_clang_completion_provider_populate_async;
   iface->populate_finish = ide_clang_completion_provider_populate_finish;
-  iface->display_proposal = ide_clang_completion_provider_display_proposal;
-  iface->get_comment = ide_clang_completion_provider_get_comment;
+  iface->display = ide_clang_completion_provider_display;
 }
 
 G_DEFINE_FINAL_TYPE_WITH_CODE (IdeClangCompletionProvider, ide_clang_completion_provider, IDE_TYPE_OBJECT,
-                         G_IMPLEMENT_INTERFACE (IDE_TYPE_COMPLETION_PROVIDER, provider_iface_init))
+                               G_IMPLEMENT_INTERFACE (GTK_SOURCE_TYPE_COMPLETION_PROVIDER, 
provider_iface_init))
 
 static void
 ide_clang_completion_provider_dispose (GObject *object)
@@ -428,6 +448,9 @@ ide_clang_completion_provider_dispose (GObject *object)
   g_clear_object (&self->client);
   g_clear_object (&self->proposals);
 
+  g_clear_pointer (&self->word, g_free);
+  g_clear_pointer (&self->refilter_word, g_free);
+
   G_OBJECT_CLASS (ide_clang_completion_provider_parent_class)->dispose (object);
 }
 
diff --git a/src/plugins/clang/ide-clang-diagnostic-provider.c 
b/src/plugins/clang/ide-clang-diagnostic-provider.c
index 48773c301..2c553cd94 100644
--- a/src/plugins/clang/ide-clang-diagnostic-provider.c
+++ b/src/plugins/clang/ide-clang-diagnostic-provider.c
@@ -20,7 +20,10 @@
 
 #define G_LOG_DOMAIN "ide-clang-diagnostic-provider"
 
+#include "config.h"
+
 #include <glib/gi18n.h>
+
 #include <libide-foundry.h>
 
 #include "ide-clang-client.h"
@@ -28,10 +31,31 @@
 
 struct _IdeClangDiagnosticProvider
 {
-  IdeObject parent_instance;
+  IdeObject       parent_instance;
+  IdeBuildSystem *build_system;
+  IdeClangClient *client;
 };
 
-static void diagnostic_provider_iface_init (IdeDiagnosticProviderInterface *iface);
+static gboolean
+ide_clang_diagnostic_provider_check_status (IdeClangDiagnosticProvider *self,
+                                            IdeTask                    *task)
+{
+  IDE_ENTRY;
+
+  g_assert (IDE_IS_CLANG_DIAGNOSTIC_PROVIDER (self));
+  g_assert (IDE_IS_TASK (task));
+
+  if (self->client == NULL || self->build_system == NULL)
+    {
+      ide_task_return_new_error (task,
+                                 G_IO_ERROR,
+                                 G_IO_ERROR_CANCELLED,
+                                 "Operation cancelled");
+      IDE_RETURN (FALSE);
+    }
+
+  IDE_RETURN (TRUE);
+}
 
 static void
 ide_clang_diagnostic_provider_diagnose_cb (GObject      *object,
@@ -43,6 +67,8 @@ ide_clang_diagnostic_provider_diagnose_cb (GObject      *object,
   g_autoptr(IdeDiagnostics) diagnostics = NULL;
   g_autoptr(GError) error = NULL;
 
+  IDE_ENTRY;
+
   g_assert (IDE_IS_CLANG_CLIENT (client));
   g_assert (G_IS_ASYNC_RESULT (result));
   g_assert (IDE_IS_TASK (task));
@@ -53,6 +79,8 @@ ide_clang_diagnostic_provider_diagnose_cb (GObject      *object,
     ide_task_return_pointer (task,
                              IDE_OBJECT (g_steal_pointer (&diagnostics)),
                              ide_object_unref_and_destroy);
+
+  IDE_EXIT;
 }
 
 static void
@@ -62,28 +90,46 @@ diagnose_get_build_flags_cb (GObject      *object,
 {
   IdeBuildSystem *build_system = (IdeBuildSystem *)object;
   g_autoptr(IdeTask) task = user_data;
-  g_autoptr(IdeClangClient) client = NULL;
+  g_autoptr(GError) error = NULL;
   g_auto(GStrv) flags = NULL;
+  IdeClangDiagnosticProvider *self;
   GCancellable *cancellable;
-  IdeContext *context;
   GFile *file;
 
+  IDE_ENTRY;
+
   g_assert (IDE_IS_BUILD_SYSTEM (build_system));
   g_assert (G_IS_ASYNC_RESULT (result));
   g_assert (IDE_IS_TASK (task));
 
-  flags = ide_build_system_get_build_flags_finish (build_system, result, NULL);
-  context = ide_object_get_context (IDE_OBJECT (build_system));
-  client = ide_object_ensure_child_typed (IDE_OBJECT (context), IDE_TYPE_CLANG_CLIENT);
+  self = ide_task_get_source_object (task);
   file = ide_task_get_task_data (task);
   cancellable = ide_task_get_cancellable (task);
 
-  ide_clang_client_diagnose_async (client,
+  g_assert (IDE_IS_CLANG_DIAGNOSTIC_PROVIDER (self));
+  g_assert (!cancellable || G_IS_CANCELLABLE (cancellable));
+  g_assert (!file || G_IS_FILE (file));
+
+  if (!(flags = ide_build_system_get_build_flags_finish (build_system, result, &error)))
+    {
+      if (!ide_error_ignore (error))
+        {
+          ide_task_return_error (task, g_steal_pointer (&error));
+          IDE_EXIT;
+        }
+    }
+
+  if (!ide_clang_diagnostic_provider_check_status (self, task))
+    IDE_EXIT;
+
+  ide_clang_client_diagnose_async (self->client,
                                    file,
                                    (const gchar * const *)flags,
                                    cancellable,
                                    ide_clang_diagnostic_provider_diagnose_cb,
                                    g_steal_pointer (&task));
+
+  IDE_EXIT;
 }
 
 static void
@@ -97,8 +143,8 @@ ide_clang_diagnostic_provider_diagnose_async (IdeDiagnosticProvider *provider,
 {
   IdeClangDiagnosticProvider *self = (IdeClangDiagnosticProvider *)provider;
   g_autoptr(IdeTask) task = NULL;
-  IdeBuildSystem *build_system;
-  IdeContext *context;
+
+  IDE_ENTRY;
 
   g_assert (IDE_IS_CLANG_DIAGNOSTIC_PROVIDER (self));
   g_assert (IDE_IS_CLANG_DIAGNOSTIC_PROVIDER (self));
@@ -107,14 +153,16 @@ ide_clang_diagnostic_provider_diagnose_async (IdeDiagnosticProvider *provider,
   ide_task_set_task_data (task, g_object_ref (file), g_object_unref);
   ide_task_set_kind (task, IDE_TASK_KIND_COMPILER);
 
-  context = ide_object_get_context (IDE_OBJECT (self));
-  build_system = ide_build_system_from_context (context);
+  if (!ide_clang_diagnostic_provider_check_status (self, task))
+    IDE_EXIT;
 
-  ide_build_system_get_build_flags_async (build_system,
+  ide_build_system_get_build_flags_async (self->build_system,
                                           file,
                                           cancellable,
                                           diagnose_get_build_flags_cb,
                                           g_steal_pointer (&task));
+
+  IDE_EXIT;
 }
 
 static IdeDiagnostics *
@@ -122,24 +170,69 @@ ide_clang_diagnostic_provider_diagnose_finish (IdeDiagnosticProvider  *provider,
                                                GAsyncResult           *result,
                                                GError                **error)
 {
+  IdeDiagnostics *ret;
+
+  IDE_ENTRY;
+
   g_return_val_if_fail (IDE_IS_CLANG_DIAGNOSTIC_PROVIDER (provider), NULL);
   g_return_val_if_fail (IDE_IS_TASK (result), NULL);
 
-  return ide_task_propagate_pointer (IDE_TASK (result), error);
+  ret = ide_task_propagate_pointer (IDE_TASK (result), error);
+
+  IDE_RETURN (ret);
+}
+
+static void
+ide_clang_diagnostic_provider_load (IdeDiagnosticProvider *provider)
+{
+  IdeClangDiagnosticProvider *self = (IdeClangDiagnosticProvider *)provider;
+  IdeBuildSystem *build_system;
+  IdeClangClient *client;
+  IdeContext *context;
+
+  IDE_ENTRY;
+
+  g_assert (IDE_IS_CLANG_DIAGNOSTIC_PROVIDER (self));
+
+  context = ide_object_get_context (IDE_OBJECT (self));
+  client = ide_object_ensure_child_typed (IDE_OBJECT (context), IDE_TYPE_CLANG_CLIENT);
+  build_system = ide_build_system_from_context (context);
+
+  g_set_object (&self->client, client);
+  g_set_object (&self->build_system, build_system);
+
+  IDE_EXIT;
+}
+
+static void
+ide_clang_diagnostic_provider_unload (IdeDiagnosticProvider *provider)
+{
+  IdeClangDiagnosticProvider *self = (IdeClangDiagnosticProvider *)provider;
+
+  IDE_ENTRY;
+
+  g_assert (IDE_IS_CLANG_DIAGNOSTIC_PROVIDER (self));
+
+  g_clear_object (&self->client);
+  g_clear_object (&self->build_system);
+
+  IDE_EXIT;
 }
 
 static void
 diagnostic_provider_iface_init (IdeDiagnosticProviderInterface *iface)
 {
+  iface->load = ide_clang_diagnostic_provider_load;
+  iface->unload = ide_clang_diagnostic_provider_unload;
   iface->diagnose_async = ide_clang_diagnostic_provider_diagnose_async;
   iface->diagnose_finish = ide_clang_diagnostic_provider_diagnose_finish;
 }
 
 G_DEFINE_FINAL_TYPE_WITH_CODE (IdeClangDiagnosticProvider,
-                         ide_clang_diagnostic_provider,
-                         IDE_TYPE_OBJECT,
-                         G_IMPLEMENT_INTERFACE (IDE_TYPE_DIAGNOSTIC_PROVIDER,
-                                                diagnostic_provider_iface_init))
+                               ide_clang_diagnostic_provider,
+                               IDE_TYPE_OBJECT,
+                               G_IMPLEMENT_INTERFACE (IDE_TYPE_DIAGNOSTIC_PROVIDER,
+                                                      diagnostic_provider_iface_init))
 
 static void
 ide_clang_diagnostic_provider_class_init (IdeClangDiagnosticProviderClass *klass)
diff --git a/src/plugins/clang/ide-clang-highlighter.c b/src/plugins/clang/ide-clang-highlighter.c
index 4c4532845..bf689fb21 100644
--- a/src/plugins/clang/ide-clang-highlighter.c
+++ b/src/plugins/clang/ide-clang-highlighter.c
@@ -42,8 +42,8 @@ struct _IdeClangHighlighter
 static void highlighter_iface_init             (IdeHighlighterInterface *iface);
 static void ide_clang_highlighter_queue_udpate (IdeClangHighlighter     *self);
 
-G_DEFINE_TYPE_EXTENDED (IdeClangHighlighter, ide_clang_highlighter, IDE_TYPE_OBJECT, G_TYPE_FLAG_FINAL,
-                        G_IMPLEMENT_INTERFACE (IDE_TYPE_HIGHLIGHTER, highlighter_iface_init))
+G_DEFINE_FINAL_TYPE_WITH_CODE (IdeClangHighlighter, ide_clang_highlighter, IDE_TYPE_OBJECT,
+                               G_IMPLEMENT_INTERFACE (IDE_TYPE_HIGHLIGHTER, highlighter_iface_init))
 
 static inline gboolean
 accepts_char (gunichar ch)
@@ -128,11 +128,19 @@ get_index_flags_cb (GObject      *object,
   g_assert (G_IS_ASYNC_RESULT (result));
   g_assert (IDE_IS_TASK (task));
 
+  file = ide_task_get_task_data (task);
+  cancellable = ide_task_get_cancellable (task);
+
+  g_assert (G_IS_FILE (file));
+  g_assert (!cancellable || G_IS_CANCELLABLE (cancellable));
+
   flags = ide_build_system_get_build_flags_finish (build_system, result, &error);
+
+  if (ide_task_return_error_if_cancelled (task))
+    return;
+
   context = ide_object_get_context (IDE_OBJECT (build_system));
   client = ide_object_ensure_child_typed (IDE_OBJECT (context), IDE_TYPE_CLANG_CLIENT);
-  file = ide_task_get_task_data (task);
-  cancellable = ide_task_get_cancellable (task);
 
   ide_clang_client_get_highlight_index_async (client,
                                               file,
@@ -283,6 +291,7 @@ ide_clang_highlighter_destroy (IdeObject *object)
 {
   IdeClangHighlighter *self = (IdeClangHighlighter *)object;
 
+  g_clear_handle_id (&self->queued_source, g_source_remove);
   g_clear_pointer (&self->index, ide_highlight_index_unref);
   g_clear_weak_pointer (&self->engine);
 
@@ -323,7 +332,8 @@ ide_clang_highlighter_do_update (IdeClangHighlighter *self)
 
   self->queued_source = 0;
 
-  if (self->engine == NULL ||
+  if (!ide_object_check_ready (IDE_OBJECT (self), NULL) ||
+      self->engine == NULL ||
       !(buffer = ide_highlight_engine_get_buffer (self->engine)) ||
       !(file = ide_buffer_get_file (buffer)) ||
       !(context = ide_object_get_context (IDE_OBJECT (self))) ||
@@ -350,7 +360,8 @@ ide_clang_highlighter_queue_udpate (IdeClangHighlighter *self)
 {
   g_assert (IDE_IS_CLANG_HIGHLIGHTER (self));
 
-  if (self->queued_source != 0)
+  if (self->queued_source != 0 ||
+      ide_object_in_destruction (IDE_OBJECT (self)))
     return;
 
   self->queued_source =
diff --git a/src/plugins/clang/ide-clang-preferences-addin.c b/src/plugins/clang/ide-clang-preferences-addin.c
index 35a60e8a0..e8520626d 100644
--- a/src/plugins/clang/ide-clang-preferences-addin.c
+++ b/src/plugins/clang/ide-clang-preferences-addin.c
@@ -18,7 +18,12 @@
  * SPDX-License-Identifier: GPL-3.0-or-later
  */
 
+#define G_LOG_DOMAIN "ide-clang-preferences-addin"
+
+#include "config.h"
+
 #include <glib/gi18n.h>
+
 #include <libide-code.h>
 #include <libide-gui.h>
 
@@ -33,96 +38,67 @@ struct _IdeClangPreferencesAddin
   guint   params_id;
 };
 
-static void preferences_addin_iface_init (IdePreferencesAddinInterface *iface);
+static const IdePreferenceGroupEntry groups[] = {
+  { "insight", "clang", 1000, N_("Clang") },
+};
 
-G_DEFINE_TYPE_EXTENDED (IdeClangPreferencesAddin, ide_clang_preferences_addin, G_TYPE_OBJECT, 
G_TYPE_FLAG_FINAL,
-                        G_IMPLEMENT_INTERFACE (IDE_TYPE_PREFERENCES_ADDIN,
-                                               preferences_addin_iface_init))
+static const IdePreferenceItemEntry items[] = {
+  { "insight", "diagnostics-providers", "clang", 0, ide_preferences_window_toggle,
+    N_("Use Clang for Diagnostics"),
+    N_("Clang will be queried for diagnostics within C, C++, and Objective-C sources"),
+    "org.gnome.builder.extension-type",
+    "/org/gnome/builder/extension-types/clang/IdeDiagnosticProvider/",
+    "enabled" },
+
+  { "insight", "completion-providers", "clang", 0, ide_preferences_window_toggle,
+    N_("Use Clang for Completions"),
+    N_("Clang will be queried for completions within C, C++, and Objective-C sources"),
+    "org.gnome.builder.extension-type",
+    "/org/gnome/builder/extension-types/clang/GtkSourceCompletionProvider/",
+    "enabled" },
+
+  { "insight", "clang", "parens", 0, ide_preferences_window_toggle,
+    N_("Complete Parenthesis"),
+    N_("Include parenthesis when completing clang proposals"),
+    "org.gnome.builder.clang", NULL, "complete-parens" },
+
+  { "insight", "clang", "params", 0, ide_preferences_window_toggle,
+    N_("Complete Parameters"),
+    N_("Include parameters and types when completing clang proposals"),
+    "org.gnome.builder.clang", NULL, "complete-params" },
+};
 
 static void
-ide_clang_preferences_addin_class_init (IdeClangPreferencesAddinClass *klass)
+ide_clang_preferences_addin_load (IdePreferencesAddin  *addin,
+                                  IdePreferencesWindow *window,
+                                  IdeContext           *context)
 {
-}
+  IDE_ENTRY;
 
-static void
-ide_clang_preferences_addin_init (IdeClangPreferencesAddin *self)
-{
-}
+  g_assert (IDE_IS_CLANG_PREFERENCES_ADDIN (addin));
+  g_assert (IDE_IS_PREFERENCES_WINDOW (window));
+  g_assert (!context || IDE_IS_CONTEXT (context));
 
-static void
-ide_clang_preferences_addin_load (IdePreferencesAddin *addin,
-                                  DzlPreferences      *preferences)
-{
-  IdeClangPreferencesAddin *self = (IdeClangPreferencesAddin *)addin;
+  ide_preferences_window_add_groups (window, groups, G_N_ELEMENTS (groups), NULL);
+  ide_preferences_window_add_items (window, items, G_N_ELEMENTS (items), window, NULL);
 
-  g_assert (IDE_IS_CLANG_PREFERENCES_ADDIN (addin));
-  g_assert (DZL_IS_PREFERENCES (preferences));
-
-  self->diagnose_id = dzl_preferences_add_switch (preferences,
-                                                  "code-insight",
-                                                  "diagnostics",
-                                                  "org.gnome.builder.extension-type",
-                                                  "enabled",
-                                                  
"/org/gnome/builder/extension-types/clang-plugin/IdeDiagnosticProvider/",
-                                                  NULL,
-                                                  _("Clang"),
-                                                  _("Show errors and warnings provided by Clang"),
-                                                  /* translators: keywords used when searching for 
preferences */
-                                                  _("clang diagnostics warnings errors"),
-                                                  50);
-
-  self->completion_id = dzl_preferences_add_switch (preferences,
-                                                    "completion",
-                                                    "providers",
-                                                    "org.gnome.builder.extension-type",
-                                                    "enabled",
-                                                    
"/org/gnome/builder/extension-types/clang-plugin/IdeCompletionProvider/",
-                                                    NULL,
-                                                    _("Suggest completions using Clang"),
-                                                    _("Use Clang to suggest completions for C and C++ 
languages"),
-                                                    NULL,
-                                                    20);
-
-  dzl_preferences_add_list_group (preferences, "completion", "clang", _("Clang Options"), 
GTK_SELECTION_NONE, 300);
-
-  self->parens_id = dzl_preferences_add_switch (preferences,
-                                                "completion",
-                                                "clang",
-                                                "org.gnome.builder.clang",
-                                                "complete-parens",
-                                                NULL,
-                                                NULL,
-                                                _("Complete Parenthesis"),
-                                                _("Include parenthesis when completing clang proposals"),
-                                                NULL,
-                                                0);
-
-  self->params_id = dzl_preferences_add_switch (preferences,
-                                                "completion",
-                                                "clang",
-                                                "org.gnome.builder.clang",
-                                                "complete-params",
-                                                NULL,
-                                                NULL,
-                                                _("Complete Parameters"),
-                                                _("Include parameters and types when completing clang 
proposals"),
-                                                NULL,
-                                                10);
+  IDE_EXIT;
 }
 
 static void
-ide_clang_preferences_addin_unload (IdePreferencesAddin *addin,
-                                    DzlPreferences      *preferences)
+ide_clang_preferences_addin_unload (IdePreferencesAddin  *addin,
+                                    IdePreferencesWindow *window,
+                                    IdeContext           *context)
 {
-  IdeClangPreferencesAddin *self = (IdeClangPreferencesAddin *)addin;
+  IDE_ENTRY;
 
   g_assert (IDE_IS_CLANG_PREFERENCES_ADDIN (addin));
-  g_assert (DZL_IS_PREFERENCES (preferences));
+  g_assert (IDE_IS_PREFERENCES_WINDOW (window));
+  g_assert (!context || IDE_IS_CONTEXT (context));
+
+  /* TODO: Remove gsettings switches */
 
-  dzl_preferences_remove_id (preferences, self->completion_id);
-  dzl_preferences_remove_id (preferences, self->diagnose_id);
-  dzl_preferences_remove_id (preferences, self->parens_id);
-  dzl_preferences_remove_id (preferences, self->params_id);
+  IDE_EXIT;
 }
 
 static void
@@ -131,3 +107,16 @@ preferences_addin_iface_init (IdePreferencesAddinInterface *iface)
   iface->load = ide_clang_preferences_addin_load;
   iface->unload = ide_clang_preferences_addin_unload;
 }
+
+G_DEFINE_FINAL_TYPE_WITH_CODE (IdeClangPreferencesAddin, ide_clang_preferences_addin, G_TYPE_OBJECT,
+                               G_IMPLEMENT_INTERFACE (IDE_TYPE_PREFERENCES_ADDIN, 
preferences_addin_iface_init))
+
+static void
+ide_clang_preferences_addin_class_init (IdeClangPreferencesAddinClass *klass)
+{
+}
+
+static void
+ide_clang_preferences_addin_init (IdeClangPreferencesAddin *self)
+{
+}
diff --git a/src/plugins/clang/ide-clang-proposals.c b/src/plugins/clang/ide-clang-proposals.c
index a0a924b9d..debc3abaa 100644
--- a/src/plugins/clang/ide-clang-proposals.c
+++ b/src/plugins/clang/ide-clang-proposals.c
@@ -22,10 +22,11 @@
 
 #include "config.h"
 
+#include <clang-c/Index.h>
+
 #include <libide-code.h>
 #include <libide-foundry.h>
 #include <libide-sourceview.h>
-#include <clang-c/Index.h>
 
 #include "ide-buffer-private.h"
 
@@ -344,7 +345,7 @@ ide_clang_proposals_do_refilter (IdeClangProposals *self,
                 keyword = NULL;
             }
 
-          if (keyword == NULL || !ide_completion_fuzzy_match (keyword, folded, &priority))
+          if (keyword == NULL || !gtk_source_completion_fuzzy_match (keyword, folded, &priority))
             g_array_remove_index_fast (self->match_indexes, i - 1);
           else
             item->priority = priority;
@@ -393,7 +394,7 @@ ide_clang_proposals_do_refilter (IdeClangProposals *self,
               Item item = { index, 0, 0, typed_text };
               guint priority;
 
-              if (ide_completion_fuzzy_match (typed_text, folded, &priority))
+              if (gtk_source_completion_fuzzy_match (typed_text, folded, &priority))
                 {
                   enum CXCursorKind kind = 0;
 
diff --git a/src/plugins/clang/ide-clang-symbol-resolver.c b/src/plugins/clang/ide-clang-symbol-resolver.c
index 90406c636..1b7870fd5 100644
--- a/src/plugins/clang/ide-clang-symbol-resolver.c
+++ b/src/plugins/clang/ide-clang-symbol-resolver.c
@@ -29,13 +29,73 @@
 
 struct _IdeClangSymbolResolver
 {
-  IdeObject parent_instance;
+  IdeObject       parent_instance;
+  IdeBuildSystem *build_system;
+  IdeClangClient *client;
 };
 
 static void symbol_resolver_iface_init (IdeSymbolResolverInterface *iface);
 
-G_DEFINE_TYPE_EXTENDED (IdeClangSymbolResolver, ide_clang_symbol_resolver, IDE_TYPE_OBJECT, 
G_TYPE_FLAG_FINAL,
-                        G_IMPLEMENT_INTERFACE (IDE_TYPE_SYMBOL_RESOLVER, symbol_resolver_iface_init))
+G_DEFINE_FINAL_TYPE_WITH_CODE (IdeClangSymbolResolver, ide_clang_symbol_resolver, IDE_TYPE_OBJECT,
+                               G_IMPLEMENT_INTERFACE (IDE_TYPE_SYMBOL_RESOLVER, symbol_resolver_iface_init))
+
+static gboolean
+ide_clang_symbol_resolver_check_status (IdeClangSymbolResolver *self,
+                                        IdeTask *task)
+{
+  IDE_ENTRY;
+
+  g_assert (IDE_IS_CLANG_SYMBOL_RESOLVER (self));
+  g_assert (IDE_IS_TASK (task));
+
+  if (self->client == NULL || self->build_system == NULL)
+    {
+      ide_task_return_new_error (task,
+                                 G_IO_ERROR,
+                                 G_IO_ERROR_CANCELLED,
+                                 "Operation cancelled");
+      IDE_RETURN (FALSE);
+    }
+
+  IDE_RETURN (TRUE);
+}
+
+static void
+ide_clang_symbol_resolver_load (IdeSymbolResolver *resolver)
+{
+  IdeClangSymbolResolver *self = (IdeClangSymbolResolver *)resolver;
+  g_autoptr(IdeContext) context = NULL;
+  g_autoptr(IdeClangClient) client = NULL;
+  IdeBuildSystem *build_system;
+
+  IDE_ENTRY;
+
+  g_assert (IDE_IS_CLANG_SYMBOL_RESOLVER (self));
+
+  context = ide_object_ref_context (IDE_OBJECT (self));
+  build_system = ide_build_system_from_context (context);
+  client = ide_object_ensure_child_typed (IDE_OBJECT (context), IDE_TYPE_CLANG_CLIENT);
+
+  g_set_object (&self->build_system, build_system);
+  g_set_object (&self->client, client);
+
+  IDE_EXIT;
+}
+
+static void
+ide_clang_symbol_resolver_unload (IdeSymbolResolver *resolver)
+{
+  IdeClangSymbolResolver *self = (IdeClangSymbolResolver *)resolver;
+
+  IDE_ENTRY;
+
+  g_assert (IDE_IS_CLANG_SYMBOL_RESOLVER (self));
+
+  g_clear_object (&self->build_system);
+  g_clear_object (&self->client);
+
+  IDE_EXIT;
+}
 
 static void
 ide_clang_symbol_resolver_lookup_symbol_cb (GObject      *object,
@@ -70,11 +130,11 @@ lookup_symbol_flags_cb (GObject      *object,
 {
   IdeBuildSystem *build_system = (IdeBuildSystem *)object;
   g_autoptr(IdeTask) task = user_data;
-  g_autoptr(IdeClangClient) client = NULL;
+  g_autoptr(GError) error = NULL;
   g_auto(GStrv) flags = NULL;
-  IdeLocation *location;
+  IdeClangSymbolResolver *self;
   GCancellable *cancellable;
-  IdeContext *context;
+  IdeLocation *location;
   GFile *file;
   guint line;
   guint column;
@@ -85,16 +145,31 @@ lookup_symbol_flags_cb (GObject      *object,
   g_assert (G_IS_ASYNC_RESULT (result));
   g_assert (IDE_IS_TASK (task));
 
-  flags = ide_build_system_get_build_flags_finish (build_system, result, NULL);
-  context = ide_object_get_context (IDE_OBJECT (build_system));
-  client = ide_object_ensure_child_typed (IDE_OBJECT (context), IDE_TYPE_CLANG_CLIENT);
+  self = ide_task_get_source_object (task);
   cancellable = ide_task_get_cancellable (task);
   location = ide_task_get_task_data (task);
+
+  g_assert (IDE_IS_CLANG_SYMBOL_RESOLVER (self));
+  g_assert (!cancellable || G_IS_CANCELLABLE (cancellable));
+  g_assert (IDE_IS_LOCATION (location));
+
+  if (!(flags = ide_build_system_get_build_flags_finish (build_system, result, &error)))
+    {
+      if (!ide_error_ignore (error))
+        {
+          ide_task_return_error (task, g_steal_pointer (&error));
+          IDE_EXIT;
+        }
+    }
+
+  if (!ide_clang_symbol_resolver_check_status (self, task))
+    IDE_EXIT;
+
   file = ide_location_get_file (location);
   line = ide_location_get_line (location);
   column = ide_location_get_line_offset (location);
 
-  ide_clang_client_locate_symbol_async (client,
+  ide_clang_client_locate_symbol_async (self->client,
                                         file,
                                         (const gchar * const *)flags,
                                         line + 1,
@@ -115,9 +190,6 @@ ide_clang_symbol_resolver_lookup_symbol_async (IdeSymbolResolver   *resolver,
 {
   IdeClangSymbolResolver *self = (IdeClangSymbolResolver *)resolver;
   g_autoptr(IdeTask) task = NULL;
-  IdeBuildSystem *build_system;
-  IdeContext *context;
-  GFile *file;
 
   IDE_ENTRY;
 
@@ -128,16 +200,13 @@ ide_clang_symbol_resolver_lookup_symbol_async (IdeSymbolResolver   *resolver,
   task = ide_task_new (self, cancellable, callback, user_data);
   ide_task_set_priority (task, G_PRIORITY_LOW);
   ide_task_set_source_tag (task, ide_clang_symbol_resolver_lookup_symbol_async);
-  ide_task_set_task_data (task,
-                          g_object_ref (location),
-                          g_object_unref);
+  ide_task_set_task_data (task, g_object_ref (location), g_object_unref);
 
-  context = ide_object_get_context (IDE_OBJECT (self));
-  build_system = ide_build_system_from_context (context);
-  file = ide_location_get_file (location);
+  if (!ide_clang_symbol_resolver_check_status (self, task))
+    IDE_EXIT;
 
-  ide_build_system_get_build_flags_async (build_system,
-                                          file,
+  ide_build_system_get_build_flags_async (self->build_system,
+                                          ide_location_get_file (location),
                                           cancellable,
                                           lookup_symbol_flags_cb,
                                           g_steal_pointer (&task));
@@ -193,28 +262,46 @@ get_symbol_tree_flags_cb (GObject      *object,
 {
   IdeBuildSystem *build_system = (IdeBuildSystem *)object;
   g_autoptr(IdeTask) task = user_data;
-  g_autoptr(IdeClangClient) client = NULL;
+  g_autoptr(GError) error = NULL;
   g_auto(GStrv) flags = NULL;
+  IdeClangSymbolResolver *self;
   GCancellable *cancellable;
-  IdeContext *context;
   GFile *file;
 
+  IDE_ENTRY;
+
   g_assert (IDE_IS_BUILD_SYSTEM (build_system));
   g_assert (G_IS_ASYNC_RESULT (result));
   g_assert (IDE_IS_TASK (task));
 
-  flags = ide_build_system_get_build_flags_finish (build_system, result, NULL);
-  context = ide_object_get_context (IDE_OBJECT (build_system));
-  client = ide_object_ensure_child_typed (IDE_OBJECT (context), IDE_TYPE_CLANG_CLIENT);
+  self = ide_task_get_source_object (task);
   cancellable = ide_task_get_cancellable (task);
   file = ide_task_get_task_data (task);
 
-  ide_clang_client_get_symbol_tree_async (client,
+  g_assert (IDE_IS_CLANG_SYMBOL_RESOLVER (self));
+  g_assert (!cancellable || G_IS_CANCELLABLE (cancellable));
+  g_assert (G_IS_FILE (file));
+
+  if (!(flags = ide_build_system_get_build_flags_finish (build_system, result, &error)))
+    {
+      if (!ide_error_ignore (error))
+        {
+          ide_task_return_error (task, g_steal_pointer (&error));
+          IDE_EXIT;
+        }
+    }
+
+  if (!ide_clang_symbol_resolver_check_status (self, task))
+    IDE_EXIT;
+
+  ide_clang_client_get_symbol_tree_async (self->client,
                                           file,
                                           (const gchar * const *)flags,
                                           cancellable,
                                           ide_clang_symbol_resolver_get_symbol_tree_cb,
                                           g_steal_pointer (&task));
+
+  IDE_EXIT;
 }
 
 static void
@@ -227,8 +314,6 @@ ide_clang_symbol_resolver_get_symbol_tree_async (IdeSymbolResolver   *resolver,
 {
   IdeClangSymbolResolver *self = (IdeClangSymbolResolver *)resolver;
   g_autoptr(IdeTask) task = NULL;
-  IdeBuildSystem *build_system;
-  IdeContext *context;
 
   IDE_ENTRY;
 
@@ -241,10 +326,10 @@ ide_clang_symbol_resolver_get_symbol_tree_async (IdeSymbolResolver   *resolver,
   ide_task_set_source_tag (task, ide_clang_symbol_resolver_get_symbol_tree_async);
   ide_task_set_task_data (task, g_object_ref (file), g_object_unref);
 
-  context = ide_object_get_context (IDE_OBJECT (self));
-  build_system = ide_build_system_from_context (context);
+  if (!ide_clang_symbol_resolver_check_status (self, task))
+    IDE_EXIT;
 
-  ide_build_system_get_build_flags_async (build_system,
+  ide_build_system_get_build_flags_async (self->build_system,
                                           file,
                                           cancellable,
                                           get_symbol_tree_flags_cb,
@@ -300,6 +385,7 @@ find_nearest_scope_flags_cb (GObject      *object,
   IdeBuildSystem *build_system = (IdeBuildSystem *)object;
   g_autoptr(IdeTask) task = user_data;
   g_autoptr(IdeClangClient) client = NULL;
+  g_autoptr(GError) error = NULL;
   g_auto(GStrv) flags = NULL;
   IdeLocation *location;
   GCancellable *cancellable;
@@ -312,8 +398,24 @@ find_nearest_scope_flags_cb (GObject      *object,
   g_assert (G_IS_ASYNC_RESULT (result));
   g_assert (IDE_IS_TASK (task));
 
-  flags = ide_build_system_get_build_flags_finish (build_system, result, NULL);
-  context = ide_object_get_context (IDE_OBJECT (build_system));
+  if (!(flags = ide_build_system_get_build_flags_finish (build_system, result, &error)))
+    {
+      if (!ide_error_ignore (error))
+        {
+          ide_task_return_error (task, g_steal_pointer (&error));
+          return;
+        }
+    }
+
+  if (!(context = ide_object_get_context (IDE_OBJECT (build_system))))
+    {
+      ide_task_return_new_error (task,
+                                 G_IO_ERROR,
+                                 G_IO_ERROR_CANCELLED,
+                                 "Operation cancelled");
+      return;
+    }
+
   client = ide_object_ensure_child_typed (IDE_OBJECT (context), IDE_TYPE_CLANG_CLIENT);
   cancellable = ide_task_get_cancellable (task);
   location = ide_task_get_task_data (task);
@@ -333,7 +435,7 @@ find_nearest_scope_flags_cb (GObject      *object,
 
 static void
 ide_clang_symbol_resolver_find_nearest_scope_async (IdeSymbolResolver   *symbol_resolver,
-                                                    IdeLocation   *location,
+                                                    IdeLocation         *location,
                                                     GCancellable        *cancellable,
                                                     GAsyncReadyCallback  callback,
                                                     gpointer             user_data)
@@ -394,6 +496,8 @@ ide_clang_symbol_resolver_class_init (IdeClangSymbolResolverClass *klass)
 static void
 symbol_resolver_iface_init (IdeSymbolResolverInterface *iface)
 {
+  iface->load = ide_clang_symbol_resolver_load;
+  iface->unload = ide_clang_symbol_resolver_unload;
   iface->lookup_symbol_async = ide_clang_symbol_resolver_lookup_symbol_async;
   iface->lookup_symbol_finish = ide_clang_symbol_resolver_lookup_symbol_finish;
   iface->get_symbol_tree_async = ide_clang_symbol_resolver_get_symbol_tree_async;
diff --git a/src/plugins/clang/ide-clang-symbol-tree.c b/src/plugins/clang/ide-clang-symbol-tree.c
index f2952a105..ef4b6e71f 100644
--- a/src/plugins/clang/ide-clang-symbol-tree.c
+++ b/src/plugins/clang/ide-clang-symbol-tree.c
@@ -53,8 +53,6 @@ static GParamSpec *properties [N_PROPS];
  * Gets the #IdeClangSymbolTree:file property.
  *
  * Returns: (transfer none): a #GFile.
- *
- * Since: 3.32
  */
 GFile *
 ide_clang_symbol_tree_get_file (IdeClangSymbolTree *self)
diff --git a/src/plugins/clang/ide-clang.c b/src/plugins/clang/ide-clang.c
index 36ad84168..a6d45f375 100644
--- a/src/plugins/clang/ide-clang.c
+++ b/src/plugins/clang/ide-clang.c
@@ -653,8 +653,6 @@ ide_clang_index_file_visitor (CXCursor     cursor,
  * from queue, else this will do Breadth first traversal on AST till it finds a
  * declaration.  On next request when decl_cursors is empty it will continue
  * traversal from where it has stopped in previously.
- *
- * Since: 3.32
  */
 static IdeCodeIndexEntry *
 ide_clang_index_file_next_entry (IndexFile                *state,
@@ -853,8 +851,6 @@ ide_clang_index_file_worker (IdeTask      *task,
  * Asynchronously requests that indexable entries are extracted from the file
  * found at @path. The results (an array of #IdeCodeIndexEntry) can be accessed
  * via ide_clang_index_file_finish() using the result provided to @callback
- *
- * Since: 3.32
  */
 void
 ide_clang_index_file_async (IdeClang            *self,
@@ -900,8 +896,6 @@ ide_clang_index_file_async (IdeClang            *self,
  * Finishes a request to index a file.
  *
  * Returns: (transfer full): a #GPtrArray of #IdeCodeIndexEntry
- *
- * Since: 3.32
  */
 GPtrArray *
 ide_clang_index_file_finish (IdeClang      *self,
@@ -1186,8 +1180,6 @@ ide_clang_diagnose_worker (IdeTask      *task,
  * Asynchronously requests that the file be diagnosed.
  *
  * This generates diagnostics related to the file after parsing it.
- *
- * Since: 3.32
  */
 void
 ide_clang_diagnose_async (IdeClang            *self,
@@ -1237,8 +1229,6 @@ ide_clang_diagnose_async (IdeClang            *self,
  *
  * Returns: (transfer full) (element-type Ide.Diagnostic):
  *   a #GPtrArray of #IdeDiagnostic
- *
- * Since: 3.32
  */
 GPtrArray *
 ide_clang_diagnose_finish (IdeClang      *self,
@@ -2317,8 +2307,6 @@ ide_clang_get_index_key_async (IdeClang            *self,
  * at a given source location.
  *
  * Returns: (transfer full): the key, or %NULL and @error is set
- *
- * Since: 3.32
  */
 gchar *
 ide_clang_get_index_key_finish (IdeClang      *self,


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