[gtksourceview/wip/chergert/vim: 48/73] add w and W movements
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtksourceview/wip/chergert/vim: 48/73] add w and W movements
- Date: Tue, 26 Oct 2021 23:20:37 +0000 (UTC)
commit e0b40cd05202cd8eeff23d79cef652fd995faa9f
Author: Christian Hergert <chergert redhat com>
Date: Sat Oct 23 10:31:00 2021 -0700
add w and W movements
gtksourceview/vim/gtk-source-vim-motion.c | 113 +++++++++++++++++++++++++++++-
1 file changed, 111 insertions(+), 2 deletions(-)
---
diff --git a/gtksourceview/vim/gtk-source-vim-motion.c b/gtksourceview/vim/gtk-source-vim-motion.c
index 4c321458..7d423d6a 100644
--- a/gtksourceview/vim/gtk-source-vim-motion.c
+++ b/gtksourceview/vim/gtk-source-vim-motion.c
@@ -39,6 +39,97 @@ struct _GtkSourceVimMotion
G_DEFINE_TYPE (GtkSourceVimMotion, gtk_source_vim_motion, GTK_SOURCE_TYPE_VIM_STATE)
+enum
+{
+ CLASS_0,
+ CLASS_NEWLINE,
+ CLASS_SPACE,
+ CLASS_SPECIAL,
+ CLASS_WORD,
+};
+
+static int
+classify_word (gunichar ch)
+{
+ switch (ch)
+ {
+ case ' ':
+ case '\t':
+ case '\n':
+ return CLASS_SPACE;
+
+ case '"': case '\'':
+ case '(': case ')':
+ case '{': case '}':
+ case '[': case ']':
+ case '<': case '>':
+ case '-': case '+': case '*': case '/':
+ case '!': case '@': case '#': case '$': case '%':
+ case '^': case '&': case ':': case ';': case '?':
+ case '|': case '=': case '\\': case '.': case ',':
+ return CLASS_SPECIAL;
+
+ case '_':
+ default:
+ return CLASS_WORD;
+ }
+}
+
+static int
+classify_WORD (gunichar ch)
+{
+ if (g_unichar_isspace (ch))
+ return CLASS_SPACE;
+ return CLASS_WORD;
+}
+
+static gboolean
+forward_classified_start (GtkTextIter *iter,
+ gint (*classify) (gunichar))
+{
+ gint begin_class;
+ gint cur_class;
+ gunichar ch;
+
+ g_assert (iter);
+
+ ch = gtk_text_iter_get_char (iter);
+ begin_class = classify (ch);
+
+ /* Move to the first non-whitespace character if necessary. */
+ if (begin_class == CLASS_SPACE)
+ {
+ for (;;)
+ {
+ if (!gtk_text_iter_forward_char (iter))
+ return FALSE;
+
+ ch = gtk_text_iter_get_char (iter);
+ cur_class = classify (ch);
+ if (cur_class != CLASS_SPACE)
+ return TRUE;
+ }
+ }
+
+ /* move to first character not at same class level. */
+ while (gtk_text_iter_forward_char (iter))
+ {
+ ch = gtk_text_iter_get_char (iter);
+ cur_class = classify (ch);
+
+ if (cur_class == CLASS_SPACE)
+ {
+ begin_class = CLASS_0;
+ continue;
+ }
+
+ if (cur_class != begin_class || cur_class == CLASS_NEWLINE)
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
static void
get_iter_at_visual_column (GtkSourceView *view,
GtkTextIter *iter,
@@ -278,6 +369,20 @@ motion_screen_middle (GtkTextIter *iter,
return TRUE;
}
+static gboolean
+motion_forward_word_start (GtkTextIter *iter,
+ GtkSourceView *view)
+{
+ return forward_classified_start (iter, classify_word);
+}
+
+static gboolean
+motion_forward_WORD_start (GtkTextIter *iter,
+ GtkSourceView *view)
+{
+ return forward_classified_start (iter, classify_WORD);
+}
+
GtkSourceVimState *
gtk_source_vim_motion_new (void)
{
@@ -396,6 +501,12 @@ gtk_source_vim_motion_handle_keypress (GtkSourceVimState *state,
case GDK_KEY_L:
return gtk_source_vim_motion_complete (self, motion_screen_bottom);
+ case GDK_KEY_w:
+ return gtk_source_vim_motion_complete (self, motion_forward_word_start);
+
+ case GDK_KEY_W:
+ return gtk_source_vim_motion_complete (self, motion_forward_WORD_start);
+
case GDK_KEY_b:
case GDK_KEY_B:
case GDK_KEY_e:
@@ -407,8 +518,6 @@ gtk_source_vim_motion_handle_keypress (GtkSourceVimState *state,
case GDK_KEY_parenleft:
case GDK_KEY_parenright:
case GDK_KEY_percent:
- case GDK_KEY_w:
- case GDK_KEY_W:
/* TODO */
G_GNUC_FALLTHROUGH;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]