aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Fox <pgf@brightstareng.com>2008-03-06 01:34:23 +0000
committerPaul Fox <pgf@brightstareng.com>2008-03-06 01:34:23 +0000
commitc51fc7bed6d6555997fdfb3879f42c6b1191465c (patch)
treef4819ba9be3b4ad6a8744775dc69631f0477312a
parentb4a5087ee006bfee20c7272e92322f9f6377d042 (diff)
downloadbusybox-w32-c51fc7bed6d6555997fdfb3879f42c6b1191465c.tar.gz
busybox-w32-c51fc7bed6d6555997fdfb3879f42c6b1191465c.tar.bz2
busybox-w32-c51fc7bed6d6555997fdfb3879f42c6b1191465c.zip
fixed the "dot" (i.e. '.') command, to properly re-init its
buffer between commands, not recalculate its length all the time, and to not reallocate its fixed-length buffer frequently. fixed the 'c', 'd', and 'y' commands to properly handle both motions that are just part of a line, and those that are multiline. for instance, now "c%" and "2cw" work correctly, whether the motions span lines or not. added some permissble motions for 'c', 'd', and 'y': namely 'h', 'l', SPACE, BS, and DEL
-rw-r--r--editors/vi.c123
1 files changed, 65 insertions, 58 deletions
diff --git a/editors/vi.c b/editors/vi.c
index 31ad96c02..d9db94322 100644
--- a/editors/vi.c
+++ b/editors/vi.c
@@ -170,6 +170,7 @@ static smallint readonly_mode = 0;
170#if ENABLE_FEATURE_VI_DOT_CMD 170#if ENABLE_FEATURE_VI_DOT_CMD
171static smallint adding2q; // are we currently adding user input to q 171static smallint adding2q; // are we currently adding user input to q
172static char *last_modifying_cmd; // [MAX_INPUT_LEN] last modifying cmd for "." 172static char *last_modifying_cmd; // [MAX_INPUT_LEN] last modifying cmd for "."
173static smallint lmc_len; // length of last_modifying_cmd
173static char *ioq, *ioq_start; // pointer to string for get_one_char to "read" 174static char *ioq, *ioq_start; // pointer to string for get_one_char to "read"
174#endif 175#endif
175#if ENABLE_FEATURE_VI_OPTIMIZE_CURSOR 176#if ENABLE_FEATURE_VI_OPTIMIZE_CURSOR
@@ -262,7 +263,7 @@ static char *bound_dot(char *); // make sure text[0] <= P < "end"
262static char *new_screen(int, int); // malloc virtual screen memory 263static char *new_screen(int, int); // malloc virtual screen memory
263static char *char_insert(char *, char); // insert the char c at 'p' 264static char *char_insert(char *, char); // insert the char c at 'p'
264static char *stupid_insert(char *, char); // stupidly insert the char c at 'p' 265static char *stupid_insert(char *, char); // stupidly insert the char c at 'p'
265static char find_range(char **, char **, char); // return pointers for an object 266static int find_range(char **, char **, char); // return pointers for an object
266static int st_test(char *, int, int, char *); // helper for skip_thing() 267static int st_test(char *, int, int, char *); // helper for skip_thing()
267static char *skip_thing(char *, int, int, int); // skip some object 268static char *skip_thing(char *, int, int, int); // skip some object
268static char *find_pair(char *, char); // find matching pair () [] {} 269static char *find_pair(char *, char); // find matching pair () [] {}
@@ -526,9 +527,9 @@ static void edit_file(char *fn)
526 offset = 0; // no horizontal offset 527 offset = 0; // no horizontal offset
527 c = '\0'; 528 c = '\0';
528#if ENABLE_FEATURE_VI_DOT_CMD 529#if ENABLE_FEATURE_VI_DOT_CMD
529 free(last_modifying_cmd);
530 free(ioq_start); 530 free(ioq_start);
531 ioq = ioq_start = last_modifying_cmd = NULL; 531 ioq = ioq_start = NULL;
532 lmc_len = 0;
532 adding2q = 0; 533 adding2q = 0;
533#endif 534#endif
534 redraw(FALSE); // dont force every col re-draw 535 redraw(FALSE); // dont force every col re-draw
@@ -1662,10 +1663,10 @@ static char *stupid_insert(char * p, char c) // stupidly insert the char c at 'p
1662 return p; 1663 return p;
1663} 1664}
1664 1665
1665static char find_range(char ** start, char ** stop, char c) 1666static int find_range(char ** start, char ** stop, char c)
1666{ 1667{
1667 char *save_dot, *p, *q; 1668 char *save_dot, *p, *q, *t;
1668 int cnt; 1669 int cnt, multiline = 0;
1669 1670
1670 save_dot = dot; 1671 save_dot = dot;
1671 p = q = dot; 1672 p = q = dot;
@@ -1677,7 +1678,7 @@ static char find_range(char ** start, char ** stop, char c)
1677 q = next_line(q); 1678 q = next_line(q);
1678 } 1679 }
1679 q = end_line(q); 1680 q = end_line(q);
1680 } else if (strchr("^%$0bBeEft", c)) { 1681 } else if (strchr("^%$0bBeEfth\b\177", c)) {
1681 // These cmds operate on char positions 1682 // These cmds operate on char positions
1682 do_cmd(c); // execute movement cmd 1683 do_cmd(c); // execute movement cmd
1683 q = dot; 1684 q = dot;
@@ -1706,17 +1707,33 @@ static char find_range(char ** start, char ** stop, char c)
1706 dot_end(); // find NL 1707 dot_end(); // find NL
1707 q = dot; 1708 q = dot;
1708 } else { 1709 } else {
1709 c = 27; // error- return an ESC char 1710 // nothing -- this causes any other values of c to
1710 //break; 1711 // represent the one-character range under the
1712 // cursor. this is correct for ' ' and 'l', but
1713 // perhaps no others.
1714 //
1711 } 1715 }
1712 *start = p;
1713 *stop = q;
1714 if (q < p) { 1716 if (q < p) {
1715 *start = q; 1717 t = q;
1716 *stop = p; 1718 q = p;
1719 p = t;
1717 } 1720 }
1721
1722 // backward char movements don't include start position
1723 if (q > p && strchr("^0bBh\b\177", c)) q--;
1724
1725 multiline = 0;
1726 for (t = p; t <= q; t++) {
1727 if (*t == '\n') {
1728 multiline = 1;
1729 break;
1730 }
1731 }
1732
1733 *start = p;
1734 *stop = q;
1718 dot = save_dot; 1735 dot = save_dot;
1719 return c; 1736 return multiline;
1720} 1737}
1721 1738
1722static int st_test(char * p, int type, int dir, char * tested) 1739static int st_test(char * p, int type, int dir, char * tested)
@@ -1780,27 +1797,12 @@ static char *find_pair(char * p, const char c)
1780 level = 1; 1797 level = 1;
1781 dir = 1; // assume forward 1798 dir = 1; // assume forward
1782 switch (c) { 1799 switch (c) {
1783 case '(': 1800 case '(': match = ')'; break;
1784 match = ')'; 1801 case '[': match = ']'; break;
1785 break; 1802 case '{': match = '}'; break;
1786 case '[': 1803 case ')': match = '('; dir = -1; break;
1787 match = ']'; 1804 case ']': match = '['; dir = -1; break;
1788 break; 1805 case '}': match = '{'; dir = -1; break;
1789 case '{':
1790 match = '}';
1791 break;
1792 case ')':
1793 match = '(';
1794 dir = -1;
1795 break;
1796 case ']':
1797 match = '[';
1798 dir = -1;
1799 break;
1800 case '}':
1801 match = '{';
1802 dir = -1;
1803 break;
1804 } 1806 }
1805 for (q = p + dir; text <= q && q < end; q += dir) { 1807 for (q = p + dir; text <= q && q < end; q += dir) {
1806 // look for match, count levels of pairs (( )) 1808 // look for match, count levels of pairs (( ))
@@ -1976,10 +1978,10 @@ static void start_new_cmd_q(char c)
1976 last_modifying_cmd = xzalloc(MAX_INPUT_LEN); 1978 last_modifying_cmd = xzalloc(MAX_INPUT_LEN);
1977 // if there is a current cmd count put it in the buffer first 1979 // if there is a current cmd count put it in the buffer first
1978 if (cmdcnt > 0) 1980 if (cmdcnt > 0)
1979 sprintf(last_modifying_cmd, "%d%c", cmdcnt, c); 1981 lmc_len = sprintf(last_modifying_cmd, "%d%c", cmdcnt, c);
1980 else { // just save char c onto queue 1982 else { // just save char c onto queue
1981 last_modifying_cmd[0] = c; 1983 last_modifying_cmd[0] = c;
1982 last_modifying_cmd[1] = '\0'; 1984 lmc_len = 1;
1983 } 1985 }
1984 adding2q = 1; 1986 adding2q = 1;
1985} 1987}
@@ -2280,9 +2282,6 @@ static char get_one_char(void)
2280 char c; 2282 char c;
2281 2283
2282#if ENABLE_FEATURE_VI_DOT_CMD 2284#if ENABLE_FEATURE_VI_DOT_CMD
2283 // ! adding2q && ioq == 0 read()
2284 // ! adding2q && ioq != 0 *ioq
2285 // adding2q *last_modifying_cmd= read()
2286 if (!adding2q) { 2285 if (!adding2q) {
2287 // we are not adding to the q. 2286 // we are not adding to the q.
2288 // but, we may be reading from a q 2287 // but, we may be reading from a q
@@ -2303,12 +2302,11 @@ static char get_one_char(void)
2303 // adding STDIN chars to q 2302 // adding STDIN chars to q
2304 c = readit(); // get the users input 2303 c = readit(); // get the users input
2305 if (last_modifying_cmd != NULL) { 2304 if (last_modifying_cmd != NULL) {
2306 int len = strlen(last_modifying_cmd); 2305 if (lmc_len >= MAX_INPUT_LEN - 1) {
2307 if (len >= MAX_INPUT_LEN - 1) {
2308 status_line_bold("last_modifying_cmd overrun"); 2306 status_line_bold("last_modifying_cmd overrun");
2309 } else { 2307 } else {
2310 // add new char to q 2308 // add new char to q
2311 last_modifying_cmd[len] = c; 2309 last_modifying_cmd[lmc_len++] = c;
2312 } 2310 }
2313 } 2311 }
2314 } 2312 }
@@ -2947,7 +2945,7 @@ static void do_cmd(char c)
2947 char c1, *p, *q, *save_dot; 2945 char c1, *p, *q, *save_dot;
2948 char buf[12]; 2946 char buf[12];
2949 int dir = dir; // for compiler 2947 int dir = dir; // for compiler
2950 int cnt, i, j, yf; 2948 int cnt, i, j;
2951 2949
2952// c1 = c; // quiet the compiler 2950// c1 = c; // quiet the compiler
2953// cnt = yf = 0; // quiet the compiler 2951// cnt = yf = 0; // quiet the compiler
@@ -3282,7 +3280,8 @@ static void do_cmd(char c)
3282 case '.': // .- repeat the last modifying command 3280 case '.': // .- repeat the last modifying command
3283 // Stuff the last_modifying_cmd back into stdin 3281 // Stuff the last_modifying_cmd back into stdin
3284 // and let it be re-executed. 3282 // and let it be re-executed.
3285 if (last_modifying_cmd != NULL) { 3283 if (last_modifying_cmd != NULL && lmc_len > 0) {
3284 last_modifying_cmd[lmc_len] = 0;
3286 ioq = ioq_start = xstrdup(last_modifying_cmd); 3285 ioq = ioq_start = xstrdup(last_modifying_cmd);
3287 } 3286 }
3288 break; 3287 break;
@@ -3668,6 +3667,8 @@ static void do_cmd(char c)
3668 case 'y': // y- yank something 3667 case 'y': // y- yank something
3669 case 'Y': // Y- Yank a line 3668 case 'Y': // Y- Yank a line
3670#endif 3669#endif
3670 {
3671 int yf, ml, whole = 0;
3671 yf = YANKDEL; // assume either "c" or "d" 3672 yf = YANKDEL; // assume either "c" or "d"
3672#if ENABLE_FEATURE_VI_YANKMARK 3673#if ENABLE_FEATURE_VI_YANKMARK
3673 if (c == 'y' || c == 'Y') 3674 if (c == 'y' || c == 'Y')
@@ -3676,7 +3677,8 @@ static void do_cmd(char c)
3676 c1 = 'y'; 3677 c1 = 'y';
3677 if (c != 'Y') 3678 if (c != 'Y')
3678 c1 = get_one_char(); // get the type of thing to delete 3679 c1 = get_one_char(); // get the type of thing to delete
3679 find_range(&p, &q, c1); 3680 // determine range, and whether it spans lines
3681 ml = find_range(&p, &q, c1);
3680 if (c1 == 27) { // ESC- user changed mind and wants out 3682 if (c1 == 27) { // ESC- user changed mind and wants out
3681 c = c1 = 27; // Escape- do nothing 3683 c = c1 = 27; // Escape- do nothing
3682 } else if (strchr("wW", c1)) { 3684 } else if (strchr("wW", c1)) {
@@ -3688,27 +3690,31 @@ static void do_cmd(char c)
3688 q--; 3690 q--;
3689 } 3691 }
3690 } 3692 }
3691 dot = yank_delete(p, q, 0, yf); // delete word 3693 dot = yank_delete(p, q, ml, yf); // delete word
3692 } else if (strchr("^0bBeEft$", c1)) { 3694 } else if (strchr("^0bBeEft%$ lh\b\177", c1)) {
3693 // single line copy text into a register and delete 3695 // partial line copy text into a register and delete
3694 dot = yank_delete(p, q, 0, yf); // delete word 3696 dot = yank_delete(p, q, ml, yf); // delete word
3695 } else if (strchr("cdykjHL%+-{}\r\n", c1)) { 3697 } else if (strchr("cdykjHL+-{}\r\n", c1)) {
3696 // multiple line copy text into a register and delete 3698 // whole line copy text into a register and delete
3697 dot = yank_delete(p, q, 1, yf); // delete lines 3699 dot = yank_delete(p, q, ml, yf); // delete lines
3700 whole = 1;
3701 } else {
3702 // could not recognize object
3703 c = c1 = 27; // error-
3704 ml = 0;
3705 indicate_error(c);
3706 }
3707 if (ml && whole) {
3698 if (c == 'c') { 3708 if (c == 'c') {
3699 dot = char_insert(dot, '\n'); 3709 dot = char_insert(dot, '\n');
3700 // on the last line of file don't move to prev line 3710 // on the last line of file don't move to prev line
3701 if (dot != (end-1)) { 3711 if (whole && dot != (end-1)) {
3702 dot_prev(); 3712 dot_prev();
3703 } 3713 }
3704 } else if (c == 'd') { 3714 } else if (c == 'd') {
3705 dot_begin(); 3715 dot_begin();
3706 dot_skip_over_ws(); 3716 dot_skip_over_ws();
3707 } 3717 }
3708 } else {
3709 // could not recognize object
3710 c = c1 = 27; // error-
3711 indicate_error(c);
3712 } 3718 }
3713 if (c1 != 27) { 3719 if (c1 != 27) {
3714 // if CHANGING, not deleting, start inserting after the delete 3720 // if CHANGING, not deleting, start inserting after the delete
@@ -3734,6 +3740,7 @@ static void do_cmd(char c)
3734#endif 3740#endif
3735 end_cmd_q(); // stop adding to q 3741 end_cmd_q(); // stop adding to q
3736 } 3742 }
3743 }
3737 break; 3744 break;
3738 case 'k': // k- goto prev line, same col 3745 case 'k': // k- goto prev line, same col
3739 case VI_K_UP: // cursor key Up 3746 case VI_K_UP: // cursor key Up