summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMateus Melchiades <matbme@duck.com>2023-03-23 21:07:22 -0300
committerChristian Hergert <chergert@redhat.com>2023-05-17 12:45:45 -0700
commit6af4d3a37e5d533cee9545ee326356413e65a627 (patch)
tree158164edb27b662c5c090a37bee053660e94af59
parent091c2b6ba369909e128ae63ea21987ea1951c977 (diff)
downloadgtksourceview-6af4d3a37e5d533cee9545ee326356413e65a627.tar.gz
vim: Visual replace text
This commit makes Vim emulation replicate the behavior of "putting" text while in visual mode. When the user presses "p" with a selected range the range's content will now be replaced by the contents of the current register. Furthermore, this commit also adds the same feature for the system clipboard by using "Ctrl + Shift + v", similar to what is present in insert mode.
-rw-r--r--gtksourceview/vim/gtksourcevimvisual.c61
1 files changed, 61 insertions, 0 deletions
diff --git a/gtksourceview/vim/gtksourcevimvisual.c b/gtksourceview/vim/gtksourcevimvisual.c
index a6f81050..bfbe99b8 100644
--- a/gtksourceview/vim/gtksourcevimvisual.c
+++ b/gtksourceview/vim/gtksourcevimvisual.c
@@ -32,6 +32,7 @@
#include "gtksourcevimmotion.h"
#include "gtksourcevimreplace.h"
#include "gtksourcevimvisual.h"
+#include "gtksourcevimregisters.h"
typedef gboolean (*KeyHandler) (GtkSourceVimVisual *self,
guint keyval,
@@ -449,6 +450,48 @@ gtk_source_vim_visual_begin_insert (GtkSourceVimVisual *self)
}
static gboolean
+gtk_source_vim_visual_put (GtkSourceVimVisual *self,
+ gboolean clipboard)
+{
+ GtkSourceVimRegisters *registers;
+ GtkSourceBuffer *buffer;
+ const char *replace_content;
+ const char *selection_content;
+ GtkTextIter start;
+ GtkTextIter end;
+
+ g_assert (GTK_SOURCE_IS_VIM_VISUAL (self));
+
+ buffer = gtk_source_vim_state_get_buffer (GTK_SOURCE_VIM_STATE (self), NULL, NULL);
+
+ if (clipboard)
+ {
+ registers = GTK_SOURCE_VIM_REGISTERS (gtk_source_vim_state_get_registers (GTK_SOURCE_VIM_STATE (self)));
+ replace_content = gtk_source_vim_registers_get (registers, "+");
+ }
+ else
+ {
+ replace_content = gtk_source_vim_state_get_current_register_value (GTK_SOURCE_VIM_STATE (self));
+ }
+
+ gtk_source_vim_visual_get_bounds (self, &start, &end);
+ gtk_text_iter_forward_char (&start);
+ selection_content = gtk_text_buffer_get_text (GTK_TEXT_BUFFER (buffer), &start, &end, FALSE);
+
+ gtk_text_buffer_begin_user_action (GTK_TEXT_BUFFER (buffer));
+ gtk_text_buffer_delete_selection (GTK_TEXT_BUFFER (buffer), TRUE, TRUE);
+ gtk_text_buffer_insert_at_cursor (GTK_TEXT_BUFFER (buffer), replace_content, strlen (replace_content));
+ gtk_source_vim_state_set_current_register_value (GTK_SOURCE_VIM_STATE (self), selection_content);
+ gtk_text_buffer_end_user_action (GTK_TEXT_BUFFER (buffer));
+
+ gtk_source_vim_state_pop (GTK_SOURCE_VIM_STATE (self));
+
+ gtk_source_vim_visual_clear (self);
+
+ return TRUE;
+}
+
+static gboolean
gtk_source_vim_visual_replace (GtkSourceVimVisual *self)
{
g_assert (GTK_SOURCE_IS_VIM_VISUAL (self));
@@ -620,6 +663,9 @@ key_handler_initial (GtkSourceVimVisual *self,
case GDK_KEY_r:
return gtk_source_vim_visual_replace (self);
+ case GDK_KEY_p:
+ return gtk_source_vim_visual_put (self, FALSE);
+
case GDK_KEY_greater:
return gtk_source_vim_visual_begin_command (self, "indent", FALSE);
@@ -857,6 +903,21 @@ gtk_source_vim_visual_handle_keypress (GtkSourceVimState *state,
return TRUE;
}
+ /* Now handle our commands */
+ if ((mods & GDK_CONTROL_MASK) != 0)
+ {
+ switch (keyval)
+ {
+ case GDK_KEY_V:
+ /* For the terminal users out there */
+ gtk_source_vim_visual_put (GTK_SOURCE_VIM_VISUAL (state), TRUE);
+ return TRUE;
+
+ default:
+ break;
+ }
+ }
+
return self->handler (self, keyval, keycode, mods, string);
}