diff options
Diffstat (limited to 'editors/vi.c')
-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 9708679b4..d6d926e35 100644 --- a/editors/vi.c +++ b/editors/vi.c | |||
@@ -3072,7 +3072,6 @@ static void refresh(int full_screen) | |||
3072 | //----- Execute a Vi Command ----------------------------------- | 3072 | //----- Execute a Vi Command ----------------------------------- |
3073 | static void do_cmd(int c) | 3073 | static void do_cmd(int c) |
3074 | { | 3074 | { |
3075 | const char *msg = msg; // for compiler | ||
3076 | char *p, *q, *save_dot; | 3075 | char *p, *q, *save_dot; |
3077 | char buf[12]; | 3076 | char buf[12]; |
3078 | int dir; | 3077 | int dir; |
@@ -3081,8 +3080,8 @@ static void do_cmd(int c) | |||
3081 | 3080 | ||
3082 | // c1 = c; // quiet the compiler | 3081 | // c1 = c; // quiet the compiler |
3083 | // cnt = yf = 0; // quiet the compiler | 3082 | // cnt = yf = 0; // quiet the compiler |
3084 | // msg = p = q = save_dot = buf; // quiet the compiler | 3083 | // p = q = save_dot = buf; // quiet the compiler |
3085 | memset(buf, '\0', 12); | 3084 | memset(buf, '\0', sizeof(buf)); |
3086 | 3085 | ||
3087 | show_status_line(); | 3086 | show_status_line(); |
3088 | 3087 | ||
@@ -3198,19 +3197,18 @@ static void do_cmd(int c) | |||
3198 | case KEYCODE_LEFT: // cursor key Left | 3197 | case KEYCODE_LEFT: // cursor key Left |
3199 | case 8: // ctrl-H- move left (This may be ERASE char) | 3198 | case 8: // ctrl-H- move left (This may be ERASE char) |
3200 | case 0x7f: // DEL- move left (This may be ERASE char) | 3199 | case 0x7f: // DEL- move left (This may be ERASE char) |
3201 | if (--cmdcnt > 0) { | 3200 | do { |
3202 | do_cmd(c); | 3201 | dot_left(); |
3203 | } | 3202 | } while (--cmdcnt > 0); |
3204 | dot_left(); | ||
3205 | break; | 3203 | break; |
3206 | case 10: // Newline ^J | 3204 | case 10: // Newline ^J |
3207 | case 'j': // j- goto next line, same col | 3205 | case 'j': // j- goto next line, same col |
3208 | case KEYCODE_DOWN: // cursor key Down | 3206 | case KEYCODE_DOWN: // cursor key Down |
3209 | if (--cmdcnt > 0) { | 3207 | do { |
3210 | do_cmd(c); | 3208 | dot_next(); // go to next B-o-l |
3211 | } | 3209 | // try stay in same col |
3212 | dot_next(); // go to next B-o-l | 3210 | dot = move_to_col(dot, ccol + offset); |
3213 | dot = move_to_col(dot, ccol + offset); // try stay in same col | 3211 | } while (--cmdcnt > 0); |
3214 | break; | 3212 | break; |
3215 | case 12: // ctrl-L force redraw whole screen | 3213 | case 12: // ctrl-L force redraw whole screen |
3216 | case 18: // ctrl-R force redraw | 3214 | case 18: // ctrl-R force redraw |
@@ -3223,11 +3221,10 @@ static void do_cmd(int c) | |||
3223 | break; | 3221 | break; |
3224 | case 13: // Carriage Return ^M | 3222 | case 13: // Carriage Return ^M |
3225 | case '+': // +- goto next line | 3223 | case '+': // +- goto next line |
3226 | if (--cmdcnt > 0) { | 3224 | do { |
3227 | do_cmd(c); | 3225 | dot_next(); |
3228 | } | 3226 | dot_skip_over_ws(); |
3229 | dot_next(); | 3227 | } while (--cmdcnt > 0); |
3230 | dot_skip_over_ws(); | ||
3231 | break; | 3228 | break; |
3232 | case 21: // ctrl-U scroll up half screen | 3229 | case 21: // ctrl-U scroll up half screen |
3233 | dot_scroll((rows - 2) / 2, -1); | 3230 | dot_scroll((rows - 2) / 2, -1); |
@@ -3245,10 +3242,9 @@ static void do_cmd(int c) | |||
3245 | case ' ': // move right | 3242 | case ' ': // move right |
3246 | case 'l': // move right | 3243 | case 'l': // move right |
3247 | case KEYCODE_RIGHT: // Cursor Key Right | 3244 | case KEYCODE_RIGHT: // Cursor Key Right |
3248 | if (--cmdcnt > 0) { | 3245 | do { |
3249 | do_cmd(c); | 3246 | dot_right(); |
3250 | } | 3247 | } while (--cmdcnt > 0); |
3251 | dot_right(); | ||
3252 | break; | 3248 | break; |
3253 | #if ENABLE_FEATURE_VI_YANKMARK | 3249 | #if ENABLE_FEATURE_VI_YANKMARK |
3254 | case '"': // "- name a register to use for Delete/Yank | 3250 | case '"': // "- name a register to use for Delete/Yank |
@@ -3330,11 +3326,12 @@ static void do_cmd(int c) | |||
3330 | #endif /* FEATURE_VI_YANKMARK */ | 3326 | #endif /* FEATURE_VI_YANKMARK */ |
3331 | case '$': // $- goto end of line | 3327 | case '$': // $- goto end of line |
3332 | case KEYCODE_END: // Cursor Key End | 3328 | case KEYCODE_END: // Cursor Key End |
3333 | if (--cmdcnt > 0) { | 3329 | for (;;) { |
3330 | dot = end_line(dot); | ||
3331 | if (--cmdcnt > 0) | ||
3332 | break; | ||
3334 | dot_next(); | 3333 | dot_next(); |
3335 | do_cmd(c); | ||
3336 | } | 3334 | } |
3337 | dot = end_line(dot); | ||
3338 | break; | 3335 | break; |
3339 | case '%': // %- find matching char of pair () [] {} | 3336 | case '%': // %- find matching char of pair () [] {} |
3340 | for (q = dot; q < end && *q != '\n'; q++) { | 3337 | for (q = dot; q < end && *q != '\n'; q++) { |
@@ -3359,38 +3356,35 @@ static void do_cmd(int c) | |||
3359 | // | 3356 | // |
3360 | //**** fall through to ... ';' | 3357 | //**** fall through to ... ';' |
3361 | case ';': // ;- look at rest of line for last forward char | 3358 | case ';': // ;- look at rest of line for last forward char |
3362 | if (--cmdcnt > 0) { | 3359 | do { |
3363 | do_cmd(';'); | 3360 | if (last_forward_char == 0) |
3364 | } | 3361 | break; |
3365 | if (last_forward_char == 0) | 3362 | q = dot + 1; |
3366 | break; | 3363 | while (q < end - 1 && *q != '\n' && *q != last_forward_char) { |
3367 | q = dot + 1; | 3364 | q++; |
3368 | while (q < end - 1 && *q != '\n' && *q != last_forward_char) { | 3365 | } |
3369 | q++; | 3366 | if (*q == last_forward_char) |
3370 | } | 3367 | dot = q; |
3371 | if (*q == last_forward_char) | 3368 | } while (--cmdcnt > 0); |
3372 | dot = q; | ||
3373 | break; | 3369 | break; |
3374 | case ',': // repeat latest 'f' in opposite direction | 3370 | case ',': // repeat latest 'f' in opposite direction |
3375 | if (--cmdcnt > 0) { | ||
3376 | do_cmd(','); | ||
3377 | } | ||
3378 | if (last_forward_char == 0) | 3371 | if (last_forward_char == 0) |
3379 | break; | 3372 | break; |
3380 | q = dot - 1; | 3373 | do { |
3381 | while (q >= text && *q != '\n' && *q != last_forward_char) { | 3374 | q = dot - 1; |
3382 | q--; | 3375 | while (q >= text && *q != '\n' && *q != last_forward_char) { |
3383 | } | 3376 | q--; |
3384 | if (q >= text && *q == last_forward_char) | 3377 | } |
3385 | dot = q; | 3378 | if (q >= text && *q == last_forward_char) |
3379 | dot = q; | ||
3380 | } while (--cmdcnt > 0); | ||
3386 | break; | 3381 | break; |
3387 | 3382 | ||
3388 | case '-': // -- goto prev line | 3383 | case '-': // -- goto prev line |
3389 | if (--cmdcnt > 0) { | 3384 | do { |
3390 | do_cmd(c); | 3385 | dot_prev(); |
3391 | } | 3386 | dot_skip_over_ws(); |
3392 | dot_prev(); | 3387 | } while (--cmdcnt > 0); |
3393 | dot_skip_over_ws(); | ||
3394 | break; | 3388 | break; |
3395 | #if ENABLE_FEATURE_VI_DOT_CMD | 3389 | #if ENABLE_FEATURE_VI_DOT_CMD |
3396 | case '.': // .- repeat the last modifying command | 3390 | case '.': // .- repeat the last modifying command |
@@ -3422,9 +3416,6 @@ static void do_cmd(int c) | |||
3422 | // user changed mind and erased the "/"- do nothing | 3416 | // user changed mind and erased the "/"- do nothing |
3423 | break; | 3417 | break; |
3424 | case 'N': // N- backward search for last pattern | 3418 | case 'N': // N- backward search for last pattern |
3425 | if (--cmdcnt > 0) { | ||
3426 | do_cmd(c); | ||
3427 | } | ||
3428 | dir = BACK; // assume BACKWARD search | 3419 | dir = BACK; // assume BACKWARD search |
3429 | p = dot - 1; | 3420 | p = dot - 1; |
3430 | if (last_search_pattern[0] == '?') { | 3421 | if (last_search_pattern[0] == '?') { |
@@ -3436,41 +3427,41 @@ static void do_cmd(int c) | |||
3436 | case 'n': // n- repeat search for last pattern | 3427 | case 'n': // n- repeat search for last pattern |
3437 | // search rest of text[] starting at next char | 3428 | // search rest of text[] starting at next char |
3438 | // if search fails return orignal "p" not the "p+1" address | 3429 | // if search fails return orignal "p" not the "p+1" address |
3439 | if (--cmdcnt > 0) { | 3430 | do { |
3440 | do_cmd(c); | 3431 | const char *msg; |
3441 | } | ||
3442 | dc3: | 3432 | dc3: |
3443 | dir = FORWARD; // assume FORWARD search | 3433 | dir = FORWARD; // assume FORWARD search |
3444 | p = dot + 1; | 3434 | p = dot + 1; |
3445 | if (last_search_pattern[0] == '?') { | 3435 | if (last_search_pattern[0] == '?') { |
3446 | dir = BACK; | 3436 | dir = BACK; |
3447 | p = dot - 1; | 3437 | p = dot - 1; |
3448 | } | 3438 | } |
3449 | dc4: | 3439 | dc4: |
3450 | q = char_search(p, last_search_pattern + 1, dir, FULL); | 3440 | q = char_search(p, last_search_pattern + 1, dir, FULL); |
3451 | if (q != NULL) { | 3441 | if (q != NULL) { |
3452 | dot = q; // good search, update "dot" | 3442 | dot = q; // good search, update "dot" |
3453 | msg = ""; | 3443 | msg = NULL; |
3454 | goto dc2; | 3444 | goto dc2; |
3455 | } | 3445 | } |
3456 | // no pattern found between "dot" and "end"- continue at top | 3446 | // no pattern found between "dot" and "end"- continue at top |
3457 | p = text; | 3447 | p = text; |
3458 | if (dir == BACK) { | ||
3459 | p = end - 1; | ||
3460 | } | ||
3461 | q = char_search(p, last_search_pattern + 1, dir, FULL); | ||
3462 | if (q != NULL) { // found something | ||
3463 | dot = q; // found new pattern- goto it | ||
3464 | msg = "search hit BOTTOM, continuing at TOP"; | ||
3465 | if (dir == BACK) { | 3448 | if (dir == BACK) { |
3466 | msg = "search hit TOP, continuing at BOTTOM"; | 3449 | p = end - 1; |
3450 | } | ||
3451 | q = char_search(p, last_search_pattern + 1, dir, FULL); | ||
3452 | if (q != NULL) { // found something | ||
3453 | dot = q; // found new pattern- goto it | ||
3454 | msg = "search hit BOTTOM, continuing at TOP"; | ||
3455 | if (dir == BACK) { | ||
3456 | msg = "search hit TOP, continuing at BOTTOM"; | ||
3457 | } | ||
3458 | } else { | ||
3459 | msg = "Pattern not found"; | ||
3467 | } | 3460 | } |
3468 | } else { | ||
3469 | msg = "Pattern not found"; | ||
3470 | } | ||
3471 | dc2: | 3461 | dc2: |
3472 | if (*msg) | 3462 | if (msg) |
3473 | status_line_bold("%s", msg); | 3463 | status_line_bold("%s", msg); |
3464 | } while (--cmdcnt > 0); | ||
3474 | break; | 3465 | break; |
3475 | case '{': // {- move backward paragraph | 3466 | case '{': // {- move backward paragraph |
3476 | q = char_search(dot, "\n\n", BACK, FULL); | 3467 | q = char_search(dot, "\n\n", BACK, FULL); |
@@ -3589,18 +3580,17 @@ static void do_cmd(int c) | |||
3589 | case 'B': // B- back a blank-delimited Word | 3580 | case 'B': // B- back a blank-delimited Word |
3590 | case 'E': // E- end of a blank-delimited word | 3581 | case 'E': // E- end of a blank-delimited word |
3591 | case 'W': // W- forward a blank-delimited word | 3582 | case 'W': // W- forward a blank-delimited word |
3592 | if (--cmdcnt > 0) { | ||
3593 | do_cmd(c); | ||
3594 | } | ||
3595 | dir = FORWARD; | 3583 | dir = FORWARD; |
3596 | if (c == 'B') | 3584 | if (c == 'B') |
3597 | dir = BACK; | 3585 | dir = BACK; |
3598 | if (c == 'W' || isspace(dot[dir])) { | 3586 | do { |
3599 | dot = skip_thing(dot, 1, dir, S_TO_WS); | 3587 | if (c == 'W' || isspace(dot[dir])) { |
3600 | dot = skip_thing(dot, 2, dir, S_OVER_WS); | 3588 | dot = skip_thing(dot, 1, dir, S_TO_WS); |
3601 | } | 3589 | dot = skip_thing(dot, 2, dir, S_OVER_WS); |
3602 | if (c != 'W') | 3590 | } |
3603 | dot = skip_thing(dot, 1, dir, S_BEFORE_WS); | 3591 | if (c != 'W') |
3592 | dot = skip_thing(dot, 1, dir, S_BEFORE_WS); | ||
3593 | } while (--cmdcnt > 0); | ||
3604 | break; | 3594 | break; |
3605 | case 'C': // C- Change to e-o-l | 3595 | case 'C': // C- Change to e-o-l |
3606 | case 'D': // D- delete to e-o-l | 3596 | case 'D': // D- delete to e-o-l |
@@ -3651,20 +3641,19 @@ static void do_cmd(int c) | |||
3651 | case 'i': // i- insert before current char | 3641 | case 'i': // i- insert before current char |
3652 | case KEYCODE_INSERT: // Cursor Key Insert | 3642 | case KEYCODE_INSERT: // Cursor Key Insert |
3653 | dc_i: | 3643 | dc_i: |
3654 | cmd_mode = 1; // start insrting | 3644 | cmd_mode = 1; // start inserting |
3655 | break; | 3645 | break; |
3656 | case 'J': // J- join current and next lines together | 3646 | case 'J': // J- join current and next lines together |
3657 | if (--cmdcnt > 1) { | 3647 | do { |
3658 | do_cmd(c); | 3648 | dot_end(); // move to NL |
3659 | } | 3649 | if (dot < end - 1) { // make sure not last char in text[] |
3660 | dot_end(); // move to NL | 3650 | *dot++ = ' '; // replace NL with space |
3661 | if (dot < end - 1) { // make sure not last char in text[] | 3651 | file_modified++; |
3662 | *dot++ = ' '; // replace NL with space | 3652 | while (isblank(*dot)) { // delete leading WS |
3663 | file_modified++; | 3653 | dot_delete(); |
3664 | while (isblank(*dot)) { // delete leading WS | 3654 | } |
3665 | dot_delete(); | ||
3666 | } | 3655 | } |
3667 | } | 3656 | } while (--cmdcnt > 0); |
3668 | end_cmd_q(); // stop adding to q | 3657 | end_cmd_q(); // stop adding to q |
3669 | break; | 3658 | break; |
3670 | case 'L': // L- goto bottom line on screen | 3659 | case 'L': // L- goto bottom line on screen |
@@ -3708,20 +3697,19 @@ static void do_cmd(int c) | |||
3708 | case 'X': // X- delete char before dot | 3697 | case 'X': // X- delete char before dot |
3709 | case 'x': // x- delete the current char | 3698 | case 'x': // x- delete the current char |
3710 | case 's': // s- substitute the current char | 3699 | case 's': // s- substitute the current char |
3711 | if (--cmdcnt > 0) { | ||
3712 | do_cmd(c); | ||
3713 | } | ||
3714 | dir = 0; | 3700 | dir = 0; |
3715 | if (c == 'X') | 3701 | if (c == 'X') |
3716 | dir = -1; | 3702 | dir = -1; |
3717 | if (dot[dir] != '\n') { | 3703 | do { |
3718 | if (c == 'X') | 3704 | if (dot[dir] != '\n') { |
3719 | dot--; // delete prev char | 3705 | if (c == 'X') |
3720 | dot = yank_delete(dot, dot, 0, YANKDEL); // delete char | 3706 | dot--; // delete prev char |
3721 | } | 3707 | dot = yank_delete(dot, dot, 0, YANKDEL); // delete char |
3722 | if (c == 's') | 3708 | } |
3723 | goto dc_i; // start insrting | 3709 | } while (--cmdcnt > 0); |
3724 | end_cmd_q(); // stop adding to q | 3710 | end_cmd_q(); // stop adding to q |
3711 | if (c == 's') | ||
3712 | goto dc_i; // start inserting | ||
3725 | break; | 3713 | break; |
3726 | case 'Z': // Z- if modified, {write}; exit | 3714 | case 'Z': // Z- if modified, {write}; exit |
3727 | // ZZ means to save file (if necessary), then exit | 3715 | // ZZ means to save file (if necessary), then exit |
@@ -3752,23 +3740,22 @@ static void do_cmd(int c) | |||
3752 | break; | 3740 | break; |
3753 | case 'b': // b- back a word | 3741 | case 'b': // b- back a word |
3754 | case 'e': // e- end of word | 3742 | case 'e': // e- end of word |
3755 | if (--cmdcnt > 0) { | ||
3756 | do_cmd(c); | ||
3757 | } | ||
3758 | dir = FORWARD; | 3743 | dir = FORWARD; |
3759 | if (c == 'b') | 3744 | if (c == 'b') |
3760 | dir = BACK; | 3745 | dir = BACK; |
3761 | if ((dot + dir) < text || (dot + dir) > end - 1) | 3746 | do { |
3762 | break; | 3747 | if ((dot + dir) < text || (dot + dir) > end - 1) |
3763 | dot += dir; | 3748 | break; |
3764 | if (isspace(*dot)) { | 3749 | dot += dir; |
3765 | dot = skip_thing(dot, (c == 'e') ? 2 : 1, dir, S_OVER_WS); | 3750 | if (isspace(*dot)) { |
3766 | } | 3751 | dot = skip_thing(dot, (c == 'e') ? 2 : 1, dir, S_OVER_WS); |
3767 | if (isalnum(*dot) || *dot == '_') { | 3752 | } |
3768 | dot = skip_thing(dot, 1, dir, S_END_ALNUM); | 3753 | if (isalnum(*dot) || *dot == '_') { |
3769 | } else if (ispunct(*dot)) { | 3754 | dot = skip_thing(dot, 1, dir, S_END_ALNUM); |
3770 | dot = skip_thing(dot, 1, dir, S_END_PUNCT); | 3755 | } else if (ispunct(*dot)) { |
3771 | } | 3756 | dot = skip_thing(dot, 1, dir, S_END_PUNCT); |
3757 | } | ||
3758 | } while (--cmdcnt > 0); | ||
3772 | break; | 3759 | break; |
3773 | case 'c': // c- change something | 3760 | case 'c': // c- change something |
3774 | case 'd': // d- delete something | 3761 | case 'd': // d- delete something |
@@ -3853,11 +3840,10 @@ static void do_cmd(int c) | |||
3853 | } | 3840 | } |
3854 | case 'k': // k- goto prev line, same col | 3841 | case 'k': // k- goto prev line, same col |
3855 | case KEYCODE_UP: // cursor key Up | 3842 | case KEYCODE_UP: // cursor key Up |
3856 | if (--cmdcnt > 0) { | 3843 | do { |
3857 | do_cmd(c); | 3844 | dot_prev(); |
3858 | } | 3845 | dot = move_to_col(dot, ccol + offset); // try stay in same col |
3859 | dot_prev(); | 3846 | } while (--cmdcnt > 0); |
3860 | dot = move_to_col(dot, ccol + offset); // try stay in same col | ||
3861 | break; | 3847 | break; |
3862 | case 'r': // r- replace the current char with user input | 3848 | case 'r': // r- replace the current char with user input |
3863 | c1 = get_one_char(); // get the replacement char | 3849 | c1 = get_one_char(); // get the replacement char |
@@ -3875,19 +3861,18 @@ static void do_cmd(int c) | |||
3875 | last_forward_char = 0; | 3861 | last_forward_char = 0; |
3876 | break; | 3862 | break; |
3877 | case 'w': // w- forward a word | 3863 | case 'w': // w- forward a word |
3878 | if (--cmdcnt > 0) { | 3864 | do { |
3879 | do_cmd(c); | 3865 | if (isalnum(*dot) || *dot == '_') { // we are on ALNUM |
3880 | } | 3866 | dot = skip_thing(dot, 1, FORWARD, S_END_ALNUM); |
3881 | if (isalnum(*dot) || *dot == '_') { // we are on ALNUM | 3867 | } else if (ispunct(*dot)) { // we are on PUNCT |
3882 | dot = skip_thing(dot, 1, FORWARD, S_END_ALNUM); | 3868 | dot = skip_thing(dot, 1, FORWARD, S_END_PUNCT); |
3883 | } else if (ispunct(*dot)) { // we are on PUNCT | 3869 | } |
3884 | dot = skip_thing(dot, 1, FORWARD, S_END_PUNCT); | 3870 | if (dot < end - 1) |
3885 | } | 3871 | dot++; // move over word |
3886 | if (dot < end - 1) | 3872 | if (isspace(*dot)) { |
3887 | dot++; // move over word | 3873 | dot = skip_thing(dot, 2, FORWARD, S_OVER_WS); |
3888 | if (isspace(*dot)) { | 3874 | } |
3889 | dot = skip_thing(dot, 2, FORWARD, S_OVER_WS); | 3875 | } while (--cmdcnt > 0); |
3890 | } | ||
3891 | break; | 3876 | break; |
3892 | case 'z': // z- | 3877 | case 'z': // z- |
3893 | c1 = get_one_char(); // get the replacement char | 3878 | c1 = get_one_char(); // get the replacement char |
@@ -3903,17 +3888,16 @@ static void do_cmd(int c) | |||
3903 | dot = move_to_col(dot, cmdcnt - 1); // try to move to column | 3888 | dot = move_to_col(dot, cmdcnt - 1); // try to move to column |
3904 | break; | 3889 | break; |
3905 | case '~': // ~- flip the case of letters a-z -> A-Z | 3890 | case '~': // ~- flip the case of letters a-z -> A-Z |
3906 | if (--cmdcnt > 0) { | 3891 | do { |
3907 | do_cmd(c); | 3892 | if (islower(*dot)) { |
3908 | } | 3893 | *dot = toupper(*dot); |
3909 | if (islower(*dot)) { | 3894 | file_modified++; |
3910 | *dot = toupper(*dot); | 3895 | } else if (isupper(*dot)) { |
3911 | file_modified++; | 3896 | *dot = tolower(*dot); |
3912 | } else if (isupper(*dot)) { | 3897 | file_modified++; |
3913 | *dot = tolower(*dot); | 3898 | } |
3914 | file_modified++; | 3899 | dot_right(); |
3915 | } | 3900 | } while (--cmdcnt > 0); |
3916 | dot_right(); | ||
3917 | end_cmd_q(); // stop adding to q | 3901 | end_cmd_q(); // stop adding to q |
3918 | break; | 3902 | break; |
3919 | //----- The Cursor and Function Keys ----------------------------- | 3903 | //----- The Cursor and Function Keys ----------------------------- |