aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2021-03-28 17:15:30 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2021-03-29 12:16:21 +0200
commit15f4ac3ca99bca8811a334f9c7603969ab7ad362 (patch)
tree36d2dc12f4174725a709a491f47d6c3b07a58891
parent50a2db7dff696c0196fcc9a27db6154983bae149 (diff)
downloadbusybox-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.c80
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
1777static 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
1775static void dot_scroll(int cnt, int dir) 1802static 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