vi: improve operations involving paragraph movement
Movement by paragraph doesn't always involve whole lines. If the cursor is positioned in the middle of a line deleting to either end of the paragraph will result in one partial line and zero or more full lines. Adjust the end of ranges delimited by paragraph movement to more closely match what vi does. function old new delta find_range 467 518 +51 at_eof - 49 +49 ------------------------------------------------------------------------------ (add/remove: 1/0 grow/shrink: 1/0 up/down: 100/0) Total: 100 bytes Signed-off-by: Ron Yorston <rmy@pobox.com> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
8b571bd7b5
commit
d56da68057
30
editors/vi.c
30
editors/vi.c
@ -3051,6 +3051,12 @@ static void int_handler(int sig)
|
|||||||
|
|
||||||
static void do_cmd(int c);
|
static void do_cmd(int c);
|
||||||
|
|
||||||
|
static int at_eof(const char *s)
|
||||||
|
{
|
||||||
|
// does 's' point to end of file, even with no terminating newline?
|
||||||
|
return ((s == end - 2 && s[1] == '\n') || s == end - 1);
|
||||||
|
}
|
||||||
|
|
||||||
static int find_range(char **start, char **stop, char c)
|
static int find_range(char **start, char **stop, char c)
|
||||||
{
|
{
|
||||||
char *save_dot, *p, *q, *t;
|
char *save_dot, *p, *q, *t;
|
||||||
@ -3064,7 +3070,7 @@ static int find_range(char **start, char **stop, char c)
|
|||||||
buftype = WHOLE;
|
buftype = WHOLE;
|
||||||
if (--cmdcnt > 0)
|
if (--cmdcnt > 0)
|
||||||
do_cmd('j');
|
do_cmd('j');
|
||||||
} else if (strchr("^%$0bBeEfFtTh|\b\177", c)) {
|
} else if (strchr("^%$0bBeEfFtTh|{}\b\177", c)) {
|
||||||
// These cmds operate on char positions
|
// These cmds operate on char positions
|
||||||
buftype = PARTIAL;
|
buftype = PARTIAL;
|
||||||
do_cmd(c); // execute movement cmd
|
do_cmd(c); // execute movement cmd
|
||||||
@ -3074,9 +3080,9 @@ static int find_range(char **start, char **stop, char c)
|
|||||||
buftype = MULTI;
|
buftype = MULTI;
|
||||||
do_cmd(c); // execute movement cmd
|
do_cmd(c); // execute movement cmd
|
||||||
// step back one char, but not if we're at end of file
|
// step back one char, but not if we're at end of file
|
||||||
if (dot > p && !((dot == end - 2 && end[-1] == '\n') || dot == end - 1))
|
if (dot > p && !at_eof(dot))
|
||||||
dot--;
|
dot--;
|
||||||
} else if (strchr("GHL+-jk{}\r\n", c)) {
|
} else if (strchr("GHL+-jk\r\n", c)) {
|
||||||
// these operate on whole lines
|
// these operate on whole lines
|
||||||
buftype = WHOLE;
|
buftype = WHOLE;
|
||||||
do_cmd(c); // execute movement cmd
|
do_cmd(c); // execute movement cmd
|
||||||
@ -3101,14 +3107,26 @@ static int find_range(char **start, char **stop, char c)
|
|||||||
p = t;
|
p = t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// movements which don't include end of range
|
||||||
|
if (q > p) {
|
||||||
|
if (strchr("^0bBFTh|\b\177", c)) {
|
||||||
|
q--;
|
||||||
|
} else if (strchr("{}", c)) {
|
||||||
|
buftype = (p == begin_line(p) && (*q == '\n' || at_eof(q))) ?
|
||||||
|
WHOLE : MULTI;
|
||||||
|
if (!at_eof(q)) {
|
||||||
|
q--;
|
||||||
|
if (q > p && p != begin_line(p))
|
||||||
|
q--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (buftype == WHOLE) {
|
if (buftype == WHOLE) {
|
||||||
p = begin_line(p);
|
p = begin_line(p);
|
||||||
q = end_line(q);
|
q = end_line(q);
|
||||||
}
|
}
|
||||||
|
|
||||||
// movements which don't include end of range
|
|
||||||
if (q > p && strchr("^0bBFTh|\b\177", c)) q--;
|
|
||||||
|
|
||||||
*start = p;
|
*start = p;
|
||||||
*stop = q;
|
*stop = q;
|
||||||
dot = save_dot;
|
dot = save_dot;
|
||||||
|
Loading…
Reference in New Issue
Block a user