diff options
| author | Ron Yorston <rmy@pobox.com> | 2021-04-15 12:04:22 +0100 |
|---|---|---|
| committer | Denys Vlasenko <vda.linux@googlemail.com> | 2021-04-15 13:09:12 +0200 |
| commit | 47c3eaa22f7bbdc1d397c3d29beae33139beecde (patch) | |
| tree | ea58556dd1994fad4232a4028a760b8e6b4a9dac | |
| parent | ac6495f6fbb97cb59ccd0a6744660346fd9b80b3 (diff) | |
| download | busybox-w32-47c3eaa22f7bbdc1d397c3d29beae33139beecde.tar.gz busybox-w32-47c3eaa22f7bbdc1d397c3d29beae33139beecde.tar.bz2 busybox-w32-47c3eaa22f7bbdc1d397c3d29beae33139beecde.zip | |
vi: correct autoindent for 'O' command
Opening a line above the current line with the 'O' command should
use the current, not previous, line to determine how much to
autoindent.
function old new delta
char_insert 531 563 +32
do_cmd 4746 4723 -23
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/1 up/down: 32/-23) Total: 9 bytes
Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
| -rw-r--r-- | editors/vi.c | 41 |
1 files changed, 29 insertions, 12 deletions
diff --git a/editors/vi.c b/editors/vi.c index 0a82f9e38..b77406967 100644 --- a/editors/vi.c +++ b/editors/vi.c | |||
| @@ -286,6 +286,7 @@ struct globals { | |||
| 286 | int text_size; // size of the allocated buffer | 286 | int text_size; // size of the allocated buffer |
| 287 | 287 | ||
| 288 | // the rest | 288 | // the rest |
| 289 | #if ENABLE_FEATURE_VI_SETOPTS | ||
| 289 | smallint vi_setops; // set by setops() | 290 | smallint vi_setops; // set by setops() |
| 290 | #define VI_AUTOINDENT (1 << 0) | 291 | #define VI_AUTOINDENT (1 << 0) |
| 291 | #define VI_ERR_METHOD (1 << 1) | 292 | #define VI_ERR_METHOD (1 << 1) |
| @@ -296,6 +297,7 @@ struct globals { | |||
| 296 | #define err_method (vi_setops & VI_ERR_METHOD) // indicate error with beep or flash | 297 | #define err_method (vi_setops & VI_ERR_METHOD) // indicate error with beep or flash |
| 297 | #define ignorecase (vi_setops & VI_IGNORECASE) | 298 | #define ignorecase (vi_setops & VI_IGNORECASE) |
| 298 | #define showmatch (vi_setops & VI_SHOWMATCH ) | 299 | #define showmatch (vi_setops & VI_SHOWMATCH ) |
| 300 | #define openabove (vi_setops & VI_TABSTOP ) | ||
| 299 | // order of constants and strings must match | 301 | // order of constants and strings must match |
| 300 | #define OPTS_STR \ | 302 | #define OPTS_STR \ |
| 301 | "ai\0""autoindent\0" \ | 303 | "ai\0""autoindent\0" \ |
| @@ -303,6 +305,15 @@ struct globals { | |||
| 303 | "ic\0""ignorecase\0" \ | 305 | "ic\0""ignorecase\0" \ |
| 304 | "sm\0""showmatch\0" \ | 306 | "sm\0""showmatch\0" \ |
| 305 | "ts\0""tabstop\0" | 307 | "ts\0""tabstop\0" |
| 308 | #define set_openabove() (vi_setops |= VI_TABSTOP) | ||
| 309 | #define clear_openabove() (vi_setops &= ~VI_TABSTOP) | ||
| 310 | #else | ||
| 311 | #define autoindent (0) | ||
| 312 | #define err_method (0) | ||
| 313 | #define openabove (0) | ||
| 314 | #define set_openabove() ((void)0) | ||
| 315 | #define clear_openabove() ((void)0) | ||
| 316 | #endif | ||
| 306 | 317 | ||
| 307 | #if ENABLE_FEATURE_VI_READONLY | 318 | #if ENABLE_FEATURE_VI_READONLY |
| 308 | smallint readonly_mode; | 319 | smallint readonly_mode; |
| @@ -2130,8 +2141,13 @@ static char *char_insert(char *p, char c, int undo) // insert the char c at 'p' | |||
| 2130 | showmatching(p - 1); | 2141 | showmatching(p - 1); |
| 2131 | } | 2142 | } |
| 2132 | if (autoindent && c == '\n') { // auto indent the new line | 2143 | if (autoindent && c == '\n') { // auto indent the new line |
| 2133 | q = prev_line(p); // use prev line as template | 2144 | // use current/previous line as template |
| 2145 | q = openabove ? p : prev_line(p); | ||
| 2134 | len = strspn(q, " \t"); // space or tab | 2146 | len = strspn(q, " \t"); // space or tab |
| 2147 | if (openabove) { | ||
| 2148 | p--; // this replaces dot_prev() in do_cmd() | ||
| 2149 | q += len; // template will be shifted by text_hole_make() | ||
| 2150 | } | ||
| 2135 | if (len) { | 2151 | if (len) { |
| 2136 | uintptr_t bias; | 2152 | uintptr_t bias; |
| 2137 | bias = text_hole_make(p, len); | 2153 | bias = text_hole_make(p, len); |
| @@ -2445,6 +2461,7 @@ static void setops(char *args, int flg_no) | |||
| 2445 | index = 1 << (index >> 1); // convert to VI_bit | 2461 | index = 1 << (index >> 1); // convert to VI_bit |
| 2446 | 2462 | ||
| 2447 | if (index & VI_TABSTOP) { | 2463 | if (index & VI_TABSTOP) { |
| 2464 | // don't set this bit in vi_setops, it's reused as 'openabove' | ||
| 2448 | int t; | 2465 | int t; |
| 2449 | if (!eq || flg_no) // no "=NNN" or it is "notabstop"? | 2466 | if (!eq || flg_no) // no "=NNN" or it is "notabstop"? |
| 2450 | goto bad; | 2467 | goto bad; |
| @@ -3841,19 +3858,19 @@ static void do_cmd(int c) | |||
| 3841 | dot = next_line(dot); | 3858 | dot = next_line(dot); |
| 3842 | dot_skip_over_ws(); | 3859 | dot_skip_over_ws(); |
| 3843 | break; | 3860 | break; |
| 3844 | case 'O': // O- open a empty line above | 3861 | case 'O': // O- open an empty line above |
| 3845 | // 0i\n ESC -i | 3862 | dot_begin(); |
| 3846 | p = begin_line(dot); | 3863 | set_openabove(); |
| 3847 | if (p[-1] == '\n') { | 3864 | goto dc3; |
| 3865 | case 'o': // o- open an empty line below | ||
| 3866 | dot_end(); | ||
| 3867 | dc3: | ||
| 3868 | dot = char_insert(dot, '\n', ALLOW_UNDO); | ||
| 3869 | if (c == 'O' && !autoindent) { | ||
| 3870 | // done in char_insert() for openabove+autoindent | ||
| 3848 | dot_prev(); | 3871 | dot_prev(); |
| 3849 | case 'o': // o- open a empty line below; Yes, I know it is in the middle of the "if (..." | ||
| 3850 | dot_end(); | ||
| 3851 | dot = char_insert(dot, '\n', ALLOW_UNDO); | ||
| 3852 | } else { | ||
| 3853 | dot_begin(); // 0 | ||
| 3854 | dot = char_insert(dot, '\n', ALLOW_UNDO); // i\n ESC | ||
| 3855 | dot_prev(); // - | ||
| 3856 | } | 3872 | } |
| 3873 | clear_openabove(); | ||
| 3857 | goto dc_i; | 3874 | goto dc_i; |
| 3858 | break; | 3875 | break; |
| 3859 | case 'R': // R- continuous Replace char | 3876 | case 'R': // R- continuous Replace char |
