[gtksourceview] Add an action signal to move to the matching bracket



commit 3ec525cc84ae25acb984b15d851fd02b242d50ba
Author: Paolo Borelli <pborelli gnome org>
Date:   Sat Jan 17 23:05:47 2015 +0100

    Add an action signal to move to the matching bracket
    
    Right now this is bound to ctrl+% (inspired by % in vim), but I am
    more than open to other suggestions, especially if we can also bind
    the variant that extends the selection

 gtksourceview/gtksourcebuffer-private.h |    5 ++
 gtksourceview/gtksourcebuffer.c         |   73 +++++++++++++-----------------
 gtksourceview/gtksourceview.c           |   69 ++++++++++++++++++++++++++++-
 3 files changed, 105 insertions(+), 42 deletions(-)
---
diff --git a/gtksourceview/gtksourcebuffer-private.h b/gtksourceview/gtksourcebuffer-private.h
index 9f1dae5..40dd368 100644
--- a/gtksourceview/gtksourcebuffer-private.h
+++ b/gtksourceview/gtksourcebuffer-private.h
@@ -58,6 +58,11 @@ void                  _gtk_source_buffer_set_as_invalid_character    (GtkSourceBuffer      
  *buf
 G_GNUC_INTERNAL
 gboolean                _gtk_source_buffer_has_invalid_chars           (GtkSourceBuffer        *buffer);
 
+G_GNUC_INTERNAL
+GtkSourceBracketMatchType
+                        _gtk_source_buffer_find_bracket_match          (GtkSourceBuffer         *buffer,
+                                                                        GtkTextIter             *orig);
+
 G_END_DECLS
 
 #endif /* __GTK_SOURCE_BUFFER_PRIVATE_H__ */
diff --git a/gtksourceview/gtksourcebuffer.c b/gtksourceview/gtksourcebuffer.c
index f29369a..0fd9e79 100644
--- a/gtksourceview/gtksourcebuffer.c
+++ b/gtksourceview/gtksourcebuffer.c
@@ -226,10 +226,6 @@ static void         gtk_source_buffer_real_apply_tag       (GtkTextBuffer           
*buffer,
 
 static void     gtk_source_buffer_real_mark_deleted    (GtkTextBuffer           *buffer,
                                                         GtkTextMark             *mark);
-static gboolean         gtk_source_buffer_find_bracket_match_with_limit (GtkSourceBuffer *buffer,
-                                                                 GtkTextIter     *orig,
-                                                                 GtkSourceBracketMatchType *result,
-                                                                 gint             max_chars);
 
 static void     gtk_source_buffer_real_undo            (GtkSourceBuffer         *buffer);
 static void     gtk_source_buffer_real_redo            (GtkSourceBuffer         *buffer);
@@ -909,10 +905,9 @@ gtk_source_buffer_move_cursor (GtkTextBuffer     *buffer,
 
        start = *iter;
        previous_state = source_buffer->priv->bracket_match;
-       if (!gtk_source_buffer_find_bracket_match_with_limit (source_buffer,
-                                                             &start,
-                                                             &source_buffer->priv->bracket_match,
-                                                             MAX_CHARS_BEFORE_FINDING_A_MATCH))
+       source_buffer->priv->bracket_match = _gtk_source_buffer_find_bracket_match (source_buffer, &start);
+
+       if (source_buffer->priv->bracket_match != GTK_SOURCE_BRACKET_MATCH_FOUND)
        {
                /* don't emit the signal at all if chars at previous and current
                   positions are nonbrackets. */
@@ -1154,11 +1149,10 @@ get_context_class_mask (GtkSourceBuffer *buffer,
        return ret;
 }
 
-static gboolean
-gtk_source_buffer_find_bracket_match_real (GtkSourceBuffer           *buffer,
-                                           GtkTextIter               *orig,
-                                          GtkSourceBracketMatchType *result,
-                                           gint                       max_chars)
+/* note that we only look MAX_CHARS_BEFORE_FINDING_A_MATCH at the most */
+static GtkSourceBracketMatchType
+gtk_source_buffer_find_bracket_match_real (GtkSourceBuffer *buffer,
+                                           GtkTextIter     *orig)
 {
        GtkTextIter iter;
 
@@ -1184,8 +1178,7 @@ gtk_source_buffer_find_bracket_match_real (GtkSourceBuffer           *buffer,
 
        if (addition == 0)
        {
-               *result = GTK_SOURCE_BRACKET_MATCH_NONE;
-               return FALSE;
+               return GTK_SOURCE_BRACKET_MATCH_NONE;
        }
 
        counter = 0;
@@ -1225,54 +1218,52 @@ gtk_source_buffer_find_bracket_match_real (GtkSourceBuffer           *buffer,
                }
        }
        while (!gtk_text_iter_is_end (&iter) && !gtk_text_iter_is_start (&iter) &&
-               ((char_cont < max_chars) || (max_chars < 0)));
+               (char_cont < MAX_CHARS_BEFORE_FINDING_A_MATCH));
 
        if (found)
        {
                *orig = iter;
-               *result = GTK_SOURCE_BRACKET_MATCH_FOUND;
+               return GTK_SOURCE_BRACKET_MATCH_FOUND;
        }
-       else if (char_cont >= max_chars && max_chars >= 0)
-       {
-               *result = GTK_SOURCE_BRACKET_MATCH_OUT_OF_RANGE;
-       }
-       else
+
+       if (char_cont >= MAX_CHARS_BEFORE_FINDING_A_MATCH)
        {
-               *result = GTK_SOURCE_BRACKET_MATCH_NOT_FOUND;
+               return GTK_SOURCE_BRACKET_MATCH_OUT_OF_RANGE;
        }
 
-       return found;
+       return GTK_SOURCE_BRACKET_MATCH_NOT_FOUND;
 }
 
 /* Note that we take into account both the character following the cursor and the
  * one preceding it. If there are brackets on both sides the one following the
  * cursor takes precedence.
  */
-static gboolean
-gtk_source_buffer_find_bracket_match_with_limit (GtkSourceBuffer           *buffer,
-                                                 GtkTextIter               *orig,
-                                                 GtkSourceBracketMatchType *result,
-                                                 gint                       max_chars)
+GtkSourceBracketMatchType
+_gtk_source_buffer_find_bracket_match (GtkSourceBuffer *buffer,
+                                       GtkTextIter     *orig)
 {
-       GtkTextIter iter;
+       GtkSourceBracketMatchType res;
 
-       if (gtk_source_buffer_find_bracket_match_real (buffer, orig, result, max_chars))
-       {
-               return TRUE;
-       }
+       res = gtk_source_buffer_find_bracket_match_real (buffer, orig);
 
-       iter = *orig;
-       if (!gtk_text_iter_starts_line (&iter) &&
-           gtk_text_iter_backward_char (&iter))
+       if (res != GTK_SOURCE_BRACKET_MATCH_FOUND)
        {
-               if (gtk_source_buffer_find_bracket_match_real (buffer, &iter, result, max_chars))
+               GtkTextIter iter;
+               iter = *orig;
+
+               if (!gtk_text_iter_starts_line (&iter) &&
+                   gtk_text_iter_backward_char (&iter))
                {
-                       *orig = iter;
-                       return TRUE;
+                       res = gtk_source_buffer_find_bracket_match_real (buffer, &iter);
+
+                       if (res == GTK_SOURCE_BRACKET_MATCH_FOUND)
+                       {
+                               *orig = iter;
+                       }
                }
        }
 
-       return FALSE;
+       return res;
 }
 
 /**
diff --git a/gtksourceview/gtksourceview.c b/gtksourceview/gtksourceview.c
index 2c8730c..e6b077c 100644
--- a/gtksourceview/gtksourceview.c
+++ b/gtksourceview/gtksourceview.c
@@ -131,6 +131,7 @@ enum {
        MOVE_LINES,
        MOVE_WORDS,
        SMART_HOME_END,
+       MOVE_TO_MATCHING_BRACKET,
        LAST_SIGNAL
 };
 
@@ -309,7 +310,42 @@ gtk_source_view_constructed (GObject *object)
        G_OBJECT_CLASS (gtk_source_view_parent_class)->constructed (object);
 }
 
-/* Private functions. */
+/* we have to do it this way since we do not have any more vfunc slots */
+static void
+move_to_matching_bracket_marshal (GClosure     *closure,
+                                  GValue       *return_value,
+                                  guint         n_param_values,
+                                  const GValue *param_values,
+                                  gpointer      invocation_hint,
+                                  gpointer      marshal_data)
+{
+       GtkSourceView *view;
+       gboolean extend_selection;
+       GtkTextBuffer *buffer;
+       GtkTextIter iter;
+
+       view = g_value_get_object (param_values + 0);
+       extend_selection = g_value_get_boolean (param_values + 1);
+
+       buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
+       gtk_text_buffer_get_iter_at_mark (buffer, &iter, gtk_text_buffer_get_insert (buffer));
+
+       if (_gtk_source_buffer_find_bracket_match (GTK_SOURCE_BUFFER (buffer),
+                                                  &iter) == GTK_SOURCE_BRACKET_MATCH_FOUND)
+       {
+               if (extend_selection)
+               {
+                       gtk_text_buffer_move_mark_by_name (buffer,
+                                                          "insert",
+                                                          &iter);
+               }
+               else
+               {
+                       gtk_text_buffer_place_cursor (buffer, &iter);
+               }
+       }
+}
+
 static void
 gtk_source_view_class_init (GtkSourceViewClass *klass)
 {
@@ -317,6 +353,8 @@ gtk_source_view_class_init (GtkSourceViewClass *klass)
        GtkTextViewClass *textview_class;
        GtkBindingSet    *binding_set;
        GtkWidgetClass   *widget_class;
+       GClosure         *closure;
+       GType             move_to_matching_bracket_params[1];
 
        object_class     = G_OBJECT_CLASS (klass);
        textview_class   = GTK_TEXT_VIEW_CLASS (klass);
@@ -640,6 +678,29 @@ gtk_source_view_class_init (GtkSourceViewClass *klass)
                              GTK_TYPE_TEXT_ITER,
                              G_TYPE_INT);
 
+       closure = g_closure_new_simple (sizeof (GClosure), NULL);
+       g_closure_set_marshal (closure, move_to_matching_bracket_marshal);
+       move_to_matching_bracket_params[0] = G_TYPE_BOOLEAN;
+
+       /**
+        * GtkSourceView::move-to-matching-bracket:
+        * @view: the #GtkSourceView
+        * @extend_selection: %TRUE if the move should extend the selection
+        *
+        * Keybinding signal to move the cursor to the matching bracket.
+        *
+        * Since: 3.16
+        */
+       signals[MOVE_TO_MATCHING_BRACKET] =
+               g_signal_newv ("move-to-matching-bracket",
+                              G_TYPE_FROM_CLASS (klass),
+                              G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+                              closure,
+                              NULL, NULL, NULL,
+                              G_TYPE_NONE,
+                              1,
+                              move_to_matching_bracket_params);
+
        binding_set = gtk_binding_set_by_class (klass);
 
        gtk_binding_entry_add_signal (binding_set,
@@ -788,6 +849,12 @@ gtk_source_view_class_init (GtkSourceViewClass *klass)
                                      "move_viewport", 2,
                                      GTK_TYPE_SCROLL_STEP, GTK_SCROLL_ENDS,
                                      G_TYPE_INT, 1);
+
+       gtk_binding_entry_add_signal (binding_set,
+                                     GDK_KEY_percent,
+                                     GDK_CONTROL_MASK,
+                                     "move_to_matching_bracket", 1,
+                                     G_TYPE_BOOLEAN, FALSE);
 }
 
 static GObject *


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