[gtksourceview/wip/chergert/vim: 21/293] start on the jump tables




commit 6c516aab8ef8f7bb273cf1094e61cbc88099b2f5
Author: Christian Hergert <chergert redhat com>
Date:   Thu Oct 21 16:27:51 2021 -0700

    start on the jump tables

 gtksourceview/vim/gtk-source-vim-normal.c | 448 ++++++++++++++++++++++++------
 1 file changed, 365 insertions(+), 83 deletions(-)
---
diff --git a/gtksourceview/vim/gtk-source-vim-normal.c b/gtksourceview/vim/gtk-source-vim-normal.c
index 7f149042..23614b7e 100644
--- a/gtksourceview/vim/gtk-source-vim-normal.c
+++ b/gtksourceview/vim/gtk-source-vim-normal.c
@@ -23,36 +23,19 @@
 
 #include "gtk-source-vim-normal.h"
 
-typedef enum
-{
-       PARSE_STATE_NUMBER  = 1 << 0,
-       PARSE_STATE_MOTION  = 1 << 1,
-       PARSE_STATE_OPER    = 1 << 2,
-       PARSE_STATE_INITIAL = (PARSE_STATE_NUMBER | PARSE_STATE_MOTION | PARSE_STATE_OPER),
-} ParseState;
-
-typedef enum
-{
-       OPER_0,
-       OPER_INSERT,
-       OPER_DELETE,
-       OPER_REPLACE,
-} Oper;
+typedef gboolean (*KeyHandler) (GtkSourceVimNormal *self,
+                                guint               keyval,
+                                guint               keycode,
+                                GdkModifierType     mods,
+                                const char         *string);
 
 struct _GtkSourceVimNormal
 {
        GtkSourceVimState parent_instance;
 
-       /* What state of parsing input are we */
-       ParseState state;
+       KeyHandler handler;
 
        int repeat;
-       Oper op;
-
-       struct {
-               char kind[8];
-               int number;
-       } motion;
 };
 
 G_DEFINE_TYPE (GtkSourceVimNormal, gtk_source_vim_normal, GTK_SOURCE_TYPE_VIM_STATE)
@@ -65,13 +48,363 @@ is_escape (guint           keyval,
                (keyval == GDK_KEY_bracketleft && (mods & GDK_CONTROL_MASK) != 0);
 }
 
-static void
-gtk_source_vim_normal_reset (GtkSourceVimNormal *self)
+static gboolean
+key_handler_motion (GtkSourceVimNormal *self,
+                    guint               keyval,
+                    guint               keycode,
+                    GdkModifierType     mods,
+                    const char         *string)
 {
        g_assert (GTK_SOURCE_IS_VIM_NORMAL (self));
 
-       self->state = PARSE_STATE_INITIAL;
-       self->repeat = 0;
+       return FALSE;
+}
+
+static gboolean
+key_handler_repeat (GtkSourceVimNormal *self,
+                    guint               keyval,
+                    guint               keycode,
+                    GdkModifierType     mods,
+                    const char         *string)
+{
+       g_assert (GTK_SOURCE_IS_VIM_NORMAL (self));
+
+       return FALSE;
+}
+
+static gboolean
+key_handler_command (GtkSourceVimNormal *self,
+                    guint               keyval,
+                    guint               keycode,
+                    GdkModifierType     mods,
+                    const char         *string)
+{
+       g_assert (GTK_SOURCE_IS_VIM_NORMAL (self));
+
+       return FALSE;
+}
+
+static gboolean
+key_handler_viewport (GtkSourceVimNormal *self,
+                      guint               keyval,
+                      guint               keycode,
+                      GdkModifierType     mods,
+                      const char         *string)
+{
+       g_assert (GTK_SOURCE_IS_VIM_NORMAL (self));
+
+       return FALSE;
+}
+
+static gboolean
+key_handler_change (GtkSourceVimNormal *self,
+                    guint               keyval,
+                    guint               keycode,
+                    GdkModifierType     mods,
+                    const char         *string)
+{
+       g_assert (GTK_SOURCE_IS_VIM_NORMAL (self));
+
+       return FALSE;
+}
+
+static gboolean
+key_handler_shift (GtkSourceVimNormal *self,
+                   guint               keyval,
+                   guint               keycode,
+                   GdkModifierType     mods,
+                   const char         *string)
+{
+       g_assert (GTK_SOURCE_IS_VIM_NORMAL (self));
+
+       return FALSE;
+}
+
+static gboolean
+key_handler_replace_one (GtkSourceVimNormal *self,
+                         guint               keyval,
+                         guint               keycode,
+                         GdkModifierType     mods,
+                         const char         *string)
+{
+       g_assert (GTK_SOURCE_IS_VIM_NORMAL (self));
+
+       return FALSE;
+}
+
+static gboolean
+key_handler_search_word (GtkSourceVimNormal *self,
+                         guint               keyval,
+                         guint               keycode,
+                         GdkModifierType     mods,
+                         const char         *string)
+{
+       g_assert (GTK_SOURCE_IS_VIM_NORMAL (self));
+
+       return FALSE;
+}
+
+static gboolean
+key_handler_search (GtkSourceVimNormal *self,
+                    guint               keyval,
+                    guint               keycode,
+                    GdkModifierType     mods,
+                    const char         *string)
+{
+       g_assert (GTK_SOURCE_IS_VIM_NORMAL (self));
+
+       return FALSE;
+}
+
+static gboolean
+key_handler_command_bar (GtkSourceVimNormal *self,
+                         guint               keyval,
+                         guint               keycode,
+                         GdkModifierType     mods,
+                         const char         *string)
+{
+       g_assert (GTK_SOURCE_IS_VIM_NORMAL (self));
+
+       return FALSE;
+}
+
+static gboolean
+key_handler_yank (GtkSourceVimNormal *self,
+                  guint               keyval,
+                  guint               keycode,
+                  GdkModifierType     mods,
+                  const char         *string)
+{
+       g_assert (GTK_SOURCE_IS_VIM_NORMAL (self));
+
+       return FALSE;
+}
+
+static gboolean
+key_handler_delete (GtkSourceVimNormal *self,
+                    guint               keyval,
+                    guint               keycode,
+                    GdkModifierType     mods,
+                    const char         *string)
+{
+       g_assert (GTK_SOURCE_IS_VIM_NORMAL (self));
+
+       return FALSE;
+}
+
+static gboolean
+key_handler_split (GtkSourceVimNormal *self,
+                   guint               keyval,
+                   guint               keycode,
+                   GdkModifierType     mods,
+                   const char         *string)
+{
+       g_assert (GTK_SOURCE_IS_VIM_NORMAL (self));
+
+       return FALSE;
+}
+
+static gboolean
+key_handler_visual (GtkSourceVimNormal *self,
+                    guint               keyval,
+                    guint               keycode,
+                    GdkModifierType     mods,
+                    const char         *string)
+{
+       g_assert (GTK_SOURCE_IS_VIM_NORMAL (self));
+
+       return FALSE;
+}
+
+static gboolean
+key_handler_increment (GtkSourceVimNormal *self,
+                       guint               keyval,
+                       guint               keycode,
+                       GdkModifierType     mods,
+                       const char         *string)
+{
+       g_assert (GTK_SOURCE_IS_VIM_NORMAL (self));
+
+       return FALSE;
+}
+
+static gboolean
+key_handler_g (GtkSourceVimNormal *self,
+               guint               keyval,
+               guint               keycode,
+               GdkModifierType     mods,
+               const char         *string)
+{
+       g_assert (GTK_SOURCE_IS_VIM_NORMAL (self));
+
+       return FALSE;
+}
+
+static gboolean
+key_handler_initial (GtkSourceVimNormal *self,
+                     guint               keyval,
+                     guint               keycode,
+                     GdkModifierType     mods,
+                     const char         *string)
+{
+       g_assert (GTK_SOURCE_IS_VIM_NORMAL (self));
+
+       if ((mods & GDK_CONTROL_MASK) != 0)
+       {
+               switch (keyval)
+               {
+                       case GDK_KEY_a:
+                       case GDK_KEY_x:
+                               self->handler = key_handler_increment;
+                               break;
+
+                       case GDK_KEY_v:
+                               self->handler = key_handler_visual;
+                               break;
+
+                       case GDK_KEY_w:
+                               self->handler = key_handler_split;
+                               break;
+
+                       default:
+                               break;
+               }
+       }
+       else
+       {
+               switch (keyval)
+               {
+                       case GDK_KEY_0: case GDK_KEY_KP_0:
+                       case GDK_KEY_asciicircum:
+                       case GDK_KEY_b:
+                       case GDK_KEY_bar:
+                       case GDK_KEY_B:
+                       case GDK_KEY_BackSpace:
+                       case GDK_KEY_dollar:
+                       case GDK_KEY_Down:
+                       case GDK_KEY_e:
+                       case GDK_KEY_E:
+                       case GDK_KEY_End:
+                       case GDK_KEY_f:
+                       case GDK_KEY_F:
+                       case GDK_KEY_G:
+                       case GDK_KEY_h:
+                       case GDK_KEY_H:
+                       case GDK_KEY_j:
+                       case GDK_KEY_k:
+                       case GDK_KEY_KP_Enter:
+                       case GDK_KEY_l:
+                       case GDK_KEY_L:
+                       case GDK_KEY_Left:
+                       case GDK_KEY_M:
+                       case GDK_KEY_n:
+                       case GDK_KEY_N:
+                       case GDK_KEY_parenleft:
+                       case GDK_KEY_parenright:
+                       case GDK_KEY_percent:
+                       case GDK_KEY_Return:
+                       case GDK_KEY_Right:
+                       case GDK_KEY_space:
+                       case GDK_KEY_underscore:
+                       case GDK_KEY_Up:
+                       case GDK_KEY_w:
+                       case GDK_KEY_W:
+                               self->handler = key_handler_motion;
+                               break;
+
+                       case GDK_KEY_1: case GDK_KEY_KP_1:
+                       case GDK_KEY_2: case GDK_KEY_KP_2:
+                       case GDK_KEY_3: case GDK_KEY_KP_3:
+                       case GDK_KEY_4: case GDK_KEY_KP_4:
+                       case GDK_KEY_5: case GDK_KEY_KP_5:
+                       case GDK_KEY_6: case GDK_KEY_KP_6:
+                       case GDK_KEY_7: case GDK_KEY_KP_7:
+                       case GDK_KEY_8: case GDK_KEY_KP_8:
+                       case GDK_KEY_9: case GDK_KEY_KP_9:
+                               self->handler = key_handler_repeat;
+                               break;
+
+                       case GDK_KEY_a:
+                       case GDK_KEY_asciitilde:
+                       case GDK_KEY_A:
+                       case GDK_KEY_C:
+                       case GDK_KEY_D:
+                       case GDK_KEY_i:
+                       case GDK_KEY_I:
+                       case GDK_KEY_J:
+                       case GDK_KEY_o:
+                       case GDK_KEY_O:
+                       case GDK_KEY_p:
+                       case GDK_KEY_P:
+                       case GDK_KEY_period:
+                       case GDK_KEY_R:
+                       case GDK_KEY_s:
+                       case GDK_KEY_S:
+                       case GDK_KEY_u:
+                       case GDK_KEY_x:
+                       case GDK_KEY_equal:
+                       case GDK_KEY_plus:
+                       case GDK_KEY_Y:
+                               self->handler = key_handler_command;
+                               break;
+
+                       case GDK_KEY_y:
+                               self->handler = key_handler_yank;
+                               break;
+
+                       case GDK_KEY_d:
+                               self->handler = key_handler_delete;
+                               break;
+
+                       case GDK_KEY_c:
+                               self->handler = key_handler_change;
+                               break;
+
+                       case GDK_KEY_g:
+                               self->handler = key_handler_g;
+                               break;
+
+                       case GDK_KEY_z:
+                               self->handler = key_handler_viewport;
+                               break;
+
+                       case GDK_KEY_greater:
+                       case GDK_KEY_less:
+                               self->handler = key_handler_shift;
+                               break;
+
+                       case GDK_KEY_r:
+                               self->handler = key_handler_replace_one;
+                               break;
+
+                       case GDK_KEY_asterisk:
+                       case GDK_KEY_numbersign:
+                               self->handler = key_handler_search_word;
+                               break;
+
+                       case GDK_KEY_slash:
+                       case GDK_KEY_question:
+                               self->handler = key_handler_search;
+                               break;
+
+                       case GDK_KEY_colon:
+                               self->handler = key_handler_command_bar;
+                               break;
+
+                       case GDK_KEY_v:
+                       case GDK_KEY_V:
+                               self->handler = key_handler_visual;
+                               break;
+
+                       default:
+                               break;
+               }
+       }
+
+       if (self->handler != key_handler_initial)
+               return self->handler (self, keyval, keycode, mods, string);
+
+       return FALSE;
 }
 
 static gboolean
@@ -87,61 +420,11 @@ gtk_source_vim_normal_handle_keypress (GtkSourceVimState *state,
 
        if (is_escape (keyval, mods))
        {
-               gtk_source_vim_normal_reset (self);
+               gtk_source_vim_normal_clear (self);
                return TRUE;
        }
 
-#if 0
-       if (keyval >= GDK_KEY_0 && keyval <= GDK_KEY_9)
-       {
-       }
-
-       if ((self->state & PARSE_STATE_NUMBER) != 0)
-       {
-               int n;
-
-               switch (keyval) {
-               case GDK_KEY_0:
-                       /* cannot lead with 0 */
-                       n = self->number == 0 ? -1 : 0;
-                       break;
-               case GDK_KEY_1: n = 1; break;
-               case GDK_KEY_2: n = 2; break;
-               case GDK_KEY_3: n = 3; break;
-               case GDK_KEY_4: n = 4; break;
-               case GDK_KEY_5: n = 5; break;
-               case GDK_KEY_6: n = 6; break;
-               case GDK_KEY_7: n = 7; break;
-               case GDK_KEY_8: n = 8; break;
-               case GDK_KEY_9: n = 9; break;
-               default: n = -1; break;
-               }
-
-               if (n >= 0)
-               {
-                       self->number = self->number * 10 + n;
-                       return TRUE;
-               }
-       }
-
-       /* 3cip and 3c2ip result in 3cip */
-
-       switch (keyval) {
-       case GDK_KEY_0:
-       case GDK_KEY_1:
-       case GDK_KEY_2:
-       case GDK_KEY_3:
-       case GDK_KEY_4;
-       case GDK_KEY_5:
-       case GDK_KEY_6:
-       case GDK_KEY_7:
-       case GDK_KEY_8:
-       case GDK_KEY_9:
-               break;
-       }
-#endif
-
-       return FALSE;
+       return self->handler (self, keyval, keycode, mods, string);
 }
 
 static void
@@ -151,7 +434,7 @@ gtk_source_vim_normal_restore (GtkSourceVimState *state,
        g_assert (GTK_SOURCE_IS_VIM_STATE (state));
        g_assert (GTK_SOURCE_IS_VIM_STATE (from));
 
-       gtk_source_vim_normal_reset (GTK_SOURCE_VIM_NORMAL (state));
+       gtk_source_vim_normal_clear (GTK_SOURCE_VIM_NORMAL (state));
 }
 
 static void
@@ -188,7 +471,6 @@ gtk_source_vim_normal_clear (GtkSourceVimNormal *self)
 {
        g_return_if_fail (GTK_SOURCE_IS_VIM_NORMAL (self));
 
-       /* TODO: clear any state other than repeat, registers, marks, etc
-        * so that input from the user feels fresh.
-        */
+       self->handler = key_handler_initial;
+       self->repeat = 0;
 }


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