[gtksourceview/wip/chergert/vim: 237/293] some basic replace mode stuff




commit 0da61da27adcc72f0c21a9ca2c79b9118a0b4a4f
Author: Christian Hergert <chergert redhat com>
Date:   Tue Nov 2 17:29:44 2021 -0700

    some basic replace mode stuff
    
    this could be done better with a replace-one state to simplify replace

 gtksourceview/vim/gtk-source-vim-normal.c  | 33 +++++++++-------
 gtksourceview/vim/gtk-source-vim-replace.c | 61 +++++++++++++++++++++++++++++-
 gtksourceview/vim/gtk-source-vim-visual.c  | 26 ++++++++++++-
 3 files changed, 104 insertions(+), 16 deletions(-)
---
diff --git a/gtksourceview/vim/gtk-source-vim-normal.c b/gtksourceview/vim/gtk-source-vim-normal.c
index 42d0512b..beda6708 100644
--- a/gtksourceview/vim/gtk-source-vim-normal.c
+++ b/gtksourceview/vim/gtk-source-vim-normal.c
@@ -22,6 +22,7 @@
 #include "config.h"
 
 #include "gtk-source-vim.h"
+#include "gtk-source-vim-char-pending.h"
 #include "gtk-source-vim-command.h"
 #include "gtk-source-vim-command-bar.h"
 #include "gtk-source-vim-delete.h"
@@ -85,6 +86,23 @@ gtk_source_vim_normal_bail (GtkSourceVimNormal *self)
        return TRUE;
 }
 
+static gboolean
+gtk_source_vim_normal_replace_one (GtkSourceVimNormal *self)
+{
+       GtkSourceVimState *replace;
+       GtkSourceVimState *char_pending;
+
+       g_assert (GTK_SOURCE_IS_VIM_NORMAL (self));
+
+       char_pending = gtk_source_vim_char_pending_new ();
+       replace = gtk_source_vim_replace_new ();
+
+       gtk_source_vim_state_push (GTK_SOURCE_VIM_STATE (self), replace);
+       gtk_source_vim_state_push (GTK_SOURCE_VIM_STATE (replace), char_pending);
+
+       return TRUE;
+}
+
 G_GNUC_NULL_TERMINATED
 static void
 gtk_source_vim_normal_begin_delete (GtkSourceVimNormal *self,
@@ -629,18 +647,6 @@ key_handler_shift (GtkSourceVimNormal *self,
        return TRUE;
 }
 
-static gboolean
-key_handler_replace_one (GtkSourceVimNormal *self,
-                         guint               keyval,
-                         guint               keycode,
-                         GdkModifierType     mods,
-                         const char         *string)
-{
-       g_assert (GTK_SOURCE_IS_VIM_NORMAL (self));
-
-       return TRUE;
-}
-
 static gboolean
 key_handler_search_word (GtkSourceVimNormal *self,
                          guint               keyval,
@@ -974,8 +980,7 @@ key_handler_initial (GtkSourceVimNormal *self,
                                break;
 
                        case GDK_KEY_r:
-                               self->handler = key_handler_replace_one;
-                               break;
+                               return gtk_source_vim_normal_replace_one (self);
 
                        case GDK_KEY_asterisk:
                        case GDK_KEY_numbersign:
diff --git a/gtksourceview/vim/gtk-source-vim-replace.c b/gtksourceview/vim/gtk-source-vim-replace.c
index 226ccc5a..956f4cce 100644
--- a/gtksourceview/vim/gtk-source-vim-replace.c
+++ b/gtksourceview/vim/gtk-source-vim-replace.c
@@ -23,6 +23,7 @@
 
 #include <glib/gi18n.h>
 
+#include "gtk-source-vim-char-pending.h"
 #include "gtk-source-vim-replace.h"
 #include "gtk-source-vim-insert-literal.h"
 
@@ -52,6 +53,42 @@ move_to_zero (GtkSourceVimReplace *self)
        gtk_text_buffer_select_range (GTK_TEXT_BUFFER (buffer), &insert, &insert);
 }
 
+static void
+gtk_source_vim_replace_selection (GtkTextIter *iter,
+                                  GtkTextIter *end,
+                                  const char  *replace)
+{
+       GtkTextBuffer *buffer;
+       guint offset;
+
+       buffer = gtk_text_iter_get_buffer (iter);
+
+       gtk_text_iter_order (iter, end);
+
+       if (gtk_text_iter_equal (iter, end) &&
+           gtk_text_iter_starts_line (iter) &&
+           gtk_text_iter_ends_line (iter))
+       {
+               gtk_text_buffer_insert (buffer, iter, replace, -1);
+               return;
+       }
+
+       offset = gtk_text_iter_get_offset (end);
+
+       do
+       {
+               GtkTextIter here = *iter;
+
+               gtk_text_iter_forward_char (iter);
+
+               if (!gtk_text_iter_ends_line (&here))
+               {
+                       gtk_text_buffer_delete (buffer, &here, iter);
+                       gtk_text_buffer_insert (buffer, iter, replace, -1);
+               }
+       } while (gtk_text_iter_get_offset (iter) < offset);
+}
+
 static gboolean
 gtk_source_vim_replace_handle_keypress (GtkSourceVimState *state,
                                         guint              keyval,
@@ -103,11 +140,33 @@ static void
 gtk_source_vim_replace_resume (GtkSourceVimState *state,
                                GtkSourceVimState *from)
 {
+       gboolean completed = FALSE;
+
        g_assert (GTK_SOURCE_IS_VIM_REPLACE (state));
-       g_assert (GTK_SOURCE_IS_VIM_REPLACE (from));
+       g_assert (GTK_SOURCE_IS_VIM_STATE (from));
 
        gtk_source_vim_state_set_overwrite (state, TRUE);
+
+       if (GTK_SOURCE_IS_VIM_CHAR_PENDING (from))
+       {
+               const char *string = gtk_source_vim_char_pending_get_string (GTK_SOURCE_VIM_CHAR_PENDING 
(from));
+
+               if (string != NULL && string[0] != 0)
+               {
+                       GtkTextIter iter, selection;
+
+                       gtk_source_vim_state_get_buffer (state, &iter, &selection);
+                       gtk_source_vim_replace_selection (&iter, &selection, string);
+                       completed = TRUE;
+               }
+       }
+
        gtk_source_vim_state_end_user_action (state);
+
+       if (completed == TRUE)
+       {
+               gtk_source_vim_state_pop (state);
+       }
 }
 
 static void
diff --git a/gtksourceview/vim/gtk-source-vim-visual.c b/gtksourceview/vim/gtk-source-vim-visual.c
index 78d0d221..15508295 100644
--- a/gtksourceview/vim/gtk-source-vim-visual.c
+++ b/gtksourceview/vim/gtk-source-vim-visual.c
@@ -23,10 +23,12 @@
 
 #include <glib/gi18n.h>
 
+#include "gtk-source-vim-char-pending.h"
 #include "gtk-source-vim-command.h"
 #include "gtk-source-vim-delete.h"
 #include "gtk-source-vim-insert.h"
 #include "gtk-source-vim-motion.h"
+#include "gtk-source-vim-replace.h"
 #include "gtk-source-vim-visual.h"
 
 typedef gboolean (*KeyHandler) (GtkSourceVimVisual *self,
@@ -378,6 +380,24 @@ gtk_source_vim_visual_begin_insert (GtkSourceVimVisual *self)
        return TRUE;
 }
 
+static gboolean
+gtk_source_vim_visual_replace (GtkSourceVimVisual *self)
+{
+       g_assert (GTK_SOURCE_IS_VIM_VISUAL (self));
+
+       self->command = gtk_source_vim_replace_new ();
+
+       gtk_source_vim_state_set_can_repeat (GTK_SOURCE_VIM_STATE (self), TRUE);
+       gtk_source_vim_state_push (GTK_SOURCE_VIM_STATE (self),
+                                  g_object_ref (self->command));
+       gtk_source_vim_state_push (GTK_SOURCE_VIM_STATE (self->command),
+                                  gtk_source_vim_char_pending_new ());
+
+       gtk_source_vim_visual_clear (self);
+
+       return TRUE;
+}
+
 static gboolean
 key_handler_g (GtkSourceVimVisual *self,
               guint               keyval,
@@ -455,6 +475,9 @@ key_handler_initial (GtkSourceVimVisual *self,
                case GDK_KEY_C:
                        return gtk_source_vim_visual_begin_insert (self);
 
+               case GDK_KEY_r:
+                       return gtk_source_vim_visual_replace (self);
+
                default:
                        break;
        }
@@ -552,7 +575,8 @@ gtk_source_vim_visual_resume (GtkSourceVimState *state,
                g_object_unref (chained);
        }
 
-       if (GTK_SOURCE_IS_VIM_INSERT (from))
+       if (GTK_SOURCE_IS_VIM_INSERT (from) ||
+           GTK_SOURCE_IS_VIM_REPLACE (from))
        {
                gtk_source_vim_state_pop (state);
        }


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