diff options
author | Ron Yorston <rmy@pobox.com> | 2022-06-27 11:23:39 +0100 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2022-06-27 11:23:39 +0100 |
commit | b0f279a48f5f7e57b6f6e941e4b59e9a1bc54548 (patch) | |
tree | 86430f2929d8e3eb162bcb83c512bf8a0fffe322 /editors/vi.c | |
parent | 164a4253b1b16f3923b175f425074ef2d1b04377 (diff) | |
parent | 2617a5e4c600b4577b2c18f794701276e55da43b (diff) | |
download | busybox-w32-b0f279a48f5f7e57b6f6e941e4b59e9a1bc54548.tar.gz busybox-w32-b0f279a48f5f7e57b6f6e941e4b59e9a1bc54548.tar.bz2 busybox-w32-b0f279a48f5f7e57b6f6e941e4b59e9a1bc54548.zip |
Merge branch 'busybox' into merge
Diffstat (limited to 'editors/vi.c')
-rw-r--r-- | editors/vi.c | 75 |
1 files changed, 52 insertions, 23 deletions
diff --git a/editors/vi.c b/editors/vi.c index e28db3ab6..b813747d1 100644 --- a/editors/vi.c +++ b/editors/vi.c | |||
@@ -413,7 +413,9 @@ struct globals { | |||
413 | char *last_search_pattern; // last pattern from a '/' or '?' search | 413 | char *last_search_pattern; // last pattern from a '/' or '?' search |
414 | #endif | 414 | #endif |
415 | #if ENABLE_FEATURE_VI_SETOPTS | 415 | #if ENABLE_FEATURE_VI_SETOPTS |
416 | int indentcol; // column of recently autoindent, 0 or -1 | 416 | int char_insert__indentcol; // column of recent autoindent or 0 |
417 | int newindent; // autoindent value for 'O'/'cc' commands | ||
418 | // or -1 to use indent from previous line | ||
417 | #endif | 419 | #endif |
418 | #if ENABLE_FEATURE_VI_FILE_FORMAT | 420 | #if ENABLE_FEATURE_VI_FILE_FORMAT |
419 | smallint fileformat; | 421 | smallint fileformat; |
@@ -546,7 +548,8 @@ struct globals { | |||
546 | #define ioq_start (G.ioq_start ) | 548 | #define ioq_start (G.ioq_start ) |
547 | #define dotcnt (G.dotcnt ) | 549 | #define dotcnt (G.dotcnt ) |
548 | #define last_search_pattern (G.last_search_pattern) | 550 | #define last_search_pattern (G.last_search_pattern) |
549 | #define indentcol (G.indentcol ) | 551 | #define char_insert__indentcol (G.char_insert__indentcol) |
552 | #define newindent (G.newindent ) | ||
550 | #define fileformat (G.fileformat ) | 553 | #define fileformat (G.fileformat ) |
551 | #define fileformats (G.fileformats ) | 554 | #define fileformats (G.fileformats ) |
552 | #define cmd_error (G.cmd_error ) | 555 | #define cmd_error (G.cmd_error ) |
@@ -581,10 +584,11 @@ struct globals { | |||
581 | 584 | ||
582 | #define INIT_G() do { \ | 585 | #define INIT_G() do { \ |
583 | SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \ | 586 | SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \ |
584 | last_modified_count = -1; \ | 587 | last_modified_count--; \ |
585 | /* "" but has space for 2 chars: */ \ | 588 | /* "" but has space for 2 chars: */ \ |
586 | IF_FEATURE_VI_SEARCH(last_search_pattern = xzalloc(2);) \ | 589 | IF_FEATURE_VI_SEARCH(last_search_pattern = xzalloc(2);) \ |
587 | tabstop = 8; \ | 590 | tabstop = 8; \ |
591 | IF_FEATURE_VI_SETOPTS(newindent--;) \ | ||
588 | } while (0) | 592 | } while (0) |
589 | 593 | ||
590 | #if ENABLE_FEATURE_VI_CRASHME | 594 | #if ENABLE_FEATURE_VI_CRASHME |
@@ -2204,6 +2208,7 @@ static size_t indent_len(char *p) | |||
2204 | static char *char_insert(char *p, char c, int undo) // insert the char c at 'p' | 2208 | static char *char_insert(char *p, char c, int undo) // insert the char c at 'p' |
2205 | { | 2209 | { |
2206 | #if ENABLE_FEATURE_VI_SETOPTS | 2210 | #if ENABLE_FEATURE_VI_SETOPTS |
2211 | # define indentcol char_insert__indentcol | ||
2207 | size_t len; | 2212 | size_t len; |
2208 | int col, ntab, nspc; | 2213 | int col, ntab, nspc; |
2209 | #endif | 2214 | #endif |
@@ -2232,7 +2237,8 @@ static char *char_insert(char *p, char c, int undo) // insert the char c at 'p' | |||
2232 | #if ENABLE_FEATURE_VI_SETOPTS | 2237 | #if ENABLE_FEATURE_VI_SETOPTS |
2233 | if (autoindent) { | 2238 | if (autoindent) { |
2234 | len = indent_len(bol); | 2239 | len = indent_len(bol); |
2235 | if (len && get_column(bol + len) == indentcol && bol[len] == '\n') { | 2240 | col = get_column(bol + len); |
2241 | if (len && col == indentcol && bol[len] == '\n') { | ||
2236 | // remove autoindent from otherwise empty line | 2242 | // remove autoindent from otherwise empty line |
2237 | text_hole_delete(bol, bol + len - 1, undo); | 2243 | text_hole_delete(bol, bol + len - 1, undo); |
2238 | p = bol; | 2244 | p = bol; |
@@ -2301,24 +2307,31 @@ static char *char_insert(char *p, char c, int undo) // insert the char c at 'p' | |||
2301 | showmatching(p - 1); | 2307 | showmatching(p - 1); |
2302 | } | 2308 | } |
2303 | if (autoindent && c == '\n') { // auto indent the new line | 2309 | if (autoindent && c == '\n') { // auto indent the new line |
2304 | // use indent of current/previous line | 2310 | if (newindent < 0) { |
2305 | bol = indentcol < 0 ? p : prev_line(p); | 2311 | // use indent of previous line |
2306 | len = indent_len(bol); | 2312 | bol = prev_line(p); |
2307 | col = get_column(bol + len); | 2313 | len = indent_len(bol); |
2308 | 2314 | col = get_column(bol + len); | |
2309 | if (len && col == indentcol) { | 2315 | |
2310 | // previous line was empty except for autoindent | 2316 | if (len && col == indentcol) { |
2311 | // move the indent to the current line | 2317 | // previous line was empty except for autoindent |
2312 | memmove(bol + 1, bol, len); | 2318 | // move the indent to the current line |
2313 | *bol = '\n'; | 2319 | memmove(bol + 1, bol, len); |
2314 | return p; | 2320 | *bol = '\n'; |
2321 | return p; | ||
2322 | } | ||
2323 | } else { | ||
2324 | // for 'O'/'cc' commands add indent before newly inserted NL | ||
2325 | if (p != end - 1) // but not for 'cc' at EOF | ||
2326 | p--; | ||
2327 | col = newindent; | ||
2315 | } | 2328 | } |
2316 | 2329 | ||
2317 | if (indentcol < 0) | 2330 | if (col) { |
2318 | p--; // open above, indent before newly inserted NL | 2331 | // only record indent if in insert/replace mode or for |
2319 | 2332 | // the 'o'/'O'/'cc' commands, which are switched to | |
2320 | if (len) { | 2333 | // insert mode early. |
2321 | indentcol = col; | 2334 | indentcol = cmd_mode != 0 ? col : 0; |
2322 | if (expandtab) { | 2335 | if (expandtab) { |
2323 | ntab = 0; | 2336 | ntab = 0; |
2324 | nspc = col; | 2337 | nspc = col; |
@@ -2340,6 +2353,7 @@ static char *char_insert(char *p, char c, int undo) // insert the char c at 'p' | |||
2340 | } | 2353 | } |
2341 | #if ENABLE_FEATURE_VI_SETOPTS | 2354 | #if ENABLE_FEATURE_VI_SETOPTS |
2342 | indentcol = 0; | 2355 | indentcol = 0; |
2356 | # undef indentcol | ||
2343 | #endif | 2357 | #endif |
2344 | return p; | 2358 | return p; |
2345 | } | 2359 | } |
@@ -4373,6 +4387,9 @@ static void do_cmd(int c) | |||
4373 | case 'i': // i- insert before current char | 4387 | case 'i': // i- insert before current char |
4374 | case KEYCODE_INSERT: // Cursor Key Insert | 4388 | case KEYCODE_INSERT: // Cursor Key Insert |
4375 | dc_i: | 4389 | dc_i: |
4390 | #if ENABLE_FEATURE_VI_SETOPTS | ||
4391 | newindent = -1; | ||
4392 | #endif | ||
4376 | cmd_mode = 1; // start inserting | 4393 | cmd_mode = 1; // start inserting |
4377 | undo_queue_commit(); // commit queue when cmd_mode changes | 4394 | undo_queue_commit(); // commit queue when cmd_mode changes |
4378 | break; | 4395 | break; |
@@ -4415,12 +4432,16 @@ static void do_cmd(int c) | |||
4415 | case 'O': // O- open an empty line above | 4432 | case 'O': // O- open an empty line above |
4416 | dot_begin(); | 4433 | dot_begin(); |
4417 | #if ENABLE_FEATURE_VI_SETOPTS | 4434 | #if ENABLE_FEATURE_VI_SETOPTS |
4418 | indentcol = -1; | 4435 | // special case: use indent of current line |
4436 | newindent = get_column(dot + indent_len(dot)); | ||
4419 | #endif | 4437 | #endif |
4420 | goto dc3; | 4438 | goto dc3; |
4421 | case 'o': // o- open an empty line below | 4439 | case 'o': // o- open an empty line below |
4422 | dot_end(); | 4440 | dot_end(); |
4423 | dc3: | 4441 | dc3: |
4442 | #if ENABLE_FEATURE_VI_SETOPTS | ||
4443 | cmd_mode = 1; // switch to insert mode early | ||
4444 | #endif | ||
4424 | dot = char_insert(dot, '\n', ALLOW_UNDO); | 4445 | dot = char_insert(dot, '\n', ALLOW_UNDO); |
4425 | if (c == 'O' && !autoindent) { | 4446 | if (c == 'O' && !autoindent) { |
4426 | // done in char_insert() for 'O'+autoindent | 4447 | // done in char_insert() for 'O'+autoindent |
@@ -4535,14 +4556,22 @@ static void do_cmd(int c) | |||
4535 | if (buftype == WHOLE) { | 4556 | if (buftype == WHOLE) { |
4536 | save_dot = p; // final cursor position is start of range | 4557 | save_dot = p; // final cursor position is start of range |
4537 | p = begin_line(p); | 4558 | p = begin_line(p); |
4559 | #if ENABLE_FEATURE_VI_SETOPTS | ||
4560 | if (c == 'c') // special case: use indent of current line | ||
4561 | newindent = get_column(p + indent_len(p)); | ||
4562 | #endif | ||
4538 | q = end_line(q); | 4563 | q = end_line(q); |
4539 | } | 4564 | } |
4540 | dot = yank_delete(p, q, buftype, yf, ALLOW_UNDO); // delete word | 4565 | dot = yank_delete(p, q, buftype, yf, ALLOW_UNDO); // delete word |
4541 | if (buftype == WHOLE) { | 4566 | if (buftype == WHOLE) { |
4542 | if (c == 'c') { | 4567 | if (c == 'c') { |
4568 | #if ENABLE_FEATURE_VI_SETOPTS | ||
4569 | cmd_mode = 1; // switch to insert mode early | ||
4570 | #endif | ||
4543 | dot = char_insert(dot, '\n', ALLOW_UNDO_CHAIN); | 4571 | dot = char_insert(dot, '\n', ALLOW_UNDO_CHAIN); |
4544 | // on the last line of file don't move to prev line | 4572 | // on the last line of file don't move to prev line, |
4545 | if (dot != (end-1)) { | 4573 | // handled in char_insert() if autoindent is enabled |
4574 | if (dot != (end-1) && !autoindent) { | ||
4546 | dot_prev(); | 4575 | dot_prev(); |
4547 | } | 4576 | } |
4548 | } else if (c == 'd') { | 4577 | } else if (c == 'd') { |