aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2022-03-03 11:35:46 +0000
committerDenys Vlasenko <vda.linux@googlemail.com>2022-03-04 22:57:05 +0100
commitfc7868602ecf0d761a9a877141add4a9b6918d02 (patch)
tree48f24ea664b9ad54a4b7ae8b028522d68504c1b2
parent55f969a006109703dd056bee1b6c1d11b0602449 (diff)
downloadbusybox-w32-fc7868602ecf0d761a9a877141add4a9b6918d02.tar.gz
busybox-w32-fc7868602ecf0d761a9a877141add4a9b6918d02.tar.bz2
busybox-w32-fc7868602ecf0d761a9a877141add4a9b6918d02.zip
vi: improved handling of backspace in replace mode
In replace mode ('R' command) the backspace character should get special treatment: - backspace only goes back to the start of the replacement; - backspacing over replaced characters restores the original text. Prior to this commit BusyBox vi deleted the characters both before and after the cursor in replace mode. function old new delta undo_pop - 235 +235 char_insert 858 884 +26 indicate_error 81 84 +3 find_range 654 657 +3 static.text_yank 77 79 +2 do_cmd 4486 4243 -243 ------------------------------------------------------------------------------ (add/remove: 1/0 grow/shrink: 4/1 up/down: 269/-243) Total: 26 bytes Signed-off-by: Ron Yorston <rmy@pobox.com> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--editors/vi.c24
1 files changed, 18 insertions, 6 deletions
diff --git a/editors/vi.c b/editors/vi.c
index d37cd48a3..4257c0fdc 100644
--- a/editors/vi.c
+++ b/editors/vi.c
@@ -224,6 +224,7 @@
224 224
225#endif 225#endif
226 226
227#define isbackspace(c) ((c) == term_orig.c_cc[VERASE] || (c) == 8 || (c) == 127)
227 228
228enum { 229enum {
229 MAX_TABSTOP = 32, // sanity limit 230 MAX_TABSTOP = 32, // sanity limit
@@ -342,6 +343,7 @@ struct globals {
342 int last_modified_count; // = -1; 343 int last_modified_count; // = -1;
343 int cmdline_filecnt; // how many file names on cmd line 344 int cmdline_filecnt; // how many file names on cmd line
344 int cmdcnt; // repetition count 345 int cmdcnt; // repetition count
346 char *rstart; // start of text in Replace mode
345 unsigned rows, columns; // the terminal screen is this size 347 unsigned rows, columns; // the terminal screen is this size
346#if ENABLE_FEATURE_VI_ASK_TERMINAL 348#if ENABLE_FEATURE_VI_ASK_TERMINAL
347 int get_rowcol_error; 349 int get_rowcol_error;
@@ -474,6 +476,7 @@ struct globals {
474#define last_modified_count (G.last_modified_count) 476#define last_modified_count (G.last_modified_count)
475#define cmdline_filecnt (G.cmdline_filecnt ) 477#define cmdline_filecnt (G.cmdline_filecnt )
476#define cmdcnt (G.cmdcnt ) 478#define cmdcnt (G.cmdcnt )
479#define rstart (G.rstart )
477#define rows (G.rows ) 480#define rows (G.rows )
478#define columns (G.columns ) 481#define columns (G.columns )
479#define crow (G.crow ) 482#define crow (G.crow )
@@ -1212,7 +1215,7 @@ static char *get_input_line(const char *prompt)
1212 c = get_one_char(); 1215 c = get_one_char();
1213 if (c == '\n' || c == '\r' || c == 27) 1216 if (c == '\n' || c == '\r' || c == 27)
1214 break; // this is end of input 1217 break; // this is end of input
1215 if (c == term_orig.c_cc[VERASE] || c == 8 || c == 127) { 1218 if (isbackspace(c)) {
1216 // user wants to erase prev char 1219 // user wants to erase prev char
1217 write1("\b \b"); // erase char on screen 1220 write1("\b \b"); // erase char on screen
1218 buf[--i] = '\0'; 1221 buf[--i] = '\0';
@@ -2174,8 +2177,16 @@ static char *char_insert(char *p, char c, int undo) // insert the char c at 'p'
2174 p += 1 + stupid_insert(p, ' '); 2177 p += 1 + stupid_insert(p, ' ');
2175 } 2178 }
2176#endif 2179#endif
2177 } else if (c == term_orig.c_cc[VERASE] || c == 8 || c == 127) { // Is this a BS 2180 } else if (isbackspace(c)) {
2178 if (p > text) { 2181 if (cmd_mode == 2) {
2182 // special treatment for backspace in Replace mode
2183 if (p > rstart) {
2184 p--;
2185#if ENABLE_FEATURE_VI_UNDO
2186 undo_pop();
2187#endif
2188 }
2189 } else if (p > text) {
2179 p--; 2190 p--;
2180 p = text_hole_delete(p, p, ALLOW_UNDO_QUEUED); // shrink buffer 1 char 2191 p = text_hole_delete(p, p, ALLOW_UNDO_QUEUED); // shrink buffer 1 char
2181 } 2192 }
@@ -3703,9 +3714,9 @@ static void do_cmd(int c)
3703 undo_queue_commit(); 3714 undo_queue_commit();
3704 } else { 3715 } else {
3705 if (1 <= c || Isprint(c)) { 3716 if (1 <= c || Isprint(c)) {
3706 if (c != 27) 3717 if (c != 27 && !isbackspace(c))
3707 dot = yank_delete(dot, dot, PARTIAL, YANKDEL, ALLOW_UNDO); // delete char 3718 dot = yank_delete(dot, dot, PARTIAL, YANKDEL, ALLOW_UNDO);
3708 dot = char_insert(dot, c, ALLOW_UNDO_CHAIN); // insert new char 3719 dot = char_insert(dot, c, ALLOW_UNDO_CHAIN);
3709 } 3720 }
3710 goto dc1; 3721 goto dc1;
3711 } 3722 }
@@ -4264,6 +4275,7 @@ static void do_cmd(int c)
4264 dc5: 4275 dc5:
4265 cmd_mode = 2; 4276 cmd_mode = 2;
4266 undo_queue_commit(); 4277 undo_queue_commit();
4278 rstart = dot;
4267 break; 4279 break;
4268 case KEYCODE_DELETE: 4280 case KEYCODE_DELETE:
4269 if (dot < end - 1) 4281 if (dot < end - 1)