vi: remember cursor column during vertical motion
When the 'j'/'k' commands or up/down arrow keys are used to move the cursor vertically 'vi' remembers the original cursor column and positions the cursor there if possible. Also, if the '$' command has been used to position the cursor at the end of a line vertical movements keep the cursor at the end of the line. Make BusyBox 'vi' do the same. function old new delta refresh 674 694 +20 do_cmd 4853 4861 +8 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 2/0 up/down: 28/0) Total: 28 bytes Signed-off-by: Ron Yorston <rmy@pobox.com> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
committed by
Denys Vlasenko
parent
18871c3f2b
commit
50a2db7dff
21
editors/vi.c
21
editors/vi.c
@ -263,6 +263,8 @@ enum {
|
|||||||
S_OVER_WS = 3, // used in skip_thing() for moving "dot"
|
S_OVER_WS = 3, // used in skip_thing() for moving "dot"
|
||||||
S_END_PUNCT = 4, // used in skip_thing() for moving "dot"
|
S_END_PUNCT = 4, // used in skip_thing() for moving "dot"
|
||||||
S_END_ALNUM = 5, // used in skip_thing() for moving "dot"
|
S_END_ALNUM = 5, // used in skip_thing() for moving "dot"
|
||||||
|
|
||||||
|
C_END = -1, // cursor is at end of line due to '$' command
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -354,6 +356,8 @@ struct globals {
|
|||||||
sigjmp_buf restart; // int_handler() jumps to location remembered here
|
sigjmp_buf restart; // int_handler() jumps to location remembered here
|
||||||
#endif
|
#endif
|
||||||
struct termios term_orig; // remember what the cooked mode was
|
struct termios term_orig; // remember what the cooked mode was
|
||||||
|
int cindex; // saved character index for up/down motion
|
||||||
|
smallint keep_index; // retain saved character index
|
||||||
#if ENABLE_FEATURE_VI_COLON
|
#if ENABLE_FEATURE_VI_COLON
|
||||||
char *initial_cmds[3]; // currently 2 entries, NULL terminated
|
char *initial_cmds[3]; // currently 2 entries, NULL terminated
|
||||||
#endif
|
#endif
|
||||||
@ -462,6 +466,8 @@ struct globals {
|
|||||||
#define context_end (G.context_end )
|
#define context_end (G.context_end )
|
||||||
#define restart (G.restart )
|
#define restart (G.restart )
|
||||||
#define term_orig (G.term_orig )
|
#define term_orig (G.term_orig )
|
||||||
|
#define cindex (G.cindex )
|
||||||
|
#define keep_index (G.keep_index )
|
||||||
#define initial_cmds (G.initial_cmds )
|
#define initial_cmds (G.initial_cmds )
|
||||||
#define readbuffer (G.readbuffer )
|
#define readbuffer (G.readbuffer )
|
||||||
#define scr_out_buf (G.scr_out_buf )
|
#define scr_out_buf (G.scr_out_buf )
|
||||||
@ -992,6 +998,9 @@ static void refresh(int full_screen)
|
|||||||
|
|
||||||
place_cursor(crow, ccol);
|
place_cursor(crow, ccol);
|
||||||
|
|
||||||
|
if (!keep_index)
|
||||||
|
cindex = ccol + offset;
|
||||||
|
|
||||||
old_offset = offset;
|
old_offset = offset;
|
||||||
#undef old_offset
|
#undef old_offset
|
||||||
}
|
}
|
||||||
@ -3096,6 +3105,7 @@ static void do_cmd(int c)
|
|||||||
// cnt = yf = 0; // quiet the compiler
|
// cnt = yf = 0; // quiet the compiler
|
||||||
// p = q = save_dot = buf; // quiet the compiler
|
// p = q = save_dot = buf; // quiet the compiler
|
||||||
memset(buf, '\0', sizeof(buf));
|
memset(buf, '\0', sizeof(buf));
|
||||||
|
keep_index = FALSE;
|
||||||
|
|
||||||
show_status_line();
|
show_status_line();
|
||||||
|
|
||||||
@ -3220,9 +3230,10 @@ static void do_cmd(int c)
|
|||||||
case KEYCODE_DOWN: // cursor key Down
|
case KEYCODE_DOWN: // cursor key Down
|
||||||
do {
|
do {
|
||||||
dot_next(); // go to next B-o-l
|
dot_next(); // go to next B-o-l
|
||||||
// try stay in same col
|
|
||||||
dot = move_to_col(dot, ccol + offset);
|
|
||||||
} while (--cmdcnt > 0);
|
} while (--cmdcnt > 0);
|
||||||
|
// try to stay in saved column
|
||||||
|
dot = cindex == C_END ? end_line(dot) : move_to_col(dot, cindex);
|
||||||
|
keep_index = TRUE;
|
||||||
break;
|
break;
|
||||||
case 12: // ctrl-L force redraw whole screen
|
case 12: // ctrl-L force redraw whole screen
|
||||||
case 18: // ctrl-R force redraw
|
case 18: // ctrl-R force redraw
|
||||||
@ -3348,6 +3359,8 @@ static void do_cmd(int c)
|
|||||||
break;
|
break;
|
||||||
dot_next();
|
dot_next();
|
||||||
}
|
}
|
||||||
|
cindex = C_END;
|
||||||
|
keep_index = TRUE;
|
||||||
break;
|
break;
|
||||||
case '%': // %- find matching char of pair () [] {}
|
case '%': // %- find matching char of pair () [] {}
|
||||||
for (q = dot; q < end && *q != '\n'; q++) {
|
for (q = dot; q < end && *q != '\n'; q++) {
|
||||||
@ -3827,8 +3840,10 @@ static void do_cmd(int c)
|
|||||||
case KEYCODE_UP: // cursor key Up
|
case KEYCODE_UP: // cursor key Up
|
||||||
do {
|
do {
|
||||||
dot_prev();
|
dot_prev();
|
||||||
dot = move_to_col(dot, ccol + offset); // try stay in same col
|
|
||||||
} while (--cmdcnt > 0);
|
} while (--cmdcnt > 0);
|
||||||
|
// try to stay in saved column
|
||||||
|
dot = cindex == C_END ? end_line(dot) : move_to_col(dot, cindex);
|
||||||
|
keep_index = TRUE;
|
||||||
break;
|
break;
|
||||||
case 'r': // r- replace the current char with user input
|
case 'r': // r- replace the current char with user input
|
||||||
c1 = get_one_char(); // get the replacement char
|
c1 = get_one_char(); // get the replacement char
|
||||||
|
Reference in New Issue
Block a user