diff options
| author | Ron Yorston <rmy@pobox.com> | 2021-03-28 17:15:30 +0100 |
|---|---|---|
| committer | Denys Vlasenko <vda.linux@googlemail.com> | 2021-03-29 12:16:21 +0200 |
| commit | 15f4ac3ca99bca8811a334f9c7603969ab7ad362 (patch) | |
| tree | 36d2dc12f4174725a709a491f47d6c3b07a58891 | |
| parent | 50a2db7dff696c0196fcc9a27db6154983bae149 (diff) | |
| download | busybox-w32-15f4ac3ca99bca8811a334f9c7603969ab7ad362.tar.gz busybox-w32-15f4ac3ca99bca8811a334f9c7603969ab7ad362.tar.bz2 busybox-w32-15f4ac3ca99bca8811a334f9c7603969ab7ad362.zip | |
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>
| -rw-r--r-- | editors/vi.c | 80 |
1 files changed, 39 insertions, 41 deletions
diff --git a/editors/vi.c b/editors/vi.c index 2c724a448..ec2d64dfb 100644 --- a/editors/vi.c +++ b/editors/vi.c | |||
| @@ -322,7 +322,8 @@ struct globals { | |||
| 322 | char *screen; // pointer to the virtual screen buffer | 322 | char *screen; // pointer to the virtual screen buffer |
| 323 | int screensize; // and its size | 323 | int screensize; // and its size |
| 324 | int tabstop; | 324 | int tabstop; |
| 325 | int last_forward_char; // last char searched for with 'f' (int because of Unicode) | 325 | int last_search_char; // last char searched for (int because of Unicode) |
| 326 | smallint last_search_cmd; // command used to invoke last char search | ||
| 326 | #if ENABLE_FEATURE_VI_CRASHME | 327 | #if ENABLE_FEATURE_VI_CRASHME |
| 327 | char last_input_char; // last char read from user | 328 | char last_input_char; // last char read from user |
| 328 | #endif | 329 | #endif |
| @@ -439,7 +440,8 @@ struct globals { | |||
| 439 | #define screensize (G.screensize ) | 440 | #define screensize (G.screensize ) |
| 440 | #define screenbegin (G.screenbegin ) | 441 | #define screenbegin (G.screenbegin ) |
| 441 | #define tabstop (G.tabstop ) | 442 | #define tabstop (G.tabstop ) |
| 442 | #define last_forward_char (G.last_forward_char ) | 443 | #define last_search_char (G.last_search_char ) |
| 444 | #define last_search_cmd (G.last_search_cmd ) | ||
| 443 | #if ENABLE_FEATURE_VI_CRASHME | 445 | #if ENABLE_FEATURE_VI_CRASHME |
| 444 | #define last_input_char (G.last_input_char ) | 446 | #define last_input_char (G.last_input_char ) |
| 445 | #endif | 447 | #endif |
| @@ -1772,6 +1774,31 @@ static void dot_skip_over_ws(void) | |||
| 1772 | dot++; | 1774 | dot++; |
| 1773 | } | 1775 | } |
| 1774 | 1776 | ||
| 1777 | static void dot_to_char(int cmd) | ||
| 1778 | { | ||
| 1779 | char *q = dot; | ||
| 1780 | int dir = islower(cmd) ? FORWARD : BACK; | ||
| 1781 | |||
| 1782 | if (last_search_char == 0) | ||
| 1783 | return; | ||
| 1784 | |||
| 1785 | do { | ||
| 1786 | do { | ||
| 1787 | q += dir; | ||
| 1788 | if ((dir == FORWARD ? q > end - 1 : q < text) || *q == '\n') | ||
| 1789 | return; | ||
| 1790 | } while (*q != last_search_char); | ||
| 1791 | } while (--cmdcnt > 0); | ||
| 1792 | |||
| 1793 | dot = q; | ||
| 1794 | |||
| 1795 | // place cursor before/after char as required | ||
| 1796 | if (cmd == 't') | ||
| 1797 | dot_left(); | ||
| 1798 | else if (cmd == 'T') | ||
| 1799 | dot_right(); | ||
| 1800 | } | ||
| 1801 | |||
| 1775 | static void dot_scroll(int cnt, int dir) | 1802 | static void dot_scroll(int cnt, int dir) |
| 1776 | { | 1803 | { |
| 1777 | char *q; | 1804 | char *q; |
| @@ -3181,11 +3208,9 @@ static void do_cmd(int c) | |||
| 3181 | //case '*': // *- | 3208 | //case '*': // *- |
| 3182 | //case '=': // =- | 3209 | //case '=': // =- |
| 3183 | //case '@': // @- | 3210 | //case '@': // @- |
| 3184 | //case 'F': // F- | ||
| 3185 | //case 'K': // K- | 3211 | //case 'K': // K- |
| 3186 | //case 'Q': // Q- | 3212 | //case 'Q': // Q- |
| 3187 | //case 'S': // S- | 3213 | //case 'S': // S- |
| 3188 | //case 'T': // T- | ||
| 3189 | //case 'V': // V- | 3214 | //case 'V': // V- |
| 3190 | //case '[': // [- | 3215 | //case '[': // [- |
| 3191 | //case '\\': // \- | 3216 | //case '\\': // \- |
| @@ -3379,36 +3404,16 @@ static void do_cmd(int c) | |||
| 3379 | indicate_error(); | 3404 | indicate_error(); |
| 3380 | break; | 3405 | break; |
| 3381 | case 'f': // f- forward to a user specified char | 3406 | case 'f': // f- forward to a user specified char |
| 3382 | last_forward_char = get_one_char(); // get the search char | 3407 | case 'F': // F- backward to a user specified char |
| 3383 | // | 3408 | case 't': // t- move to char prior to next x |
| 3384 | // dont separate these two commands. 'f' depends on ';' | 3409 | case 'T': // T- move to char after previous x |
| 3385 | // | 3410 | last_search_char = get_one_char(); // get the search char |
| 3386 | //**** fall through to ... ';' | 3411 | last_search_cmd = c; |
| 3387 | case ';': // ;- look at rest of line for last forward char | 3412 | // fall through |
| 3388 | do { | 3413 | case ';': // ;- look at rest of line for last search char |
| 3389 | if (last_forward_char == 0) | 3414 | case ',': // ,- repeat latest search in opposite direction |
| 3390 | break; | 3415 | dot_to_char(c != ',' ? last_search_cmd : last_search_cmd ^ 0x20); |
| 3391 | q = dot + 1; | ||
| 3392 | while (q < end - 1 && *q != '\n' && *q != last_forward_char) { | ||
| 3393 | q++; | ||
| 3394 | } | ||
| 3395 | if (*q == last_forward_char) | ||
| 3396 | dot = q; | ||
| 3397 | } while (--cmdcnt > 0); | ||
| 3398 | break; | ||
| 3399 | case ',': // repeat latest 'f' in opposite direction | ||
| 3400 | if (last_forward_char == 0) | ||
| 3401 | break; | ||
| 3402 | do { | ||
| 3403 | q = dot - 1; | ||
| 3404 | while (q >= text && *q != '\n' && *q != last_forward_char) { | ||
| 3405 | q--; | ||
| 3406 | } | ||
| 3407 | if (q >= text && *q == last_forward_char) | ||
| 3408 | dot = q; | ||
| 3409 | } while (--cmdcnt > 0); | ||
| 3410 | break; | 3416 | break; |
| 3411 | |||
| 3412 | case '-': // -- goto prev line | 3417 | case '-': // -- goto prev line |
| 3413 | do { | 3418 | do { |
| 3414 | dot_prev(); | 3419 | dot_prev(); |
| @@ -3854,13 +3859,6 @@ static void do_cmd(int c) | |||
| 3854 | } | 3859 | } |
| 3855 | end_cmd_q(); // stop adding to q | 3860 | end_cmd_q(); // stop adding to q |
| 3856 | break; | 3861 | break; |
| 3857 | case 't': // t- move to char prior to next x | ||
| 3858 | last_forward_char = get_one_char(); | ||
| 3859 | do_cmd(';'); | ||
| 3860 | if (*dot == last_forward_char) | ||
| 3861 | dot_left(); | ||
| 3862 | last_forward_char = 0; | ||
| 3863 | break; | ||
| 3864 | case 'w': // w- forward a word | 3862 | case 'w': // w- forward a word |
| 3865 | do { | 3863 | do { |
| 3866 | if (isalnum(*dot) || *dot == '_') { // we are on ALNUM | 3864 | if (isalnum(*dot) || *dot == '_') { // we are on ALNUM |
| @@ -4204,7 +4202,7 @@ static void edit_file(char *fn) | |||
| 4204 | mark[26] = mark[27] = text; // init "previous context" | 4202 | mark[26] = mark[27] = text; // init "previous context" |
| 4205 | #endif | 4203 | #endif |
| 4206 | 4204 | ||
| 4207 | last_forward_char = '\0'; | 4205 | last_search_char = '\0'; |
| 4208 | #if ENABLE_FEATURE_VI_CRASHME | 4206 | #if ENABLE_FEATURE_VI_CRASHME |
| 4209 | last_input_char = '\0'; | 4207 | last_input_char = '\0'; |
| 4210 | #endif | 4208 | #endif |
