fixed the "dot" (i.e. '.') command, to properly re-init its
buffer between commands, not recalculate its length all the time, and to not reallocate its fixed-length buffer frequently. fixed the 'c', 'd', and 'y' commands to properly handle both motions that are just part of a line, and those that are multiline. for instance, now "c%" and "2cw" work correctly, whether the motions span lines or not. added some permissble motions for 'c', 'd', and 'y': namely 'h', 'l', SPACE, BS, and DEL
This commit is contained in:
parent
b4a5087ee0
commit
c51fc7bed6
123
editors/vi.c
123
editors/vi.c
@ -170,6 +170,7 @@ static smallint readonly_mode = 0;
|
|||||||
#if ENABLE_FEATURE_VI_DOT_CMD
|
#if ENABLE_FEATURE_VI_DOT_CMD
|
||||||
static smallint adding2q; // are we currently adding user input to q
|
static smallint adding2q; // are we currently adding user input to q
|
||||||
static char *last_modifying_cmd; // [MAX_INPUT_LEN] last modifying cmd for "."
|
static char *last_modifying_cmd; // [MAX_INPUT_LEN] last modifying cmd for "."
|
||||||
|
static smallint lmc_len; // length of last_modifying_cmd
|
||||||
static char *ioq, *ioq_start; // pointer to string for get_one_char to "read"
|
static char *ioq, *ioq_start; // pointer to string for get_one_char to "read"
|
||||||
#endif
|
#endif
|
||||||
#if ENABLE_FEATURE_VI_OPTIMIZE_CURSOR
|
#if ENABLE_FEATURE_VI_OPTIMIZE_CURSOR
|
||||||
@ -262,7 +263,7 @@ static char *bound_dot(char *); // make sure text[0] <= P < "end"
|
|||||||
static char *new_screen(int, int); // malloc virtual screen memory
|
static char *new_screen(int, int); // malloc virtual screen memory
|
||||||
static char *char_insert(char *, char); // insert the char c at 'p'
|
static char *char_insert(char *, char); // insert the char c at 'p'
|
||||||
static char *stupid_insert(char *, char); // stupidly insert the char c at 'p'
|
static char *stupid_insert(char *, char); // stupidly insert the char c at 'p'
|
||||||
static char find_range(char **, char **, char); // return pointers for an object
|
static int find_range(char **, char **, char); // return pointers for an object
|
||||||
static int st_test(char *, int, int, char *); // helper for skip_thing()
|
static int st_test(char *, int, int, char *); // helper for skip_thing()
|
||||||
static char *skip_thing(char *, int, int, int); // skip some object
|
static char *skip_thing(char *, int, int, int); // skip some object
|
||||||
static char *find_pair(char *, char); // find matching pair () [] {}
|
static char *find_pair(char *, char); // find matching pair () [] {}
|
||||||
@ -526,9 +527,9 @@ static void edit_file(char *fn)
|
|||||||
offset = 0; // no horizontal offset
|
offset = 0; // no horizontal offset
|
||||||
c = '\0';
|
c = '\0';
|
||||||
#if ENABLE_FEATURE_VI_DOT_CMD
|
#if ENABLE_FEATURE_VI_DOT_CMD
|
||||||
free(last_modifying_cmd);
|
|
||||||
free(ioq_start);
|
free(ioq_start);
|
||||||
ioq = ioq_start = last_modifying_cmd = NULL;
|
ioq = ioq_start = NULL;
|
||||||
|
lmc_len = 0;
|
||||||
adding2q = 0;
|
adding2q = 0;
|
||||||
#endif
|
#endif
|
||||||
redraw(FALSE); // dont force every col re-draw
|
redraw(FALSE); // dont force every col re-draw
|
||||||
@ -1662,10 +1663,10 @@ static char *stupid_insert(char * p, char c) // stupidly insert the char c at 'p
|
|||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char find_range(char ** start, char ** stop, char c)
|
static int find_range(char ** start, char ** stop, char c)
|
||||||
{
|
{
|
||||||
char *save_dot, *p, *q;
|
char *save_dot, *p, *q, *t;
|
||||||
int cnt;
|
int cnt, multiline = 0;
|
||||||
|
|
||||||
save_dot = dot;
|
save_dot = dot;
|
||||||
p = q = dot;
|
p = q = dot;
|
||||||
@ -1677,7 +1678,7 @@ static char find_range(char ** start, char ** stop, char c)
|
|||||||
q = next_line(q);
|
q = next_line(q);
|
||||||
}
|
}
|
||||||
q = end_line(q);
|
q = end_line(q);
|
||||||
} else if (strchr("^%$0bBeEft", c)) {
|
} else if (strchr("^%$0bBeEfth\b\177", c)) {
|
||||||
// These cmds operate on char positions
|
// These cmds operate on char positions
|
||||||
do_cmd(c); // execute movement cmd
|
do_cmd(c); // execute movement cmd
|
||||||
q = dot;
|
q = dot;
|
||||||
@ -1706,17 +1707,33 @@ static char find_range(char ** start, char ** stop, char c)
|
|||||||
dot_end(); // find NL
|
dot_end(); // find NL
|
||||||
q = dot;
|
q = dot;
|
||||||
} else {
|
} else {
|
||||||
c = 27; // error- return an ESC char
|
// nothing -- this causes any other values of c to
|
||||||
//break;
|
// represent the one-character range under the
|
||||||
|
// cursor. this is correct for ' ' and 'l', but
|
||||||
|
// perhaps no others.
|
||||||
|
//
|
||||||
}
|
}
|
||||||
|
if (q < p) {
|
||||||
|
t = q;
|
||||||
|
q = p;
|
||||||
|
p = t;
|
||||||
|
}
|
||||||
|
|
||||||
|
// backward char movements don't include start position
|
||||||
|
if (q > p && strchr("^0bBh\b\177", c)) q--;
|
||||||
|
|
||||||
|
multiline = 0;
|
||||||
|
for (t = p; t <= q; t++) {
|
||||||
|
if (*t == '\n') {
|
||||||
|
multiline = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
*start = p;
|
*start = p;
|
||||||
*stop = q;
|
*stop = q;
|
||||||
if (q < p) {
|
|
||||||
*start = q;
|
|
||||||
*stop = p;
|
|
||||||
}
|
|
||||||
dot = save_dot;
|
dot = save_dot;
|
||||||
return c;
|
return multiline;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int st_test(char * p, int type, int dir, char * tested)
|
static int st_test(char * p, int type, int dir, char * tested)
|
||||||
@ -1780,27 +1797,12 @@ static char *find_pair(char * p, const char c)
|
|||||||
level = 1;
|
level = 1;
|
||||||
dir = 1; // assume forward
|
dir = 1; // assume forward
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case '(':
|
case '(': match = ')'; break;
|
||||||
match = ')';
|
case '[': match = ']'; break;
|
||||||
break;
|
case '{': match = '}'; break;
|
||||||
case '[':
|
case ')': match = '('; dir = -1; break;
|
||||||
match = ']';
|
case ']': match = '['; dir = -1; break;
|
||||||
break;
|
case '}': match = '{'; dir = -1; break;
|
||||||
case '{':
|
|
||||||
match = '}';
|
|
||||||
break;
|
|
||||||
case ')':
|
|
||||||
match = '(';
|
|
||||||
dir = -1;
|
|
||||||
break;
|
|
||||||
case ']':
|
|
||||||
match = '[';
|
|
||||||
dir = -1;
|
|
||||||
break;
|
|
||||||
case '}':
|
|
||||||
match = '{';
|
|
||||||
dir = -1;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
for (q = p + dir; text <= q && q < end; q += dir) {
|
for (q = p + dir; text <= q && q < end; q += dir) {
|
||||||
// look for match, count levels of pairs (( ))
|
// look for match, count levels of pairs (( ))
|
||||||
@ -1976,10 +1978,10 @@ static void start_new_cmd_q(char c)
|
|||||||
last_modifying_cmd = xzalloc(MAX_INPUT_LEN);
|
last_modifying_cmd = xzalloc(MAX_INPUT_LEN);
|
||||||
// if there is a current cmd count put it in the buffer first
|
// if there is a current cmd count put it in the buffer first
|
||||||
if (cmdcnt > 0)
|
if (cmdcnt > 0)
|
||||||
sprintf(last_modifying_cmd, "%d%c", cmdcnt, c);
|
lmc_len = sprintf(last_modifying_cmd, "%d%c", cmdcnt, c);
|
||||||
else { // just save char c onto queue
|
else { // just save char c onto queue
|
||||||
last_modifying_cmd[0] = c;
|
last_modifying_cmd[0] = c;
|
||||||
last_modifying_cmd[1] = '\0';
|
lmc_len = 1;
|
||||||
}
|
}
|
||||||
adding2q = 1;
|
adding2q = 1;
|
||||||
}
|
}
|
||||||
@ -2280,9 +2282,6 @@ static char get_one_char(void)
|
|||||||
char c;
|
char c;
|
||||||
|
|
||||||
#if ENABLE_FEATURE_VI_DOT_CMD
|
#if ENABLE_FEATURE_VI_DOT_CMD
|
||||||
// ! adding2q && ioq == 0 read()
|
|
||||||
// ! adding2q && ioq != 0 *ioq
|
|
||||||
// adding2q *last_modifying_cmd= read()
|
|
||||||
if (!adding2q) {
|
if (!adding2q) {
|
||||||
// we are not adding to the q.
|
// we are not adding to the q.
|
||||||
// but, we may be reading from a q
|
// but, we may be reading from a q
|
||||||
@ -2303,12 +2302,11 @@ static char get_one_char(void)
|
|||||||
// adding STDIN chars to q
|
// adding STDIN chars to q
|
||||||
c = readit(); // get the users input
|
c = readit(); // get the users input
|
||||||
if (last_modifying_cmd != NULL) {
|
if (last_modifying_cmd != NULL) {
|
||||||
int len = strlen(last_modifying_cmd);
|
if (lmc_len >= MAX_INPUT_LEN - 1) {
|
||||||
if (len >= MAX_INPUT_LEN - 1) {
|
|
||||||
status_line_bold("last_modifying_cmd overrun");
|
status_line_bold("last_modifying_cmd overrun");
|
||||||
} else {
|
} else {
|
||||||
// add new char to q
|
// add new char to q
|
||||||
last_modifying_cmd[len] = c;
|
last_modifying_cmd[lmc_len++] = c;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2947,7 +2945,7 @@ static void do_cmd(char c)
|
|||||||
char c1, *p, *q, *save_dot;
|
char c1, *p, *q, *save_dot;
|
||||||
char buf[12];
|
char buf[12];
|
||||||
int dir = dir; // for compiler
|
int dir = dir; // for compiler
|
||||||
int cnt, i, j, yf;
|
int cnt, i, j;
|
||||||
|
|
||||||
// c1 = c; // quiet the compiler
|
// c1 = c; // quiet the compiler
|
||||||
// cnt = yf = 0; // quiet the compiler
|
// cnt = yf = 0; // quiet the compiler
|
||||||
@ -3282,7 +3280,8 @@ static void do_cmd(char c)
|
|||||||
case '.': // .- repeat the last modifying command
|
case '.': // .- repeat the last modifying command
|
||||||
// Stuff the last_modifying_cmd back into stdin
|
// Stuff the last_modifying_cmd back into stdin
|
||||||
// and let it be re-executed.
|
// and let it be re-executed.
|
||||||
if (last_modifying_cmd != NULL) {
|
if (last_modifying_cmd != NULL && lmc_len > 0) {
|
||||||
|
last_modifying_cmd[lmc_len] = 0;
|
||||||
ioq = ioq_start = xstrdup(last_modifying_cmd);
|
ioq = ioq_start = xstrdup(last_modifying_cmd);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -3668,6 +3667,8 @@ static void do_cmd(char c)
|
|||||||
case 'y': // y- yank something
|
case 'y': // y- yank something
|
||||||
case 'Y': // Y- Yank a line
|
case 'Y': // Y- Yank a line
|
||||||
#endif
|
#endif
|
||||||
|
{
|
||||||
|
int yf, ml, whole = 0;
|
||||||
yf = YANKDEL; // assume either "c" or "d"
|
yf = YANKDEL; // assume either "c" or "d"
|
||||||
#if ENABLE_FEATURE_VI_YANKMARK
|
#if ENABLE_FEATURE_VI_YANKMARK
|
||||||
if (c == 'y' || c == 'Y')
|
if (c == 'y' || c == 'Y')
|
||||||
@ -3676,7 +3677,8 @@ static void do_cmd(char c)
|
|||||||
c1 = 'y';
|
c1 = 'y';
|
||||||
if (c != 'Y')
|
if (c != 'Y')
|
||||||
c1 = get_one_char(); // get the type of thing to delete
|
c1 = get_one_char(); // get the type of thing to delete
|
||||||
find_range(&p, &q, c1);
|
// determine range, and whether it spans lines
|
||||||
|
ml = find_range(&p, &q, c1);
|
||||||
if (c1 == 27) { // ESC- user changed mind and wants out
|
if (c1 == 27) { // ESC- user changed mind and wants out
|
||||||
c = c1 = 27; // Escape- do nothing
|
c = c1 = 27; // Escape- do nothing
|
||||||
} else if (strchr("wW", c1)) {
|
} else if (strchr("wW", c1)) {
|
||||||
@ -3688,27 +3690,31 @@ static void do_cmd(char c)
|
|||||||
q--;
|
q--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dot = yank_delete(p, q, 0, yf); // delete word
|
dot = yank_delete(p, q, ml, yf); // delete word
|
||||||
} else if (strchr("^0bBeEft$", c1)) {
|
} else if (strchr("^0bBeEft%$ lh\b\177", c1)) {
|
||||||
// single line copy text into a register and delete
|
// partial line copy text into a register and delete
|
||||||
dot = yank_delete(p, q, 0, yf); // delete word
|
dot = yank_delete(p, q, ml, yf); // delete word
|
||||||
} else if (strchr("cdykjHL%+-{}\r\n", c1)) {
|
} else if (strchr("cdykjHL+-{}\r\n", c1)) {
|
||||||
// multiple line copy text into a register and delete
|
// whole line copy text into a register and delete
|
||||||
dot = yank_delete(p, q, 1, yf); // delete lines
|
dot = yank_delete(p, q, ml, yf); // delete lines
|
||||||
|
whole = 1;
|
||||||
|
} else {
|
||||||
|
// could not recognize object
|
||||||
|
c = c1 = 27; // error-
|
||||||
|
ml = 0;
|
||||||
|
indicate_error(c);
|
||||||
|
}
|
||||||
|
if (ml && whole) {
|
||||||
if (c == 'c') {
|
if (c == 'c') {
|
||||||
dot = char_insert(dot, '\n');
|
dot = char_insert(dot, '\n');
|
||||||
// on the last line of file don't move to prev line
|
// on the last line of file don't move to prev line
|
||||||
if (dot != (end-1)) {
|
if (whole && dot != (end-1)) {
|
||||||
dot_prev();
|
dot_prev();
|
||||||
}
|
}
|
||||||
} else if (c == 'd') {
|
} else if (c == 'd') {
|
||||||
dot_begin();
|
dot_begin();
|
||||||
dot_skip_over_ws();
|
dot_skip_over_ws();
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
// could not recognize object
|
|
||||||
c = c1 = 27; // error-
|
|
||||||
indicate_error(c);
|
|
||||||
}
|
}
|
||||||
if (c1 != 27) {
|
if (c1 != 27) {
|
||||||
// if CHANGING, not deleting, start inserting after the delete
|
// if CHANGING, not deleting, start inserting after the delete
|
||||||
@ -3734,6 +3740,7 @@ static void do_cmd(char c)
|
|||||||
#endif
|
#endif
|
||||||
end_cmd_q(); // stop adding to q
|
end_cmd_q(); // stop adding to q
|
||||||
}
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 'k': // k- goto prev line, same col
|
case 'k': // k- goto prev line, same col
|
||||||
case VI_K_UP: // cursor key Up
|
case VI_K_UP: // cursor key Up
|
||||||
|
Loading…
x
Reference in New Issue
Block a user