[gtksourceview/wip/chergert/vim] start on some motion iters



commit ab559ce5ff1fbd63f5b93ff82fb2f441a874c1e4
Author: Christian Hergert <chergert redhat com>
Date:   Thu Nov 4 14:47:23 2021 -0700

    start on some motion iters
    
    this will help later with text objects

 gtksourceview/vim/gtk-source-vim-motion.c | 262 ++++++++++++++++++++++++++++++
 gtksourceview/vim/gtk-source-vim-motion.h |  23 +++
 2 files changed, 285 insertions(+)
---
diff --git a/gtksourceview/vim/gtk-source-vim-motion.c b/gtksourceview/vim/gtk-source-vim-motion.c
index efd367d4..c985ad8c 100644
--- a/gtksourceview/vim/gtk-source-vim-motion.c
+++ b/gtksourceview/vim/gtk-source-vim-motion.c
@@ -115,6 +115,12 @@ get_adjusted_count (GtkSourceVimMotion *self)
        return gtk_source_vim_state_get_count (GTK_SOURCE_VIM_STATE (self)) + self->alter_count;
 }
 
+static inline gboolean
+iter_isspace (const GtkTextIter *iter)
+{
+       return g_unichar_isspace (gtk_text_iter_get_char (iter));
+}
+
 static inline gboolean
 get_number (guint  keyval,
             int   *n)
@@ -1987,3 +1993,259 @@ gtk_source_vim_motion_set_linewise_keyval (GtkSourceVimMotion *self,
 
        self->linewise_keyval = keyval;
 }
+
+gboolean
+gtk_source_vim_iter_forward_word_end (GtkTextIter *iter)
+{
+       return forward_classified_end (iter, classify_word_newline_stop);
+}
+
+gboolean
+gtk_source_vim_iter_forward_WORD_end (GtkTextIter *iter)
+{
+       return forward_classified_end (iter, classify_WORD_newline_stop);
+}
+
+gboolean
+gtk_source_vim_iter_backward_word_start (GtkTextIter *iter)
+{
+       return backward_classified_start (iter, classify_word_newline_stop);
+}
+
+gboolean
+gtk_source_vim_iter_backward_WORD_start (GtkTextIter *iter)
+{
+       return backward_classified_start (iter, classify_WORD_newline_stop);
+}
+
+static inline gboolean
+unichar_ends_sentence (gunichar ch)
+{
+       switch (ch)
+       {
+               case '.':
+               case '!':
+               case '?':
+                       return TRUE;
+
+               default:
+                       return FALSE;
+       }
+}
+
+static inline gboolean
+unichar_can_trail_sentence (gunichar ch)
+{
+       switch (ch)
+       {
+               case '.':
+               case '!':
+               case '?':
+               case '\'':
+               case '"':
+               case ')':
+               case ']':
+                       return TRUE;
+
+               default:
+                       return FALSE;
+       }
+}
+
+gboolean
+gtk_source_vim_iter_forward_sentence_end (GtkTextIter *iter)
+{
+       /* From VIM:
+        *
+        * A sentence is defined as ending at a '.', '!' or '?' followed by either the
+        * end of a line, or by a space or tab.  Any number of closing ')', ']', '"'
+        * and ''' characters may appear after the '.', '!' or '?' before the spaces,
+        * tabs or end of line.  A paragraph and section boundary is also a sentence
+        * boundary.
+        */
+
+       if (gtk_text_iter_is_end (iter))
+               return FALSE;
+
+       /* First find a .!? */
+       while (gtk_text_iter_forward_char (iter))
+       {
+               gunichar ch = gtk_text_iter_get_char (iter);
+
+               if (unichar_ends_sentence (ch))
+                       break;
+
+               /* If we reached a newline, and the next char is also
+                * a newline, then we stop at this newline.
+                */
+               if (gtk_text_iter_ends_line (iter))
+               {
+                       GtkTextIter peek = *iter;
+
+                       if (gtk_text_iter_forward_char (&peek) || gtk_text_iter_is_end (&peek))
+                       {
+                               return TRUE;
+                       }
+               }
+       }
+
+       /* Read past any acceptable trailing chars */
+       while (gtk_text_iter_forward_char (iter))
+       {
+               gunichar ch = gtk_text_iter_get_char (iter);
+
+               if (!unichar_can_trail_sentence (ch))
+                       break;
+       }
+
+       /* If we are on a space or end of a buffer, then we found the end */
+       if (gtk_text_iter_is_end (iter) || iter_isspace (iter))
+       {
+               return TRUE;
+       }
+
+       /* This is not a suitable sentence candidate. We must try again */
+       return gtk_source_vim_iter_forward_sentence_end (iter);
+}
+
+gboolean
+gtk_source_vim_iter_backward_sentence_start (GtkTextIter *iter)
+{
+       return motion_backward_sentence_start (iter, NULL);
+}
+
+gboolean
+gtk_source_vim_iter_forward_paragraph_end (GtkTextIter *iter)
+{
+       return motion_forward_paragraph_end (iter, NULL);
+}
+
+gboolean
+gtk_source_vim_iter_backward_paragraph_start (GtkTextIter *iter)
+{
+       return motion_backward_paragraph_start (iter, NULL);
+}
+
+static gboolean
+find_predicate (gunichar ch,
+                gpointer data)
+{
+       return GSIZE_TO_POINTER (ch) == data;
+}
+
+static gboolean
+gtk_source_vim_iter_backward_block_start (GtkTextIter *iter,
+                                          gunichar     ch)
+{
+       return gtk_text_iter_backward_find_char (iter, find_predicate, GSIZE_TO_POINTER (ch), NULL);
+}
+
+static gboolean
+gtk_source_vim_iter_forward_block_end (GtkTextIter *iter,
+                                       gunichar     ch)
+{
+       return gtk_text_iter_forward_find_char (iter, find_predicate, GSIZE_TO_POINTER (ch), NULL);
+}
+
+gboolean
+gtk_source_vim_iter_backward_block_paren_start (GtkTextIter *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, ')');
+}
+
+gboolean
+gtk_source_vim_iter_backward_block_brace_start (GtkTextIter *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, '}');
+}
+
+gboolean
+gtk_source_vim_iter_forward_block_bracket_end (GtkTextIter *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, '[');
+}
+
+gboolean
+gtk_source_vim_iter_forward_block_lt_gt_end (GtkTextIter *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, '<');
+}
+
+static gboolean
+gtk_source_vim_iter_backward_quote_start (GtkTextIter *iter,
+                                          gunichar     ch)
+{
+       GtkTextIter limit = *iter;
+       gtk_text_iter_set_line_offset (iter, 0);
+       return gtk_text_iter_backward_find_char (iter, find_predicate, GSIZE_TO_POINTER (ch), &limit);
+}
+
+static gboolean
+gtk_source_vim_iter_forward_quote_end (GtkTextIter *iter,
+                                       gunichar     ch)
+{
+       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);
+}
+
+gboolean
+gtk_source_vim_iter_forward_quote_double (GtkTextIter *iter)
+{
+       return gtk_source_vim_iter_forward_quote_end (iter, '"');
+}
+
+gboolean
+gtk_source_vim_iter_backward_quote_double (GtkTextIter *iter)
+{
+       return gtk_source_vim_iter_backward_quote_start (iter, '"');
+}
+
+gboolean
+gtk_source_vim_iter_forward_quote_single (GtkTextIter *iter)
+{
+       return gtk_source_vim_iter_forward_quote_end (iter, '\'');
+}
+
+gboolean
+gtk_source_vim_iter_backward_quote_single (GtkTextIter *iter)
+{
+       return gtk_source_vim_iter_backward_quote_start (iter, '\'');
+}
+
+gboolean
+gtk_source_vim_iter_forward_quote_grave (GtkTextIter *iter)
+{
+       return gtk_source_vim_iter_forward_quote_end (iter, '`');
+}
+
+gboolean
+gtk_source_vim_iter_backward_quote_grave (GtkTextIter *iter)
+{
+       return gtk_source_vim_iter_backward_quote_start (iter, '`');
+}
diff --git a/gtksourceview/vim/gtk-source-vim-motion.h b/gtksourceview/vim/gtk-source-vim-motion.h
index 3dda7eac..9399c2eb 100644
--- a/gtksourceview/vim/gtk-source-vim-motion.h
+++ b/gtksourceview/vim/gtk-source-vim-motion.h
@@ -55,4 +55,27 @@ gboolean           gtk_source_vim_motion_apply                     (GtkSourceVim
 gboolean           gtk_source_vim_motion_invalidates_visual_column (GtkSourceVimMotion *self);
 gboolean           gtk_source_vim_motion_is_linewise               (GtkSourceVimMotion *self);
 
+gboolean gtk_source_vim_iter_backward_block_brace_start   (GtkTextIter *iter);
+gboolean gtk_source_vim_iter_backward_block_bracket_start (GtkTextIter *iter);
+gboolean gtk_source_vim_iter_backward_block_lt_gt_start   (GtkTextIter *iter);
+gboolean gtk_source_vim_iter_backward_block_paren_start   (GtkTextIter *iter);
+gboolean gtk_source_vim_iter_backward_paragraph_start     (GtkTextIter *iter);
+gboolean gtk_source_vim_iter_backward_quote_double        (GtkTextIter *iter);
+gboolean gtk_source_vim_iter_backward_quote_grave         (GtkTextIter *iter);
+gboolean gtk_source_vim_iter_backward_quote_single        (GtkTextIter *iter);
+gboolean gtk_source_vim_iter_backward_sentence_start      (GtkTextIter *iter);
+gboolean gtk_source_vim_iter_backward_word_start          (GtkTextIter *iter);
+gboolean gtk_source_vim_iter_backward_WORD_start          (GtkTextIter *iter);
+gboolean gtk_source_vim_iter_forward_block_brace_end      (GtkTextIter *iter);
+gboolean gtk_source_vim_iter_forward_block_bracket_end    (GtkTextIter *iter);
+gboolean gtk_source_vim_iter_forward_block_lt_gt_end      (GtkTextIter *iter);
+gboolean gtk_source_vim_iter_forward_block_paren_end      (GtkTextIter *iter);
+gboolean gtk_source_vim_iter_forward_paragraph_end        (GtkTextIter *iter);
+gboolean gtk_source_vim_iter_forward_quote_double         (GtkTextIter *iter);
+gboolean gtk_source_vim_iter_forward_quote_grave          (GtkTextIter *iter);
+gboolean gtk_source_vim_iter_forward_quote_single         (GtkTextIter *iter);
+gboolean gtk_source_vim_iter_forward_sentence_end         (GtkTextIter *iter);
+gboolean gtk_source_vim_iter_forward_word_end             (GtkTextIter *iter);
+gboolean gtk_source_vim_iter_forward_WORD_end             (GtkTextIter *iter);
+
 G_END_DECLS


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