[gtksourceview/wip/chergert/vim: 48/73] add w and W movements




commit e0b40cd05202cd8eeff23d79cef652fd995faa9f
Author: Christian Hergert <chergert redhat com>
Date:   Sat Oct 23 10:31:00 2021 -0700

    add w and W movements

 gtksourceview/vim/gtk-source-vim-motion.c | 113 +++++++++++++++++++++++++++++-
 1 file changed, 111 insertions(+), 2 deletions(-)
---
diff --git a/gtksourceview/vim/gtk-source-vim-motion.c b/gtksourceview/vim/gtk-source-vim-motion.c
index 4c321458..7d423d6a 100644
--- a/gtksourceview/vim/gtk-source-vim-motion.c
+++ b/gtksourceview/vim/gtk-source-vim-motion.c
@@ -39,6 +39,97 @@ struct _GtkSourceVimMotion
 
 G_DEFINE_TYPE (GtkSourceVimMotion, gtk_source_vim_motion, GTK_SOURCE_TYPE_VIM_STATE)
 
+enum
+{
+       CLASS_0,
+       CLASS_NEWLINE,
+       CLASS_SPACE,
+       CLASS_SPECIAL,
+       CLASS_WORD,
+};
+
+static int
+classify_word (gunichar ch)
+{
+       switch (ch)
+       {
+               case ' ':
+               case '\t':
+               case '\n':
+                       return CLASS_SPACE;
+
+               case '"': case '\'':
+               case '(': case ')':
+               case '{': case '}':
+               case '[': case ']':
+               case '<': case '>':
+               case '-': case '+': case '*': case '/':
+               case '!': case '@': case '#': case '$': case '%':
+               case '^': case '&': case ':': case ';': case '?':
+               case '|': case '=': case '\\': case '.': case ',':
+                       return CLASS_SPECIAL;
+
+               case '_':
+               default:
+                       return CLASS_WORD;
+       }
+}
+
+static int
+classify_WORD (gunichar ch)
+{
+       if (g_unichar_isspace (ch))
+               return CLASS_SPACE;
+       return CLASS_WORD;
+}
+
+static gboolean
+forward_classified_start (GtkTextIter  *iter,
+                          gint        (*classify) (gunichar))
+{
+       gint begin_class;
+       gint cur_class;
+       gunichar ch;
+
+       g_assert (iter);
+
+       ch = gtk_text_iter_get_char (iter);
+       begin_class = classify (ch);
+
+       /* Move to the first non-whitespace character if necessary. */
+       if (begin_class == CLASS_SPACE)
+       {
+               for (;;)
+               {
+                       if (!gtk_text_iter_forward_char (iter))
+                               return FALSE;
+
+                       ch = gtk_text_iter_get_char (iter);
+                       cur_class = classify (ch);
+                       if (cur_class != CLASS_SPACE)
+                               return TRUE;
+               }
+       }
+
+       /* move to first character not at same class level. */
+       while (gtk_text_iter_forward_char (iter))
+       {
+               ch = gtk_text_iter_get_char (iter);
+               cur_class = classify (ch);
+
+               if (cur_class == CLASS_SPACE)
+               {
+                       begin_class = CLASS_0;
+                       continue;
+               }
+
+               if (cur_class != begin_class || cur_class == CLASS_NEWLINE)
+                       return TRUE;
+       }
+
+       return FALSE;
+}
+
 static void
 get_iter_at_visual_column (GtkSourceView *view,
                            GtkTextIter   *iter,
@@ -278,6 +369,20 @@ motion_screen_middle (GtkTextIter   *iter,
        return TRUE;
 }
 
+static gboolean
+motion_forward_word_start (GtkTextIter   *iter,
+                           GtkSourceView *view)
+{
+       return forward_classified_start (iter, classify_word);
+}
+
+static gboolean
+motion_forward_WORD_start (GtkTextIter   *iter,
+                           GtkSourceView *view)
+{
+       return forward_classified_start (iter, classify_WORD);
+}
+
 GtkSourceVimState *
 gtk_source_vim_motion_new (void)
 {
@@ -396,6 +501,12 @@ gtk_source_vim_motion_handle_keypress (GtkSourceVimState *state,
                case GDK_KEY_L:
                        return gtk_source_vim_motion_complete (self, motion_screen_bottom);
 
+               case GDK_KEY_w:
+                       return gtk_source_vim_motion_complete (self, motion_forward_word_start);
+
+               case GDK_KEY_W:
+                       return gtk_source_vim_motion_complete (self, motion_forward_WORD_start);
+
                case GDK_KEY_b:
                case GDK_KEY_B:
                case GDK_KEY_e:
@@ -407,8 +518,6 @@ gtk_source_vim_motion_handle_keypress (GtkSourceVimState *state,
                case GDK_KEY_parenleft:
                case GDK_KEY_parenright:
                case GDK_KEY_percent:
-               case GDK_KEY_w:
-               case GDK_KEY_W:
                        /* TODO */
                        G_GNUC_FALLTHROUGH;
 


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