[gtksourceview/wip/chergert/vim: 336/363] start adding search movements
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtksourceview/wip/chergert/vim: 336/363] start adding search movements
- Date: Mon, 8 Nov 2021 19:53:55 +0000 (UTC)
commit bea68bba943d0a7a3c64e0b7085c0b48ef96802a
Author: Christian Hergert <chergert redhat com>
Date: Sat Nov 6 15:20:25 2021 -0700
start adding search movements
gtksourceview/vim/gtk-source-vim-motion.c | 148 +++++++++++++++++++++++++++++-
gtksourceview/vim/gtk-source-vim-normal.c | 19 +---
gtksourceview/vim/gtk-source-vim-state.c | 49 ++++++++++
gtksourceview/vim/gtk-source-vim-state.h | 137 +++++++++++++--------------
4 files changed, 268 insertions(+), 85 deletions(-)
---
diff --git a/gtksourceview/vim/gtk-source-vim-motion.c b/gtksourceview/vim/gtk-source-vim-motion.c
index 578000f8..c278b613 100644
--- a/gtksourceview/vim/gtk-source-vim-motion.c
+++ b/gtksourceview/vim/gtk-source-vim-motion.c
@@ -21,7 +21,9 @@
#include "config.h"
-#include "gtksourceview.h"
+#include <gtksourceview/gtksourceview.h>
+#include <gtksourceview/gtksourcesearchcontext.h>
+#include <gtksourceview/gtksourcesearchsettings.h>
#include "gtk-source-vim-char-pending.h"
#include "gtk-source-vim-motion.h"
@@ -105,6 +107,9 @@ struct _GtkSourceVimMotion
* as paragraph or sentence movements.
*/
MotionWise wise : 1;
+
+ /* If search is reversed (flips n vs N) */
+ guint reverse_search : 1;
};
G_DEFINE_TYPE (GtkSourceVimMotion, gtk_source_vim_motion, GTK_SOURCE_TYPE_VIM_STATE)
@@ -1243,6 +1248,141 @@ motion_line_number (GtkTextIter *iter,
return TRUE;
}
+static char *
+word_under_cursor (const GtkTextIter *iter)
+{
+ GtkTextIter begin, end;
+
+ end = *iter;
+ if (!gtk_source_vim_iter_ends_word (&end))
+ {
+ if (!gtk_source_vim_iter_forward_word_end (&end))
+ return FALSE;
+ }
+
+ begin = end;
+ if (!gtk_source_vim_iter_starts_word (&begin))
+ {
+ gtk_source_vim_iter_backward_word_start (&begin);
+ }
+
+ gtk_text_iter_forward_char (&end);
+
+ return gtk_text_iter_get_slice (&begin, &end);
+}
+
+static char *
+WORD_under_cursor (const GtkTextIter *iter)
+{
+ GtkTextIter begin, end;
+
+ end = *iter;
+ if (!gtk_source_vim_iter_ends_WORD (&end))
+ {
+ if (!gtk_source_vim_iter_forward_WORD_end (&end))
+ return FALSE;
+ }
+
+ begin = end;
+ if (!gtk_source_vim_iter_starts_WORD (&begin))
+ {
+ gtk_source_vim_iter_backward_WORD_start (&begin);
+ }
+
+ gtk_text_iter_forward_char (&end);
+
+ return gtk_text_iter_get_slice (&begin, &end);
+}
+
+static gboolean
+motion_forward_search (GtkTextIter *iter,
+ GtkSourceVimMotion *self,
+ gboolean WORD,
+ gboolean reverse)
+{
+ GtkSourceSearchContext *context;
+ GtkSourceSearchSettings *settings;
+ const char *search_text;
+ char *word;
+ gboolean has_wrapped_around;
+ gboolean ret = FALSE;
+ int count;
+
+ g_assert (iter != NULL);
+ g_assert (GTK_SOURCE_IS_VIM_MOTION (self));
+
+ if (self->apply_count != 1)
+ {
+ return FALSE;
+ }
+
+ self->reverse_search = !!reverse;
+
+ gtk_source_vim_state_get_search (GTK_SOURCE_VIM_STATE (self), &settings, &context);
+
+ if (!gtk_source_search_settings_get_at_word_boundaries (settings))
+ {
+ gtk_source_search_settings_set_at_word_boundaries (settings, TRUE);
+ }
+
+ word = WORD ? WORD_under_cursor (iter) : word_under_cursor (iter);
+ search_text = gtk_source_search_settings_get_search_text (settings);
+
+ if (g_strcmp0 (word, search_text) != 0)
+ {
+ gtk_source_search_settings_set_search_text (settings, word);
+ }
+
+ if (!reverse)
+ {
+ gtk_text_iter_forward_char (iter);
+ }
+
+ g_free (word);
+
+ count = gtk_source_vim_state_get_count (GTK_SOURCE_VIM_STATE (self));
+
+ for (guint i = 0; i < count; i++)
+ {
+ gboolean matched;
+
+ if (reverse)
+ matched = gtk_source_search_context_backward (context, iter, iter, NULL,
&has_wrapped_around);
+ else
+ matched = gtk_source_search_context_forward (context, iter, iter, NULL,
&has_wrapped_around);
+
+ if (!matched)
+ break;
+
+ ret = TRUE;
+ }
+
+ return ret;
+}
+
+static gboolean
+motion_forward_search_word (GtkTextIter *iter,
+ GtkSourceVimMotion *self)
+{
+ return motion_forward_search (iter, self, FALSE, FALSE);
+}
+
+static gboolean
+motion_backward_search_word (GtkTextIter *iter,
+ GtkSourceVimMotion *self)
+{
+ return motion_forward_search (iter, self, FALSE, TRUE);
+}
+
+#if 0
+static gboolean
+motion_forward_search_WORD (GtkTextIter *iter,
+ GtkSourceVimMotion *self)
+{
+ return motion_forward_search (iter, self, TRUE, FALSE);
+}
+#endif
+
GtkSourceVimState *
gtk_source_vim_motion_new (void)
{
@@ -1514,6 +1654,12 @@ gtk_source_vim_motion_handle_keypress (GtkSourceVimState *state,
case GDK_KEY_braceright:
return gtk_source_vim_motion_complete (self, motion_forward_paragraph_end, EXCLUSIVE,
CHARWISE);
+ case GDK_KEY_asterisk:
+ return gtk_source_vim_motion_complete (self, motion_forward_search_word, EXCLUSIVE,
CHARWISE);
+
+ case GDK_KEY_numbersign:
+ return gtk_source_vim_motion_complete (self, motion_backward_search_word, INCLUSIVE,
CHARWISE);
+
case GDK_KEY_n:
case GDK_KEY_N:
case GDK_KEY_percent:
diff --git a/gtksourceview/vim/gtk-source-vim-normal.c b/gtksourceview/vim/gtk-source-vim-normal.c
index 7a70dddb..33c380a0 100644
--- a/gtksourceview/vim/gtk-source-vim-normal.c
+++ b/gtksourceview/vim/gtk-source-vim-normal.c
@@ -901,18 +901,6 @@ key_handler_shift (GtkSourceVimNormal *self,
}
}
-static gboolean
-key_handler_search_word (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 (GtkSourceVimNormal *self,
guint keyval,
@@ -1085,6 +1073,7 @@ key_handler_initial (GtkSourceVimNormal *self,
case GDK_KEY_0:
case GDK_KEY_KP_0:
case GDK_KEY_asciicircum:
+ case GDK_KEY_asterisk:
case GDK_KEY_b:
case GDK_KEY_bar:
case GDK_KEY_B:
@@ -1110,6 +1099,7 @@ key_handler_initial (GtkSourceVimNormal *self,
case GDK_KEY_Left:
case GDK_KEY_M:
case GDK_KEY_n:
+ case GDK_KEY_numbersign:
case GDK_KEY_N:
case GDK_KEY_parenleft:
case GDK_KEY_parenright:
@@ -1196,11 +1186,6 @@ key_handler_initial (GtkSourceVimNormal *self,
case GDK_KEY_r:
return gtk_source_vim_normal_replace_one (self);
- case GDK_KEY_asterisk:
- case GDK_KEY_numbersign:
- self->handler = key_handler_search_word;
- break;
-
case GDK_KEY_slash:
case GDK_KEY_question:
self->handler = key_handler_search;
diff --git a/gtksourceview/vim/gtk-source-vim-state.c b/gtksourceview/vim/gtk-source-vim-state.c
index a32cc173..58bfbbaf 100644
--- a/gtksourceview/vim/gtk-source-vim-state.c
+++ b/gtksourceview/vim/gtk-source-vim-state.c
@@ -24,6 +24,8 @@
#include <string.h>
#include "gtksourcebuffer.h"
+#include "gtksourcesearchcontext.h"
+#include "gtksourcesearchsettings.h"
#include "gtksourceutils-private.h"
#include "gtksourceview.h"
@@ -51,6 +53,10 @@ typedef struct
*/
GtkSourceVimState *child;
+ /* We have a custom search context/settings just for our VIM */
+ GtkSourceSearchContext *search_context;
+ GtkSourceSearchSettings *search_settings;
+
/* A queue of all our children, using @link of the children nodes
* to insert into the queue without extra allocations.
*/
@@ -274,6 +280,9 @@ gtk_source_vim_state_dispose (GObject *object)
priv->current_register = NULL;
+ g_clear_object (&priv->search_context);
+ g_clear_object (&priv->search_settings);
+
g_clear_weak_pointer (&priv->view);
gtk_source_vim_state_release (&priv->registers);
@@ -1240,3 +1249,43 @@ gtk_source_vim_state_get_editable (GtkSourceVimState *self)
return gtk_text_view_get_editable (GTK_TEXT_VIEW (view));
}
+
+void
+gtk_source_vim_state_get_search (GtkSourceVimState *self,
+ GtkSourceSearchSettings **settings,
+ GtkSourceSearchContext **context)
+{
+ GtkSourceVimStatePrivate *priv;
+ GtkSourceVimState *root;
+ GtkSourceBuffer *buffer;
+
+ g_return_if_fail (GTK_SOURCE_IS_VIM_STATE (self));
+
+ root = gtk_source_vim_state_get_root (self);
+ priv = gtk_source_vim_state_get_instance_private (root);
+ buffer = gtk_source_vim_state_get_buffer (self, NULL, NULL);
+
+ if (priv->search_settings == NULL)
+ {
+ priv->search_settings = gtk_source_search_settings_new ();
+ gtk_source_search_settings_set_wrap_around (priv->search_settings, TRUE);
+ gtk_source_search_settings_set_regex_enabled (priv->search_settings, TRUE);
+ gtk_source_search_settings_set_case_sensitive (priv->search_settings, TRUE);
+ }
+
+ if (priv->search_context == NULL)
+ {
+ priv->search_context = gtk_source_search_context_new (buffer, priv->search_settings);
+ gtk_source_search_context_set_highlight (priv->search_context, TRUE);
+ }
+
+ if (settings != NULL)
+ {
+ *settings = priv->search_settings;
+ }
+
+ if (context != NULL)
+ {
+ *context = priv->search_context;
+ }
+}
diff --git a/gtksourceview/vim/gtk-source-vim-state.h b/gtksourceview/vim/gtk-source-vim-state.h
index f980b697..1ff0b065 100644
--- a/gtksourceview/vim/gtk-source-vim-state.h
+++ b/gtksourceview/vim/gtk-source-vim-state.h
@@ -57,73 +57,76 @@ struct _GtkSourceVimStateClass
GString *string);
};
-gboolean gtk_source_vim_state_get_editable (GtkSourceVimState *self);
-void gtk_source_vim_state_set_parent (GtkSourceVimState *self,
- GtkSourceVimState *parent);
-void gtk_source_vim_state_unparent (GtkSourceVimState *self);
-void gtk_source_vim_state_push (GtkSourceVimState *self,
- GtkSourceVimState *new_state);
-void gtk_source_vim_state_pop (GtkSourceVimState *self);
-void gtk_source_vim_state_append_command (GtkSourceVimState *self,
- GString *string);
-void gtk_source_vim_state_beep (GtkSourceVimState *self);
-GtkSourceVimState *gtk_source_vim_state_get_child (GtkSourceVimState *self);
-GtkSourceVimState *gtk_source_vim_state_get_current (GtkSourceVimState *self);
-GtkSourceView *gtk_source_vim_state_get_view (GtkSourceVimState *self);
-GtkSourceBuffer *gtk_source_vim_state_get_buffer (GtkSourceVimState *self,
- GtkTextIter *insert,
- GtkTextIter *selection_bound);
-GtkSourceVimState *gtk_source_vim_state_get_root (GtkSourceVimState *self);
-GtkSourceVimState *gtk_source_vim_state_get_parent (GtkSourceVimState *self);
-GtkSourceVimState *gtk_source_vim_state_get_registers (GtkSourceVimState *self);
-int gtk_source_vim_state_get_count (GtkSourceVimState *self);
-gboolean gtk_source_vim_state_get_count_set (GtkSourceVimState *self);
-void gtk_source_vim_state_set_count (GtkSourceVimState *self,
- int count);
-gboolean gtk_source_vim_state_get_can_repeat (GtkSourceVimState *self);
-void gtk_source_vim_state_set_can_repeat (GtkSourceVimState *self,
- gboolean can_repeat);
-void gtk_source_vim_state_begin_user_action (GtkSourceVimState *self);
-void gtk_source_vim_state_end_user_action (GtkSourceVimState *self);
-gboolean gtk_source_vim_state_handle_event (GtkSourceVimState *self,
- GdkEvent *event);
-void gtk_source_vim_state_set_overwrite (GtkSourceVimState *self,
- gboolean overwrite);
-gboolean gtk_source_vim_state_synthesize (GtkSourceVimState *self,
- guint keyval,
- GdkModifierType mods);
-void gtk_source_vim_state_repeat (GtkSourceVimState *self);
-int gtk_source_vim_state_get_visible_lines (GtkSourceVimState *self);
-void gtk_source_vim_state_scroll_page (GtkSourceVimState *self,
- int count);
-void gtk_source_vim_state_scroll_half_page (GtkSourceVimState *self,
- int count);
-void gtk_source_vim_state_scroll_line (GtkSourceVimState *self,
- int count);
-void gtk_source_vim_state_z_scroll (GtkSourceVimState *self,
- double yalign);
-void gtk_source_vim_state_select (GtkSourceVimState *self,
- const GtkTextIter *insert,
- const GtkTextIter *selection);
-const char *gtk_source_vim_state_get_current_register (GtkSourceVimState *self);
-void gtk_source_vim_state_set_current_register (GtkSourceVimState *self,
- const char *current_register);
-const char *gtk_source_vim_state_get_current_register_value (GtkSourceVimState *self);
-void gtk_source_vim_state_set_current_register_value (GtkSourceVimState *self,
- const char *value);
-void gtk_source_vim_state_place_cursor_onscreen (GtkSourceVimState *self);
-void gtk_source_vim_state_keyval_to_string (guint keyval,
- GdkModifierType mods,
- char str[16]);
-void gtk_source_vim_state_keyval_unescaped (guint keyval,
- GdkModifierType mods,
- char str[16]);
-guint gtk_source_vim_state_get_visual_column (GtkSourceVimState *self);
-void gtk_source_vim_state_set_visual_column (GtkSourceVimState *self,
- int visual_column);
-void gtk_source_vim_state_select_linewise (GtkSourceVimState *self,
- GtkTextIter *insert,
- GtkTextIter *selection);
+gboolean gtk_source_vim_state_get_editable (GtkSourceVimState *self);
+void gtk_source_vim_state_set_parent (GtkSourceVimState *self,
+ GtkSourceVimState *parent);
+void gtk_source_vim_state_unparent (GtkSourceVimState *self);
+void gtk_source_vim_state_push (GtkSourceVimState *self,
+ GtkSourceVimState *new_state);
+void gtk_source_vim_state_pop (GtkSourceVimState *self);
+void gtk_source_vim_state_append_command (GtkSourceVimState *self,
+ GString *string);
+void gtk_source_vim_state_beep (GtkSourceVimState *self);
+GtkSourceVimState *gtk_source_vim_state_get_child (GtkSourceVimState *self);
+GtkSourceVimState *gtk_source_vim_state_get_current (GtkSourceVimState *self);
+GtkSourceView *gtk_source_vim_state_get_view (GtkSourceVimState *self);
+GtkSourceBuffer *gtk_source_vim_state_get_buffer (GtkSourceVimState *self,
+ GtkTextIter *insert,
+ GtkTextIter
*selection_bound);
+GtkSourceVimState *gtk_source_vim_state_get_root (GtkSourceVimState *self);
+GtkSourceVimState *gtk_source_vim_state_get_parent (GtkSourceVimState *self);
+GtkSourceVimState *gtk_source_vim_state_get_registers (GtkSourceVimState *self);
+int gtk_source_vim_state_get_count (GtkSourceVimState *self);
+gboolean gtk_source_vim_state_get_count_set (GtkSourceVimState *self);
+void gtk_source_vim_state_set_count (GtkSourceVimState *self,
+ int count);
+gboolean gtk_source_vim_state_get_can_repeat (GtkSourceVimState *self);
+void gtk_source_vim_state_set_can_repeat (GtkSourceVimState *self,
+ gboolean can_repeat);
+void gtk_source_vim_state_begin_user_action (GtkSourceVimState *self);
+void gtk_source_vim_state_end_user_action (GtkSourceVimState *self);
+gboolean gtk_source_vim_state_handle_event (GtkSourceVimState *self,
+ GdkEvent *event);
+void gtk_source_vim_state_set_overwrite (GtkSourceVimState *self,
+ gboolean overwrite);
+gboolean gtk_source_vim_state_synthesize (GtkSourceVimState *self,
+ guint keyval,
+ GdkModifierType mods);
+void gtk_source_vim_state_repeat (GtkSourceVimState *self);
+int gtk_source_vim_state_get_visible_lines (GtkSourceVimState *self);
+void gtk_source_vim_state_scroll_page (GtkSourceVimState *self,
+ int count);
+void gtk_source_vim_state_scroll_half_page (GtkSourceVimState *self,
+ int count);
+void gtk_source_vim_state_scroll_line (GtkSourceVimState *self,
+ int count);
+void gtk_source_vim_state_z_scroll (GtkSourceVimState *self,
+ double yalign);
+void gtk_source_vim_state_select (GtkSourceVimState *self,
+ const GtkTextIter *insert,
+ const GtkTextIter *selection);
+const char *gtk_source_vim_state_get_current_register (GtkSourceVimState *self);
+void gtk_source_vim_state_set_current_register (GtkSourceVimState *self,
+ const char
*current_register);
+const char *gtk_source_vim_state_get_current_register_value (GtkSourceVimState *self);
+void gtk_source_vim_state_set_current_register_value (GtkSourceVimState *self,
+ const char *value);
+void gtk_source_vim_state_place_cursor_onscreen (GtkSourceVimState *self);
+guint gtk_source_vim_state_get_visual_column (GtkSourceVimState *self);
+void gtk_source_vim_state_set_visual_column (GtkSourceVimState *self,
+ int visual_column);
+void gtk_source_vim_state_select_linewise (GtkSourceVimState *self,
+ GtkTextIter *insert,
+ GtkTextIter *selection);
+void gtk_source_vim_state_get_search (GtkSourceVimState *self,
+ GtkSourceSearchSettings **settings,
+ GtkSourceSearchContext **context);
+void gtk_source_vim_state_keyval_to_string (guint keyval,
+ GdkModifierType mods,
+ char string[16]);
+void gtk_source_vim_state_keyval_unescaped (guint keyval,
+ GdkModifierType mods,
+ char string[16]);
static inline void
gtk_source_vim_state_release (GtkSourceVimState **dest)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]