tvi: find cursor position after insertion in vi_input() - neatvi - [fork] simpl… | |
git clone git://src.adamsgaard.dk/neatvi | |
Log | |
Files | |
Refs | |
README | |
--- | |
commit 674db133b8d6995f54c4cb682d7193dbda7ca62a | |
parent 7344f210fcb3b51fa46f90f0ace3bbe126cb47b8 | |
Author: Ali Gholami Rudi <[email protected]> | |
Date: Tue, 12 May 2015 22:45:59 +0430 | |
vi: find cursor position after insertion in vi_input() | |
Diffstat: | |
M led.c | 36 +++++++++++------------------… | |
M ren.c | 9 --------- | |
M uc.c | 14 -------------- | |
M vi.c | 51 ++++++++++++++++++++++++++++-… | |
M vi.h | 4 +--- | |
5 files changed, 60 insertions(+), 54 deletions(-) | |
--- | |
diff --git a/led.c b/led.c | |
t@@ -90,30 +90,26 @@ static int led_lastword(char *s) | |
return r - s; | |
} | |
-/* the position of the cursor for inserting another character */ | |
-static int led_insertionpos(struct sbuf *sb) | |
-{ | |
- int len = sbuf_len(sb); | |
- char *chr = keymap(led_kmap, 'a'); | |
- int col; | |
- sbuf_str(sb, chr); | |
- col = ren_cursor(sbuf_buf(sb), | |
- ren_pos(sbuf_buf(sb), uc_slen(sbuf_buf(sb)) - 1)); | |
- sbuf_cut(sb, len); | |
- return col; | |
-} | |
- | |
static void led_printparts(char *pref, char *main, char *post) | |
{ | |
struct sbuf *ln; | |
- int col; | |
+ int off, pos; | |
ln = sbuf_make(); | |
sbuf_str(ln, pref); | |
sbuf_str(ln, main); | |
- col = led_insertionpos(ln); | |
+ off = uc_slen(sbuf_buf(ln)); | |
sbuf_str(ln, post); | |
+ /* cursor position for inserting the next character */ | |
+ if (post[0]) { | |
+ pos = ren_cursor(sbuf_buf(ln), ren_pos(sbuf_buf(ln), off)); | |
+ } else { | |
+ int len = sbuf_len(ln); | |
+ sbuf_str(ln, keymap(led_kmap, 'a')); | |
+ pos = ren_pos(sbuf_buf(ln), off); | |
+ sbuf_cut(ln, len); | |
+ } | |
led_print(sbuf_buf(ln), -1); | |
- term_pos(-1, led_pos(sbuf_buf(ln), col)); | |
+ term_pos(-1, led_pos(sbuf_buf(ln), ren_cursor(sbuf_buf(ln), pos))); | |
sbuf_free(ln); | |
} | |
t@@ -177,19 +173,15 @@ char *led_prompt(char *pref, char *post) | |
} | |
/* read visual command input */ | |
-char *led_input(char *pref, char *post, int *row, int *col) | |
+char *led_input(char *pref, char *post) | |
{ | |
struct sbuf *sb = sbuf_make(); | |
int key; | |
- *row = 0; | |
while (1) { | |
char *ln = led_line(pref, post, &key, &led_kmap); | |
- if (pref) | |
- sbuf_str(sb, pref); | |
sbuf_str(sb, ln); | |
if (key == '\n') | |
sbuf_chr(sb, '\n'); | |
- *col = ren_last(pref ? sbuf_buf(sb) : ln); | |
led_printparts(pref ? pref : "", ln, key == '\n' ? "" : post); | |
if (key == '\n') | |
term_chr('\n'); | |
t@@ -198,9 +190,7 @@ char *led_input(char *pref, char *post, int *row, int *col) | |
free(ln); | |
if (key != '\n') | |
break; | |
- (*row)++; | |
} | |
- sbuf_str(sb, post); | |
if (key == TERMESC) | |
return sbuf_done(sb); | |
sbuf_free(sb); | |
diff --git a/ren.c b/ren.c | |
t@@ -55,15 +55,6 @@ char *ren_translate(char *s) | |
return sbuf_done(sb); | |
} | |
-int ren_last(char *s) | |
-{ | |
- int n = uc_slen(s); | |
- int *pos = ren_position(s); | |
- int ret = n ? pos[n - 1] : 0; | |
- free(pos); | |
- return ret; | |
-} | |
- | |
/* find the next character after visual position p; if cur start from p itself… | |
static int pos_next(int *pos, int n, int p, int cur) | |
{ | |
diff --git a/uc.c b/uc.c | |
t@@ -285,20 +285,6 @@ static int uc_comb(int c) | |
c == 0x0670; /* superscript ale… | |
} | |
-/* the direction of the given utf-8 character */ | |
-int uc_dir(char *s) | |
-{ | |
- int u, c = (unsigned char) s[0]; | |
- if (c < 128 && (ispunct(c) || isspace(c))) | |
- return 0; | |
- if (c < 128 && isalnum(c)) | |
- return 1; | |
- u = uc_code(s); | |
- if (UC_R2L(u)) | |
- return -1; | |
- return 1; | |
-} | |
- | |
static void uc_cput(char *d, int c) | |
{ | |
int l = 0; | |
diff --git a/vi.c b/vi.c | |
t@@ -398,7 +398,12 @@ static int vi_insertionoffset(char *s, int c1, int before) | |
return l2 < l1 ? l1 + 1 : l1; | |
} | |
ren_region(s, c1, c2, &l1, &l2, 0); | |
- return l1 < l2 ? l2 : l1; | |
+ c1 = ren_pos(s, l1); | |
+ c2 = ren_pos(s, l2); | |
+ if (c1 < c2) | |
+ return l1 < l2 ? l2 : l1; | |
+ else | |
+ return l1 < l2 ? l1 : l2; | |
} | |
static void vi_commandregion(int *r1, int *r2, int *c1, int *c2, int *l1, int … | |
t@@ -454,6 +459,42 @@ static void vi_delete(int r1, int c1, int r2, int c2, int… | |
free(post); | |
} | |
+static int lastline(char *str) | |
+{ | |
+ char *s = str; | |
+ char *r = s; | |
+ while (s && s[0]) { | |
+ r = s; | |
+ s = strchr(s == str ? s : s + 1, '\n'); | |
+ } | |
+ return r - str; | |
+} | |
+ | |
+static int linecount(char *s) | |
+{ | |
+ int n; | |
+ for (n = 0; s; n++) | |
+ if ((s = strchr(s, '\n'))) | |
+ s++; | |
+ return n; | |
+} | |
+ | |
+static char *vi_input(char *pref, char *post, int *row, int *col) | |
+{ | |
+ char *rep = led_input(pref, post); | |
+ struct sbuf *sb = sbuf_make(); | |
+ int last, off; | |
+ sbuf_str(sb, pref); | |
+ sbuf_str(sb, rep); | |
+ last = lastline(sbuf_buf(sb)); | |
+ off = uc_slen(sbuf_buf(sb) + last); | |
+ sbuf_str(sb, post); | |
+ *row = linecount(sbuf_buf(sb)) - 1; | |
+ *col = ren_pos(sbuf_buf(sb) + last, MAX(0, off - 1)); | |
+ free(rep); | |
+ return sbuf_done(sb); | |
+} | |
+ | |
static void vi_change(int r1, int c1, int r2, int c2, int lnmode, int closed) | |
{ | |
char *region; | |
t@@ -467,11 +508,11 @@ static void vi_change(int r1, int c1, int r2, int c2, in… | |
free(region); | |
pref = lnmode ? uc_dup("") : uc_sub(lbuf_get(xb, r1), 0, l1); | |
post = lnmode ? uc_dup("\n") : uc_sub(lbuf_get(xb, r2), l2, -1); | |
- rep = led_input(pref, post, &row, &col); | |
+ rep = vi_input(pref, post, &row, &col); | |
if (rep) { | |
lbuf_rm(xb, r1, r2 + 1); | |
lbuf_put(xb, r1, rep); | |
- xrow = r1 + row; | |
+ xrow = r1 + row - 1; | |
xcol = col; | |
free(rep); | |
} | |
t@@ -529,14 +570,14 @@ static void vc_insert(int cmd) | |
off = ln ? vi_insertionoffset(ln, xcol, 0) : 0; | |
pref = ln ? uc_sub(ln, 0, off) : uc_dup(""); | |
post = ln ? uc_sub(ln, off, -1) : uc_dup("\n"); | |
- rep = led_input(pref, post, &row, &col); | |
+ rep = vi_input(pref, post, &row, &col); | |
if ((cmd == 'o' || cmd == 'O') && !lbuf_len(xb)) | |
lbuf_put(xb, 0, "\n"); | |
if (rep) { | |
if (cmd != 'o' && cmd != 'O') | |
lbuf_rm(xb, xrow, xrow + 1); | |
lbuf_put(xb, xrow, rep); | |
- xrow += row; | |
+ xrow += row - 1; | |
xcol = col; | |
free(rep); | |
} | |
diff --git a/vi.h b/vi.h | |
t@@ -49,7 +49,6 @@ 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_off(char *s, int pos); | |
-int ren_last(char *s); | |
int ren_wid(char *s); | |
int ren_region(char *s, int c1, int c2, int *l1, int *l2, int closed); | |
t@@ -66,7 +65,6 @@ void reg_done(void); | |
/* utf-8 helper functions */ | |
int uc_len(char *s); | |
-int uc_dir(char *s); | |
int uc_wid(char *s); | |
int uc_slen(char *s); | |
int uc_code(char *s); | |
t@@ -106,7 +104,7 @@ void term_commit(void); | |
/* line-oriented input and output */ | |
char *led_prompt(char *pref, char *post); | |
-char *led_input(char *pref, char *post, int *row, int *col); | |
+char *led_input(char *pref, char *post); | |
void led_print(char *msg, int row); | |
char *led_keymap(int c); | |
int led_pos(char *s, int pos); |