[gtksourceview] Add an action signal to move to the matching bracket
- From: Paolo Borelli <pborelli src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtksourceview] Add an action signal to move to the matching bracket
- Date: Sat, 17 Jan 2015 22:07:50 +0000 (UTC)
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]