|
|
@@ -43,6 +43,12 @@ struct globals *ptr_to_globals;
|
|
|
|
|
|
#endif
|
|
|
|
|
|
+#ifdef RT_USING_POSIX_TERMIOS
|
|
|
+#define isbackspace(c) ((c) == term_orig.c_cc[VERASE] || (c) == 8 || (c) == 127)
|
|
|
+#else
|
|
|
+#define isbackspace(c) ((c) == 8 || (c) == 127)
|
|
|
+#endif /* RT_USING_POSIX_TERMIOS */
|
|
|
+
|
|
|
enum {
|
|
|
MAX_TABSTOP = 32, // sanity limit
|
|
|
// User input len. Need not be extra big.
|
|
|
@@ -159,6 +165,7 @@ struct globals {
|
|
|
int last_modified_count; // = -1;
|
|
|
int cmdline_filecnt; // how many file names on cmd line
|
|
|
int cmdcnt; // repetition count
|
|
|
+ char *rstart; // start of text in Replace mode
|
|
|
unsigned rows, columns; // the terminal screen is this size
|
|
|
#if ENABLE_FEATURE_VI_ASK_TERMINAL
|
|
|
int get_rowcol_error;
|
|
|
@@ -279,6 +286,7 @@ struct globals {
|
|
|
#define last_modified_count (G.last_modified_count)
|
|
|
#define cmdline_filecnt (G.cmdline_filecnt )
|
|
|
#define cmdcnt (G.cmdcnt )
|
|
|
+#define rstart (G.rstart )
|
|
|
#define rows (G.rows )
|
|
|
#define columns (G.columns )
|
|
|
#define crow (G.crow )
|
|
|
@@ -2123,12 +2131,16 @@ static char *char_insert(char *p, char c, int undo) // insert the char c at 'p'
|
|
|
p += 1 + stupid_insert(p, ' ');
|
|
|
}
|
|
|
#endif
|
|
|
- } else if (
|
|
|
- #ifdef RT_USING_POSIX_TERMIOS
|
|
|
- c == term_orig.c_cc[VERASE] ||
|
|
|
- #endif
|
|
|
- c == 8 || c == 127) { // Is this a BS
|
|
|
- if (p > text) {
|
|
|
+ } else if (isbackspace(c)) {
|
|
|
+ if (cmd_mode == 2) {
|
|
|
+ // special treatment for backspace in Replace mode
|
|
|
+ if (p > rstart) {
|
|
|
+ p--;
|
|
|
+#if ENABLE_FEATURE_VI_UNDO
|
|
|
+ undo_pop();
|
|
|
+#endif
|
|
|
+ }
|
|
|
+ } else if (p > text) {
|
|
|
p--;
|
|
|
p = text_hole_delete(p, p, ALLOW_UNDO_QUEUED); // shrink buffer 1 char
|
|
|
}
|
|
|
@@ -3016,11 +3028,7 @@ static char *get_input_line(const char *prompt)
|
|
|
c = get_one_char();
|
|
|
if (c == '\n' || c == '\r' || c == 27)
|
|
|
break; // this is end of input
|
|
|
- if (
|
|
|
- #ifdef RT_USING_POSIX_TERMIOS
|
|
|
- c == term_orig.c_cc[VERASE] ||
|
|
|
- #endif
|
|
|
- c == 8 || c == 127) {
|
|
|
+ if (isbackspace(c)) {
|
|
|
// user wants to erase prev char
|
|
|
vi_puts("\b \b"); // erase char on screen
|
|
|
buf[--i] = '\0';
|
|
|
@@ -3605,9 +3613,9 @@ static void do_cmd(int c)
|
|
|
undo_queue_commit();
|
|
|
} else {
|
|
|
if (1 <= c || Isprint(c)) {
|
|
|
- if (c != 27)
|
|
|
- dot = yank_delete(dot, dot, PARTIAL, YANKDEL, ALLOW_UNDO); // delete char
|
|
|
- dot = char_insert(dot, c, ALLOW_UNDO_CHAIN); // insert new char
|
|
|
+ if (c != 27 && !isbackspace(c))
|
|
|
+ dot = yank_delete(dot, dot, PARTIAL, YANKDEL, ALLOW_UNDO);
|
|
|
+ dot = char_insert(dot, c, ALLOW_UNDO_CHAIN);
|
|
|
}
|
|
|
goto dc1;
|
|
|
}
|
|
|
@@ -4159,6 +4167,7 @@ static void do_cmd(int c)
|
|
|
dc5:
|
|
|
cmd_mode = 2;
|
|
|
undo_queue_commit();
|
|
|
+ rstart = dot;
|
|
|
break;
|
|
|
case KEYCODE_DELETE:
|
|
|
if (dot < end - 1)
|