[gnome-builder] quick-highlight: rewrite quick-highlight plugin



commit e69aa82df3c27b44840a75b025d011eff0cd4e09
Author: Christian Hergert <chergert redhat com>
Date:   Wed Oct 11 21:39:37 2017 -0700

    quick-highlight: rewrite quick-highlight plugin
    
    This tracks the IdeEditorSearch so that we don't collide with
    other search requests.

 .../gbp-quick-highlight-editor-view-addin.c        |  274 ++++++++++++++++++++
 .../gbp-quick-highlight-editor-view-addin.h        |   29 ++
 .../quick-highlight/gbp-quick-highlight-plugin.c   |    4 +-
 src/plugins/quick-highlight/meson.build            |    4 +-
 4 files changed, 307 insertions(+), 4 deletions(-)
---
diff --git a/src/plugins/quick-highlight/gbp-quick-highlight-editor-view-addin.c 
b/src/plugins/quick-highlight/gbp-quick-highlight-editor-view-addin.c
new file mode 100644
index 0000000..708f034
--- /dev/null
+++ b/src/plugins/quick-highlight/gbp-quick-highlight-editor-view-addin.c
@@ -0,0 +1,274 @@
+/* gbp-quick-highlight-editor-view-addin.c
+ *
+ * Copyright © 2016 Martin Blanchard <tchaik gmx com>
+ * Copyright © 2017 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#define G_LOG_DOMAIN "gbp-quick-highlight-editor-view-addin"
+
+#include <ide.h>
+
+#include "gbp-quick-highlight-editor-view-addin.h"
+
+#define HIGHLIGHT_STYLE_NAME "current-line"
+
+struct _GbpQuickHighlightEditorViewAddin
+{
+  GObject                 parent_instance;
+
+  IdeEditorView          *view;
+
+  DzlSignalGroup         *buffer_signals;
+  DzlSignalGroup         *search_signals;
+  GtkSourceSearchContext *search_context;
+
+  guint                   queued_match_source;
+
+  guint                   has_selection : 1;
+  guint                   search_active : 1;
+};
+
+static gboolean
+do_delayed_quick_highlight (GbpQuickHighlightEditorViewAddin *self)
+{
+  GtkSourceSearchSettings *search_settings;
+  g_autofree gchar *slice = NULL;
+  IdeBuffer *buffer;
+  GtkTextIter begin;
+  GtkTextIter end;
+
+  g_assert (GBP_IS_QUICK_HIGHLIGHT_EDITOR_VIEW_ADDIN (self));
+  g_assert (self->view != NULL);
+
+  self->queued_match_source = 0;
+
+  /*
+   * Get the curretn selection, if any. Short circuit if we find a situation
+   * that should have caused us to cancel the current quick-highlight.
+   */
+  buffer = ide_editor_view_get_buffer (self->view);
+  if (self->search_active ||
+      !self->has_selection ||
+      !gtk_text_buffer_get_selection_bounds (GTK_TEXT_BUFFER (buffer), &begin, &end))
+    {
+      g_clear_object (&self->search_context);
+      return G_SOURCE_REMOVE;
+    }
+
+  /*
+   * If the current selection goes across a line, then ignore trying to match
+   * anything similar as it's unlikely to be what the user wants.
+   */
+  gtk_text_iter_order (&begin, &end);
+  if (gtk_text_iter_get_line (&begin) != gtk_text_iter_get_line (&end))
+    {
+      g_clear_object (&self->search_context);
+      return G_SOURCE_REMOVE;
+    }
+
+  /*
+   * Create our search context to scan the buffer if necessary.
+   */
+  if (self->search_context == NULL)
+    {
+      g_autoptr(GtkSourceSearchSettings) settings = NULL;
+      GtkSourceStyleScheme *style_scheme;
+      GtkSourceStyle *style = NULL;
+
+      style_scheme = gtk_source_buffer_get_style_scheme (GTK_SOURCE_BUFFER (buffer));
+      if (style_scheme != NULL)
+        style = gtk_source_style_scheme_get_style (style_scheme, HIGHLIGHT_STYLE_NAME);
+
+      settings = g_object_new (GTK_SOURCE_TYPE_SEARCH_SETTINGS,
+                               "at-word-boundaries", FALSE,
+                               "case-sensitive", TRUE,
+                               "regex-enabled", FALSE,
+                               NULL);
+
+      /* Set highlight to false initially, or we get the wrong style from
+       * the the GtkSourceSearchContext.
+       */
+      self->search_context = g_object_new (GTK_SOURCE_TYPE_SEARCH_CONTEXT,
+                                           "buffer", buffer,
+                                           "highlight", FALSE,
+                                           "match-style", style,
+                                           "settings", settings,
+                                           NULL);
+    }
+
+  search_settings = gtk_source_search_context_get_settings (self->search_context);
+
+  /* Now assign our search text */
+  slice = gtk_text_iter_get_slice (&begin, &end);
+  gtk_source_search_settings_set_search_text (search_settings, slice);
+
+  /* (Re)enable highlight so that we have the correct style */
+  gtk_source_search_context_set_highlight (self->search_context, TRUE);
+
+  return G_SOURCE_REMOVE;
+}
+
+static void
+buffer_cursor_moved (GbpQuickHighlightEditorViewAddin *self,
+                     const GtkTextIter                *location,
+                     IdeBuffer                        *buffer)
+{
+  g_assert (GBP_IS_QUICK_HIGHLIGHT_EDITOR_VIEW_ADDIN (self));
+  g_assert (location != NULL);
+  g_assert (IDE_IS_BUFFER (buffer));
+
+  if (self->has_selection && !self->search_active)
+    {
+      if (self->queued_match_source == 0)
+        self->queued_match_source =
+          gdk_threads_add_idle_full (G_PRIORITY_LOW + 100,
+                                     (GSourceFunc) do_delayed_quick_highlight,
+                                     g_object_ref (self),
+                                     g_object_unref);
+    }
+  else
+    {
+      ide_clear_source (&self->queued_match_source);
+      g_clear_object (&self->search_context);
+    }
+}
+
+static void
+buffer_notify_style_scheme (GbpQuickHighlightEditorViewAddin *self,
+                            GParamSpec                       *pspec,
+                            IdeBuffer                        *buffer)
+{
+  g_assert (GBP_IS_QUICK_HIGHLIGHT_EDITOR_VIEW_ADDIN (self));
+  g_assert (IDE_IS_BUFFER (buffer));
+
+  if (self->search_context != NULL)
+    {
+      GtkSourceStyleScheme *style_scheme;
+      GtkSourceStyle *style = NULL;
+
+      style_scheme = gtk_source_buffer_get_style_scheme (GTK_SOURCE_BUFFER (buffer));
+      if (style_scheme != NULL)
+        style = gtk_source_style_scheme_get_style (style_scheme, HIGHLIGHT_STYLE_NAME);
+
+      gtk_source_search_context_set_match_style (self->search_context, style);
+    }
+}
+
+static void
+buffer_notify_has_selection (GbpQuickHighlightEditorViewAddin *self,
+                             GParamSpec                       *pspec,
+                             IdeBuffer                        *buffer)
+{
+  g_assert (GBP_IS_QUICK_HIGHLIGHT_EDITOR_VIEW_ADDIN (self));
+  g_assert (IDE_IS_BUFFER (buffer));
+
+  self->has_selection = gtk_text_buffer_get_has_selection (GTK_TEXT_BUFFER (buffer));
+}
+
+static void
+search_notify_active (GbpQuickHighlightEditorViewAddin *self,
+                      GParamSpec                       *pspec,
+                      IdeEditorSearch                  *search)
+{
+  g_assert (GBP_IS_QUICK_HIGHLIGHT_EDITOR_VIEW_ADDIN (self));
+  g_assert (IDE_IS_EDITOR_SEARCH (search));
+
+  self->search_active = ide_editor_search_get_active (search);
+  do_delayed_quick_highlight (self);
+}
+
+static void
+gbp_quick_highlight_editor_view_addin_load (IdeEditorViewAddin *addin,
+                                            IdeEditorView      *view)
+{
+  GbpQuickHighlightEditorViewAddin *self = (GbpQuickHighlightEditorViewAddin *)addin;
+
+  g_assert (GBP_IS_QUICK_HIGHLIGHT_EDITOR_VIEW_ADDIN (addin));
+  g_assert (IDE_IS_EDITOR_VIEW (view));
+
+  self->view = view;
+
+  self->buffer_signals = dzl_signal_group_new (IDE_TYPE_BUFFER);
+
+  dzl_signal_group_connect_swapped (self->buffer_signals,
+                                    "notify::has-selection",
+                                    G_CALLBACK (buffer_notify_has_selection),
+                                    self);
+
+  dzl_signal_group_connect_swapped (self->buffer_signals,
+                                    "notify::style-scheme",
+                                    G_CALLBACK (buffer_notify_style_scheme),
+                                    self);
+
+  dzl_signal_group_connect_swapped (self->buffer_signals,
+                                    "cursor-moved",
+                                    G_CALLBACK (buffer_cursor_moved),
+                                    self);
+
+  self->search_signals = dzl_signal_group_new (IDE_TYPE_EDITOR_SEARCH);
+
+  dzl_signal_group_connect_swapped (self->search_signals,
+                                    "notify::active",
+                                    G_CALLBACK (search_notify_active),
+                                    self);
+
+  dzl_signal_group_set_target (self->buffer_signals, ide_editor_view_get_buffer (view));
+  dzl_signal_group_set_target (self->search_signals, ide_editor_view_get_search (view));
+}
+
+static void
+gbp_quick_highlight_editor_view_addin_unload (IdeEditorViewAddin *addin,
+                                              IdeEditorView      *view)
+{
+  GbpQuickHighlightEditorViewAddin *self = (GbpQuickHighlightEditorViewAddin *)addin;
+
+  g_assert (GBP_IS_QUICK_HIGHLIGHT_EDITOR_VIEW_ADDIN (addin));
+  g_assert (IDE_IS_EDITOR_VIEW (view));
+
+  g_clear_object (&self->search_context);
+  ide_clear_source (&self->queued_match_source);
+
+  dzl_signal_group_set_target (self->buffer_signals, NULL);
+  g_clear_object (&self->buffer_signals);
+
+  dzl_signal_group_set_target (self->search_signals, NULL);
+  g_clear_object (&self->search_signals);
+
+  self->view = NULL;
+}
+
+static void
+editor_view_addin_iface_init (IdeEditorViewAddinInterface *iface)
+{
+  iface->load = gbp_quick_highlight_editor_view_addin_load;
+  iface->unload = gbp_quick_highlight_editor_view_addin_unload;
+}
+
+G_DEFINE_TYPE_WITH_CODE (GbpQuickHighlightEditorViewAddin,
+                         gbp_quick_highlight_editor_view_addin,
+                         G_TYPE_OBJECT,
+                         G_IMPLEMENT_INTERFACE (IDE_TYPE_EDITOR_VIEW_ADDIN,
+                                                editor_view_addin_iface_init))
+
+static void
+gbp_quick_highlight_editor_view_addin_class_init (GbpQuickHighlightEditorViewAddinClass *klass)
+{
+}
+
+static void
+gbp_quick_highlight_editor_view_addin_init (GbpQuickHighlightEditorViewAddin *self)
+{
+}
diff --git a/src/plugins/quick-highlight/gbp-quick-highlight-editor-view-addin.h 
b/src/plugins/quick-highlight/gbp-quick-highlight-editor-view-addin.h
new file mode 100644
index 0000000..4cd8ffd
--- /dev/null
+++ b/src/plugins/quick-highlight/gbp-quick-highlight-editor-view-addin.h
@@ -0,0 +1,29 @@
+/* gbp-quick-highlight-editor-view-addin.h
+ *
+ * Copyright © 2016 Martin Blanchard <tchaik gmx com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define GBP_TYPE_QUICK_HIGHLIGHT_EDITOR_VIEW_ADDIN (gbp_quick_highlight_editor_view_addin_get_type())
+
+G_DECLARE_FINAL_TYPE (GbpQuickHighlightEditorViewAddin, gbp_quick_highlight_editor_view_addin, GBP, 
QUICK_HIGHLIGHT_EDITOR_VIEW_ADDIN, GObject)
+
+G_END_DECLS
diff --git a/src/plugins/quick-highlight/gbp-quick-highlight-plugin.c 
b/src/plugins/quick-highlight/gbp-quick-highlight-plugin.c
index 0b6f55b..3bbdb24 100644
--- a/src/plugins/quick-highlight/gbp-quick-highlight-plugin.c
+++ b/src/plugins/quick-highlight/gbp-quick-highlight-plugin.c
@@ -19,7 +19,7 @@
 #include <libpeas/peas.h>
 #include <ide.h>
 
-#include "gbp-quick-highlight-view-addin.h"
+#include "gbp-quick-highlight-editor-view-addin.h"
 #include "gbp-quick-highlight-preferences.h"
 
 void
@@ -27,7 +27,7 @@ gbp_quick_highlight_register_types (PeasObjectModule *module)
 {
   peas_object_module_register_extension_type (module,
                                               IDE_TYPE_EDITOR_VIEW_ADDIN,
-                                              GBP_TYPE_QUICK_HIGHLIGHT_VIEW_ADDIN);
+                                              GBP_TYPE_QUICK_HIGHLIGHT_EDITOR_VIEW_ADDIN);
   peas_object_module_register_extension_type (module,
                                               IDE_TYPE_PREFERENCES_ADDIN,
                                               GBP_TYPE_QUICK_HIGHLIGHT_PREFERENCES);
diff --git a/src/plugins/quick-highlight/meson.build b/src/plugins/quick-highlight/meson.build
index 5bbf6ac..a22cdb4 100644
--- a/src/plugins/quick-highlight/meson.build
+++ b/src/plugins/quick-highlight/meson.build
@@ -8,8 +8,8 @@ quick_highlight_resources = gnome.compile_resources(
 
 quick_highlight_sources = [
   'gbp-quick-highlight-plugin.c',
-  'gbp-quick-highlight-view-addin.c',
-  'gbp-quick-highlight-view-addin.h',
+  'gbp-quick-highlight-editor-view-addin.c',
+  'gbp-quick-highlight-editor-view-addin.h',
   'gbp-quick-highlight-preferences.c',
   'gbp-quick-highlight-preferences.h',
 ]


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