[gnome-builder/wip/uajain/word-completion: 1/4] Include back search from insertion cursor



commit 81ff106b4c3c220ae82a99ea5d15e77d0b5e2fbb
Author: Umang Jain <mailumangjain gmail com>
Date:   Wed Aug 30 15:47:05 2017 +0530

    Include back search from insertion cursor

 libide/sourceview/ide-word-completion-provider.c |  134 +++++++++++++++++++++-
 1 files changed, 128 insertions(+), 6 deletions(-)
---
diff --git a/libide/sourceview/ide-word-completion-provider.c 
b/libide/sourceview/ide-word-completion-provider.c
index 14e157d..839a689 100644
--- a/libide/sourceview/ide-word-completion-provider.c
+++ b/libide/sourceview/ide-word-completion-provider.c
@@ -108,6 +108,114 @@ refresh_iters (IdeWordCompletionProvider *self,
 }
 
 static void
+backward_search_finished (GtkSourceSearchContext *search_context,
+                          GAsyncResult           *result,
+                          gpointer                user_data)
+{
+  g_autoptr(IdeWordCompletionProvider) self = user_data;
+  IdeWordCompletionProviderPrivate *priv = ide_word_completion_provider_get_instance_private (self);
+  IdeWordCompletionItem *proposal;
+  GtkTextBuffer *buffer = NULL;
+  GtkTextIter insert_iter;
+  GtkTextIter match_start;
+  GtkTextIter match_end;
+  GError *error = NULL;
+  gboolean has_wrapped_around;
+
+  g_assert (IDE_IS_WORD_COMPLETION_PROVIDER (self));
+  g_assert (G_IS_ASYNC_RESULT (result));
+
+  if (priv->context == NULL || !gtk_source_completion_context_get_iter (priv->context, &insert_iter))
+    return;
+
+  buffer = gtk_text_iter_get_buffer (&insert_iter);
+
+  if (gtk_source_search_context_backward_finish2 (search_context,
+                                                  result,
+                                                  &match_start,
+                                                  &match_end,
+                                                  &has_wrapped_around,
+                                                  &error))
+    {
+      gchar *text = NULL;
+
+      priv->start_mark = gtk_text_buffer_create_mark (buffer, NULL, &match_start, FALSE);
+      priv->end_mark = gtk_text_buffer_create_mark (buffer, NULL, &match_end, FALSE);
+
+      if (priv->start_mark == NULL || priv->end_mark == NULL)
+        {
+          g_warning ("Cannot set start and end marks for word completion matches.");
+          return;
+        }
+
+      gtk_source_completion_context_get_iter (priv->context, &insert_iter);
+
+      if (gtk_text_iter_equal (&match_end, &insert_iter) && priv->wrap_around_flag)
+        goto finish;
+
+      if (error != NULL)
+        {
+          g_warning ("Unable to get word completion proposals: %s", error->message);
+          g_clear_error (&error);
+          goto finish;
+        }
+
+      if (!refresh_iters (self, &match_start, &match_end))
+        {
+          g_warning ("Cannot refresh GtkTextIters for word completion matches.");
+          return;
+        }
+
+      text = gtk_text_iter_get_text (&match_start, &match_end);
+
+      if (!g_hash_table_contains (priv->all_proposals, text))
+        {
+          gint offset;
+
+          offset = gtk_text_iter_get_offset (&insert_iter) - gtk_text_iter_get_offset (&match_start);
+
+          /*  Scan must have wrapped around giving offset as negative */
+          if (offset < 0)
+            {
+              GtkTextIter end_iter;
+
+              gtk_text_buffer_get_end_iter (buffer, &end_iter);
+
+              offset = gtk_text_iter_get_offset (&end_iter) -
+                       gtk_text_iter_get_offset (&match_start) +
+                       gtk_text_iter_get_offset (&insert_iter);
+
+              priv->wrap_around_flag = TRUE;
+             }
+
+         g_assert (offset >= 0);
+
+         proposal = ide_word_completion_item_new (text, offset, NULL);
+         ide_completion_results_take_proposal (IDE_COMPLETION_RESULTS (priv->results),
+                                                IDE_COMPLETION_ITEM (proposal));
+
+         g_hash_table_add (priv->all_proposals, g_steal_pointer (&text));
+       }
+
+      gtk_text_buffer_get_iter_at_mark (buffer, &match_end, priv->end_mark);
+      gtk_source_search_context_forward_async (priv->search_context,
+                                               &match_end,
+                                               NULL,
+                                               (GAsyncReadyCallback) backward_search_finished,
+                                               g_object_ref (self));
+      gtk_text_buffer_delete_mark (buffer, priv->start_mark);
+      gtk_text_buffer_delete_mark (buffer, priv->end_mark);
+      return;
+    }
+
+finish:
+  ide_completion_results_present (IDE_COMPLETION_RESULTS (priv->results),
+                                  GTK_SOURCE_COMPLETION_PROVIDER (self), priv->context);
+
+  g_clear_pointer (&priv->all_proposals, g_hash_table_destroy);
+}
+
+static void
 forward_search_finished (GtkSourceSearchContext *search_context,
                          GAsyncResult           *result,
                          gpointer                user_data)
@@ -172,8 +280,9 @@ forward_search_finished (GtkSourceSearchContext *search_context,
         {
           gint offset;
 
-          /*  Scan must have wrapped around giving offset as negative */
           offset = gtk_text_iter_get_offset (&match_start) - gtk_text_iter_get_offset (&insert_iter);
+
+          /*  Scan must have wrapped around giving offset as negative */
           if (offset < 0)
             {
               GtkTextIter end_iter;
@@ -304,11 +413,24 @@ ide_word_completion_provider_populate (GtkSourceCompletionProvider *provider,
 
   priv->all_proposals = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
 
-  gtk_source_search_context_forward_async (priv->search_context,
-                                           &insert_iter,
-                                           NULL,
-                                           (GAsyncReadyCallback)forward_search_finished,
-                                           g_object_ref (self));
+  if (priv->direction == 1)  /* Ctrl-n : Scan forward*/
+    {
+      gtk_source_search_context_forward_async (priv->search_context,
+                                               &insert_iter,
+                                               NULL,
+                                               (GAsyncReadyCallback)forward_search_finished,
+                                               g_object_ref (self));
+
+    }
+  else if (priv->direction == -1) /* Ctrl-p : Scan backward */
+    {
+      gtk_source_search_context_backward_async (priv->search_context,
+                                                &insert_iter,
+                                                NULL,
+                                                (GAsyncReadyCallback)backward_search_finished,
+                                                g_object_ref (self));
+
+    }
 }
 
 static gboolean


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