aboutsummaryrefslogtreecommitdiff
path: root/editors/vi.c
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2022-06-27 11:23:39 +0100
committerRon Yorston <rmy@pobox.com>2022-06-27 11:23:39 +0100
commitb0f279a48f5f7e57b6f6e941e4b59e9a1bc54548 (patch)
tree86430f2929d8e3eb162bcb83c512bf8a0fffe322 /editors/vi.c
parent164a4253b1b16f3923b175f425074ef2d1b04377 (diff)
parent2617a5e4c600b4577b2c18f794701276e55da43b (diff)
downloadbusybox-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.c75
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)
2204static char *char_insert(char *p, char c, int undo) // insert the char c at 'p' 2208static 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') {