[gtksourceview/wip/chergert/vim] improve yank/paste
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtksourceview/wip/chergert/vim] improve yank/paste
- Date: Fri, 29 Oct 2021 22:50:20 +0000 (UTC)
commit 882296207062b2a12921fdf0c1e09216e6e08380
Author: Christian Hergert <chergert redhat com>
Date: Fri Oct 29 15:50:12 2021 -0700
improve yank/paste
use internal command name for paste
gtksourceview/vim/gtk-source-vim-command.c | 124 ++++++++++++++++++++++++-----
gtksourceview/vim/gtk-source-vim-normal.c | 5 +-
2 files changed, 110 insertions(+), 19 deletions(-)
---
diff --git a/gtksourceview/vim/gtk-source-vim-command.c b/gtksourceview/vim/gtk-source-vim-command.c
index 134b9f1e..bf7c9f75 100644
--- a/gtksourceview/vim/gtk-source-vim-command.c
+++ b/gtksourceview/vim/gtk-source-vim-command.c
@@ -21,18 +21,24 @@
#include "config.h"
+#include <string.h>
+
#include "gtksourcebuffer.h"
#include "gtk-source-vim-command.h"
+#include "gtk-source-vim-registers.h"
typedef void (*Command) (GtkSourceVimCommand *self);
struct _GtkSourceVimCommand
{
GtkSourceVimState parent_instance;
+
GtkSourceVimMotion *motion;
GtkSourceVimMotion *selection_motion;
char *command;
+
+ guint ignore_mark : 1;
};
G_DEFINE_TYPE (GtkSourceVimCommand, gtk_source_vim_command, GTK_SOURCE_TYPE_VIM_STATE)
@@ -76,20 +82,90 @@ gtk_source_vim_command_join (GtkSourceVimCommand *self)
gtk_text_buffer_end_user_action (GTK_TEXT_BUFFER (buffer));
gtk_source_vim_state_set_can_repeat (GTK_SOURCE_VIM_STATE (self), TRUE);
+
+ self->ignore_mark = TRUE;
}
static void
gtk_source_vim_command_yank (GtkSourceVimCommand *self)
{
+ GtkSourceVimState *registers;
+ GtkTextIter iter;
+ GtkTextIter selection;
+ gboolean needs_newline = FALSE;
+ char *text;
+
+ gtk_source_vim_state_get_buffer (GTK_SOURCE_VIM_STATE (self), &iter, &selection);
+
+ /* Swallow the \n too if we can for line-wise copy */
+ gtk_text_iter_order (&selection, &iter);
+
+ if (gtk_text_iter_ends_line (&iter))
+ gtk_text_iter_forward_char (&iter);
+
+ if (gtk_text_iter_is_end (&iter))
+ needs_newline = TRUE;
+
+ text = gtk_text_iter_get_slice (&iter, &selection);
+ registers = gtk_source_vim_state_get_registers (GTK_SOURCE_VIM_STATE (self));
+
+ if (needs_newline)
+ gtk_source_vim_registers_take (GTK_SOURCE_VIM_REGISTERS (registers),
+ NULL,
+ g_strdup_printf ("%s\n", text));
+ else
+ gtk_source_vim_registers_take (GTK_SOURCE_VIM_REGISTERS (registers),
+ NULL,
+ g_steal_pointer (&text));
+
+ g_free (text);
+}
+
+static void
+gtk_source_vim_command_paste_after (GtkSourceVimCommand *self)
+{
+ GtkSourceVimState *registers;
GtkSourceBuffer *buffer;
- GtkSourceView *view;
- GdkClipboard *clipboard;
+ GtkTextIter iter;
+ GtkTextIter selection;
+ const char *text;
+ int count;
- buffer = gtk_source_vim_state_get_buffer (GTK_SOURCE_VIM_STATE (self), NULL, NULL);
- view = gtk_source_vim_state_get_view (GTK_SOURCE_VIM_STATE (self));
- clipboard = gtk_widget_get_primary_clipboard (GTK_WIDGET (view));
+ buffer = gtk_source_vim_state_get_buffer (GTK_SOURCE_VIM_STATE (self), &iter, &selection);
+ registers = gtk_source_vim_state_get_registers (GTK_SOURCE_VIM_STATE (self));
+ text = gtk_source_vim_registers_get (GTK_SOURCE_VIM_REGISTERS (registers), NULL);
+ count = gtk_source_vim_state_get_count (GTK_SOURCE_VIM_STATE (self));
- gtk_text_buffer_copy_clipboard (GTK_TEXT_BUFFER (buffer), clipboard);
+ if (text == NULL)
+ {
+ return;
+ }
+
+ gtk_text_iter_order (&selection, &iter);
+
+ gtk_source_vim_state_begin_user_action (GTK_SOURCE_VIM_STATE (self));
+
+ /* If there is a \n, this is a linewise paste */
+ if (g_str_has_suffix (text, "\n"))
+ {
+ 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);
+ gtk_text_buffer_insert (GTK_TEXT_BUFFER (buffer), &iter, text, strlen (text) - 1);
+ } while (--count > 0);
+ }
+ else
+ {
+ do
+ {
+ gtk_text_buffer_insert (GTK_TEXT_BUFFER (buffer), &iter, text, -1);
+ } while (--count > 0);
+ }
+
+ gtk_source_vim_state_end_user_action (GTK_SOURCE_VIM_STATE (self));
}
static void
@@ -140,19 +216,22 @@ static void
gtk_source_vim_command_repeat (GtkSourceVimState *state)
{
GtkSourceVimCommand *self = (GtkSourceVimCommand *)state;
+ GtkSourceBuffer *buffer;
Command command;
GtkTextIter iter;
GtkTextIter selection;
+ GtkTextMark *mark;
g_assert (GTK_SOURCE_IS_VIM_COMMAND (self));
- if (self->command == NULL)
- return;
-
- if (!(command = g_hash_table_lookup (commands, self->command)))
+ if (self->command == NULL ||
+ !(command = g_hash_table_lookup (commands, self->command)))
+ {
return;
+ }
- gtk_source_vim_state_get_buffer (state, &iter, &selection);
+ buffer = gtk_source_vim_state_get_buffer (state, &iter, &selection);
+ mark = gtk_text_buffer_create_mark (GTK_TEXT_BUFFER (buffer), NULL, &iter, TRUE);
if (self->motion)
{
@@ -167,6 +246,14 @@ gtk_source_vim_command_repeat (GtkSourceVimState *state)
gtk_source_vim_state_select (state, &iter, &selection);
command (self);
+
+ if (!self->ignore_mark)
+ {
+ gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (buffer), &iter, mark);
+ gtk_text_buffer_select_range (GTK_TEXT_BUFFER (buffer), &iter, &iter);
+ }
+
+ gtk_text_buffer_delete_mark (GTK_TEXT_BUFFER (buffer), mark);
}
static void
@@ -292,13 +379,14 @@ gtk_source_vim_command_class_init (GtkSourceVimCommandClass *klass)
#define ADD_COMMAND(name, func) \
g_hash_table_insert(commands, (char*)name, (gpointer)func)
- ADD_COMMAND (":join", gtk_source_vim_command_join);
- ADD_COMMAND (":j", gtk_source_vim_command_join);
- ADD_COMMAND (":undo", gtk_source_vim_command_undo);
- ADD_COMMAND (":u", gtk_source_vim_command_undo);
- ADD_COMMAND (":redo", gtk_source_vim_command_redo);
- ADD_COMMAND (":yank", gtk_source_vim_command_yank);
- ADD_COMMAND (":y", gtk_source_vim_command_yank);
+ ADD_COMMAND (":join", gtk_source_vim_command_join);
+ ADD_COMMAND (":j", gtk_source_vim_command_join);
+ ADD_COMMAND (":undo", gtk_source_vim_command_undo);
+ ADD_COMMAND (":u", gtk_source_vim_command_undo);
+ ADD_COMMAND (":redo", gtk_source_vim_command_redo);
+ ADD_COMMAND (":yank", gtk_source_vim_command_yank);
+ ADD_COMMAND (":y", gtk_source_vim_command_yank);
+ ADD_COMMAND (":_paste_after", gtk_source_vim_command_paste_after);
#undef ADD_COMMAND
}
diff --git a/gtksourceview/vim/gtk-source-vim-normal.c b/gtksourceview/vim/gtk-source-vim-normal.c
index 3547aad3..18133c34 100644
--- a/gtksourceview/vim/gtk-source-vim-normal.c
+++ b/gtksourceview/vim/gtk-source-vim-normal.c
@@ -416,8 +416,11 @@ key_handler_command (GtkSourceVimNormal *self,
":yank");
return TRUE;
- case GDK_KEY_asciitilde:
case GDK_KEY_p:
+ gtk_source_vim_normal_begin_command (self, NULL, NULL, ":_paste_after");
+ return TRUE;
+
+ case GDK_KEY_asciitilde:
case GDK_KEY_P:
case GDK_KEY_equal:
case GDK_KEY_plus:
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]