[gtksourceview/wip/chergert/vim] stash/restore cursor positions across visual command



commit bc02cb6c970996519d377db76e21df652ed408e9
Author: Christian Hergert <chergert redhat com>
Date:   Wed Nov 3 14:51:06 2021 -0700

    stash/restore cursor positions across visual command
    
    these appear to get applied differently based on whether the movement was
    up or down.

 gtksourceview/vim/gtk-source-vim-visual.c | 54 +++++++++++++++++++++++++++++++
 1 file changed, 54 insertions(+)
---
diff --git a/gtksourceview/vim/gtk-source-vim-visual.c b/gtksourceview/vim/gtk-source-vim-visual.c
index d358d3d7..9cbf124e 100644
--- a/gtksourceview/vim/gtk-source-vim-visual.c
+++ b/gtksourceview/vim/gtk-source-vim-visual.c
@@ -63,6 +63,15 @@ struct _GtkSourceVimVisual
        GtkTextMark *cursor;
 };
 
+typedef struct
+{
+       GtkTextBuffer *buffer;
+       int            cmp;
+       guint          line;
+       guint          line_offset;
+       guint          start_line;
+} CursorInfo;
+
 static gboolean gtk_source_vim_visual_bail (GtkSourceVimVisual *self);
 static gboolean key_handler_initial        (GtkSourceVimVisual *self,
                                             guint               keyval,
@@ -72,6 +81,45 @@ static gboolean key_handler_initial        (GtkSourceVimVisual *self,
 
 G_DEFINE_TYPE (GtkSourceVimVisual, gtk_source_vim_visual, GTK_SOURCE_TYPE_VIM_STATE)
 
+static void
+cursor_info_stash (GtkSourceVimVisual *self,
+                   CursorInfo         *info)
+{
+       GtkTextIter cursor;
+       GtkTextIter started_at;
+
+       g_assert (GTK_SOURCE_IS_VIM_VISUAL (self));
+
+       info->buffer = gtk_text_mark_get_buffer (self->cursor);
+
+       gtk_text_buffer_get_iter_at_mark (info->buffer, &cursor, self->cursor);
+       gtk_text_buffer_get_iter_at_mark (info->buffer, &started_at, self->started_at);
+
+       info->cmp = gtk_text_iter_compare (&cursor, &started_at);
+       info->line = gtk_text_iter_get_line (&cursor);
+       info->line_offset = gtk_text_iter_get_line_offset (&cursor);
+       info->start_line = MIN (gtk_text_iter_get_line (&started_at), info->line);
+}
+
+static void
+cursor_info_restore (CursorInfo *info)
+{
+       if (info->cmp > 0)
+       {
+               GtkTextIter iter;
+
+               gtk_text_buffer_get_iter_at_line (info->buffer, &iter, info->start_line);
+               gtk_text_buffer_select_range (info->buffer, &iter, &iter);
+       }
+       else
+       {
+               GtkTextIter iter;
+
+               gtk_text_buffer_get_iter_at_line_offset (info->buffer, &iter, info->line, info->line_offset);
+               gtk_text_buffer_select_range (info->buffer, &iter, &iter);
+       }
+}
+
 static void
 track_visible_column (GtkSourceVimVisual *self)
 {
@@ -287,12 +335,16 @@ static gboolean
 gtk_source_vim_visual_begin_command (GtkSourceVimVisual *self,
                                      const char         *command)
 {
+       CursorInfo info;
+
        g_assert (GTK_SOURCE_IS_VIM_VISUAL (self));
        g_assert (command != NULL);
 
        gtk_source_vim_visual_clear (self);
        g_clear_object (&self->command);
 
+       cursor_info_stash (self, &info);
+
        self->command = gtk_source_vim_command_new (command);
        gtk_source_vim_state_set_parent (self->command, GTK_SOURCE_VIM_STATE (self));
        gtk_source_vim_state_repeat (self->command);
@@ -302,6 +354,8 @@ gtk_source_vim_visual_begin_command (GtkSourceVimVisual *self,
                gtk_source_vim_state_set_can_repeat (GTK_SOURCE_VIM_STATE (self), TRUE);
        }
 
+       cursor_info_restore (&info);
+
        gtk_source_vim_state_pop (GTK_SOURCE_VIM_STATE (self));
 
        return TRUE;


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