tled: include pref and post in the string returned from led_input() - neatvi - [fork] simple vi-type editor with UTF-8 support
(HTM) git clone git://src.adamsgaard.dk/neatvi
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) README
---
(DIR) commit 6b9ca3203a7dd6f7c9c5c5d6d0abe61dd6d96360
(DIR) parent e7a96b18114c4757ad98d73c59292c3eb8bc6785
(HTM) Author: Ali Gholami Rudi <ali@rudi.ir>
Date: Thu, 22 Oct 2015 11:31:05 +0330
led: include pref and post in the string returned from led_input()
Diffstat:
M led.c | 42 +++++++++++++++++++++-----------
M vi.c | 52 +++++++++++++++----------------
M vi.h | 2 +-
3 files changed, 54 insertions(+), 42 deletions(-)
---
(DIR) diff --git a/led.c b/led.c
t@@ -295,30 +295,43 @@ static char *led_line(char *pref, char *post, char *ai, int ai_max, int *key, ch
/* read an ex command */
char *led_prompt(char *pref, char *post, char **kmap)
{
- char *s;
int key;
- s = led_line(pref, post, "", 0, &key, kmap);
- if (key == '\n')
- return s;
+ char *s = led_line(pref, post, "", 0, &key, kmap);
+ if (key == '\n') {
+ struct sbuf *sb = sbuf_make();
+ if (pref)
+ sbuf_str(sb, pref);
+ sbuf_str(sb, s);
+ if (post)
+ sbuf_str(sb, post);
+ free(s);
+ return sbuf_done(sb);
+ }
free(s);
return NULL;
}
/* read visual command input */
-char *led_input(char *pref, char *post, char *ai, int ai_max, char **kmap)
+char *led_input(char *pref, char *post, char **kmap)
{
struct sbuf *sb = sbuf_make();
- char *ai_1st = NULL; /* first line auto-indentation */
+ char ai[128];
+ int ai_max = xai ? sizeof(ai) - 1 : 0;
+ int n = 0;
int key;
+ while (n < ai_max && (*pref == ' ' || *pref == '\t'))
+ ai[n++] = *pref++;
+ ai[n] = '\0';
while (1) {
char *ln = led_line(pref, post, ai, ai_max, &key, kmap);
int ln_sp = 0; /* number of initial spaces in ln */
while (ln[ln_sp] && (ln[ln_sp] == ' ' || ln[ln_sp] == '\t'))
ln_sp++;
- if (pref)
- ai_1st = uc_dup(pref[0] || ln[ln_sp] ? ai : "");
- if (!pref && ln[ln_sp])
+ if (ln[ln_sp] || (pref && pref[0]) ||
+ (key != '\n' && post[0] && post[0] != '\n'))
sbuf_str(sb, ai);
+ if (pref)
+ sbuf_str(sb, pref);
sbuf_str(sb, ln);
if (key == '\n')
sbuf_chr(sb, '\n');
t@@ -334,16 +347,17 @@ char *led_input(char *pref, char *post, char *ai, int ai_max, char **kmap)
memcpy(ai + ai_len, ln, ai_new);
ai[ai_len + ai_new] = '\0';
}
- pref = NULL;
free(ln);
if (key != '\n')
break;
term_room(1);
- while (ai_max && post[0] && (post[0] == ' ' || post[0] == '\t'))
- post++;
+ pref = NULL;
+ n = 0;
+ while (xai && (post[n] == ' ' || post[n] == '\t'))
+ n++;
+ memmove(post, post + n, strlen(post) - n + 1);
}
- strcpy(ai, ai_1st);
- free(ai_1st);
+ sbuf_str(sb, post);
if (TK_INT(key))
return sbuf_done(sb);
sbuf_free(sb);
(DIR) diff --git a/vi.c b/vi.c
t@@ -84,9 +84,15 @@ static char *vi_char(void)
static char *vi_prompt(char *msg, char **kmap)
{
+ char *r, *s;
term_pos(xrows, led_pos(msg, 0));
term_kill();
- return led_prompt(msg, "", kmap);
+ s = led_prompt(msg, "", kmap);
+ if (!s)
+ return NULL;
+ r = uc_dup(strlen(s) >= strlen(msg) ? s + strlen(msg) : s);
+ free(s);
+ return r;
}
/* read an ex input line */
t@@ -596,40 +602,30 @@ static int linecount(char *s)
return n;
}
-static int indentscopy(char *d, char *s, int len)
+static int charcount(char *text, char *post)
{
+ int tlen = strlen(text);
+ int plen = strlen(post);
+ char *nl = text;
int i;
- for (i = 0; i < len - 1 && (s[i] == ' ' || s[i] == '\t'); i++)
- d[i] = s[i];
- d[i] = '\0';
- return i;
+ if (tlen < plen)
+ return 0;
+ for (i = 0; i < tlen - plen; i++)
+ if (text[i] == '\n')
+ nl = text + i + 1;
+ return uc_slen(nl) - uc_slen(post);
}
static char *vi_input(char *pref, char *post, int *row, int *off)
{
- char ai[64] = "";
- char *rep, *s;
- struct sbuf *sb;
- int last;
- if (xai)
- pref += indentscopy(ai, pref, sizeof(ai));
- rep = led_input(pref, post, ai, xai ? sizeof(ai) - 1 : 0, &vi_kmap);
+ char *rep = led_input(pref, post, &vi_kmap);
if (!rep)
return NULL;
- sb = sbuf_make();
- sbuf_str(sb, ai);
- sbuf_str(sb, pref);
- sbuf_str(sb, rep);
- s = sbuf_buf(sb);
- last = uc_lastline(s) - s;
- *off = MAX(0, uc_slen(sbuf_buf(sb) + last) - 1);
- if (last)
- while (xai && (post[0] == ' ' || post[0] == '\t'))
- post++;
- sbuf_str(sb, post);
- *row = linecount(sbuf_buf(sb)) - 1;
- free(rep);
- return sbuf_done(sb);
+ *row = linecount(rep) - 1;
+ *off = charcount(rep, post) - 1;
+ if (*off < 0)
+ *off = 0;
+ return rep;
}
static char *vi_indents(char *ln)
t@@ -804,6 +800,8 @@ static int vc_insert(int cmd)
off = xoff;
if (cmd == 'a' || cmd == 'A')
off = xoff + 1;
+ if (ln && ln[0] == '\n')
+ off = 0;
pref = ln && cmd != 'o' && cmd != 'O' ? uc_sub(ln, 0, off) : vi_indents(ln);
post = ln && cmd != 'o' && cmd != 'O' ? uc_sub(ln, off, -1) : uc_dup("\n");
vi_drawrm(xrow, xrow, cmd == 'o' || cmd == 'O');
(DIR) diff --git a/vi.h b/vi.h
t@@ -126,7 +126,7 @@ char *term_cmd(int *n);
/* line-oriented input and output */
char *led_prompt(char *pref, char *post, char **kmap);
-char *led_input(char *pref, char *post, char *ai, int ai_max, char **kmap);
+char *led_input(char *pref, char *post, char **kmap);
char *led_read(char **kmap);
void led_print(char *msg, int row);
int led_pos(char *s, int pos);