[gnome-builder] plugins/clang: port to GTK 4
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder] plugins/clang: port to GTK 4
- Date: Tue, 12 Jul 2022 06:39:14 +0000 (UTC)
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]