summaryrefslogtreecommitdiff
path: root/editors/vi.c
diff options
context:
space:
mode:
authorRon Yorston2021-03-28 17:15:30 +0100
committerDenys Vlasenko2021-03-29 12:16:21 +0200
commit15f4ac3ca99bca8811a334f9c7603969ab7ad362 (patch)
tree36d2dc12f4174725a709a491f47d6c3b07a58891 /editors/vi.c
parent50a2db7dff696c0196fcc9a27db6154983bae149 (diff)
downloadbusybox-15f4ac3ca99bca8811a334f9c7603969ab7ad362.zip
busybox-15f4ac3ca99bca8811a334f9c7603969ab7ad362.tar.gz
vi: improvements to character search within line
- Use a common routine to handle all commands to search for a character in a line. - When searching for the nth occurrence of a character don't move the cursor if fewer than n occurrences are present. - Add support for the 'T' command, search backwards for character after next occurrence of given character. function old new delta do_cmd 4861 4805 -56 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 0/1 up/down: 0/-56) Total: -56 bytes v2: Add parentheses to avoid searches continuing past end of line. Signed-off-by: Ron Yorston <rmy@pobox.com> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'editors/vi.c')
-rw-r--r--editors/vi.c80
1 files changed, 39 insertions, 41 deletions
diff --git a/editors/vi.c b/editors/vi.c
index 2c724a4..ec2d64d 100644
--- a/editors/vi.c
+++ b/editors/vi.c
@@ -322,7 +322,8 @@ struct globals {
char *screen; // pointer to the virtual screen buffer
int screensize; // and its size
int tabstop;
- int last_forward_char; // last char searched for with 'f' (int because of Unicode)
+ int last_search_char; // last char searched for (int because of Unicode)
+ smallint last_search_cmd; // command used to invoke last char search
#if ENABLE_FEATURE_VI_CRASHME
char last_input_char; // last char read from user
#endif
@@ -439,7 +440,8 @@ struct globals {
#define screensize (G.screensize )
#define screenbegin (G.screenbegin )
#define tabstop (G.tabstop )
-#define last_forward_char (G.last_forward_char )
+#define last_search_char (G.last_search_char )
+#define last_search_cmd (G.last_search_cmd )
#if ENABLE_FEATURE_VI_CRASHME
#define last_input_char (G.last_input_char )
#endif
@@ -1772,6 +1774,31 @@ static void dot_skip_over_ws(void)
dot++;
}
+static void dot_to_char(int cmd)
+{
+ char *q = dot;
+ int dir = islower(cmd) ? FORWARD : BACK;
+
+ if (last_search_char == 0)
+ return;
+
+ do {
+ do {
+ q += dir;
+ if ((dir == FORWARD ? q > end - 1 : q < text) || *q == '\n')
+ return;
+ } while (*q != last_search_char);
+ } while (--cmdcnt > 0);
+
+ dot = q;
+
+ // place cursor before/after char as required
+ if (cmd == 't')
+ dot_left();
+ else if (cmd == 'T')
+ dot_right();
+}
+
static void dot_scroll(int cnt, int dir)
{
char *q;
@@ -3181,11 +3208,9 @@ static void do_cmd(int c)
//case '*': // *-
//case '=': // =-
//case '@': // @-
- //case 'F': // F-
//case 'K': // K-
//case 'Q': // Q-
//case 'S': // S-
- //case 'T': // T-
//case 'V': // V-
//case '[': // [-
//case '\\': // \-
@@ -3379,36 +3404,16 @@ static void do_cmd(int c)
indicate_error();
break;
case 'f': // f- forward to a user specified char
- last_forward_char = get_one_char(); // get the search char
- //
- // dont separate these two commands. 'f' depends on ';'
- //
- //**** fall through to ... ';'
- case ';': // ;- look at rest of line for last forward char
- do {
- if (last_forward_char == 0)
- break;
- q = dot + 1;
- while (q < end - 1 && *q != '\n' && *q != last_forward_char) {
- q++;
- }
- if (*q == last_forward_char)
- dot = q;
- } while (--cmdcnt > 0);
- break;
- case ',': // repeat latest 'f' in opposite direction
- if (last_forward_char == 0)
- break;
- do {
- q = dot - 1;
- while (q >= text && *q != '\n' && *q != last_forward_char) {
- q--;
- }
- if (q >= text && *q == last_forward_char)
- dot = q;
- } while (--cmdcnt > 0);
+ case 'F': // F- backward to a user specified char
+ case 't': // t- move to char prior to next x
+ case 'T': // T- move to char after previous x
+ last_search_char = get_one_char(); // get the search char
+ last_search_cmd = c;
+ // fall through
+ case ';': // ;- look at rest of line for last search char
+ case ',': // ,- repeat latest search in opposite direction
+ dot_to_char(c != ',' ? last_search_cmd : last_search_cmd ^ 0x20);
break;
-
case '-': // -- goto prev line
do {
dot_prev();
@@ -3854,13 +3859,6 @@ static void do_cmd(int c)
}
end_cmd_q(); // stop adding to q
break;
- case 't': // t- move to char prior to next x
- last_forward_char = get_one_char();
- do_cmd(';');
- if (*dot == last_forward_char)
- dot_left();
- last_forward_char = 0;
- break;
case 'w': // w- forward a word
do {
if (isalnum(*dot) || *dot == '_') { // we are on ALNUM
@@ -4204,7 +4202,7 @@ static void edit_file(char *fn)
mark[26] = mark[27] = text; // init "previous context"
#endif
- last_forward_char = '\0';
+ last_search_char = '\0';
#if ENABLE_FEATURE_VI_CRASHME
last_input_char = '\0';
#endif