[gtksourceview/wip/chergert/vim: 363/363] implement / and ? search with regex




commit eb1366b08de7fcc645bb787c69eedbfaf9ddcf17
Author: Christian Hergert <chergert redhat com>
Date:   Sun Nov 7 14:19:28 2021 -0800

    implement / and ? search with regex
    
    not as proper magicy as vim, but gets the job done for now. will still
    need mark range work for use w/ visual, etc

 gtksourceview/vim/gtk-source-vim-command.c | 124 +++++++++++++++++++++++++++--
 gtksourceview/vim/gtk-source-vim-normal.c  |  21 +++++
 2 files changed, 137 insertions(+), 8 deletions(-)
---
diff --git a/gtksourceview/vim/gtk-source-vim-command.c b/gtksourceview/vim/gtk-source-vim-command.c
index f5368e07..e7eb4ef8 100644
--- a/gtksourceview/vim/gtk-source-vim-command.c
+++ b/gtksourceview/vim/gtk-source-vim-command.c
@@ -621,6 +621,102 @@ gtk_source_vim_command_nohl (GtkSourceVimCommand *self)
        gtk_source_search_context_set_highlight (context, FALSE);
 }
 
+static void
+gtk_source_vim_command_search (GtkSourceVimCommand *self)
+{
+       GtkSourceSearchContext *context;
+       GtkSourceSearchSettings *settings;
+       GtkSourceBuffer *buffer;
+       GtkSourceView *view;
+       GtkTextIter iter, selection;
+       GtkTextIter match;
+       GRegex *regex;
+
+       g_assert (GTK_SOURCE_IS_VIM_COMMAND (self));
+
+       buffer = gtk_source_vim_state_get_buffer (GTK_SOURCE_VIM_STATE (self), &iter, &selection);
+       view = gtk_source_vim_state_get_view (GTK_SOURCE_VIM_STATE (self));
+
+       gtk_source_vim_state_set_reverse_search (GTK_SOURCE_VIM_STATE (self), FALSE);
+       gtk_source_vim_state_get_search (GTK_SOURCE_VIM_STATE (self), &settings, &context);
+
+       if ((regex = g_regex_new (self->options, 0, 0, NULL)))
+       {
+               gtk_source_search_settings_set_search_text (settings, self->options);
+               gtk_source_search_settings_set_regex_enabled (settings, TRUE);
+               g_regex_unref (regex);
+       }
+       else
+       {
+               gtk_source_search_settings_set_regex_enabled (settings, FALSE);
+               gtk_source_search_settings_set_search_text (settings, self->options);
+       }
+
+       gtk_source_search_settings_set_at_word_boundaries (settings, FALSE);
+       gtk_source_search_context_set_highlight (context, TRUE);
+
+       if (gtk_source_search_context_forward (context, &iter, &match, NULL, NULL))
+       {
+               gtk_text_buffer_select_range (GTK_TEXT_BUFFER (buffer), &match, &match);
+               gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW (view), &match, 0.25, TRUE, 1.0, 0.0);
+
+               self->ignore_mark = TRUE;
+       }
+       else
+       {
+               gtk_source_search_context_set_highlight (context, FALSE);
+       }
+}
+
+static void
+gtk_source_vim_command_search_reverse (GtkSourceVimCommand *self)
+{
+       GtkSourceSearchContext *context;
+       GtkSourceSearchSettings *settings;
+       GtkSourceBuffer *buffer;
+       GtkSourceView *view;
+       GtkTextIter iter, selection;
+       GtkTextIter match;
+       GRegex *regex;
+
+       g_assert (GTK_SOURCE_IS_VIM_COMMAND (self));
+
+       buffer = gtk_source_vim_state_get_buffer (GTK_SOURCE_VIM_STATE (self), &iter, &selection);
+       view = gtk_source_vim_state_get_view (GTK_SOURCE_VIM_STATE (self));
+
+       gtk_source_vim_state_set_reverse_search (GTK_SOURCE_VIM_STATE (self), TRUE);
+       gtk_source_vim_state_get_search (GTK_SOURCE_VIM_STATE (self), &settings, &context);
+
+       if ((regex = g_regex_new (self->options, 0, 0, NULL)))
+       {
+               gtk_source_search_settings_set_search_text (settings, self->options);
+               gtk_source_search_settings_set_regex_enabled (settings, TRUE);
+               g_regex_unref (regex);
+       }
+       else
+       {
+               gtk_source_search_settings_set_regex_enabled (settings, FALSE);
+               gtk_source_search_settings_set_search_text (settings, self->options);
+       }
+
+       gtk_source_search_settings_set_at_word_boundaries (settings, FALSE);
+       gtk_source_search_context_set_highlight (context, TRUE);
+
+       gtk_text_iter_backward_char (&iter);
+
+       if (gtk_source_search_context_backward (context, &iter, &match, NULL, NULL))
+       {
+               gtk_text_buffer_select_range (GTK_TEXT_BUFFER (buffer), &match, &match);
+               gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW (view), &match, 0.25, TRUE, 1.0, 0.0);
+
+               self->ignore_mark = TRUE;
+       }
+       else
+       {
+               gtk_source_search_context_set_highlight (context, FALSE);
+       }
+}
+
 static void
 gtk_source_vim_command_append_command (GtkSourceVimState *state,
                                        GString           *string)
@@ -892,6 +988,8 @@ gtk_source_vim_command_class_init (GtkSourceVimCommandClass *klass)
        ADD_COMMAND ("indent",         gtk_source_vim_command_indent);
        ADD_COMMAND ("unindent",       gtk_source_vim_command_unindent);
        ADD_COMMAND ("format",         gtk_source_vim_command_format);
+       ADD_COMMAND ("search",         gtk_source_vim_command_search);
+       ADD_COMMAND ("search-reverse", gtk_source_vim_command_search_reverse);
 #undef ADD_COMMAND
 
        g_ptr_array_sort (commands_sorted, sort_longest_first);
@@ -1035,6 +1133,21 @@ gtk_source_vim_command_new_parsed (GtkSourceVimState *current,
                g_print ("Working within a range\n");
        }
 
+       if (*command_line == '/')
+       {
+               ret = GTK_SOURCE_VIM_COMMAND (gtk_source_vim_command_new ("search"));
+               ret->options = g_strdup (command_line+1);
+
+               goto finish;
+       }
+       else if (*command_line == '?')
+       {
+               ret = GTK_SOURCE_VIM_COMMAND (gtk_source_vim_command_new ("search-reverse"));
+               ret->options = g_strdup (command_line+1);
+
+               goto finish;
+       }
+
        if (strchr (command_line, ' '))
        {
                char **split = g_strsplit (command_line, " ", 2);
@@ -1049,16 +1162,11 @@ gtk_source_vim_command_new_parsed (GtkSourceVimState *current,
                g_strfreev (split);
                g_free (name);
 
-               goto finish;
+               if (ret != NULL)
+                       goto finish;
        }
-       else if (*command_line == '/')
-       {
-               ret = GTK_SOURCE_VIM_COMMAND (gtk_source_vim_command_new ("search"));
-               ret->options = g_strdup (command_line+1);
 
-               goto finish;
-       }
-       else if (*command_line == 's')
+       if (*command_line == 's')
        {
                ret = GTK_SOURCE_VIM_COMMAND (gtk_source_vim_command_new ("search-and-replace"));
                ret->options = g_strdup (command_line+1);
diff --git a/gtksourceview/vim/gtk-source-vim-normal.c b/gtksourceview/vim/gtk-source-vim-normal.c
index 8e6b9b4c..bc02fcfe 100644
--- a/gtksourceview/vim/gtk-source-vim-normal.c
+++ b/gtksourceview/vim/gtk-source-vim-normal.c
@@ -930,8 +930,29 @@ key_handler_search (GtkSourceVimNormal *self,
                     GdkModifierType     mods,
                     const char         *string)
 {
+       GtkSourceVimState *command_bar;
+       const char *text;
+
        g_assert (GTK_SOURCE_IS_VIM_NORMAL (self));
 
+       switch (keyval)
+       {
+               case GDK_KEY_slash:
+                       text = "/";
+                       break;
+
+               case GDK_KEY_question:
+                       text = "?";
+                       break;
+
+               default:
+                       return gtk_source_vim_normal_bail (self);
+       }
+
+       command_bar = gtk_source_vim_command_bar_new ();
+       gtk_source_vim_command_bar_set_text (GTK_SOURCE_VIM_COMMAND_BAR (command_bar), text);
+       gtk_source_vim_state_push (GTK_SOURCE_VIM_STATE (self), command_bar);
+
        return TRUE;
 }
 


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