mirror of
https://git.busybox.net/busybox.git
synced 2024-11-27 07:33:26 +08:00
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>
This commit is contained in:
parent
50a2db7dff
commit
15f4ac3ca9
80
editors/vi.c
80
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);
|
||||
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 ',': // 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);
|
||||
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
|
||||
|
Loading…
Reference in New Issue
Block a user