[gtksourceview/wip/chergert/vim] walk over opposite braces/brackets/etc



commit ea19d2040bb33b5891e315eabc825035d4ec4dde
Author: Christian Hergert <chergert redhat com>
Date:   Fri Nov 5 11:59:41 2021 -0700

    walk over opposite braces/brackets/etc

 gtksourceview/vim/gtk-source-vim-motion.c | 56 ++++++++++++++++++++-----------
 testsuite/test-vim-text-object.c          |  5 +++
 2 files changed, 42 insertions(+), 19 deletions(-)
---
diff --git a/gtksourceview/vim/gtk-source-vim-motion.c b/gtksourceview/vim/gtk-source-vim-motion.c
index 95ea24d1..73933f13 100644
--- a/gtksourceview/vim/gtk-source-vim-motion.c
+++ b/gtksourceview/vim/gtk-source-vim-motion.c
@@ -2136,92 +2136,109 @@ gtk_source_vim_iter_backward_paragraph_start (GtkTextIter *iter)
        return motion_backward_paragraph_start (iter, NULL);
 }
 
+typedef struct
+{
+       gunichar ch;
+       gunichar opposite;
+       int count;
+} FindPredicate;
+
 static gboolean
 find_predicate (gunichar ch,
                 gpointer data)
 {
-       return GSIZE_TO_POINTER (ch) == data;
+       FindPredicate *find = data;
+
+       if (ch == find->opposite)
+               find->count++;
+       else if (ch == find->ch)
+               find->count--;
+
+       return find->count == 0;
 }
 
 static gboolean
 gtk_source_vim_iter_backward_block_start (GtkTextIter *iter,
-                                          gunichar     ch)
+                                          gunichar     ch,
+                                          gunichar     opposite)
 {
+       FindPredicate find = { ch, opposite, 1 };
+
        if (gtk_text_iter_get_char (iter) == ch)
                return TRUE;
 
-       /* TODO: need to count unclosed blocks */
-
-       return gtk_text_iter_backward_find_char (iter, find_predicate, GSIZE_TO_POINTER (ch), NULL);
+       return gtk_text_iter_backward_find_char (iter, find_predicate, &find, NULL);
 }
 
 static gboolean
 gtk_source_vim_iter_forward_block_end (GtkTextIter *iter,
-                                       gunichar     ch)
+                                       gunichar     ch,
+                                       gunichar     opposite)
 {
+       FindPredicate find = { ch, opposite, 1 };
+
        if (gtk_text_iter_get_char (iter) == ch)
                return TRUE;
 
-       /* TODO: need to count unclosed blocks */
-
-       return gtk_text_iter_forward_find_char (iter, find_predicate, GSIZE_TO_POINTER (ch), NULL);
+       return gtk_text_iter_forward_find_char (iter, find_predicate, &find, NULL);
 }
 
 gboolean
 gtk_source_vim_iter_backward_block_paren_start (GtkTextIter *iter)
 {
-       return gtk_source_vim_iter_backward_block_start (iter, '(');
+       return gtk_source_vim_iter_backward_block_start (iter, '(', ')');
 }
 
 gboolean
 gtk_source_vim_iter_forward_block_paren_end (GtkTextIter *iter)
 {
-       return gtk_source_vim_iter_forward_block_end (iter, ')');
+       return gtk_source_vim_iter_forward_block_end (iter, ')', '(');
 }
 
 gboolean
 gtk_source_vim_iter_backward_block_brace_start (GtkTextIter *iter)
 {
-       return gtk_source_vim_iter_backward_block_start (iter, '{');
+       return gtk_source_vim_iter_backward_block_start (iter, '{', '}');
 }
 
 gboolean
 gtk_source_vim_iter_forward_block_brace_end (GtkTextIter *iter)
 {
-       return gtk_source_vim_iter_forward_block_end (iter, '}');
+       return gtk_source_vim_iter_forward_block_end (iter, '}', '{');
 }
 
 gboolean
 gtk_source_vim_iter_forward_block_bracket_end (GtkTextIter *iter)
 {
-       return gtk_source_vim_iter_forward_block_end (iter, ']');
+       return gtk_source_vim_iter_forward_block_end (iter, ']', '[');
 }
 
 gboolean
 gtk_source_vim_iter_backward_block_bracket_start (GtkTextIter *iter)
 {
-       return gtk_source_vim_iter_backward_block_start (iter, '[');
+       return gtk_source_vim_iter_backward_block_start (iter, '[', ']');
 }
 
 gboolean
 gtk_source_vim_iter_forward_block_lt_gt_end (GtkTextIter *iter)
 {
-       return gtk_source_vim_iter_forward_block_end (iter, '>');
+       return gtk_source_vim_iter_forward_block_end (iter, '>', '<');
 }
 
 gboolean
 gtk_source_vim_iter_backward_block_lt_gt_start (GtkTextIter *iter)
 {
-       return gtk_source_vim_iter_backward_block_start (iter, '<');
+       return gtk_source_vim_iter_backward_block_start (iter, '<', '>');
 }
 
 static gboolean
 gtk_source_vim_iter_backward_quote_start (GtkTextIter *iter,
                                           gunichar     ch)
 {
+       FindPredicate find = { ch, 0 , 1 };
        GtkTextIter limit = *iter;
        gtk_text_iter_set_line_offset (&limit, 0);
-       return gtk_text_iter_backward_find_char (iter, find_predicate, GSIZE_TO_POINTER (ch), &limit);
+       return gtk_text_iter_backward_find_char (iter, find_predicate, &find, NULL);
 }
 
 static gboolean
@@ -2246,12 +2263,13 @@ static gboolean
 gtk_source_vim_iter_forward_quote_end (GtkTextIter *iter,
                                        gunichar     ch)
 {
+       FindPredicate find = { ch, 0, 1 };
        GtkTextIter limit = *iter;
 
        if (!gtk_text_iter_ends_line (&limit))
                gtk_text_iter_forward_to_line_end (&limit);
 
-       return gtk_text_iter_forward_find_char (iter, find_predicate, GSIZE_TO_POINTER (ch), &limit);
+       return gtk_text_iter_forward_find_char (iter, find_predicate, &find, NULL);
 }
 
 gboolean
diff --git a/testsuite/test-vim-text-object.c b/testsuite/test-vim-text-object.c
index d402cdbd..4315c244 100644
--- a/testsuite/test-vim-text-object.c
+++ b/testsuite/test-vim-text-object.c
@@ -124,6 +124,11 @@ test_block (void)
        run_test (gtk_source_vim_text_object_new_inner_block_lt_gt (), "<a></a>", 1, "a", FALSE);
        run_test (gtk_source_vim_text_object_new_inner_block_lt_gt (), "<a></a>", 2, "a", FALSE);
        run_test (gtk_source_vim_text_object_new_inner_block_lt_gt (), "<a></a>", 3, "/a", FALSE);
+
+       run_test (gtk_source_vim_text_object_new_inner_block_bracket (), "[a[b[c]]]", 0, "a[b[c]]", FALSE);
+       run_test (gtk_source_vim_text_object_new_inner_block_bracket (), "[a[b[c]]]", 4, "c", FALSE);
+       run_test (gtk_source_vim_text_object_new_inner_block_bracket (), "[a[b[c]]]", 5, "c", FALSE);
+       run_test (gtk_source_vim_text_object_new_inner_block_bracket (), "[a[b[c]]]", 6, "c", FALSE);
 }
 
 static void


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