diff options
-rw-r--r-- | editors/vi.c | 30 |
1 files changed, 24 insertions, 6 deletions
diff --git a/editors/vi.c b/editors/vi.c index 5d4b0f20e..323ca4427 100644 --- a/editors/vi.c +++ b/editors/vi.c | |||
@@ -3051,6 +3051,12 @@ static void int_handler(int sig) | |||
3051 | 3051 | ||
3052 | static void do_cmd(int c); | 3052 | static void do_cmd(int c); |
3053 | 3053 | ||
3054 | static int at_eof(const char *s) | ||
3055 | { | ||
3056 | // does 's' point to end of file, even with no terminating newline? | ||
3057 | return ((s == end - 2 && s[1] == '\n') || s == end - 1); | ||
3058 | } | ||
3059 | |||
3054 | static int find_range(char **start, char **stop, char c) | 3060 | static int find_range(char **start, char **stop, char c) |
3055 | { | 3061 | { |
3056 | char *save_dot, *p, *q, *t; | 3062 | char *save_dot, *p, *q, *t; |
@@ -3064,7 +3070,7 @@ static int find_range(char **start, char **stop, char c) | |||
3064 | buftype = WHOLE; | 3070 | buftype = WHOLE; |
3065 | if (--cmdcnt > 0) | 3071 | if (--cmdcnt > 0) |
3066 | do_cmd('j'); | 3072 | do_cmd('j'); |
3067 | } else if (strchr("^%$0bBeEfFtTh|\b\177", c)) { | 3073 | } else if (strchr("^%$0bBeEfFtTh|{}\b\177", c)) { |
3068 | // These cmds operate on char positions | 3074 | // These cmds operate on char positions |
3069 | buftype = PARTIAL; | 3075 | buftype = PARTIAL; |
3070 | do_cmd(c); // execute movement cmd | 3076 | do_cmd(c); // execute movement cmd |
@@ -3074,9 +3080,9 @@ static int find_range(char **start, char **stop, char c) | |||
3074 | buftype = MULTI; | 3080 | buftype = MULTI; |
3075 | do_cmd(c); // execute movement cmd | 3081 | do_cmd(c); // execute movement cmd |
3076 | // step back one char, but not if we're at end of file | 3082 | // step back one char, but not if we're at end of file |
3077 | if (dot > p && !((dot == end - 2 && end[-1] == '\n') || dot == end - 1)) | 3083 | if (dot > p && !at_eof(dot)) |
3078 | dot--; | 3084 | dot--; |
3079 | } else if (strchr("GHL+-jk{}\r\n", c)) { | 3085 | } else if (strchr("GHL+-jk\r\n", c)) { |
3080 | // these operate on whole lines | 3086 | // these operate on whole lines |
3081 | buftype = WHOLE; | 3087 | buftype = WHOLE; |
3082 | do_cmd(c); // execute movement cmd | 3088 | do_cmd(c); // execute movement cmd |
@@ -3101,14 +3107,26 @@ static int find_range(char **start, char **stop, char c) | |||
3101 | p = t; | 3107 | p = t; |
3102 | } | 3108 | } |
3103 | 3109 | ||
3110 | // movements which don't include end of range | ||
3111 | if (q > p) { | ||
3112 | if (strchr("^0bBFTh|\b\177", c)) { | ||
3113 | q--; | ||
3114 | } else if (strchr("{}", c)) { | ||
3115 | buftype = (p == begin_line(p) && (*q == '\n' || at_eof(q))) ? | ||
3116 | WHOLE : MULTI; | ||
3117 | if (!at_eof(q)) { | ||
3118 | q--; | ||
3119 | if (q > p && p != begin_line(p)) | ||
3120 | q--; | ||
3121 | } | ||
3122 | } | ||
3123 | } | ||
3124 | |||
3104 | if (buftype == WHOLE) { | 3125 | if (buftype == WHOLE) { |
3105 | p = begin_line(p); | 3126 | p = begin_line(p); |
3106 | q = end_line(q); | 3127 | q = end_line(q); |
3107 | } | 3128 | } |
3108 | 3129 | ||
3109 | // movements which don't include end of range | ||
3110 | if (q > p && strchr("^0bBFTh|\b\177", c)) q--; | ||
3111 | |||
3112 | *start = p; | 3130 | *start = p; |
3113 | *stop = q; | 3131 | *stop = q; |
3114 | dot = save_dot; | 3132 | dot = save_dot; |