aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2021-04-15 12:04:22 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2021-04-15 13:09:12 +0200
commit47c3eaa22f7bbdc1d397c3d29beae33139beecde (patch)
treeea58556dd1994fad4232a4028a760b8e6b4a9dac
parentac6495f6fbb97cb59ccd0a6744660346fd9b80b3 (diff)
downloadbusybox-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.c41
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