[gtksourceview/wip/chergert/vim: 45/363] handle gg ge and gE commands
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtksourceview/wip/chergert/vim: 45/363] handle gg ge and gE commands
- Date: Mon, 8 Nov 2021 19:53:45 +0000 (UTC)
commit c67074c9f3d53fcf3090aa375c09687720220716
Author: Christian Hergert <chergert redhat com>
Date: Sat Oct 23 12:23:40 2021 -0700
handle gg ge and gE commands
gtksourceview/vim/gtk-source-vim-motion.c | 84 +++++++++++++++++++++++++++++--
gtksourceview/vim/gtk-source-vim-normal.c | 22 ++++++--
gtksourceview/vim/gtk-source-vim-state.c | 13 +++++
gtksourceview/vim/gtk-source-vim-state.h | 3 ++
4 files changed, 114 insertions(+), 8 deletions(-)
---
diff --git a/gtksourceview/vim/gtk-source-vim-motion.c b/gtksourceview/vim/gtk-source-vim-motion.c
index 31040eff..ab5a33ce 100644
--- a/gtksourceview/vim/gtk-source-vim-motion.c
+++ b/gtksourceview/vim/gtk-source-vim-motion.c
@@ -31,10 +31,24 @@ typedef gboolean (*Motion) (GtkTextIter *iter,
struct _GtkSourceVimMotion
{
GtkSourceVimState parent_instance;
- Motion motion;
- int number;
- guint apply_on_leave : 1;
- guint failed : 1;
+
+ /* A function to apply the motion */
+ Motion motion;
+
+ /* A number for the motion like `3e`. */
+ int number;
+
+ /* Apply the motion when leaving the state. This is useful
+ * so that you can either capture a motion for future use
+ * or simply apply it immediately.
+ */
+ guint apply_on_leave : 1;
+
+ /* If the command starts with `g` such as `ge` or `gE`. */
+ guint g_command : 1;
+
+ /* If we called gtk_source_vim_motion_bail(). */
+ guint failed : 1;
};
G_DEFINE_TYPE (GtkSourceVimMotion, gtk_source_vim_motion, GTK_SOURCE_TYPE_VIM_STATE)
@@ -560,6 +574,37 @@ motion_backward_WORD_end (GtkTextIter *iter,
return backward_classified_end (iter, classify_WORD);
}
+static gboolean
+motion_buffer_start (GtkTextIter *iter,
+ GtkSourceView *view)
+{
+ if (!gtk_text_iter_is_start (iter))
+ {
+ gtk_text_iter_set_offset (iter, 0);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static gboolean
+motion_buffer_start_first_char (GtkTextIter *iter,
+ GtkSourceView *view)
+{
+ GtkTextIter before = *iter;
+
+ motion_buffer_start (iter, view);
+
+ while (!gtk_text_iter_ends_line (iter) &&
+ g_unichar_isspace (gtk_text_iter_get_char (iter)))
+ {
+ if (!gtk_text_iter_forward_char (iter))
+ break;
+ }
+
+ return !gtk_text_iter_equal (&before, iter);
+}
+
GtkSourceVimState *
gtk_source_vim_motion_new (void)
{
@@ -599,6 +644,26 @@ gtk_source_vim_motion_handle_keypress (GtkSourceVimState *state,
g_assert (GTK_SOURCE_IS_VIM_MOTION (self));
+ if (self->g_command)
+ {
+ switch (keyval)
+ {
+ case GDK_KEY_g:
+ return gtk_source_vim_motion_complete (self, motion_buffer_start_first_char);
+
+ case GDK_KEY_e:
+ return gtk_source_vim_motion_complete (self, motion_backward_word_end);
+
+ case GDK_KEY_E:
+ return gtk_source_vim_motion_complete (self, motion_backward_WORD_end);
+
+ default:
+ return gtk_source_vim_motion_bail (self);
+ }
+
+ g_assert_not_reached ();
+ }
+
if (self->number != 0)
{
if (keyval >= GDK_KEY_0 && keyval <= GDK_KEY_9)
@@ -669,6 +734,10 @@ gtk_source_vim_motion_handle_keypress (GtkSourceVimState *state,
case GDK_KEY_G:
return gtk_source_vim_motion_complete (self, motion_last_line_first_char);
+ case GDK_KEY_g:
+ self->g_command = TRUE;
+ return TRUE;
+
case GDK_KEY_H:
return gtk_source_vim_motion_complete (self, motion_screen_top);
@@ -724,6 +793,11 @@ gtk_source_vim_motion_repeat (GtkSourceVimState *state,
g_assert (GTK_SOURCE_IS_VIM_MOTION (self));
+ if (self->failed)
+ {
+ return;
+ }
+
buffer = gtk_source_vim_state_get_buffer (state, &insert, &selection);
has_selection = !gtk_text_iter_equal (&insert, &selection);
@@ -751,7 +825,9 @@ gtk_source_vim_motion_leave (GtkSourceVimState *state)
g_assert (GTK_SOURCE_IS_VIM_MOTION (self));
if (self->apply_on_leave)
+ {
gtk_source_vim_motion_repeat (state, 1);
+ }
}
static void
diff --git a/gtksourceview/vim/gtk-source-vim-normal.c b/gtksourceview/vim/gtk-source-vim-normal.c
index 97bb0740..c9362283 100644
--- a/gtksourceview/vim/gtk-source-vim-normal.c
+++ b/gtksourceview/vim/gtk-source-vim-normal.c
@@ -289,9 +289,24 @@ key_handler_g (GtkSourceVimNormal *self,
GdkModifierType mods,
const char *string)
{
+ GtkSourceVimState *new_state;
+
g_assert (GTK_SOURCE_IS_VIM_NORMAL (self));
- return TRUE;
+ switch (keyval)
+ {
+ case GDK_KEY_g:
+ case GDK_KEY_e:
+ case GDK_KEY_E:
+ new_state = gtk_source_vim_motion_new ();
+ gtk_source_vim_state_push (GTK_SOURCE_VIM_STATE (self), new_state);
+ gtk_source_vim_state_synthesize (new_state, GDK_KEY_g, 0);
+ gtk_source_vim_state_synthesize (new_state, keyval, mods);
+ return TRUE;
+
+ default:
+ return gtk_source_vim_normal_bail (self);
+ }
}
static gboolean
@@ -306,9 +321,8 @@ key_handler_motion (GtkSourceVimNormal *self,
g_assert (GTK_SOURCE_IS_VIM_NORMAL (self));
new_state = gtk_source_vim_motion_new ();
- gtk_source_vim_motion_set_apply_on_leave (GTK_SOURCE_VIM_MOTION (new_state), TRUE);
gtk_source_vim_state_push (GTK_SOURCE_VIM_STATE (self), new_state);
- GTK_SOURCE_VIM_STATE_GET_CLASS (new_state)->handle_keypress (new_state, keyval, keycode, mods,
string);
+ gtk_source_vim_state_synthesize (new_state, keyval, mods);
return TRUE;
}
@@ -471,7 +485,7 @@ key_handler_initial (GtkSourceVimNormal *self,
case GDK_KEY_g:
self->handler = key_handler_g;
- break;
+ return TRUE;
case GDK_KEY_z:
self->handler = key_handler_viewport;
diff --git a/gtksourceview/vim/gtk-source-vim-state.c b/gtksourceview/vim/gtk-source-vim-state.c
index 96db0d16..c4a122d9 100644
--- a/gtksourceview/vim/gtk-source-vim-state.c
+++ b/gtksourceview/vim/gtk-source-vim-state.c
@@ -459,3 +459,16 @@ gtk_source_vim_state_set_overwrite (GtkSourceVimState *self,
gtk_text_view_set_overwrite (GTK_TEXT_VIEW (priv->view), overwrite);
}
}
+
+gboolean
+gtk_source_vim_state_synthesize (GtkSourceVimState *self,
+ guint keyval,
+ GdkModifierType mods)
+{
+ char string[16];
+
+ g_return_val_if_fail (GTK_SOURCE_IS_VIM_STATE (self), FALSE);
+
+ keyval_to_string (keyval, mods, string);
+ return GTK_SOURCE_VIM_STATE_GET_CLASS (self)->handle_keypress (self, keyval, 0, mods, string);
+}
diff --git a/gtksourceview/vim/gtk-source-vim-state.h b/gtksourceview/vim/gtk-source-vim-state.h
index 206cf303..1d12802b 100644
--- a/gtksourceview/vim/gtk-source-vim-state.h
+++ b/gtksourceview/vim/gtk-source-vim-state.h
@@ -71,6 +71,9 @@ gboolean gtk_source_vim_state_handle_event (GtkSourceVimState *self,
void gtk_source_vim_state_set_overwrite (GtkSourceVimState *self,
gboolean overwrite);
gboolean gtk_source_vim_state_get_can_repeat (GtkSourceVimState *self);
+gboolean gtk_source_vim_state_synthesize (GtkSourceVimState *self,
+ guint keyval,
+ GdkModifierType mods);
void gtk_source_vim_state_repeat (GtkSourceVimState *self,
int repeat);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]