[gtksourceview] vim: add helper to ignore command leaving visual



commit 6383293a77aef0705f04d541713375257e88094e
Author: Christian Hergert <chergert redhat com>
Date:   Fri Nov 12 16:15:16 2021 -0800

    vim: add helper to ignore command leaving visual
    
    Sometimes a command shouldn't cause us to leave visual mode (such as
    searching to a position with / or ?).

 gtksourceview/vim/gtksourcevimstate.h  | 19 +++++++++++++++----
 gtksourceview/vim/gtksourcevimvisual.c | 18 ++++++++++++++++--
 gtksourceview/vim/gtksourcevimvisual.h | 21 ++++++++++++++-------
 3 files changed, 45 insertions(+), 13 deletions(-)
---
diff --git a/gtksourceview/vim/gtksourcevimstate.h b/gtksourceview/vim/gtksourcevimstate.h
index d8bf8405..ee1dd94f 100644
--- a/gtksourceview/vim/gtksourcevimstate.h
+++ b/gtksourceview/vim/gtksourcevimstate.h
@@ -127,11 +127,11 @@ void               gtk_source_vim_state_set_reverse_search         (GtkSourceVim
 GtkTextMark       *gtk_source_vim_state_get_mark                   (GtkSourceVimState        *self,
                                                                     const char               *name);
 void               gtk_source_vim_state_set_mark                   (GtkSourceVimState        *self,
-                                                                   const char               *name,
-                                                                   const GtkTextIter        *iter);
+                                                                    const char               *name,
+                                                                    const GtkTextIter        *iter);
 gboolean           gtk_source_vim_state_get_iter_at_mark           (GtkSourceVimState        *self,
-                                                                   const char               *name,
-                                                                   GtkTextIter              *iter);
+                                                                    const char               *name,
+                                                                    GtkTextIter              *iter);
 void               gtk_source_vim_state_keyval_to_string           (guint                     keyval,
                                                                     GdkModifierType           mods,
                                                                     char                      string[16]);
@@ -196,4 +196,15 @@ gtk_source_vim_state_is_ctrl_c (guint           keyval,
        return keyval == GDK_KEY_c && (mods & GDK_CONTROL_MASK) != 0;
 }
 
+static inline GtkSourceVimState *
+gtk_source_vim_state_get_ancestor (GtkSourceVimState *state,
+                                   GType              type)
+{
+  if (state == NULL)
+    return NULL;
+  if (G_TYPE_CHECK_INSTANCE_TYPE (state, type))
+    return state;
+  return gtk_source_vim_state_get_ancestor (gtk_source_vim_state_get_parent (state), type);
+}
+
 G_END_DECLS
diff --git a/gtksourceview/vim/gtksourcevimvisual.c b/gtksourceview/vim/gtksourcevimvisual.c
index fc2cac4b..0850351e 100644
--- a/gtksourceview/vim/gtksourcevimvisual.c
+++ b/gtksourceview/vim/gtksourcevimvisual.c
@@ -63,6 +63,8 @@ struct _GtkSourceVimVisual
        GtkTextMark *cursor;
 
        int count;
+
+       guint ignore_command : 1;
 };
 
 typedef struct
@@ -713,14 +715,18 @@ gtk_source_vim_visual_resume (GtkSourceVimState *state,
        {
                GtkSourceVimState *command = gtk_source_vim_command_bar_take_command 
(GTK_SOURCE_VIM_COMMAND_BAR (from));
 
-               if (command != NULL)
+               if (command != NULL && !self->ignore_command)
                {
                        gtk_source_vim_state_reparent (command, self, &self->command);
                        g_object_unref (command);
                }
 
                gtk_source_vim_state_unparent (from);
-               gtk_source_vim_state_pop (state);
+
+               if (self->ignore_command)
+                       self->ignore_command = FALSE;
+               else
+                       gtk_source_vim_state_pop (state);
        }
        else if (from == self->command)
        {
@@ -932,3 +938,11 @@ gtk_source_vim_visual_clone (GtkSourceVimVisual *self)
 
        return ret;
 }
+
+void
+gtk_source_vim_visual_ignore_command (GtkSourceVimVisual *self)
+{
+       g_return_if_fail (GTK_SOURCE_IS_VIM_VISUAL (self));
+
+       self->ignore_command = TRUE;
+}
diff --git a/gtksourceview/vim/gtksourcevimvisual.h b/gtksourceview/vim/gtksourcevimvisual.h
index d7b5a5f8..2167b596 100644
--- a/gtksourceview/vim/gtksourcevimvisual.h
+++ b/gtksourceview/vim/gtksourcevimvisual.h
@@ -36,12 +36,19 @@ typedef enum
 
 G_DECLARE_FINAL_TYPE (GtkSourceVimVisual, gtk_source_vim_visual, GTK_SOURCE, VIM_VISUAL, GtkSourceVimState)
 
-GtkSourceVimState *gtk_source_vim_visual_new        (GtkSourceVimVisualMode  mode);
-GtkSourceVimState *gtk_source_vim_visual_clone      (GtkSourceVimVisual     *self);
-gboolean           gtk_source_vim_visual_get_bounds (GtkSourceVimVisual     *self,
-                                                     GtkTextIter            *cursor,
-                                                     GtkTextIter            *started_at);
-void               gtk_source_vim_visual_warp       (GtkSourceVimVisual     *self,
-                                                     const GtkTextIter      *iter);
+GtkSourceVimState *gtk_source_vim_visual_new            (GtkSourceVimVisualMode  mode);
+GtkSourceVimState *gtk_source_vim_visual_clone          (GtkSourceVimVisual     *self);
+gboolean           gtk_source_vim_visual_get_bounds     (GtkSourceVimVisual     *self,
+                                                         GtkTextIter            *cursor,
+                                                         GtkTextIter            *started_at);
+void               gtk_source_vim_visual_warp           (GtkSourceVimVisual     *self,
+                                                         const GtkTextIter      *iter);
+void               gtk_source_vim_visual_ignore_command (GtkSourceVimVisual     *self);
+
+static inline gboolean
+GTK_SOURCE_IN_VIM_VISUAL (gpointer data)
+{
+       return gtk_source_vim_state_get_ancestor (data, GTK_SOURCE_TYPE_VIM_VISUAL) != NULL;
+}
 
 G_END_DECLS


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