aboutsummaryrefslogtreecommitdiff
path: root/editors/vi.c
diff options
context:
space:
mode:
Diffstat (limited to 'editors/vi.c')
-rw-r--r--editors/vi.c294
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 -----------------------------------
3073static void do_cmd(int c) 3073static 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 -----------------------------