[gtksourceview/wip/chergert/vim] get some basic plumbing working



commit f08693117c8feb5714391e77f94c7d1bdbee1f2e
Author: Christian Hergert <chergert redhat com>
Date:   Fri Oct 22 08:43:46 2021 -0700

    get some basic plumbing working

 gtksourceview/vim/gtk-source-vim-insert.c | 77 ++++++++++++++++++++++++++++---
 gtksourceview/vim/gtk-source-vim-normal.c | 49 +++++++++-----------
 gtksourceview/vim/gtk-source-vim-normal.h |  4 +-
 gtksourceview/vim/gtk-source-vim-state.c  | 44 +++++++++---------
 gtksourceview/vim/gtk-source-vim-state.h  |  8 ++++
 gtksourceview/vim/gtk-source-vim.c        |  9 ++--
 tests/test-vim.c                          |  9 ++--
 7 files changed, 131 insertions(+), 69 deletions(-)
---
diff --git a/gtksourceview/vim/gtk-source-vim-insert.c b/gtksourceview/vim/gtk-source-vim-insert.c
index 5e699ec5..d0877b4c 100644
--- a/gtksourceview/vim/gtk-source-vim-insert.c
+++ b/gtksourceview/vim/gtk-source-vim-insert.c
@@ -37,14 +37,42 @@ gtk_source_vim_insert_new (void)
        return g_object_new (GTK_SOURCE_TYPE_VIM_INSERT, NULL);
 }
 
+static gboolean
+clear_to_first_char (GtkSourceVimInsert *self)
+{
+       GtkSourceBuffer *buffer;
+       GtkTextIter insert;
+       GtkTextIter begin;
+
+       g_assert (GTK_SOURCE_IS_VIM_INSERT (self));
+
+       buffer = gtk_source_vim_state_get_buffer (GTK_SOURCE_VIM_STATE (self), &insert, NULL);
+       begin = insert;
+       gtk_text_iter_set_line_offset (&begin, 0);
+
+       while (gtk_text_iter_compare (&begin, &insert) < 0 &&
+              g_unichar_isspace (gtk_text_iter_get_char (&begin)))
+       {
+               gtk_text_iter_forward_char (&begin);
+       }
+
+       gtk_text_buffer_delete (GTK_TEXT_BUFFER (buffer), &begin, &insert);
+
+       return TRUE;
+}
+
 static gboolean
 gtk_source_vim_insert_literal (GtkSourceVimInsert *self,
                                const char         *string)
 {
+       GtkSourceBuffer *buffer;
+       GtkTextIter insert;
+
        g_assert (GTK_SOURCE_IS_VIM_INSERT (self));
        g_assert (string != NULL);
 
-       /* TODO */
+       buffer = gtk_source_vim_state_get_buffer (GTK_SOURCE_VIM_STATE (self), &insert, NULL);
+       gtk_text_buffer_insert (GTK_TEXT_BUFFER (buffer), &insert, string, -1);
 
        return TRUE;
 }
@@ -88,8 +116,22 @@ gtk_source_vim_insert_handle_event (GtkSourceVimState *state,
                        case GDK_KEY_Escape:
                                return gtk_source_vim_insert_literal (self, "\e");
 
+                       case GDK_KEY_l:
+                               if ((mods & GDK_CONTROL_MASK) != 0)
+                                       return gtk_source_vim_insert_literal (self, "\f");
+                               G_GNUC_FALLTHROUGH;
+
                        default:
-                               break;
+                       {
+                               char outbuf[8] = {0};
+                               gunichar ch = gdk_keyval_to_unicode (keyval);
+                               int len = g_unichar_to_utf8 (ch, outbuf);
+
+                               if (len > 0)
+                                       gtk_source_vim_insert_literal (self, outbuf);
+
+                               return TRUE;
+                       }
                }
        }
 
@@ -97,15 +139,36 @@ gtk_source_vim_insert_handle_event (GtkSourceVimState *state,
        if (gtk_text_view_im_context_filter_keypress (GTK_TEXT_VIEW (view), event))
                return TRUE;
 
-       /* ctrl+v to begin insert literal */
-       if (self->insert_literal == FALSE &&
-           keyval == GDK_KEY_v &&
-           ((mods & GDK_CONTROL_MASK) != 0))
+       /* Leave insert mode if Escape/ctrl+[ was pressed */
+       if (gtk_source_vim_state_is_escape (keyval, mods))
        {
-               self->insert_literal = TRUE;
+               gtk_source_vim_state_pop (GTK_SOURCE_VIM_STATE (self));
                return TRUE;
        }
 
+       /* ctrl+v to begin insert literal */
+       if (self->insert_literal == FALSE)
+       {
+               if (keyval == GDK_KEY_v && (mods & GDK_CONTROL_MASK) != 0)
+               {
+                       self->insert_literal = TRUE;
+                       return TRUE;
+               }
+       }
+
+       /* Now handle our commands */
+       if ((mods & GDK_CONTROL_MASK) != 0)
+       {
+               switch (keyval)
+               {
+                       case GDK_KEY_u:
+                               return clear_to_first_char (self);
+
+                       default:
+                               break;
+               }
+       }
+
        /* Pass-through to the next controller */
 
        return FALSE;
diff --git a/gtksourceview/vim/gtk-source-vim-normal.c b/gtksourceview/vim/gtk-source-vim-normal.c
index 42bd6871..ec6a1b91 100644
--- a/gtksourceview/vim/gtk-source-vim-normal.c
+++ b/gtksourceview/vim/gtk-source-vim-normal.c
@@ -49,14 +49,6 @@ static gboolean key_handler_initial (GtkSourceVimNormal *self,
 
 G_DEFINE_TYPE (GtkSourceVimNormal, gtk_source_vim_normal, GTK_SOURCE_TYPE_VIM_STATE)
 
-static inline gboolean
-is_escape (guint           keyval,
-          GdkModifierType mods)
-{
-       return keyval == GDK_KEY_Escape ||
-               (keyval == GDK_KEY_bracketleft && (mods & GDK_CONTROL_MASK) != 0);
-}
-
 static gboolean
 gtk_source_vim_normal_bail (GtkSourceVimNormal *self)
 {
@@ -77,7 +69,7 @@ key_handler_motion (GtkSourceVimNormal *self,
 {
        g_assert (GTK_SOURCE_IS_VIM_NORMAL (self));
 
-       return FALSE;
+       return TRUE;
 }
 
 static gboolean
@@ -123,7 +115,7 @@ key_handler_command (GtkSourceVimNormal *self,
                     GdkModifierType     mods,
                     const char         *string)
 {
-       g_autoptr(GtkSourceVimState) new_state = NULL;
+       GtkSourceVimState *new_state = NULL;
 
        g_assert (GTK_SOURCE_IS_VIM_NORMAL (self));
 
@@ -132,7 +124,7 @@ key_handler_command (GtkSourceVimNormal *self,
                case GDK_KEY_i:
                        new_state = gtk_source_vim_insert_new ();
                        gtk_source_vim_state_push (GTK_SOURCE_VIM_STATE (self), new_state);
-                       break;
+                       return TRUE;
 
                case GDK_KEY_a:
                case GDK_KEY_asciitilde:
@@ -160,7 +152,7 @@ key_handler_command (GtkSourceVimNormal *self,
                        return gtk_source_vim_normal_bail (self);
        }
 
-       return FALSE;
+       return TRUE;
 }
 
 static gboolean
@@ -172,7 +164,7 @@ key_handler_viewport (GtkSourceVimNormal *self,
 {
        g_assert (GTK_SOURCE_IS_VIM_NORMAL (self));
 
-       return FALSE;
+       return TRUE;
 }
 
 static gboolean
@@ -184,7 +176,7 @@ key_handler_change (GtkSourceVimNormal *self,
 {
        g_assert (GTK_SOURCE_IS_VIM_NORMAL (self));
 
-       return FALSE;
+       return TRUE;
 }
 
 static gboolean
@@ -196,7 +188,7 @@ key_handler_shift (GtkSourceVimNormal *self,
 {
        g_assert (GTK_SOURCE_IS_VIM_NORMAL (self));
 
-       return FALSE;
+       return TRUE;
 }
 
 static gboolean
@@ -208,7 +200,7 @@ key_handler_replace_one (GtkSourceVimNormal *self,
 {
        g_assert (GTK_SOURCE_IS_VIM_NORMAL (self));
 
-       return FALSE;
+       return TRUE;
 }
 
 static gboolean
@@ -220,7 +212,7 @@ key_handler_search_word (GtkSourceVimNormal *self,
 {
        g_assert (GTK_SOURCE_IS_VIM_NORMAL (self));
 
-       return FALSE;
+       return TRUE;
 }
 
 static gboolean
@@ -232,7 +224,7 @@ key_handler_search (GtkSourceVimNormal *self,
 {
        g_assert (GTK_SOURCE_IS_VIM_NORMAL (self));
 
-       return FALSE;
+       return TRUE;
 }
 
 static gboolean
@@ -244,7 +236,7 @@ key_handler_command_bar (GtkSourceVimNormal *self,
 {
        g_assert (GTK_SOURCE_IS_VIM_NORMAL (self));
 
-       return FALSE;
+       return TRUE;
 }
 
 static gboolean
@@ -256,7 +248,7 @@ key_handler_yank (GtkSourceVimNormal *self,
 {
        g_assert (GTK_SOURCE_IS_VIM_NORMAL (self));
 
-       return FALSE;
+       return TRUE;
 }
 
 static gboolean
@@ -268,7 +260,7 @@ key_handler_delete (GtkSourceVimNormal *self,
 {
        g_assert (GTK_SOURCE_IS_VIM_NORMAL (self));
 
-       return FALSE;
+       return TRUE;
 }
 
 static gboolean
@@ -280,7 +272,7 @@ key_handler_split (GtkSourceVimNormal *self,
 {
        g_assert (GTK_SOURCE_IS_VIM_NORMAL (self));
 
-       return FALSE;
+       return TRUE;
 }
 
 static gboolean
@@ -292,7 +284,7 @@ key_handler_visual (GtkSourceVimNormal *self,
 {
        g_assert (GTK_SOURCE_IS_VIM_NORMAL (self));
 
-       return FALSE;
+       return TRUE;
 }
 
 static gboolean
@@ -304,7 +296,7 @@ key_handler_increment (GtkSourceVimNormal *self,
 {
        g_assert (GTK_SOURCE_IS_VIM_NORMAL (self));
 
-       return FALSE;
+       return TRUE;
 }
 
 static gboolean
@@ -316,7 +308,7 @@ key_handler_g (GtkSourceVimNormal *self,
 {
        g_assert (GTK_SOURCE_IS_VIM_NORMAL (self));
 
-       return FALSE;
+       return TRUE;
 }
 
 static gboolean
@@ -498,7 +490,7 @@ gtk_source_vim_normal_handle_keypress (GtkSourceVimState *state,
 
        g_assert (GTK_SOURCE_IS_VIM_STATE (self));
 
-       if (is_escape (keyval, mods))
+       if (gtk_source_vim_state_is_escape (keyval, mods))
        {
                gtk_source_vim_normal_clear (self);
                return TRUE;
@@ -538,12 +530,13 @@ gtk_source_vim_normal_class_init (GtkSourceVimNormalClass *klass)
 static void
 gtk_source_vim_normal_init (GtkSourceVimNormal *self)
 {
+       self->handler = key_handler_initial;
 }
 
-GtkSourceVimNormal *
+GtkSourceVimState *
 gtk_source_vim_normal_new (void)
 {
-       return g_object_new (GTK_SOURCE_TYPE_VIM_STATE, NULL);
+       return g_object_new (GTK_SOURCE_TYPE_VIM_NORMAL, NULL);
 }
 
 void
diff --git a/gtksourceview/vim/gtk-source-vim-normal.h b/gtksourceview/vim/gtk-source-vim-normal.h
index 7ff91c18..5b73798c 100644
--- a/gtksourceview/vim/gtk-source-vim-normal.h
+++ b/gtksourceview/vim/gtk-source-vim-normal.h
@@ -29,7 +29,7 @@ G_BEGIN_DECLS
 
 G_DECLARE_FINAL_TYPE (GtkSourceVimNormal, gtk_source_vim_normal, GTK_SOURCE, VIM_NORMAL, GtkSourceVimState)
 
-GtkSourceVimNormal *gtk_source_vim_normal_new   (void);
-void                gtk_source_vim_normal_clear (GtkSourceVimNormal *self);
+GtkSourceVimState *gtk_source_vim_normal_new   (void);
+void               gtk_source_vim_normal_clear (GtkSourceVimNormal *self);
 
 G_END_DECLS
diff --git a/gtksourceview/vim/gtk-source-vim-state.c b/gtksourceview/vim/gtk-source-vim-state.c
index 378988cc..8b3561fa 100644
--- a/gtksourceview/vim/gtk-source-vim-state.c
+++ b/gtksourceview/vim/gtk-source-vim-state.c
@@ -92,11 +92,6 @@ static gboolean
 gtk_source_vim_state_real_handle_event (GtkSourceVimState *self,
                                         GdkEvent          *event)
 {
-       guint keyval;
-       guint keycode;
-       GdkModifierType mods;
-       char string[16];
-
        g_assert (GTK_SOURCE_IS_VIM_STATE (self));
        g_assert (event != NULL);
 
@@ -105,17 +100,22 @@ gtk_source_vim_state_real_handle_event (GtkSourceVimState *self,
                return FALSE;
        }
 
-       if (GTK_SOURCE_VIM_STATE_GET_CLASS (self)->handle_keypress == NULL)
+       if (GTK_SOURCE_VIM_STATE_GET_CLASS (self)->handle_keypress != NULL)
        {
-               return FALSE;
-       }
+               guint keyval;
+               guint keycode;
+               GdkModifierType mods;
+               char string[16];
 
-       keyval = gdk_key_event_get_keyval (event);
-       keycode = gdk_key_event_get_keycode (event);
-       mods = gdk_key_event_get_consumed_modifiers (event);
-       keyval_to_string (keyval, mods, string);
+               keyval = gdk_key_event_get_keyval (event);
+               keycode = gdk_key_event_get_keycode (event);
+               mods = gdk_key_event_get_consumed_modifiers (event);
+               keyval_to_string (keyval, mods, string);
 
-       return GTK_SOURCE_VIM_STATE_GET_CLASS (self)->handle_keypress (self, keyval, keycode, mods, string);
+               return GTK_SOURCE_VIM_STATE_GET_CLASS (self)->handle_keypress (self, keyval, keycode, mods, 
string);
+       }
+
+       return FALSE;
 }
 
 static void
@@ -414,21 +414,23 @@ void
 gtk_source_vim_state_pop (GtkSourceVimState *self)
 {
        GtkSourceVimStatePrivate *priv = gtk_source_vim_state_get_instance_private (self);
-       g_autoptr(GtkSourceVimState) child = NULL;
+       g_autoptr(GtkSourceVimState) parent = NULL;
 
        g_return_if_fail (GTK_SOURCE_IS_VIM_STATE (self));
-       g_return_if_fail (GTK_SOURCE_IS_VIM_STATE (priv->child));
+       g_return_if_fail (priv->child == NULL);
+       g_return_if_fail (GTK_SOURCE_IS_VIM_STATE (priv->parent));
 
-       g_set_object (&child, priv->child);
-       priv->child = NULL;
+       parent = g_object_ref (priv->parent);
 
-       if (GTK_SOURCE_VIM_STATE_GET_CLASS (child)->leave)
+       if (GTK_SOURCE_VIM_STATE_GET_CLASS (self)->leave)
        {
-               GTK_SOURCE_VIM_STATE_GET_CLASS (self)->leave (child);
+               GTK_SOURCE_VIM_STATE_GET_CLASS (self)->leave (self);
        }
 
-       if (GTK_SOURCE_VIM_STATE_GET_CLASS (self)->restore)
+       if (GTK_SOURCE_VIM_STATE_GET_CLASS (parent)->restore)
        {
-               GTK_SOURCE_VIM_STATE_GET_CLASS (self)->restore (self, child);
+               GTK_SOURCE_VIM_STATE_GET_CLASS (parent)->restore (parent, self);
        }
+
+       g_object_unref (self);
 }
diff --git a/gtksourceview/vim/gtk-source-vim-state.h b/gtksourceview/vim/gtk-source-vim-state.h
index 84f8efeb..60146ec4 100644
--- a/gtksourceview/vim/gtk-source-vim-state.h
+++ b/gtksourceview/vim/gtk-source-vim-state.h
@@ -71,4 +71,12 @@ gboolean           gtk_source_vim_state_get_can_repeat (GtkSourceVimState *self)
 void               gtk_source_vim_state_repeat         (GtkSourceVimState *self,
                                                         int                repeat);
 
+static inline gboolean
+gtk_source_vim_state_is_escape (guint           keyval,
+                                GdkModifierType mods)
+{
+       return keyval == GDK_KEY_Escape ||
+              (keyval == GDK_KEY_bracketleft && (mods & GDK_CONTROL_MASK) != 0);
+}
+
 G_END_DECLS
diff --git a/gtksourceview/vim/gtk-source-vim.c b/gtksourceview/vim/gtk-source-vim.c
index fff5d177..1ec87368 100644
--- a/gtksourceview/vim/gtk-source-vim.c
+++ b/gtksourceview/vim/gtk-source-vim.c
@@ -78,13 +78,10 @@ static void
 gtk_source_vim_constructed (GObject *object)
 {
        GtkSourceVim *self = (GtkSourceVim *)object;
-       g_autoptr(GtkSourceVimNormal) normal = NULL;
 
        G_OBJECT_CLASS (gtk_source_vim_parent_class)->constructed (object);
 
-       normal = gtk_source_vim_normal_new ();
-       gtk_source_vim_state_push (GTK_SOURCE_VIM_STATE (self),
-                                  GTK_SOURCE_VIM_STATE (normal));
+       gtk_source_vim_state_push (GTK_SOURCE_VIM_STATE (self), gtk_source_vim_normal_new ());
 }
 
 static void
@@ -180,7 +177,7 @@ gtk_source_vim_get_command_text (GtkSourceVim *self)
                /* TODO */
        }
 
-       return NULL;
+       return "";
 }
 
 const char *
@@ -197,7 +194,7 @@ gtk_source_vim_get_command_bar_text (GtkSourceVim *self)
                /* TODO */
        }
 
-       return NULL;
+       return "";
 }
 
 void
diff --git a/tests/test-vim.c b/tests/test-vim.c
index fd078e10..88269c1c 100644
--- a/tests/test-vim.c
+++ b/tests/test-vim.c
@@ -68,19 +68,18 @@ main (int argc,
                             "top-margin", 6,
                             "left-margin", 6,
                             NULL);
-       command_bar = g_object_new (GTK_TYPE_TEXT,
+       command_bar = g_object_new (GTK_TYPE_LABEL,
                                    "xalign", 0.0f,
-                                   "margin-top", 6,
-                                   "margin-bottom", 6,
+                                   "margin-top", 6,
+                                   "margin-bottom", 6,
                                    NULL);
 
        gtk_window_set_child (window, GTK_WIDGET (scroller));
        gtk_scrolled_window_set_child (scroller, GTK_WIDGET (view));
        gtk_text_view_set_gutter (GTK_TEXT_VIEW (view), GTK_TEXT_WINDOW_BOTTOM, GTK_WIDGET (command_bar));
-       gtk_editable_set_editable (GTK_EDITABLE (command_bar), FALSE);
 
        im_context = gtk_source_vim_im_context_new ();
-       g_object_bind_property (im_context, "command-text", command_bar, "text", G_BINDING_SYNC_CREATE);
+       g_object_bind_property (im_context, "command-bar-text", command_bar, "label", G_BINDING_SYNC_CREATE);
        gtk_im_context_set_client_widget (im_context, GTK_WIDGET (view));
 
        key = gtk_event_controller_key_new ();


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