diff options
-rw-r--r-- | editors/vi.c | 294 |
1 files changed, 139 insertions, 155 deletions
diff --git a/editors/vi.c b/editors/vi.c index 96a0c8df7..71d600834 100644 --- a/editors/vi.c +++ b/editors/vi.c | |||
@@ -3063,7 +3063,6 @@ static void refresh(int full_screen) | |||
3063 | //----- Execute a Vi Command ----------------------------------- | 3063 | //----- Execute a Vi Command ----------------------------------- |
3064 | static void do_cmd(int c) | 3064 | static void do_cmd(int c) |
3065 | { | 3065 | { |
3066 | const char *msg = msg; // for compiler | ||
3067 | char *p, *q, *save_dot; | 3066 | char *p, *q, *save_dot; |
3068 | char buf[12]; | 3067 | char buf[12]; |
3069 | int dir; | 3068 | int dir; |
@@ -3072,8 +3071,8 @@ static void do_cmd(int c) | |||
3072 | 3071 | ||
3073 | // c1 = c; // quiet the compiler | 3072 | // c1 = c; // quiet the compiler |
3074 | // cnt = yf = 0; // quiet the compiler | 3073 | // cnt = yf = 0; // quiet the compiler |
3075 | // msg = p = q = save_dot = buf; // quiet the compiler | 3074 | // p = q = save_dot = buf; // quiet the compiler |
3076 | memset(buf, '\0', 12); | 3075 | memset(buf, '\0', sizeof(buf)); |
3077 | 3076 | ||
3078 | show_status_line(); | 3077 | show_status_line(); |
3079 | 3078 | ||
@@ -3189,19 +3188,18 @@ static void do_cmd(int c) | |||
3189 | case KEYCODE_LEFT: // cursor key Left | 3188 | case KEYCODE_LEFT: // cursor key Left |
3190 | case 8: // ctrl-H- move left (This may be ERASE char) | 3189 | case 8: // ctrl-H- move left (This may be ERASE char) |
3191 | case 0x7f: // DEL- move left (This may be ERASE char) | 3190 | case 0x7f: // DEL- move left (This may be ERASE char) |
3192 | if (--cmdcnt > 0) { | 3191 | do { |
3193 | do_cmd(c); | 3192 | dot_left(); |
3194 | } | 3193 | } while (--cmdcnt > 0); |
3195 | dot_left(); | ||
3196 | break; | 3194 | break; |
3197 | case 10: // Newline ^J | 3195 | case 10: // Newline ^J |
3198 | case 'j': // j- goto next line, same col | 3196 | case 'j': // j- goto next line, same col |
3199 | case KEYCODE_DOWN: // cursor key Down | 3197 | case KEYCODE_DOWN: // cursor key Down |
3200 | if (--cmdcnt > 0) { | 3198 | do { |
3201 | do_cmd(c); | 3199 | dot_next(); // go to next B-o-l |
3202 | } | 3200 | // try stay in same col |
3203 | dot_next(); // go to next B-o-l | 3201 | dot = move_to_col(dot, ccol + offset); |
3204 | dot = move_to_col(dot, ccol + offset); // try stay in same col | 3202 | } while (--cmdcnt > 0); |
3205 | break; | 3203 | break; |
3206 | case 12: // ctrl-L force redraw whole screen | 3204 | case 12: // ctrl-L force redraw whole screen |
3207 | case 18: // ctrl-R force redraw | 3205 | case 18: // ctrl-R force redraw |
@@ -3214,11 +3212,10 @@ static void do_cmd(int c) | |||
3214 | break; | 3212 | break; |
3215 | case 13: // Carriage Return ^M | 3213 | case 13: // Carriage Return ^M |
3216 | case '+': // +- goto next line | 3214 | case '+': // +- goto next line |
3217 | if (--cmdcnt > 0) { | 3215 | do { |
3218 | do_cmd(c); | 3216 | dot_next(); |
3219 | } | 3217 | dot_skip_over_ws(); |
3220 | dot_next(); | 3218 | } while (--cmdcnt > 0); |
3221 | dot_skip_over_ws(); | ||
3222 | break; | 3219 | break; |
3223 | case 21: // ctrl-U scroll up half screen | 3220 | case 21: // ctrl-U scroll up half screen |
3224 | dot_scroll((rows - 2) / 2, -1); | 3221 | dot_scroll((rows - 2) / 2, -1); |
@@ -3236,10 +3233,9 @@ static void do_cmd(int c) | |||
3236 | case ' ': // move right | 3233 | case ' ': // move right |
3237 | case 'l': // move right | 3234 | case 'l': // move right |
3238 | case KEYCODE_RIGHT: // Cursor Key Right | 3235 | case KEYCODE_RIGHT: // Cursor Key Right |
3239 | if (--cmdcnt > 0) { | 3236 | do { |
3240 | do_cmd(c); | 3237 | dot_right(); |
3241 | } | 3238 | } while (--cmdcnt > 0); |
3242 | dot_right(); | ||
3243 | break; | 3239 | break; |
3244 | #if ENABLE_FEATURE_VI_YANKMARK | 3240 | #if ENABLE_FEATURE_VI_YANKMARK |
3245 | case '"': // "- name a register to use for Delete/Yank | 3241 | case '"': // "- name a register to use for Delete/Yank |
@@ -3321,11 +3317,12 @@ static void do_cmd(int c) | |||
3321 | #endif /* FEATURE_VI_YANKMARK */ | 3317 | #endif /* FEATURE_VI_YANKMARK */ |
3322 | case '$': // $- goto end of line | 3318 | case '$': // $- goto end of line |
3323 | case KEYCODE_END: // Cursor Key End | 3319 | case KEYCODE_END: // Cursor Key End |
3324 | if (--cmdcnt > 0) { | 3320 | for (;;) { |
3321 | dot = end_line(dot); | ||
3322 | if (--cmdcnt > 0) | ||
3323 | break; | ||
3325 | dot_next(); | 3324 | dot_next(); |
3326 | do_cmd(c); | ||
3327 | } | 3325 | } |
3328 | dot = end_line(dot); | ||
3329 | break; | 3326 | break; |
3330 | case '%': // %- find matching char of pair () [] {} | 3327 | case '%': // %- find matching char of pair () [] {} |
3331 | for (q = dot; q < end && *q != '\n'; q++) { | 3328 | for (q = dot; q < end && *q != '\n'; q++) { |
@@ -3350,38 +3347,35 @@ static void do_cmd(int c) | |||
3350 | // | 3347 | // |
3351 | //**** fall through to ... ';' | 3348 | //**** fall through to ... ';' |
3352 | case ';': // ;- look at rest of line for last forward char | 3349 | case ';': // ;- look at rest of line for last forward char |
3353 | if (--cmdcnt > 0) { | 3350 | do { |
3354 | do_cmd(';'); | 3351 | if (last_forward_char == 0) |
3355 | } | 3352 | break; |
3356 | if (last_forward_char == 0) | 3353 | q = dot + 1; |
3357 | break; | 3354 | while (q < end - 1 && *q != '\n' && *q != last_forward_char) { |
3358 | q = dot + 1; | 3355 | q++; |
3359 | while (q < end - 1 && *q != '\n' && *q != last_forward_char) { | 3356 | } |
3360 | q++; | 3357 | if (*q == last_forward_char) |
3361 | } | 3358 | dot = q; |
3362 | if (*q == last_forward_char) | 3359 | } while (--cmdcnt > 0); |
3363 | dot = q; | ||
3364 | break; | 3360 | break; |
3365 | case ',': // repeat latest 'f' in opposite direction | 3361 | case ',': // repeat latest 'f' in opposite direction |
3366 | if (--cmdcnt > 0) { | ||
3367 | do_cmd(','); | ||
3368 | } | ||
3369 | if (last_forward_char == 0) | 3362 | if (last_forward_char == 0) |
3370 | break; | 3363 | break; |
3371 | q = dot - 1; | 3364 | do { |
3372 | while (q >= text && *q != '\n' && *q != last_forward_char) { | 3365 | q = dot - 1; |
3373 | q--; | 3366 | while (q >= text && *q != '\n' && *q != last_forward_char) { |
3374 | } | 3367 | q--; |
3375 | if (q >= text && *q == last_forward_char) | 3368 | } |
3376 | dot = q; | 3369 | if (q >= text && *q == last_forward_char) |
3370 | dot = q; | ||
3371 | } while (--cmdcnt > 0); | ||
3377 | break; | 3372 | break; |
3378 | 3373 | ||
3379 | case '-': // -- goto prev line | 3374 | case '-': // -- goto prev line |
3380 | if (--cmdcnt > 0) { | 3375 | do { |
3381 | do_cmd(c); | 3376 | dot_prev(); |
3382 | } | 3377 | dot_skip_over_ws(); |
3383 | dot_prev(); | 3378 | } while (--cmdcnt > 0); |
3384 | dot_skip_over_ws(); | ||
3385 | break; | 3379 | break; |
3386 | #if ENABLE_FEATURE_VI_DOT_CMD | 3380 | #if ENABLE_FEATURE_VI_DOT_CMD |
3387 | case '.': // .- repeat the last modifying command | 3381 | case '.': // .- repeat the last modifying command |
@@ -3413,9 +3407,6 @@ static void do_cmd(int c) | |||
3413 | // user changed mind and erased the "/"- do nothing | 3407 | // user changed mind and erased the "/"- do nothing |
3414 | break; | 3408 | break; |
3415 | case 'N': // N- backward search for last pattern | 3409 | case 'N': // N- backward search for last pattern |
3416 | if (--cmdcnt > 0) { | ||
3417 | do_cmd(c); | ||
3418 | } | ||
3419 | dir = BACK; // assume BACKWARD search | 3410 | dir = BACK; // assume BACKWARD search |
3420 | p = dot - 1; | 3411 | p = dot - 1; |
3421 | if (last_search_pattern[0] == '?') { | 3412 | if (last_search_pattern[0] == '?') { |
@@ -3427,41 +3418,41 @@ static void do_cmd(int c) | |||
3427 | case 'n': // n- repeat search for last pattern | 3418 | case 'n': // n- repeat search for last pattern |
3428 | // search rest of text[] starting at next char | 3419 | // search rest of text[] starting at next char |
3429 | // if search fails return orignal "p" not the "p+1" address | 3420 | // if search fails return orignal "p" not the "p+1" address |
3430 | if (--cmdcnt > 0) { | 3421 | do { |
3431 | do_cmd(c); | 3422 | const char *msg; |
3432 | } | ||
3433 | dc3: | 3423 | dc3: |
3434 | dir = FORWARD; // assume FORWARD search | 3424 | dir = FORWARD; // assume FORWARD search |
3435 | p = dot + 1; | 3425 | p = dot + 1; |
3436 | if (last_search_pattern[0] == '?') { | 3426 | if (last_search_pattern[0] == '?') { |
3437 | dir = BACK; | 3427 | dir = BACK; |
3438 | p = dot - 1; | 3428 | p = dot - 1; |
3439 | } | 3429 | } |
3440 | dc4: | 3430 | dc4: |
3441 | q = char_search(p, last_search_pattern + 1, dir, FULL); | 3431 | q = char_search(p, last_search_pattern + 1, dir, FULL); |
3442 | if (q != NULL) { | 3432 | if (q != NULL) { |
3443 | dot = q; // good search, update "dot" | 3433 | dot = q; // good search, update "dot" |
3444 | msg = ""; | 3434 | msg = NULL; |
3445 | goto dc2; | 3435 | goto dc2; |
3446 | } | 3436 | } |
3447 | // no pattern found between "dot" and "end"- continue at top | 3437 | // no pattern found between "dot" and "end"- continue at top |
3448 | p = text; | 3438 | p = text; |
3449 | if (dir == BACK) { | ||
3450 | p = end - 1; | ||
3451 | } | ||
3452 | q = char_search(p, last_search_pattern + 1, dir, FULL); | ||
3453 | if (q != NULL) { // found something | ||
3454 | dot = q; // found new pattern- goto it | ||
3455 | msg = "search hit BOTTOM, continuing at TOP"; | ||
3456 | if (dir == BACK) { | 3439 | if (dir == BACK) { |
3457 | msg = "search hit TOP, continuing at BOTTOM"; | 3440 | p = end - 1; |
3441 | } | ||
3442 | q = char_search(p, last_search_pattern + 1, dir, FULL); | ||
3443 | if (q != NULL) { // found something | ||
3444 | dot = q; // found new pattern- goto it | ||
3445 | msg = "search hit BOTTOM, continuing at TOP"; | ||
3446 | if (dir == BACK) { | ||
3447 | msg = "search hit TOP, continuing at BOTTOM"; | ||
3448 | } | ||
3449 | } else { | ||
3450 | msg = "Pattern not found"; | ||
3458 | } | 3451 | } |
3459 | } else { | ||
3460 | msg = "Pattern not found"; | ||
3461 | } | ||
3462 | dc2: | 3452 | dc2: |
3463 | if (*msg) | 3453 | if (msg) |
3464 | status_line_bold("%s", msg); | 3454 | status_line_bold("%s", msg); |
3455 | } while (--cmdcnt > 0); | ||
3465 | break; | 3456 | break; |
3466 | case '{': // {- move backward paragraph | 3457 | case '{': // {- move backward paragraph |
3467 | q = char_search(dot, "\n\n", BACK, FULL); | 3458 | q = char_search(dot, "\n\n", BACK, FULL); |
@@ -3580,18 +3571,17 @@ static void do_cmd(int c) | |||
3580 | case 'B': // B- back a blank-delimited Word | 3571 | case 'B': // B- back a blank-delimited Word |
3581 | case 'E': // E- end of a blank-delimited word | 3572 | case 'E': // E- end of a blank-delimited word |
3582 | case 'W': // W- forward a blank-delimited word | 3573 | case 'W': // W- forward a blank-delimited word |
3583 | if (--cmdcnt > 0) { | ||
3584 | do_cmd(c); | ||
3585 | } | ||
3586 | dir = FORWARD; | 3574 | dir = FORWARD; |
3587 | if (c == 'B') | 3575 | if (c == 'B') |
3588 | dir = BACK; | 3576 | dir = BACK; |
3589 | if (c == 'W' || isspace(dot[dir])) { | 3577 | do { |
3590 | dot = skip_thing(dot, 1, dir, S_TO_WS); | 3578 | if (c == 'W' || isspace(dot[dir])) { |
3591 | dot = skip_thing(dot, 2, dir, S_OVER_WS); | 3579 | dot = skip_thing(dot, 1, dir, S_TO_WS); |
3592 | } | 3580 | dot = skip_thing(dot, 2, dir, S_OVER_WS); |
3593 | if (c != 'W') | 3581 | } |
3594 | dot = skip_thing(dot, 1, dir, S_BEFORE_WS); | 3582 | if (c != 'W') |
3583 | dot = skip_thing(dot, 1, dir, S_BEFORE_WS); | ||
3584 | } while (--cmdcnt > 0); | ||
3595 | break; | 3585 | break; |
3596 | case 'C': // C- Change to e-o-l | 3586 | case 'C': // C- Change to e-o-l |
3597 | case 'D': // D- delete to e-o-l | 3587 | case 'D': // D- delete to e-o-l |
@@ -3642,20 +3632,19 @@ static void do_cmd(int c) | |||
3642 | case 'i': // i- insert before current char | 3632 | case 'i': // i- insert before current char |
3643 | case KEYCODE_INSERT: // Cursor Key Insert | 3633 | case KEYCODE_INSERT: // Cursor Key Insert |
3644 | dc_i: | 3634 | dc_i: |
3645 | cmd_mode = 1; // start insrting | 3635 | cmd_mode = 1; // start inserting |
3646 | break; | 3636 | break; |
3647 | case 'J': // J- join current and next lines together | 3637 | case 'J': // J- join current and next lines together |
3648 | if (--cmdcnt > 1) { | 3638 | do { |
3649 | do_cmd(c); | 3639 | dot_end(); // move to NL |
3650 | } | 3640 | if (dot < end - 1) { // make sure not last char in text[] |
3651 | dot_end(); // move to NL | 3641 | *dot++ = ' '; // replace NL with space |
3652 | if (dot < end - 1) { // make sure not last char in text[] | 3642 | file_modified++; |
3653 | *dot++ = ' '; // replace NL with space | 3643 | while (isblank(*dot)) { // delete leading WS |
3654 | file_modified++; | 3644 | dot_delete(); |
3655 | while (isblank(*dot)) { // delete leading WS | 3645 | } |
3656 | dot_delete(); | ||
3657 | } | 3646 | } |
3658 | } | 3647 | } while (--cmdcnt > 0); |
3659 | end_cmd_q(); // stop adding to q | 3648 | end_cmd_q(); // stop adding to q |
3660 | break; | 3649 | break; |
3661 | case 'L': // L- goto bottom line on screen | 3650 | case 'L': // L- goto bottom line on screen |
@@ -3699,20 +3688,19 @@ static void do_cmd(int c) | |||
3699 | case 'X': // X- delete char before dot | 3688 | case 'X': // X- delete char before dot |
3700 | case 'x': // x- delete the current char | 3689 | case 'x': // x- delete the current char |
3701 | case 's': // s- substitute the current char | 3690 | case 's': // s- substitute the current char |
3702 | if (--cmdcnt > 0) { | ||
3703 | do_cmd(c); | ||
3704 | } | ||
3705 | dir = 0; | 3691 | dir = 0; |
3706 | if (c == 'X') | 3692 | if (c == 'X') |
3707 | dir = -1; | 3693 | dir = -1; |
3708 | if (dot[dir] != '\n') { | 3694 | do { |
3709 | if (c == 'X') | 3695 | if (dot[dir] != '\n') { |
3710 | dot--; // delete prev char | 3696 | if (c == 'X') |
3711 | dot = yank_delete(dot, dot, 0, YANKDEL); // delete char | 3697 | dot--; // delete prev char |
3712 | } | 3698 | dot = yank_delete(dot, dot, 0, YANKDEL); // delete char |
3713 | if (c == 's') | 3699 | } |
3714 | goto dc_i; // start insrting | 3700 | } while (--cmdcnt > 0); |
3715 | end_cmd_q(); // stop adding to q | 3701 | end_cmd_q(); // stop adding to q |
3702 | if (c == 's') | ||
3703 | goto dc_i; // start inserting | ||
3716 | break; | 3704 | break; |
3717 | case 'Z': // Z- if modified, {write}; exit | 3705 | case 'Z': // Z- if modified, {write}; exit |
3718 | // ZZ means to save file (if necessary), then exit | 3706 | // ZZ means to save file (if necessary), then exit |
@@ -3743,23 +3731,22 @@ static void do_cmd(int c) | |||
3743 | break; | 3731 | break; |
3744 | case 'b': // b- back a word | 3732 | case 'b': // b- back a word |
3745 | case 'e': // e- end of word | 3733 | case 'e': // e- end of word |
3746 | if (--cmdcnt > 0) { | ||
3747 | do_cmd(c); | ||
3748 | } | ||
3749 | dir = FORWARD; | 3734 | dir = FORWARD; |
3750 | if (c == 'b') | 3735 | if (c == 'b') |
3751 | dir = BACK; | 3736 | dir = BACK; |
3752 | if ((dot + dir) < text || (dot + dir) > end - 1) | 3737 | do { |
3753 | break; | 3738 | if ((dot + dir) < text || (dot + dir) > end - 1) |
3754 | dot += dir; | 3739 | break; |
3755 | if (isspace(*dot)) { | 3740 | dot += dir; |
3756 | dot = skip_thing(dot, (c == 'e') ? 2 : 1, dir, S_OVER_WS); | 3741 | if (isspace(*dot)) { |
3757 | } | 3742 | dot = skip_thing(dot, (c == 'e') ? 2 : 1, dir, S_OVER_WS); |
3758 | if (isalnum(*dot) || *dot == '_') { | 3743 | } |
3759 | dot = skip_thing(dot, 1, dir, S_END_ALNUM); | 3744 | if (isalnum(*dot) || *dot == '_') { |
3760 | } else if (ispunct(*dot)) { | 3745 | dot = skip_thing(dot, 1, dir, S_END_ALNUM); |
3761 | dot = skip_thing(dot, 1, dir, S_END_PUNCT); | 3746 | } else if (ispunct(*dot)) { |
3762 | } | 3747 | dot = skip_thing(dot, 1, dir, S_END_PUNCT); |
3748 | } | ||
3749 | } while (--cmdcnt > 0); | ||
3763 | break; | 3750 | break; |
3764 | case 'c': // c- change something | 3751 | case 'c': // c- change something |
3765 | case 'd': // d- delete something | 3752 | case 'd': // d- delete something |
@@ -3844,11 +3831,10 @@ static void do_cmd(int c) | |||
3844 | } | 3831 | } |
3845 | case 'k': // k- goto prev line, same col | 3832 | case 'k': // k- goto prev line, same col |
3846 | case KEYCODE_UP: // cursor key Up | 3833 | case KEYCODE_UP: // cursor key Up |
3847 | if (--cmdcnt > 0) { | 3834 | do { |
3848 | do_cmd(c); | 3835 | dot_prev(); |
3849 | } | 3836 | dot = move_to_col(dot, ccol + offset); // try stay in same col |
3850 | dot_prev(); | 3837 | } while (--cmdcnt > 0); |
3851 | dot = move_to_col(dot, ccol + offset); // try stay in same col | ||
3852 | break; | 3838 | break; |
3853 | case 'r': // r- replace the current char with user input | 3839 | case 'r': // r- replace the current char with user input |
3854 | c1 = get_one_char(); // get the replacement char | 3840 | c1 = get_one_char(); // get the replacement char |
@@ -3866,19 +3852,18 @@ static void do_cmd(int c) | |||
3866 | last_forward_char = 0; | 3852 | last_forward_char = 0; |
3867 | break; | 3853 | break; |
3868 | case 'w': // w- forward a word | 3854 | case 'w': // w- forward a word |
3869 | if (--cmdcnt > 0) { | 3855 | do { |
3870 | do_cmd(c); | 3856 | if (isalnum(*dot) || *dot == '_') { // we are on ALNUM |
3871 | } | 3857 | dot = skip_thing(dot, 1, FORWARD, S_END_ALNUM); |
3872 | if (isalnum(*dot) || *dot == '_') { // we are on ALNUM | 3858 | } else if (ispunct(*dot)) { // we are on PUNCT |
3873 | dot = skip_thing(dot, 1, FORWARD, S_END_ALNUM); | 3859 | dot = skip_thing(dot, 1, FORWARD, S_END_PUNCT); |
3874 | } else if (ispunct(*dot)) { // we are on PUNCT | 3860 | } |
3875 | dot = skip_thing(dot, 1, FORWARD, S_END_PUNCT); | 3861 | if (dot < end - 1) |
3876 | } | 3862 | dot++; // move over word |
3877 | if (dot < end - 1) | 3863 | if (isspace(*dot)) { |
3878 | dot++; // move over word | 3864 | dot = skip_thing(dot, 2, FORWARD, S_OVER_WS); |
3879 | if (isspace(*dot)) { | 3865 | } |
3880 | dot = skip_thing(dot, 2, FORWARD, S_OVER_WS); | 3866 | } while (--cmdcnt > 0); |
3881 | } | ||
3882 | break; | 3867 | break; |
3883 | case 'z': // z- | 3868 | case 'z': // z- |
3884 | c1 = get_one_char(); // get the replacement char | 3869 | c1 = get_one_char(); // get the replacement char |
@@ -3894,17 +3879,16 @@ static void do_cmd(int c) | |||
3894 | dot = move_to_col(dot, cmdcnt - 1); // try to move to column | 3879 | dot = move_to_col(dot, cmdcnt - 1); // try to move to column |
3895 | break; | 3880 | break; |
3896 | case '~': // ~- flip the case of letters a-z -> A-Z | 3881 | case '~': // ~- flip the case of letters a-z -> A-Z |
3897 | if (--cmdcnt > 0) { | 3882 | do { |
3898 | do_cmd(c); | 3883 | if (islower(*dot)) { |
3899 | } | 3884 | *dot = toupper(*dot); |
3900 | if (islower(*dot)) { | 3885 | file_modified++; |
3901 | *dot = toupper(*dot); | 3886 | } else if (isupper(*dot)) { |
3902 | file_modified++; | 3887 | *dot = tolower(*dot); |
3903 | } else if (isupper(*dot)) { | 3888 | file_modified++; |
3904 | *dot = tolower(*dot); | 3889 | } |
3905 | file_modified++; | 3890 | dot_right(); |
3906 | } | 3891 | } while (--cmdcnt > 0); |
3907 | dot_right(); | ||
3908 | end_cmd_q(); // stop adding to q | 3892 | end_cmd_q(); // stop adding to q |
3909 | break; | 3893 | break; |
3910 | //----- The Cursor and Function Keys ----------------------------- | 3894 | //----- The Cursor and Function Keys ----------------------------- |