[gtksourceview/wip/chergert/vim] start on search & replace



commit 190b94f9e211c492be2c4031d188e44c849f42bf
Author: Christian Hergert <chergert redhat com>
Date:   Mon Nov 8 17:02:10 2021 -0800

    start on search & replace

 gtksourceview/vim/gtk-source-vim-command.c | 92 +++++++++++++++++++++++++++++-
 1 file changed, 89 insertions(+), 3 deletions(-)
---
diff --git a/gtksourceview/vim/gtk-source-vim-command.c b/gtksourceview/vim/gtk-source-vim-command.c
index fbb2e59f..5c3dd009 100644
--- a/gtksourceview/vim/gtk-source-vim-command.c
+++ b/gtksourceview/vim/gtk-source-vim-command.c
@@ -885,18 +885,93 @@ gtk_source_vim_command_parse_search_and_replace (const char  *str,
 static void
 gtk_source_vim_command_search_replace (GtkSourceVimCommand *self)
 {
+       GtkSourceSearchSettings *settings = NULL;
+       GtkSourceSearchContext *context = NULL;
+       GtkSourceBuffer *buffer;
+       GtkTextIter iter;
+       GtkTextIter match_start;
+       GtkTextIter match_end;
+       const char *replace_str;
        char *search = NULL;
        char *replace = NULL;
        char *options = NULL;
+       gboolean wrapped = FALSE;
+       gboolean flag_g = FALSE;
+       guint line = 0;
+       int last_line;
 
        g_assert (GTK_SOURCE_IS_VIM_COMMAND (self));
 
-       if (gtk_source_vim_command_parse_search_and_replace (self->options, &search, &replace, &options))
+       if (!gtk_source_vim_command_parse_search_and_replace (self->options, &search, &replace, &options))
+               goto cleanup;
+
+       if (search == NULL || search[0] == 0)
+               goto cleanup;
+
+       replace_str = replace ? replace : "";
+
+       for (const char *c = options ? options : ""; *c; c = g_utf8_next_char (c))
        {
-               g_print ("Search: %s\nReplace: %s\nOptions: %s\n",
-                        search, replace, options);
+               flag_g |= *c == 'g';
        }
 
+       gtk_source_vim_state_get_search (GTK_SOURCE_VIM_STATE (self), &settings, &context);
+       gtk_source_vim_state_set_reverse_search (GTK_SOURCE_VIM_STATE (self), FALSE);
+
+       gtk_source_search_settings_set_at_word_boundaries (settings, FALSE);
+       gtk_source_search_settings_set_regex_enabled (settings, TRUE);
+       gtk_source_search_settings_set_search_text (settings, search);
+       gtk_source_search_context_set_highlight (context, FALSE);
+
+       buffer = gtk_source_search_context_get_buffer (context);
+
+       if (self->mark_begin)
+               gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (buffer), &iter, self->mark_begin);
+       else
+               gtk_text_buffer_get_selection_bounds (GTK_TEXT_BUFFER (buffer), &iter, NULL);
+
+       line = gtk_text_iter_get_line (&iter);
+       last_line = -1;
+
+       gtk_text_buffer_begin_user_action (GTK_TEXT_BUFFER (buffer));
+
+       while (gtk_source_search_context_forward (context, &iter, &match_start, &match_end, &wrapped) && 
!wrapped)
+       {
+               guint cur_line = gtk_text_iter_get_line (&match_start);
+
+               if (self->mark_end)
+               {
+                       GtkTextIter end;
+                       gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (buffer), &end, self->mark_end);
+                       if (gtk_text_iter_compare (&end, &match_end) < 0)
+                               break;
+               }
+               else if (gtk_text_iter_get_line (&match_start) != line)
+               {
+                       /* If we have no bounds, it's only the current line */
+                       break;
+               }
+
+               if (cur_line == last_line && !flag_g)
+               {
+                       goto next_result;
+               }
+
+               last_line = cur_line;
+               if (!gtk_source_search_context_replace (context, &match_start, &match_end, replace_str, -1, 
NULL))
+               {
+                       break;
+               }
+
+       next_result:
+               iter = match_end;
+               gtk_text_iter_forward_char (&iter);
+       }
+
+       gtk_text_buffer_end_user_action (GTK_TEXT_BUFFER (buffer));
+
+cleanup:
+
        g_free (search);
        g_free (replace);
        g_free (options);
@@ -1280,6 +1355,17 @@ parse_position (GtkSourceVimState  *current,
                        return FALSE;
 
                gtk_text_buffer_get_iter_at_mark (buffer, iter, mark);
+
+               /* As of Vim 7.3, substitutions applied to a range defined by
+                * marks or a visual selection (which uses a special type of
+                * marks '< and '>) are not bounded by the column position of
+                * the marks by default.
+                */
+               if (*c == '<' && !gtk_text_iter_starts_line (iter))
+                       gtk_text_iter_set_line_offset (iter, 0);
+               else if (*c == '>' && !gtk_text_iter_ends_line (iter))
+                       gtk_text_iter_forward_to_line_end (iter);
+
                *str = ++c;
                return TRUE;
        }


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