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);