[gtksourceview/wip/chergert/vim: 167/293] improve yank and offset positioning + direction




commit 08995f9a03e4b263e1f6851ccdb6c1d9bc70c88a
Author: Christian Hergert <chergert redhat com>
Date:   Fri Oct 29 17:23:02 2021 -0700

    improve yank and offset positioning + direction

 gtksourceview/vim/gtk-source-vim-command.c | 54 ++++++++++++++++++++++++++++--
 1 file changed, 52 insertions(+), 2 deletions(-)
---
diff --git a/gtksourceview/vim/gtk-source-vim-command.c b/gtksourceview/vim/gtk-source-vim-command.c
index 4ea9c6c0..0c01c22e 100644
--- a/gtksourceview/vim/gtk-source-vim-command.c
+++ b/gtksourceview/vim/gtk-source-vim-command.c
@@ -54,6 +54,30 @@ enum {
 static GParamSpec *properties[N_PROPS];
 static GHashTable *commands;
 
+static void
+extend_lines (GtkTextIter *a,
+              GtkTextIter *b)
+{
+       if (gtk_text_iter_equal (a, b))
+       {
+               gtk_text_iter_set_line_offset (a, 0);
+               if (!gtk_text_iter_ends_line (b))
+                       gtk_text_iter_forward_to_line_end (b);
+       }
+       else if (gtk_text_iter_compare (a, b) < 0)
+       {
+               gtk_text_iter_set_line_offset (a, 0);
+               if (!gtk_text_iter_ends_line (b))
+                       gtk_text_iter_forward_to_line_end (b);
+       }
+       else
+       {
+               gtk_text_iter_set_line_offset (b, 0);
+               if (!gtk_text_iter_ends_line (a))
+                       gtk_text_iter_forward_to_line_end (a);
+       }
+}
+
 static void
 gtk_source_vim_command_join (GtkSourceVimCommand *self)
 {
@@ -97,7 +121,12 @@ gtk_source_vim_command_yank (GtkSourceVimCommand *self)
 
        gtk_source_vim_state_get_buffer (GTK_SOURCE_VIM_STATE (self), &iter, &selection);
 
-       /* Swallow the \n too if we can for line-wise copy */
+       /* if linewise, then extend to whole lines */
+       if (gtk_text_iter_get_line (&iter) != gtk_text_iter_get_line (&selection))
+       {
+               extend_lines (&iter, &selection);
+       }
+
        gtk_text_iter_order (&selection, &iter);
 
        if (gtk_text_iter_ends_line (&iter))
@@ -148,14 +177,26 @@ gtk_source_vim_command_paste_after (GtkSourceVimCommand *self)
        /* If there is a \n, this is a linewise paste */
        if (g_str_has_suffix (text, "\n"))
        {
+               int offset = -1;
+
                do
                {
                        if (!gtk_text_iter_ends_line (&iter))
                                gtk_text_iter_forward_to_line_end (&iter);
 
                        gtk_text_buffer_insert (GTK_TEXT_BUFFER (buffer), &iter, "\n", -1);
+
+                       /* Save to place cursor later */
+                       if (offset == -1)
+                               offset = gtk_text_iter_get_offset (&iter);
+
                        gtk_text_buffer_insert (GTK_TEXT_BUFFER (buffer), &iter, text, strlen (text) - 1);
                } while (--count > 0);
+
+               /* try to place cursor in same position as vim */
+               gtk_text_buffer_get_iter_at_offset (GTK_TEXT_BUFFER (buffer), &iter, offset);
+               gtk_source_vim_state_select (GTK_SOURCE_VIM_STATE (self), &iter, &iter);
+               self->ignore_mark = TRUE;
        }
        else
        {
@@ -197,11 +238,20 @@ gtk_source_vim_command_paste_before (GtkSourceVimCommand *self)
        /* If there is a \n, this is a linewise paste */
        if (g_str_has_suffix (text, "\n"))
        {
+               int offset;
+
+               gtk_text_iter_set_line_offset (&iter, 0);
+               offset = gtk_text_iter_get_offset (&iter);
+
                do
                {
-                       gtk_text_iter_set_line_offset (&iter, 0);
                        gtk_text_buffer_insert (GTK_TEXT_BUFFER (buffer), &iter, text, -1);
                } while (--count > 0);
+
+               /* try to place cursor in same position as vim */
+               gtk_text_buffer_get_iter_at_offset (GTK_TEXT_BUFFER (buffer), &iter, offset);
+               gtk_source_vim_state_select (GTK_SOURCE_VIM_STATE (self), &iter, &iter);
+               self->ignore_mark = TRUE;
        }
        else
        {


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