[gnome-builder] vim: implement forward_word closer to VIM style.
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder] vim: implement forward_word closer to VIM style.
- Date: Mon, 6 Oct 2014 10:25:30 +0000 (UTC)
commit 34d5f651e27f3092f47dfc2422bce26b0319048f
Author: Christian Hergert <christian hergert me>
Date: Mon Oct 6 03:25:17 2014 -0700
vim: implement forward_word closer to VIM style.
The one place where I notice things still aren't matching up is newlines.
VIM will jump to the empty line before moving to the next word.
Still need to do:
* word end (e)
* backword word (b)
src/editor/gb-editor-vim.c | 86 ++++++++++++++++++++++++++++++++++++++++----
1 files changed, 79 insertions(+), 7 deletions(-)
---
diff --git a/src/editor/gb-editor-vim.c b/src/editor/gb-editor-vim.c
index 942a5bd..5fdda81 100644
--- a/src/editor/gb-editor-vim.c
+++ b/src/editor/gb-editor-vim.c
@@ -826,33 +826,105 @@ gb_editor_vim_move_forward (GbEditorVim *vim)
}
}
+enum
+{
+ CLASS_0,
+ CLASS_SPACE,
+ CLASS_SPECIAL,
+ CLASS_WORD,
+};
+
+static int
+gb_editor_vim_classify (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 void
gb_editor_vim_move_forward_word (GbEditorVim *vim)
{
GtkTextBuffer *buffer;
+ GtkTextMark *insert;
GtkTextIter iter;
GtkTextIter selection;
- GtkTextMark *insert;
+ gunichar ch;
gboolean has_selection;
+ gboolean found = FALSE;
+ gint begin_class;
+ gint cur_class;
g_assert (GB_IS_EDITOR_VIM (vim));
/*
- * TODO: Make the word boundaries more like VIM.
+ * TODO: VIM will jump to an empty line before going to the next word.
*/
buffer = gtk_text_view_get_buffer (vim->priv->text_view);
has_selection = gb_editor_vim_get_selection_bounds (vim, &iter, &selection);
- if (gtk_text_iter_inside_word (&iter))
+ ch = gtk_text_iter_get_char (&iter);
+ begin_class = gb_editor_vim_classify (ch);
+
+ /* Move to the first non-whitespace character if necessary. */
+ if (begin_class == CLASS_SPACE)
+ {
+ for (;;)
+ {
+ if (!gtk_text_iter_forward_char (&iter))
+ goto not_found;
+
+ ch = gtk_text_iter_get_char (&iter);
+ cur_class = gb_editor_vim_classify (ch);
+ if (cur_class != CLASS_SPACE)
+ goto finish;
+ }
+ }
+
+ /* move to first character not at same class level. */
+ while (gtk_text_iter_forward_char (&iter))
{
- if (!gtk_text_iter_forward_word_end (&iter))
- gtk_text_buffer_get_end_iter (buffer, &iter);
+ ch = gtk_text_iter_get_char (&iter);
+ cur_class = gb_editor_vim_classify (ch);
+
+ if (cur_class == CLASS_SPACE)
+ {
+ begin_class = CLASS_0;
+ continue;
+ }
+
+ if (cur_class != begin_class)
+ {
+ found = TRUE;
+ break;
+ }
}
- if (gtk_text_iter_forward_word_end (&iter))
- gtk_text_iter_backward_word_start (&iter);
+not_found:
+ if (!found)
+ gtk_text_buffer_get_end_iter (buffer, &iter);
+finish:
if (has_selection)
{
if (gtk_text_iter_equal (&iter, &selection))
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]