| 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); |
| 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 *l2, int closed)
t@@ -454,6 +459,42 @@ static void vi_delete(int r1, int c1, int r2, int c2, int lnmode, int closed)
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, int lnmode, int closed)
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);
} |
| 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); |