Branch: refs/heads/master Author: Jiří Techet techet@gmail.com Committer: Jiří Techet techet@gmail.com Date: Fri, 10 Mar 2023 20:41:52 UTC Commit: e045c740f50a278fa3a8621ac139273e5d8c26c9 https://github.com/geany/geany-plugins/commit/e045c740f50a278fa3a8621ac13927...
Log Message: ----------- vimode: implement "iw", "ow", "iW" and "oW" text objects
This enables a family of word-related text object commands such as: "ciw", "diw", "viw" etc.
Fixes #1155.
Modified Paths: -------------- vimode/README vimode/src/cmd-runner.c vimode/src/cmds/motion-word.c vimode/src/cmds/motion-word.h vimode/src/cmds/txtobjs.c vimode/src/cmds/txtobjs.h
Modified: vimode/README 4 lines changed, 4 insertions(+), 0 deletions(-) =================================================================== @@ -448,10 +448,12 @@ a new command, please do not forget to update the table below.:: v_a< a< "a <>" from '<' to the matching '>' v_a> a> same as a< v_aB aB "a Block" from "[{" to "]}" (with brackets) + v_aW aW "a WORD" (with white space) v_a[ a[ "a []" from '[' to the matching ']' v_a] a] same as a[ v_a` a` string in backticks v_ab ab "a block" from "[(" to "])" (with braces) + v_aw aw "a word" (with white space) v_a{ a{ same as aB v_a} a} same as aB v_iquote i" double quoted string without the quotes @@ -461,10 +463,12 @@ a new command, please do not forget to update the table below.:: v_i< i< "inner <>" from '<' to the matching '>' v_i> i> same as i< v_iB iB "inner Block" from "[{" and "]}" + v_iW iW "inner WORD" v_i[ i[ "inner []" from '[' to the matching ']' v_i] i] same as i[ v_i` i` string in backticks without the backticks v_ib ib "inner block" from "[(" to "])" + v_iw iw "inner word" v_i{ i{ same as iB v_i} i} same as iB
Modified: vimode/src/cmd-runner.c 4 lines changed, 4 insertions(+), 0 deletions(-) =================================================================== @@ -222,6 +222,8 @@ CmdDef operator_cmds[] = { {cmd_select_less, GDK_KEY_a, GDK_KEY_greater, 0, 0, FALSE, FALSE}, \ {cmd_select_bracket, GDK_KEY_a, GDK_KEY_bracketleft, 0, 0, FALSE, FALSE}, \ {cmd_select_bracket, GDK_KEY_a, GDK_KEY_bracketright, 0, 0, FALSE, FALSE}, \ + {cmd_select_word, GDK_KEY_a, GDK_KEY_w, 0, 0, FALSE, FALSE}, \ + {cmd_select_word_space, GDK_KEY_a, GDK_KEY_W, 0, 0, FALSE, FALSE}, \ /* inner */ \ {cmd_select_quotedbl_inner, GDK_KEY_i, GDK_KEY_quotedbl, 0, 0, FALSE, FALSE}, \ {cmd_select_quoteleft_inner, GDK_KEY_i, GDK_KEY_quoteleft, 0, 0, FALSE, FALSE}, \ @@ -236,6 +238,8 @@ CmdDef operator_cmds[] = { {cmd_select_less_inner, GDK_KEY_i, GDK_KEY_greater, 0, 0, FALSE, FALSE}, \ {cmd_select_bracket_inner, GDK_KEY_i, GDK_KEY_bracketleft, 0, 0, FALSE, FALSE}, \ {cmd_select_bracket_inner, GDK_KEY_i, GDK_KEY_bracketright, 0, 0, FALSE, FALSE}, \ + {cmd_select_word_inner, GDK_KEY_i, GDK_KEY_w, 0, 0, FALSE, FALSE}, \ + {cmd_select_word_space_inner, GDK_KEY_i, GDK_KEY_W, 0, 0, FALSE, FALSE}, \ /* END */
Modified: vimode/src/cmds/motion-word.c 90 lines changed, 90 insertions(+), 0 deletions(-) =================================================================== @@ -295,5 +295,95 @@ void cmd_goto_previous_word_end_space(CmdContext *c, CmdParams *p) pos = find_previous_word_end_space(p->sci, pos, p->num); SET_POS(p->sci, pos, TRUE); } + + +void get_word_range(ScintillaObject *sci, gboolean word_space, gboolean inner, + gint pos, gint num, gint *sel_start, gint *sel_len) +{ + guint i; + gint start_pos = pos; + gint end_pos; + gchar ch = SSM(sci, SCI_GETCHARAT, pos, 0); + gchar prev_ch = SSM(sci, SCI_GETCHARAT, PREV(sci, pos), 0); + gchar next_ch = SSM(sci, SCI_GETCHARAT, NEXT(sci, pos), 0); + + if (word_space) + { + if (is_space(prev_ch) && !is_space(ch)) + ; // already there + else if (is_space(ch) && !is_space(prev_ch)) + ; // already there + else if (is_space(ch)) + start_pos = NEXT(sci, find_previous_word_end_space(sci, pos, 1)); + else if (!is_space(ch)) + start_pos = find_previous_word_space(sci, pos, 1); + + if (inner && !is_space(ch) && is_space(next_ch)) + { + num--; // already there once + pos = NEXT(sci, pos); + } + + for (i = 0; i < num; i++) + { + if (is_space(ch)) + { + if (inner) + pos = find_next_word_space(sci, pos, 1); + else + pos = find_next_word_end_space(sci, pos, 1, TRUE); + } + else if (!is_space(ch)) + { + if (inner) + pos = find_next_word_end_space(sci, pos, 1, TRUE); + else + pos = find_next_word_space(sci, pos, 1); + } + } + + end_pos = pos; } + else + { + if ((is_space(prev_ch) || is_nonwordchar(prev_ch)) && is_wordchar(ch)) + ; // already there + else if ((is_wordchar(prev_ch) || is_nonwordchar(prev_ch)) && is_space(ch)) + ; // already there + else if ((is_space(prev_ch) || is_wordchar(prev_ch)) && is_nonwordchar(ch)) + ; // already there + else if (is_space(ch) || is_nonwordchar(ch)) + start_pos = NEXT(sci, find_previous_word_end(sci, pos, 1)); + else if (is_wordchar(ch)) + start_pos = find_previous_word(sci, pos, 1); + + if (inner && (is_space(next_ch) || is_nonwordchar(next_ch)) && is_wordchar(ch)) + { + num--; // already there once + pos = NEXT(sci, pos); + } + + for (i = 0; i < num; i++) + { + if (is_space(ch) || is_nonwordchar(ch)) + { + if (inner) + pos = find_next_word(sci, pos, 1); + else + pos = find_next_word_end(sci, pos, 1, TRUE); + } + else if (is_wordchar(ch)) + { + if (inner) + pos = find_next_word_end(sci, pos, 1, TRUE); + else + pos = find_next_word(sci, pos, 1); + } + } + + end_pos = pos; + } + + *sel_start = start_pos; + *sel_len = end_pos - start_pos; }
Modified: vimode/src/cmds/motion-word.h 3 lines changed, 3 insertions(+), 0 deletions(-) =================================================================== @@ -31,4 +31,7 @@ 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 get_word_range(ScintillaObject *sci, gboolean word_space, gboolean inner, + gint pos, gint num, gint *sel_start, gint *sel_len); + #endif
Modified: vimode/src/cmds/txtobjs.c 44 lines changed, 44 insertions(+), 0 deletions(-) =================================================================== @@ -17,6 +17,7 @@ */
#include "cmds/txtobjs.h" +#include "cmds/motion-word.h"
static gint find_upper_level_brace(ScintillaObject *sci, gint pos, gint open_brace, gint close_brace) @@ -188,3 +189,46 @@ void cmd_select_bracket_inner(CmdContext *c, CmdParams *p) { select_brace(c, p, '[', ']', TRUE); } + + +static void select_word(CmdContext *c, CmdParams *p, gboolean word_space, gboolean inner) +{ + gint sel_start, sel_len; + + get_word_range(p->sci, word_space, inner, p->pos, p->num, &sel_start, &sel_len); + + if (VI_IS_VISUAL(vi_get_mode())) + { + c->sel_anchor = sel_start; + SET_POS(p->sci, sel_start + sel_len, TRUE); + } + else + { + p->sel_start = sel_start; + p->sel_len = sel_len; + } +} + + +void cmd_select_word(CmdContext *c, CmdParams *p) +{ + select_word(c, p, FALSE, FALSE); +} + + +void cmd_select_word_space(CmdContext *c, CmdParams *p) +{ + select_word(c, p, TRUE, FALSE); +} + + +void cmd_select_word_inner(CmdContext *c, CmdParams *p) +{ + select_word(c, p, FALSE, TRUE); +} + + +void cmd_select_word_space_inner(CmdContext *c, CmdParams *p) +{ + select_word(c, p, TRUE, TRUE); +}
Modified: vimode/src/cmds/txtobjs.h 4 lines changed, 4 insertions(+), 0 deletions(-) =================================================================== @@ -29,6 +29,8 @@ void cmd_select_brace(CmdContext *c, CmdParams *p); void cmd_select_paren(CmdContext *c, CmdParams *p); void cmd_select_less(CmdContext *c, CmdParams *p); void cmd_select_bracket(CmdContext *c, CmdParams *p); +void cmd_select_word(CmdContext *c, CmdParams *p); +void cmd_select_word_space(CmdContext *c, CmdParams *p);
void cmd_select_quotedbl_inner(CmdContext *c, CmdParams *p); void cmd_select_quoteleft_inner(CmdContext *c, CmdParams *p); @@ -37,5 +39,7 @@ void cmd_select_brace_inner(CmdContext *c, CmdParams *p); void cmd_select_paren_inner(CmdContext *c, CmdParams *p); void cmd_select_less_inner(CmdContext *c, CmdParams *p); void cmd_select_bracket_inner(CmdContext *c, CmdParams *p); +void cmd_select_word_inner(CmdContext *c, CmdParams *p); +void cmd_select_word_space_inner(CmdContext *c, CmdParams *p);
#endif
-------------- This E-Mail was brought to you by github_commit_mail.py (Source: https://github.com/geany/infrastructure).