[geany/geany-plugins] b77774: vimode: Don't use word navigation from Scintilla
Jiří Techet
git-noreply at xxxxx
Mon Oct 7 12:34:19 UTC 2019
Branch: refs/heads/master
Author: Jiří Techet <techet at gmail.com>
Committer: Jiří Techet <techet at gmail.com>
Date: Mon, 07 Oct 2019 12:34:19 UTC
Commit: b77774eb46833aba061f537cef5ffb5c8b45eaab
https://github.com/geany/geany-plugins/commit/b77774eb46833aba061f537cef5ffb5c8b45eaab
Log Message:
-----------
vimode: Don't use word navigation from Scintilla
Scintilla does different things when using SCI_WORDRIGHT, SCI_WORDLEFT,
SCI_WORDRIGHTEND and SCI_WORDLEFTEND than what we want for commands like
"w", "b", "W", "B", "e", "E", "ge", "gE". For instance, for
ident1 = id|ent2+ident3;
where | represents the cursor, SCI_WORDRIGHT does
ident1 = ident2+|ident3;
while Vim's "w" does
ident1 = ident2|+ident3;
For this reason we have to reimplement all the word navigation by ourselves
to better emulate the behavior of Vim. This patch tries to do that.
Modified Paths:
--------------
vimode/src/Makefile.am
vimode/src/cmd-runner.c
vimode/src/cmds/motion-word.c
vimode/src/cmds/motion-word.h
vimode/src/cmds/motion.c
vimode/src/cmds/motion.h
Modified: vimode/src/Makefile.am
2 lines changed, 2 insertions(+), 0 deletions(-)
===================================================================
@@ -26,6 +26,8 @@ vi_srcs = \
excmd-prompt.c \
cmds/motion.h \
cmds/motion.c \
+ cmds/motion-word.h \
+ cmds/motion-word.c \
cmds/txtobjs.h \
cmds/txtobjs.c \
cmds/changemode.h \
Modified: vimode/src/cmd-runner.c
1 lines changed, 1 insertions(+), 0 deletions(-)
===================================================================
@@ -20,6 +20,7 @@
#include "utils.h"
#include "cmds/motion.h"
+#include "cmds/motion-word.h"
#include "cmds/txtobjs.h"
#include "cmds/changemode.h"
#include "cmds/edit.h"
Modified: vimode/src/cmds/motion-word.c
266 lines changed, 266 insertions(+), 0 deletions(-)
===================================================================
@@ -0,0 +1,266 @@
+/*
+ * Copyright 2019 Jiri Techet <techet at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "cmds/motion-word.h"
+
+typedef gboolean (*CharacterPredicate)(gchar c);
+
+
+static void get_current(ScintillaObject *sci, gchar *ch, gint *pos)
+{
+ *pos = SSM(sci, SCI_GETCURRENTPOS, 0, 0);
+ *ch = SSM(sci, SCI_GETCHARAT, *pos, 0);
+}
+
+
+static void move_left(ScintillaObject *sci, gchar *ch, gint *pos)
+{
+ *pos = PREV(sci, *pos);
+ *ch = SSM(sci, SCI_GETCHARAT, *pos, 0);
+}
+
+
+static void move_right(ScintillaObject *sci, gchar *ch, gint *pos)
+{
+ *pos = NEXT(sci, *pos);
+ *ch = SSM(sci, SCI_GETCHARAT, *pos, 0);
+}
+
+
+static gboolean is_wordchar(gchar c)
+{
+ return g_ascii_isalnum(c) || c == '_' || (c >= 192 && c <= 255);
+}
+
+
+static gboolean is_space(gchar c)
+{
+ return g_ascii_isspace(c);
+}
+
+
+static gboolean is_nonspace(gchar c)
+{
+ return !is_space(c);
+}
+
+
+static gboolean is_nonwordchar(gchar c)
+{
+ return !is_wordchar(c) && !is_space(c);
+}
+
+
+static gboolean skip_to_left(CharacterPredicate is_in_group, ScintillaObject *sci, gchar *ch, gint *pos)
+{
+ gboolean moved = FALSE;
+ while (is_in_group(*ch) && *pos > 0)
+ {
+ move_left(sci, ch, pos);
+ moved = TRUE;
+ }
+ return moved;
+}
+
+
+static gboolean skip_to_right(CharacterPredicate is_in_group, ScintillaObject *sci, gchar *ch, gint *pos, gint len)
+{
+ gboolean moved = FALSE;
+ while (is_in_group(*ch) && *pos < len)
+ {
+ move_right(sci, ch, pos);
+ moved = TRUE;
+ }
+ return moved;
+}
+
+
+void cmd_goto_next_word(CmdContext *c, CmdParams *p)
+{
+ gint i;
+ gint len = SSM(p->sci, SCI_GETLENGTH, 0, 0);
+
+ for (i = 0; i < p->num; i++)
+ {
+ gint pos;
+ gchar ch;
+
+ get_current(p->sci, &ch, &pos);
+
+ if (!skip_to_right(is_wordchar, p->sci, &ch, &pos, len))
+ skip_to_right(is_nonwordchar, p->sci, &ch, &pos, len);
+ skip_to_right(is_space, p->sci, &ch, &pos, len);
+
+ if (!is_space(ch))
+ SET_POS(p->sci, pos, TRUE);
+ }
+}
+
+
+void cmd_goto_previous_word(CmdContext *c, CmdParams *p)
+{
+ gint i;
+ for (i = 0; i < p->num; i++)
+ {
+ gint pos;
+ gchar ch;
+
+ get_current(p->sci, &ch, &pos);
+ move_left(p->sci, &ch, &pos);
+
+ skip_to_left(is_space, p->sci, &ch, &pos);
+ if (!skip_to_left(is_wordchar, p->sci, &ch, &pos))
+ skip_to_left(is_nonwordchar, p->sci, &ch, &pos);
+
+ if (pos != 0 || is_space(ch))
+ move_right(p->sci, &ch, &pos);
+ if (!is_space(ch))
+ SET_POS(p->sci, pos, TRUE);
+ }
+}
+
+
+void cmd_goto_next_word_end(CmdContext *c, CmdParams *p)
+{
+ gint i;
+ gint len = SSM(p->sci, SCI_GETLENGTH, 0, 0);
+
+ for (i = 0; i < p->num; i++)
+ {
+ gint pos;
+ gchar ch;
+
+ get_current(p->sci, &ch, &pos);
+ move_right(p->sci, &ch, &pos);
+
+ skip_to_right(is_space, p->sci, &ch, &pos, len);
+ if (!skip_to_right(is_wordchar, p->sci, &ch, &pos, len))
+ skip_to_right(is_nonwordchar, p->sci, &ch, &pos, len);
+
+ if (pos < len - 1 || is_space(ch))
+ move_left(p->sci, &ch, &pos);
+ if (!is_space(ch))
+ SET_POS(p->sci, pos, TRUE);
+ }
+}
+
+
+void cmd_goto_previous_word_end(CmdContext *c, CmdParams *p)
+{
+ gint i;
+ for (i = 0; i < p->num; i++)
+ {
+ gint pos;
+ gchar ch;
+
+ get_current(p->sci, &ch, &pos);
+
+ if (!skip_to_left(is_wordchar, p->sci, &ch, &pos))
+ skip_to_left(is_nonwordchar, p->sci, &ch, &pos);
+ skip_to_left(is_space, p->sci, &ch, &pos);
+
+ if (!is_space(ch))
+ SET_POS(p->sci, pos, TRUE);
+ }
+}
+
+
+void cmd_goto_next_word_space(CmdContext *c, CmdParams *p)
+{
+ gint i;
+ gint len = SSM(p->sci, SCI_GETLENGTH, 0, 0);
+
+ for (i = 0; i < p->num; i++)
+ {
+ gint pos;
+ gchar ch;
+
+ get_current(p->sci, &ch, &pos);
+
+ skip_to_right(is_nonspace, p->sci, &ch, &pos, len);
+ skip_to_right(is_space, p->sci, &ch, &pos, len);
+
+ if (!is_space(ch))
+ SET_POS(p->sci, pos, TRUE);
+ }
+}
+
+
+void cmd_goto_previous_word_space(CmdContext *c, CmdParams *p)
+{
+ gint i;
+ for (i = 0; i < p->num; i++)
+ {
+ gint pos;
+ gchar ch;
+
+ get_current(p->sci, &ch, &pos);
+ move_left(p->sci, &ch, &pos);
+
+ skip_to_left(is_space, p->sci, &ch, &pos);
+ skip_to_left(is_nonspace, p->sci, &ch, &pos);
+
+ if (pos != 0 || is_space(ch))
+ move_right(p->sci, &ch, &pos);
+ if (!is_space(ch))
+ SET_POS(p->sci, pos, TRUE);
+ }
+}
+
+
+void cmd_goto_next_word_end_space(CmdContext *c, CmdParams *p)
+{
+ gint i;
+ gint len = SSM(p->sci, SCI_GETLENGTH, 0, 0);
+
+ for (i = 0; i < p->num; i++)
+ {
+ gint pos;
+ gchar ch;
+
+ get_current(p->sci, &ch, &pos);
+ move_right(p->sci, &ch, &pos);
+
+ skip_to_right(is_space, p->sci, &ch, &pos, len);
+ skip_to_right(is_nonspace, p->sci, &ch, &pos, len);
+
+ if (pos < len - 1 || is_space(ch))
+ move_left(p->sci, &ch, &pos);
+ if (!is_space(ch))
+ SET_POS(p->sci, pos, TRUE);
+ }
+}
+
+
+void cmd_goto_previous_word_end_space(CmdContext *c, CmdParams *p)
+{
+ gint i;
+ for (i = 0; i < p->num; i++)
+ {
+ gint pos;
+ gchar ch;
+
+ get_current(p->sci, &ch, &pos);
+
+ skip_to_left(is_nonspace, p->sci, &ch, &pos);
+ skip_to_left(is_space, p->sci, &ch, &pos);
+
+ if (!is_space(ch))
+ SET_POS(p->sci, pos, TRUE);
+ }
+}
Modified: vimode/src/cmds/motion-word.h
34 lines changed, 34 insertions(+), 0 deletions(-)
===================================================================
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2019 Jiri Techet <techet at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __VIMODE_CMDS_MOTION_WORD_H__
+#define __VIMODE_CMDS_MOTION_WORD_H__
+
+#include "context.h"
+#include "cmd-params.h"
+
+void cmd_goto_next_word(CmdContext *c, CmdParams *p);
+void cmd_goto_previous_word(CmdContext *c, CmdParams *p);
+void cmd_goto_next_word_end(CmdContext *c, CmdParams *p);
+void cmd_goto_previous_word_end(CmdContext *c, CmdParams *p);
+void cmd_goto_next_word_space(CmdContext *c, CmdParams *p);
+void cmd_goto_previous_word_space(CmdContext *c, CmdParams *p);
+void cmd_goto_next_word_end_space(CmdContext *c, CmdParams *p);
+void cmd_goto_previous_word_end_space(CmdContext *c, CmdParams *p);
+
+#endif
Modified: vimode/src/cmds/motion.c
138 lines changed, 0 insertions(+), 138 deletions(-)
===================================================================
@@ -214,144 +214,6 @@ void cmd_goto_doc_percentage(CmdContext *c, CmdParams *p)
}
-static void goto_word_end(CmdContext *c, CmdParams *p, gboolean forward)
-{
- gint i;
-
- if (VI_IS_COMMAND(vi_get_mode()))
- SSM(p->sci, SCI_CHARRIGHT, 0, 0);
-
- for (i = 0; i < p->num; i++)
- {
- gint orig_pos = SSM(p->sci, SCI_GETCURRENTPOS, 0, 0);
- gint pos;
- gint line_start_pos;
-
- SSM(p->sci, forward ? SCI_WORDRIGHTEND : SCI_WORDLEFTEND, 0, 0);
- line_start_pos = SSM(p->sci, SCI_POSITIONFROMLINE, GET_CUR_LINE(p->sci), 0);
- pos = SSM(p->sci, SCI_GETCURRENTPOS, 0, 0);
- if (pos == orig_pos)
- break;
- /* For some reason, Scintilla treats newlines as word parts and cursor
- * is left before/after newline. Repeat again in this case. */
- if (pos == line_start_pos)
- SSM(p->sci, forward ? SCI_WORDRIGHTEND : SCI_WORDLEFTEND, 0, 0);
- }
-
- if (VI_IS_COMMAND(vi_get_mode()))
- SSM(p->sci, SCI_CHARLEFT, 0, 0);
-}
-
-
-static void goto_word_start(CmdContext *c, CmdParams *p, gboolean forward)
-{
- gint i;
- for (i = 0; i < p->num; i++)
- {
- gint orig_pos = SSM(p->sci, SCI_GETCURRENTPOS, 0, 0);
- gint pos;
- gint line_end_pos;
-
- SSM(p->sci, forward ? SCI_WORDRIGHT : SCI_WORDLEFT, 0, 0);
- line_end_pos = SSM(p->sci, SCI_GETLINEENDPOSITION, GET_CUR_LINE(p->sci), 0);
- pos = SSM(p->sci, SCI_GETCURRENTPOS, 0, 0);
- if (pos == orig_pos)
- break;
- /* For some reason, Scintilla treats newlines as word parts and cursor
- * is left before/after newline. Repeat again in this case. */
- if (pos == line_end_pos)
- SSM(p->sci, forward ? SCI_WORDRIGHT : SCI_WORDLEFT, 0, 0);
- }
-}
-
-
-void cmd_goto_next_word(CmdContext *c, CmdParams *p)
-{
- goto_word_start(c, p, TRUE);
-}
-
-
-void cmd_goto_previous_word(CmdContext *c, CmdParams *p)
-{
- goto_word_start(c, p, FALSE);
-}
-
-
-void cmd_goto_next_word_end(CmdContext *c, CmdParams *p)
-{
- goto_word_end(c, p, TRUE);
-}
-
-
-void cmd_goto_previous_word_end(CmdContext *c, CmdParams *p)
-{
- goto_word_end(c, p, FALSE);
-}
-
-
-static void use_all_wordchars(ScintillaObject *sci)
-{
- guchar wc[512];
- gint i;
- gint j = 0;
- for (i = 0; i < 256; i++)
- {
- if (g_ascii_isprint(i) && !g_ascii_isspace(i))
- wc[j++] = i;
- }
- wc[j] = '\0';
- SSM(sci, SCI_SETWORDCHARS, 0, (sptr_t)wc);
-}
-
-
-void cmd_goto_next_word_space(CmdContext *c, CmdParams *p)
-{
- guchar wc[512];
- SSM(p->sci, SCI_GETWORDCHARS, 0, (sptr_t)wc);
- use_all_wordchars(p->sci);
-
- goto_word_start(c, p, TRUE);
-
- SSM(p->sci, SCI_SETWORDCHARS, 0, (sptr_t)wc);
-}
-
-
-void cmd_goto_previous_word_space(CmdContext *c, CmdParams *p)
-{
- guchar wc[512];
- SSM(p->sci, SCI_GETWORDCHARS, 0, (sptr_t)wc);
- use_all_wordchars(p->sci);
-
- goto_word_start(c, p, FALSE);
-
- SSM(p->sci, SCI_SETWORDCHARS, 0, (sptr_t)wc);
-}
-
-
-void cmd_goto_next_word_end_space(CmdContext *c, CmdParams *p)
-{
- guchar wc[512];
- SSM(p->sci, SCI_GETWORDCHARS, 0, (sptr_t)wc);
- use_all_wordchars(p->sci);
-
- goto_word_end(c, p, TRUE);
-
- SSM(p->sci, SCI_SETWORDCHARS, 0, (sptr_t)wc);
-}
-
-
-void cmd_goto_previous_word_end_space(CmdContext *c, CmdParams *p)
-{
- guchar wc[512];
- SSM(p->sci, SCI_GETWORDCHARS, 0, (sptr_t)wc);
- use_all_wordchars(p->sci);
-
- goto_word_end(c, p, FALSE);
-
- SSM(p->sci, SCI_SETWORDCHARS, 0, (sptr_t)wc);
-}
-
-
void cmd_goto_line_start(CmdContext *c, CmdParams *p)
{
SSM(p->sci, SCI_HOME, 0, 0);
Modified: vimode/src/cmds/motion.h
9 lines changed, 0 insertions(+), 9 deletions(-)
===================================================================
@@ -41,15 +41,6 @@ void cmd_goto_screen_middle(CmdContext *c, CmdParams *p);
void cmd_goto_screen_bottom(CmdContext *c, CmdParams *p);
void cmd_goto_doc_percentage(CmdContext *c, CmdParams *p);
-void cmd_goto_next_word(CmdContext *c, CmdParams *p);
-void cmd_goto_previous_word(CmdContext *c, CmdParams *p);
-void cmd_goto_next_word_end(CmdContext *c, CmdParams *p);
-void cmd_goto_previous_word_end(CmdContext *c, CmdParams *p);
-void cmd_goto_next_word_space(CmdContext *c, CmdParams *p);
-void cmd_goto_previous_word_space(CmdContext *c, CmdParams *p);
-void cmd_goto_next_word_end_space(CmdContext *c, CmdParams *p);
-void cmd_goto_previous_word_end_space(CmdContext *c, CmdParams *p);
-
void cmd_goto_line_start(CmdContext *c, CmdParams *p);
void cmd_goto_line_start_nonempty(CmdContext *c, CmdParams *p);
void cmd_goto_line_end(CmdContext *c, CmdParams *p);
--------------
This E-Mail was brought to you by github_commit_mail.py (Source: https://github.com/geany/infrastructure).
More information about the Plugins-Commits
mailing list