[gtksourceview] Bracket matching: fix bug with wrong bracket highlighted near the cursor
- From: Sébastien Wilmet <swilmet src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtksourceview] Bracket matching: fix bug with wrong bracket highlighted near the cursor
- Date: Fri, 23 Oct 2015 13:09:33 +0000 (UTC)
commit 9fdad3e1c69eb11177d874740c987e28c965296a
Author: Sébastien Wilmet <swilmet gnome org>
Date: Fri Oct 23 14:44:13 2015 +0200
Bracket matching: fix bug with wrong bracket highlighted near the cursor
Return explicitly the two iters: @bracket and @bracket_match. @bracket
is either on the right or on the left of the cursor.
The bug occurred with the following content, when the cursor is between
the two closing parenthesis:
(ab))
The second ) was highlighted. Now the first ) is highlighted.
gtksourceview/gtksourcebuffer-private.h | 4 +-
gtksourceview/gtksourcebuffer.c | 100 ++++++++++++++++++-------------
gtksourceview/gtksourceview.c | 19 ++++--
tests/test-buffer.c | 56 ++++++++++-------
4 files changed, 106 insertions(+), 73 deletions(-)
---
diff --git a/gtksourceview/gtksourcebuffer-private.h b/gtksourceview/gtksourcebuffer-private.h
index b7d65be..7a553da 100644
--- a/gtksourceview/gtksourcebuffer-private.h
+++ b/gtksourceview/gtksourcebuffer-private.h
@@ -61,7 +61,9 @@ gboolean _gtk_source_buffer_has_invalid_chars (GtkSourceBuffer
*buffer
G_GNUC_INTERNAL
GtkSourceBracketMatchType
_gtk_source_buffer_find_bracket_match (GtkSourceBuffer *buffer,
- GtkTextIter *pos);
+ const GtkTextIter *pos,
+ GtkTextIter *bracket,
+ GtkTextIter
*bracket_match);
G_GNUC_INTERNAL
void _gtk_source_buffer_save_and_clear_selection (GtkSourceBuffer *buffer);
diff --git a/gtksourceview/gtksourcebuffer.c b/gtksourceview/gtksourcebuffer.c
index 73d5538..466df07 100644
--- a/gtksourceview/gtksourcebuffer.c
+++ b/gtksourceview/gtksourcebuffer.c
@@ -882,13 +882,15 @@ gtk_source_buffer_move_cursor (GtkTextBuffer *buffer,
GtkTextMark *mark)
{
GtkSourceBuffer *source_buffer;
- GtkTextIter start, end;
- gunichar cursor_char;
+ GtkTextIter start;
+ GtkTextIter end;
+ GtkTextIter bracket;
+ GtkTextIter bracket_match;
GtkSourceBracketMatchType previous_state;
g_return_if_fail (GTK_SOURCE_IS_BUFFER (buffer));
g_return_if_fail (iter != NULL);
- g_return_if_fail (mark != NULL);
+ g_return_if_fail (GTK_IS_TEXT_MARK (mark));
g_return_if_fail (gtk_text_iter_get_buffer (iter) == buffer);
if (mark != gtk_text_buffer_get_insert (buffer))
@@ -921,21 +923,24 @@ gtk_source_buffer_move_cursor (GtkTextBuffer *buffer,
return;
}
- start = *iter;
previous_state = source_buffer->priv->bracket_match;
- source_buffer->priv->bracket_match = _gtk_source_buffer_find_bracket_match (source_buffer, &start);
+ source_buffer->priv->bracket_match = _gtk_source_buffer_find_bracket_match (source_buffer,
+ iter,
+ &bracket,
+ &bracket_match);
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. */
+ /* Don't emit the signal at all if chars at previous and current
+ * positions are nonbrackets.
+ */
if (previous_state != GTK_SOURCE_BRACKET_MATCH_NONE ||
source_buffer->priv->bracket_match != GTK_SOURCE_BRACKET_MATCH_NONE)
{
g_signal_emit (source_buffer,
buffer_signals[BRACKET_MATCHED],
0,
- &end,
+ &end, /* FIXME end may be uninitialized here... */
source_buffer->priv->bracket_match);
}
}
@@ -944,31 +949,33 @@ gtk_source_buffer_move_cursor (GtkTextBuffer *buffer,
g_signal_emit (source_buffer,
buffer_signals[BRACKET_MATCHED],
0,
- &start,
- source_buffer->priv->bracket_match);
+ &bracket_match,
+ GTK_SOURCE_BRACKET_MATCH_FOUND);
/* allow_bracket_match will allow the bracket match tag to be
- applied to the buffer. See apply_tag_real for more
- information */
+ * applied to the buffer. See apply_tag_real for more
+ * information.
+ */
source_buffer->priv->allow_bracket_match = TRUE;
/* Mark matching bracket */
- if (!source_buffer->priv->bracket_mark_match)
+ if (source_buffer->priv->bracket_mark_match == NULL)
{
source_buffer->priv->bracket_mark_match =
gtk_text_buffer_create_mark (buffer,
NULL,
- &start,
+ &bracket_match,
TRUE);
}
else
{
gtk_text_buffer_move_mark (buffer,
source_buffer->priv->bracket_mark_match,
- &start);
+ &bracket_match);
}
- end = start;
+ start = bracket_match;
+ end = bracket_match;
gtk_text_iter_forward_char (&end);
gtk_text_buffer_apply_tag (buffer,
get_bracket_match_tag (source_buffer),
@@ -976,29 +983,23 @@ gtk_source_buffer_move_cursor (GtkTextBuffer *buffer,
&end);
/* Mark the bracket near the cursor */
- start = *iter;
- cursor_char = gtk_text_iter_get_char (&start);
- if (bracket_pair (cursor_char, NULL) == 0)
- {
- gtk_text_iter_backward_char (&start);
- }
-
- if (!source_buffer->priv->bracket_mark_cursor)
+ if (source_buffer->priv->bracket_mark_cursor == NULL)
{
source_buffer->priv->bracket_mark_cursor =
gtk_text_buffer_create_mark (buffer,
NULL,
- &start,
+ &bracket,
FALSE);
}
else
{
gtk_text_buffer_move_mark (buffer,
source_buffer->priv->bracket_mark_cursor,
- &start);
+ &bracket);
}
- end = start;
+ start = bracket;
+ end = bracket;
gtk_text_iter_forward_char (&end);
gtk_text_buffer_apply_tag (buffer,
get_bracket_match_tag (source_buffer),
@@ -1260,35 +1261,50 @@ gtk_source_buffer_find_bracket_match_real (GtkSourceBuffer *buffer,
return GTK_SOURCE_BRACKET_MATCH_NOT_FOUND;
}
-/* Moves @pos to the matching bracket, if found.
- * Note that we take into account both the character following @pos and the one
+/* Note that we take into account both the character following @pos and the one
* preceding it. If there are brackets on both sides, the one following @pos
* takes precedence.
+ * @bracket and @bracket_match are valid only if GTK_SOURCE_BRACKET_MATCH_FOUND
+ * is returned. @bracket is set either to @pos or @pos-1.
*/
GtkSourceBracketMatchType
-_gtk_source_buffer_find_bracket_match (GtkSourceBuffer *buffer,
- GtkTextIter *pos)
+_gtk_source_buffer_find_bracket_match (GtkSourceBuffer *buffer,
+ const GtkTextIter *pos,
+ GtkTextIter *bracket,
+ GtkTextIter *bracket_match)
{
- GtkTextIter bracket_match;
GtkSourceBracketMatchType result;
+ GtkTextIter prev;
- bracket_match = *pos;
- result = gtk_source_buffer_find_bracket_match_real (buffer, &bracket_match);
+ g_return_val_if_fail (GTK_SOURCE_IS_BUFFER (buffer), GTK_SOURCE_BRACKET_MATCH_NONE);
+ g_return_val_if_fail (pos != NULL, GTK_SOURCE_BRACKET_MATCH_NONE);
+ g_return_val_if_fail (bracket_match != NULL, GTK_SOURCE_BRACKET_MATCH_NONE);
- if (result != GTK_SOURCE_BRACKET_MATCH_FOUND)
- {
- bracket_match = *pos;
+ *bracket_match = *pos;
+ result = gtk_source_buffer_find_bracket_match_real (buffer, bracket_match);
- if (!gtk_text_iter_starts_line (&bracket_match) &&
- gtk_text_iter_backward_char (&bracket_match))
+ if (result == GTK_SOURCE_BRACKET_MATCH_FOUND)
+ {
+ if (bracket != NULL)
{
- result = gtk_source_buffer_find_bracket_match_real (buffer, &bracket_match);
+ *bracket = *pos;
}
+
+ return GTK_SOURCE_BRACKET_MATCH_FOUND;
}
- if (result == GTK_SOURCE_BRACKET_MATCH_FOUND)
+ prev = *pos;
+ if (!gtk_text_iter_starts_line (&prev) &&
+ gtk_text_iter_backward_cursor_position (&prev))
+ {
+ *bracket_match = prev;
+ result = gtk_source_buffer_find_bracket_match_real (buffer, bracket_match);
+ }
+
+ if (result == GTK_SOURCE_BRACKET_MATCH_FOUND &&
+ bracket != NULL)
{
- *pos = bracket_match;
+ *bracket = prev;
}
return result;
diff --git a/gtksourceview/gtksourceview.c b/gtksourceview/gtksourceview.c
index 738e6f0..dbc70dd 100644
--- a/gtksourceview/gtksourceview.c
+++ b/gtksourceview/gtksourceview.c
@@ -320,23 +320,28 @@ gtk_source_view_move_to_matching_bracket (GtkSourceView *view,
GtkTextView *text_view = GTK_TEXT_VIEW (view);
GtkTextBuffer *buffer;
GtkTextMark *insert_mark;
- GtkTextIter iter;
+ GtkTextIter insert;
+ GtkTextIter bracket_match;
+ GtkSourceBracketMatchType result;
buffer = gtk_text_view_get_buffer (text_view);
insert_mark = gtk_text_buffer_get_insert (buffer);
- gtk_text_buffer_get_iter_at_mark (buffer, &iter, insert_mark);
+ gtk_text_buffer_get_iter_at_mark (buffer, &insert, insert_mark);
+
+ result = _gtk_source_buffer_find_bracket_match (GTK_SOURCE_BUFFER (buffer),
+ &insert,
+ NULL,
+ &bracket_match);
- if (_gtk_source_buffer_find_bracket_match (GTK_SOURCE_BUFFER (buffer),
- &iter) == GTK_SOURCE_BRACKET_MATCH_FOUND)
+ if (result == GTK_SOURCE_BRACKET_MATCH_FOUND)
{
if (extend_selection)
{
- gtk_text_buffer_move_mark (buffer, insert_mark,
- &iter);
+ gtk_text_buffer_move_mark (buffer, insert_mark, &bracket_match);
}
else
{
- gtk_text_buffer_place_cursor (buffer, &iter);
+ gtk_text_buffer_place_cursor (buffer, &bracket_match);
}
gtk_text_view_scroll_mark_onscreen (text_view, insert_mark);
diff --git a/tests/test-buffer.c b/tests/test-buffer.c
index b09e36e..cfc7869 100644
--- a/tests/test-buffer.c
+++ b/tests/test-buffer.c
@@ -282,24 +282,38 @@ test_sort_lines (void)
static void
do_test_bracket_matching (GtkSourceBuffer *source_buffer,
const gchar *text,
- gint offset_before,
- gint expected_offset_after,
+ gint offset,
+ gint expected_offset_bracket,
+ gint expected_offset_match,
GtkSourceBracketMatchType expected_result)
{
GtkTextBuffer *text_buffer = GTK_TEXT_BUFFER (source_buffer);
GtkTextIter iter;
+ GtkTextIter bracket;
+ GtkTextIter bracket_match;
GtkSourceBracketMatchType result;
- gint offset_after;
gtk_text_buffer_set_text (text_buffer, text, -1);
- gtk_text_buffer_get_iter_at_offset (text_buffer, &iter, offset_before);
+ gtk_text_buffer_get_iter_at_offset (text_buffer, &iter, offset);
- result = _gtk_source_buffer_find_bracket_match (source_buffer, &iter);
+ result = _gtk_source_buffer_find_bracket_match (source_buffer,
+ &iter,
+ &bracket,
+ &bracket_match);
g_assert_cmpint (result, ==, expected_result);
- offset_after = gtk_text_iter_get_offset (&iter);
- g_assert_cmpint (offset_after, ==, expected_offset_after);
+ if (result == GTK_SOURCE_BRACKET_MATCH_FOUND)
+ {
+ gint offset_bracket;
+ gint offset_match;
+
+ offset_bracket = gtk_text_iter_get_offset (&bracket);
+ offset_match = gtk_text_iter_get_offset (&bracket_match);
+
+ g_assert_cmpint (offset_bracket, ==, expected_offset_bracket);
+ g_assert_cmpint (offset_match, ==, expected_offset_match);
+ }
}
static void
@@ -316,22 +330,18 @@ test_bracket_matching (void)
g_assert (c_language != NULL);
gtk_source_buffer_set_language (buffer, c_language);
- do_test_bracket_matching (buffer, "(ab)", 0, 3, GTK_SOURCE_BRACKET_MATCH_FOUND);
- do_test_bracket_matching (buffer, "(ab)", 1, 3, GTK_SOURCE_BRACKET_MATCH_FOUND);
- do_test_bracket_matching (buffer, "(ab)", 2, 2, GTK_SOURCE_BRACKET_MATCH_NONE);
- do_test_bracket_matching (buffer, "(ab)", 3, 0, GTK_SOURCE_BRACKET_MATCH_FOUND);
- do_test_bracket_matching (buffer, "(ab)", 4, 0, GTK_SOURCE_BRACKET_MATCH_FOUND);
-
- do_test_bracket_matching (buffer, "(ab))", 0, 3, GTK_SOURCE_BRACKET_MATCH_FOUND);
- do_test_bracket_matching (buffer, "(ab))", 1, 3, GTK_SOURCE_BRACKET_MATCH_FOUND);
- do_test_bracket_matching (buffer, "(ab))", 2, 2, GTK_SOURCE_BRACKET_MATCH_NONE);
- do_test_bracket_matching (buffer, "(ab))", 3, 0, GTK_SOURCE_BRACKET_MATCH_FOUND);
- /* FIXME ok, the bracket at offset 3 (on the left) matches the bracket
- * at offset 0. But the highlighting is wrong, the second ) is
- * highlighted.
- */
- do_test_bracket_matching (buffer, "(ab))", 4, 0, GTK_SOURCE_BRACKET_MATCH_FOUND);
- do_test_bracket_matching (buffer, "(ab))", 5, 5, GTK_SOURCE_BRACKET_MATCH_NOT_FOUND);
+ do_test_bracket_matching (buffer, "(ab)", 0, 0, 3, GTK_SOURCE_BRACKET_MATCH_FOUND);
+ do_test_bracket_matching (buffer, "(ab)", 1, 0, 3, GTK_SOURCE_BRACKET_MATCH_FOUND);
+ do_test_bracket_matching (buffer, "(ab)", 2, -1, -1, GTK_SOURCE_BRACKET_MATCH_NONE);
+ do_test_bracket_matching (buffer, "(ab)", 3, 3, 0, GTK_SOURCE_BRACKET_MATCH_FOUND);
+ do_test_bracket_matching (buffer, "(ab)", 4, 3, 0, GTK_SOURCE_BRACKET_MATCH_FOUND);
+
+ do_test_bracket_matching (buffer, "(ab))", 0, 0, 3, GTK_SOURCE_BRACKET_MATCH_FOUND);
+ do_test_bracket_matching (buffer, "(ab))", 1, 0, 3, GTK_SOURCE_BRACKET_MATCH_FOUND);
+ do_test_bracket_matching (buffer, "(ab))", 2, -1, -1, GTK_SOURCE_BRACKET_MATCH_NONE);
+ do_test_bracket_matching (buffer, "(ab))", 3, 3, 0, GTK_SOURCE_BRACKET_MATCH_FOUND);
+ do_test_bracket_matching (buffer, "(ab))", 4, 3, 0, GTK_SOURCE_BRACKET_MATCH_FOUND);
+ do_test_bracket_matching (buffer, "(ab))", 5, -1, -1, GTK_SOURCE_BRACKET_MATCH_NOT_FOUND);
g_object_unref (buffer);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]