tvi: do not move the cursor past EOL - neatvi - [fork] simple vi-type editor wi… | |
git clone git://src.adamsgaard.dk/neatvi | |
Log | |
Files | |
Refs | |
README | |
--- | |
commit 40532b52979509bb1bb5332e8f9bd9bb6e15dc72 | |
parent 0c2fb9f33f08de99cfc4e5b61e14259bbbe2c468 | |
Author: Ali Gholami Rudi <[email protected]> | |
Date: Sun, 17 May 2015 14:26:11 +0430 | |
vi: do not move the cursor past EOL | |
Diffstat: | |
M ren.c | 22 ++++++++++++++++++++-- | |
M vi.c | 27 ++++++++++++++++----------- | |
M vi.h | 3 ++- | |
3 files changed, 38 insertions(+), 14 deletions(-) | |
--- | |
diff --git a/ren.c b/ren.c | |
t@@ -38,7 +38,7 @@ int ren_wid(char *s) | |
return ret; | |
} | |
-/* find the next character after visual position p; if cur start from p itself… | |
+/* find the next character after visual position p; if cur, start from p itsel… | |
static int pos_next(int *pos, int n, int p, int cur) | |
{ | |
int i, ret = -1; | |
t@@ -48,7 +48,7 @@ static int pos_next(int *pos, int n, int p, int cur) | |
return ret >= 0 ? pos[ret] : -1; | |
} | |
-/* find the previous character after visual position p; if cur start from p it… | |
+/* find the previous character after visual position p; if cur, start from p i… | |
static int pos_prev(int *pos, int n, int p, int cur) | |
{ | |
int i, ret = -1; | |
t@@ -93,12 +93,30 @@ int ren_cursor(char *s, int p) | |
n = uc_slen(s); | |
pos = ren_position(s); | |
p = pos_prev(pos, n, p, 1); | |
+ if (uc_code(uc_chr(s, ren_off(s, p))) == '\n') | |
+ p = pos_prev(pos, n, p, 0); | |
next = pos_next(pos, n, p, 0); | |
p = (next >= 0 ? next : pos[n]) - 1; | |
free(pos); | |
return p >= 0 ? p : 0; | |
} | |
+/* real cursor position; never past EOL */ | |
+int ren_noeol(char *s, int p) | |
+{ | |
+ int n; | |
+ int *pos; | |
+ if (!s) | |
+ return 0; | |
+ n = uc_slen(s); | |
+ pos = ren_position(s); | |
+ p = pos_prev(pos, n, p, 1); | |
+ if (uc_code(uc_chr(s, ren_off(s, p))) == '\n') | |
+ p = pos_prev(pos, n, p, 0); | |
+ free(pos); | |
+ return p >= 0 ? p : 0; | |
+} | |
+ | |
/* the position of the next character */ | |
int ren_next(char *s, int p, int dir) | |
{ | |
diff --git a/vi.c b/vi.c | |
t@@ -529,8 +529,7 @@ static int vi_motion(int *row, int *col) | |
lbuf_postindents(xb, row, col); | |
break; | |
case '$': | |
- lbuf_eol(xb, row, col, +1); | |
- lbuf_lnnext(xb, row, col, -1); | |
+ *col = 1024; | |
break; | |
case '|': | |
*col = cnt - 1; | |
t@@ -796,6 +795,8 @@ static int vc_motion(int cmd) | |
vi_arg2 = vi_prefix(); | |
if (vi_arg2 < 0) | |
return 1; | |
+ c1 = ren_noeol(lbuf_get(xb, r1), xcol); | |
+ c2 = c1; | |
if ((mv = vi_motionln(&r2, cmd))) { | |
c2 = -1; | |
} else if (!(mv = vi_motion(&r2, &c2))) { | |
t@@ -804,7 +805,7 @@ static int vc_motion(int cmd) | |
} | |
if (mv < 0) | |
return 1; | |
- if (!strchr("fFtTeE$", mv)) | |
+ if (!strchr("fFtTeE", mv)) | |
closed = 0; | |
lnmode = c2 < 0; | |
if (lnmode) { | |
t@@ -1013,23 +1014,27 @@ static void vi(void) | |
term_pos(xrow, led_pos(lbuf_get(xb, xrow), xcol)); | |
while (!xquit) { | |
int redraw = 0; | |
- int orow = xrow; | |
- int ocol = xcol; | |
+ int nrow = xrow; | |
+ int ncol = ren_noeol(lbuf_get(xb, xrow), xcol); | |
int mv, n; | |
vi_arg2 = 0; | |
vi_ybuf = vi_yankbuf(); | |
vi_arg1 = vi_prefix(); | |
if (!vi_ybuf) | |
vi_ybuf = vi_yankbuf(); | |
- mv = vi_motion(&xrow, &xcol); | |
+ mv = vi_motion(&nrow, &ncol); | |
if (mv > 0) { | |
if (strchr("\'GHML/?{}[]", mv)) | |
- lbuf_mark(xb, '\'', orow); | |
- if (xcol < 0) { | |
- if (strchr("jk", mv)) | |
- xcol = ocol; | |
- else | |
+ lbuf_mark(xb, '\'', xrow); | |
+ xrow = nrow; | |
+ if (ncol < 0) { | |
+ if (!strchr("jk", mv)) | |
lbuf_postindents(xb, &xrow, &xcol); | |
+ } else { | |
+ if (strchr("|$", mv)) | |
+ xcol = ncol; | |
+ else | |
+ xcol = ren_noeol(lbuf_get(xb, xrow), n… | |
} | |
} else if (mv == 0) { | |
int c = vi_read(); | |
diff --git a/vi.h b/vi.h | |
t@@ -45,10 +45,11 @@ void rset_free(struct rset *re); | |
/* rendering lines */ | |
int *ren_position(char *s); | |
-int ren_cursor(char *s, int pos); | |
int ren_next(char *s, int p, int dir); | |
int ren_eol(char *s, int dir); | |
int ren_pos(char *s, int off); | |
+int ren_cursor(char *s, int pos); | |
+int ren_noeol(char *s, int p); | |
int ren_off(char *s, int pos); | |
int ren_wid(char *s); | |
int ren_region(char *s, int c1, int c2, int *l1, int *l2, int closed); |