[gnome-builder] ctags: add () to function expansion



commit ad7ad7d9a1e7325f049ffbd54faeb08aa50bf7dd
Author: Christian Hergert <chergert redhat com>
Date:   Tue Jan 30 18:56:41 2018 -0800

    ctags: add () to function expansion
    
    Also, respect the spacing setting in the FileSettings.

 src/plugins/ctags/ide-ctags-completion-item.c      | 51 ++++++++++++++++
 src/plugins/ctags/ide-ctags-completion-item.h      |  8 ++-
 .../ctags/ide-ctags-completion-provider-private.h  |  1 +
 src/plugins/ctags/ide-ctags-completion-provider.c  | 70 ++++++++++++----------
 4 files changed, 95 insertions(+), 35 deletions(-)
---
diff --git a/src/plugins/ctags/ide-ctags-completion-item.c b/src/plugins/ctags/ide-ctags-completion-item.c
index bb3e5456d..7e41a395c 100644
--- a/src/plugins/ctags/ide-ctags-completion-item.c
+++ b/src/plugins/ctags/ide-ctags-completion-item.c
@@ -211,3 +211,54 @@ _ide_ctags_completion_item_register_type (GTypeModule *module)
 {
   ide_ctags_completion_item_register_type (module);
 }
+
+gboolean
+ide_ctags_completion_item_is_function (IdeCtagsCompletionItem *self)
+{
+  g_return_val_if_fail (IDE_IS_CTAGS_COMPLETION_ITEM (self), FALSE);
+  g_return_val_if_fail (self->entry != NULL, FALSE);
+
+  return self->entry->kind == IDE_CTAGS_INDEX_ENTRY_FUNCTION;
+}
+
+IdeSourceSnippet *
+ide_ctags_completion_item_get_snippet (IdeCtagsCompletionItem *self,
+                                       IdeFileSettings        *file_settings)
+{
+  g_autoptr(IdeSourceSnippet) ret = NULL;
+  g_autoptr(IdeSourceSnippetChunk) chunk1 = NULL;
+
+  g_return_val_if_fail (IDE_IS_CTAGS_COMPLETION_ITEM (self), NULL);
+  g_return_val_if_fail (!file_settings || IDE_IS_FILE_SETTINGS (file_settings), NULL);
+
+  ret = ide_source_snippet_new (NULL, NULL);
+
+  chunk1 = ide_source_snippet_chunk_new ();
+  ide_source_snippet_chunk_set_spec (chunk1, self->entry->name);
+  ide_source_snippet_add_chunk (ret, chunk1);
+
+  if (ide_ctags_completion_item_is_function (self))
+    {
+      g_autoptr(IdeSourceSnippetChunk) chunk2 = ide_source_snippet_chunk_new ();
+      g_autoptr(IdeSourceSnippetChunk) chunk3 = ide_source_snippet_chunk_new ();
+      g_autoptr(IdeSourceSnippetChunk) chunk4 = ide_source_snippet_chunk_new ();
+      IdeSpacesStyle style = IDE_SPACES_STYLE_BEFORE_LEFT_PAREN;
+
+      if (file_settings != NULL)
+        style = ide_file_settings_get_spaces_style (file_settings);
+
+      if (style & IDE_SPACES_STYLE_BEFORE_LEFT_PAREN)
+        ide_source_snippet_chunk_set_spec (chunk2, " (");
+      else
+        ide_source_snippet_chunk_set_spec (chunk2, "(");
+
+      ide_source_snippet_chunk_set_tab_stop (chunk3, 0);
+      ide_source_snippet_chunk_set_spec (chunk4, ")");
+
+      ide_source_snippet_add_chunk (ret, chunk2);
+      ide_source_snippet_add_chunk (ret, chunk3);
+      ide_source_snippet_add_chunk (ret, chunk4);
+    }
+
+  return g_steal_pointer (&ret);
+}
diff --git a/src/plugins/ctags/ide-ctags-completion-item.h b/src/plugins/ctags/ide-ctags-completion-item.h
index facc7ccd5..cf63076a8 100644
--- a/src/plugins/ctags/ide-ctags-completion-item.h
+++ b/src/plugins/ctags/ide-ctags-completion-item.h
@@ -30,8 +30,10 @@ G_BEGIN_DECLS
 
 G_DECLARE_FINAL_TYPE (IdeCtagsCompletionItem, ide_ctags_completion_item, IDE, CTAGS_COMPLETION_ITEM, 
IdeCompletionItem)
 
-IdeCtagsCompletionItem *
-ide_ctags_completion_item_new (IdeCtagsCompletionProvider *provider,
-                               const IdeCtagsIndexEntry   *entry);
+IdeCtagsCompletionItem *ide_ctags_completion_item_new         (IdeCtagsCompletionProvider *provider,
+                                                               const IdeCtagsIndexEntry   *entry);
+gboolean                ide_ctags_completion_item_is_function (IdeCtagsCompletionItem     *self);
+IdeSourceSnippet       *ide_ctags_completion_item_get_snippet (IdeCtagsCompletionItem     *self,
+                                                               IdeFileSettings            *file_settings);
 
 G_END_DECLS
diff --git a/src/plugins/ctags/ide-ctags-completion-provider-private.h 
b/src/plugins/ctags/ide-ctags-completion-provider-private.h
index a8dd86959..b6bcd469f 100644
--- a/src/plugins/ctags/ide-ctags-completion-provider-private.h
+++ b/src/plugins/ctags/ide-ctags-completion-provider-private.h
@@ -30,6 +30,7 @@ struct _IdeCtagsCompletionProvider
   GPtrArray            *indexes;
   IdeCompletionResults *results;
   gchar                *current_word;
+  IdeSourceView        *view;
 };
 
 G_END_DECLS
diff --git a/src/plugins/ctags/ide-ctags-completion-provider.c 
b/src/plugins/ctags/ide-ctags-completion-provider.c
index 3edbf42ea..e560070e9 100644
--- a/src/plugins/ctags/ide-ctags-completion-provider.c
+++ b/src/plugins/ctags/ide-ctags-completion-provider.c
@@ -183,16 +183,21 @@ ide_ctags_completion_provider_populate (GtkSourceCompletionProvider *provider,
   IdeCtagsCompletionProvider *self = (IdeCtagsCompletionProvider *)provider;
   const gchar * const *allowed;
   g_autofree gchar *casefold = NULL;
-  gint word_len;
-  guint i;
-  guint j;
   g_autoptr(GHashTable) completions = NULL;
+  g_autoptr(GtkSourceCompletion) completion = NULL;
+  gint word_len;
 
   IDE_ENTRY;
 
   g_assert (IDE_IS_CTAGS_COMPLETION_PROVIDER (self));
   g_assert (GTK_SOURCE_IS_COMPLETION_CONTEXT (context));
 
+  g_object_get (context,
+                "completion", &completion,
+                NULL);
+
+  self->view = IDE_SOURCE_VIEW (gtk_source_completion_get_view (completion));
+
   g_clear_pointer (&self->current_word, g_free);
   self->current_word = ide_completion_provider_context_current_word (context);
 
@@ -218,7 +223,7 @@ ide_ctags_completion_provider_populate (GtkSourceCompletionProvider *provider,
 
   completions = g_hash_table_new (g_str_hash, g_str_equal);
 
-  for (i = 0; i < self->indexes->len; i++)
+  for (guint i = 0; i < self->indexes->len; i++)
     {
       g_autofree gchar *copy = g_strdup (self->current_word);
       IdeCtagsIndex *index = g_ptr_array_index (self->indexes, i);
@@ -227,6 +232,11 @@ ide_ctags_completion_provider_populate (GtkSourceCompletionProvider *provider,
       gsize n_entries = 0;
       gchar gdata_key[64];
 
+      /* NOTE: "ctags-%d" is turned into a GQuark and therefore lives the
+       *       length of the process. But it's generally under 1000 so not a
+       *       really big deal for now.
+       */
+
       /*
        * Make sure we hold a reference to the index for the lifetime of the results.
        * When the results are released, so could our indexes.
@@ -244,7 +254,7 @@ ide_ctags_completion_provider_populate (GtkSourceCompletionProvider *provider,
       if ((entries == NULL) || (n_entries == 0))
         continue;
 
-      for (j = 0; j < n_entries; j++)
+      for (guint j = 0; j < n_entries; j++)
         {
           const IdeCtagsIndexEntry *entry = &entries [j];
           IdeCtagsCompletionItem *item;
@@ -326,8 +336,7 @@ ide_ctags_completion_provider_match (GtkSourceCompletionProvider *provider,
 }
 
 static gboolean
-is_reserved_word (GtkTextBuffer *buffer,
-                  const gchar   *word)
+is_reserved_word (const gchar *word)
 {
   /* TODO: Check by language */
   return g_hash_table_contains (reserved, word);
@@ -341,47 +350,44 @@ ide_ctags_completion_provider_activate_proposal (GtkSourceCompletionProvider *pr
   IdeCtagsCompletionProvider *self = (IdeCtagsCompletionProvider *)provider;
   IdeCtagsCompletionItem *item = (IdeCtagsCompletionItem *)proposal;
   g_auto(GStrv) contexts = NULL;
+  IdeFileSettings *file_settings = NULL;
   GtkTextBuffer *buffer;
+  IdeFile *file;
   GtkTextIter begin;
 
   g_assert (IDE_IS_CTAGS_COMPLETION_PROVIDER (self));
+  g_assert (self->view != NULL);
+  g_assert (IDE_IS_SOURCE_VIEW (self->view));
   g_assert (IDE_IS_CTAGS_COMPLETION_ITEM (item));
   g_assert (iter != NULL);
 
   begin = *iter;
 
   buffer = gtk_text_iter_get_buffer (iter);
+  g_assert (IDE_IS_BUFFER (buffer));
+
+  file = ide_buffer_get_file (IDE_BUFFER (buffer));
+  g_assert (IDE_IS_FILE (file));
+
+  file_settings = ide_file_peek_settings (file);
 
-  /*
-   * NOTE:
-   *
-   * Try to reduce our insertion to just the new text. This avoids a delete
-   * which can be troublesome when we are working on a snippet. Ideally we
-   * would improve snippets, but due to various limitations in GtkTextBuffer
-   * and GtkTextView, we don't have an answer for that yet.
-   */
   if (_ide_source_iter_backward_visible_word_start (&begin))
     {
-      g_autofree gchar *current_text = gtk_text_iter_get_slice (&begin, iter);
-      g_autofree gchar *proposal_text = gtk_source_completion_proposal_get_text (proposal);
+      g_autofree gchar *slice = gtk_text_iter_get_slice (&begin, iter);
+      g_autoptr(IdeSourceSnippet) snippet = NULL;
 
-      /*
-       * If this is a keyword for the language, we probably didn't mean
-       * to activate this completion proposal.
-       */
-      if (is_reserved_word (buffer, current_text))
+      /* Ignore reserved words */
+      if (is_reserved_word (slice))
         return TRUE;
 
-      if (g_str_has_prefix (proposal_text, current_text))
-        {
-          gtk_text_buffer_begin_user_action (buffer);
-          gtk_text_buffer_insert (buffer,
-                                  iter,
-                                  proposal_text + strlen (current_text),
-                                  -1);
-          gtk_text_buffer_end_user_action (buffer);
-          return TRUE;
-        }
+      snippet = ide_ctags_completion_item_get_snippet (item, file_settings);
+
+      gtk_text_buffer_begin_user_action (buffer);
+      gtk_text_buffer_delete (buffer, &begin, iter);
+      ide_source_view_push_snippet (self->view, snippet, iter);
+      gtk_text_buffer_end_user_action (buffer);
+
+      return TRUE;
     }
 
   /* Fallback and let the default handler take care of things */


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