tled: ^T and ^D to modify autoindent - 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 1aaf74068c7eee5e00a1743ee660fcb4576ddb30
 (DIR) parent b4b9f99e7ed6100016bcfc64b7e66e3d10e8ce70
 (HTM) Author: Ali Gholami Rudi <ali@rudi.ir>
       Date:   Fri, 15 May 2015 01:43:16 +0430
       
       led: ^T and ^D to modify autoindent
       
       Diffstat:
         M led.c                               |      33 ++++++++++++++++++++++++-------
         M vi.c                                |      19 ++++++++++++++++++-
         M vi.h                                |       2 +-
       
       3 files changed, 45 insertions(+), 9 deletions(-)
       ---
 (DIR) diff --git a/led.c b/led.c
       t@@ -90,11 +90,12 @@ static int led_lastword(char *s)
                return r - s;
        }
        
       -static void led_printparts(char *pref, char *main, char *post)
       +static void led_printparts(char *ai, char *pref, char *main, char *post)
        {
                struct sbuf *ln;
                int off, pos;
                ln = sbuf_make();
       +        sbuf_str(ln, ai);
                sbuf_str(ln, pref);
                sbuf_str(ln, main);
                off = uc_slen(sbuf_buf(ln));
       t@@ -113,9 +114,10 @@ static void led_printparts(char *pref, char *main, char *post)
                sbuf_free(ln);
        }
        
       -static char *led_line(char *pref, char *post, int *key, char ***kmap)
       +static char *led_line(char *pref, char *post, char *ai, int ai_max, int *key, char ***kmap)
        {
                struct sbuf *sb;
       +        int ai_len = strlen(ai);
                int c;
                sb = sbuf_make();
                if (!pref)
       t@@ -123,7 +125,7 @@ static char *led_line(char *pref, char *post, int *key, char ***kmap)
                if (!post)
                        post = "";
                while (1) {
       -                led_printparts(pref, sbuf_buf(sb), post);
       +                led_printparts(ai, pref, sbuf_buf(sb), post);
                        c = term_read(-1);
                        switch (c) {
                        case TK_CTL('f'):
       t@@ -147,6 +149,14 @@ static char *led_line(char *pref, char *post, int *key, char ***kmap)
                                if (sbuf_len(sb))
                                        sbuf_cut(sb, led_lastword(sbuf_buf(sb)));
                                break;
       +                case TK_CTL('t'):
       +                        if (ai_len < ai_max)
       +                                ai[ai_len++] = '\t';
       +                        break;
       +                case TK_CTL('d'):
       +                        if (ai_len > 0)
       +                                ai[--ai_len] = '\0';
       +                        break;
                        default:
                                if (c == '\n' || TK_INT(c))
                                        break;
       t@@ -165,7 +175,7 @@ char *led_prompt(char *pref, char *post)
                char **kmap = kmap_def;
                char *s;
                int key;
       -        s = led_line(pref, post, &key, &kmap);
       +        s = led_line(pref, post, "", 0, &key, &kmap);
                if (key == '\n')
                        return s;
                free(s);
       t@@ -173,16 +183,21 @@ char *led_prompt(char *pref, char *post)
        }
        
        /* read visual command input */
       -char *led_input(char *pref, char *post)
       +char *led_input(char *pref, char *post, char *ai, int ai_max)
        {
                struct sbuf *sb = sbuf_make();
       +        char *first_ai = NULL;
                int key;
                while (1) {
       -                char *ln = led_line(pref, post, &key, &led_kmap);
       +                char *ln = led_line(pref, post, ai, ai_max, &key, &led_kmap);
       +                if (pref)
       +                        first_ai = uc_dup(ai);
       +                if (!pref)
       +                        sbuf_str(sb, ai);
                        sbuf_str(sb, ln);
                        if (key == '\n')
                                sbuf_chr(sb, '\n');
       -                led_printparts(pref ? pref : "", ln, key == '\n' ? "" : post);
       +                led_printparts(ai, pref ? pref : "", ln, key == '\n' ? "" : post);
                        if (key == '\n')
                                term_chr('\n');
                        pref = NULL;
       t@@ -190,7 +205,11 @@ char *led_input(char *pref, char *post)
                        free(ln);
                        if (key != '\n')
                                break;
       +                while (ai_max && post[0] && (post[0] == ' ' || post[0] == '\t'))
       +                        post++;
                }
       +        strcpy(ai, first_ai);
       +        free(first_ai);
                if (TK_INT(key))
                        return sbuf_done(sb);
                sbuf_free(sb);
 (DIR) diff --git a/vi.c b/vi.c
       t@@ -587,18 +587,35 @@ static int linecount(char *s)
                return n;
        }
        
       +static int indentscopy(char *d, char *s, int len)
       +{
       +        int i;
       +        for (i = 0; i < len - 1 && (s[i] == ' ' || s[i] == '\t'); i++)
       +                d[i] = s[i];
       +        d[i] = '\0';
       +        return i;
       +}
       +
        static char *vi_input(char *pref, char *post, int *row, int *col)
        {
       -        char *rep = led_input(pref, post);
       +        char ai[64] = "";
       +        char *rep;
                struct sbuf *sb;
                int last, off;
       +        if (xautoindent)
       +                pref += indentscopy(ai, pref, sizeof(ai));
       +        rep = led_input(pref, post, ai, xautoindent ? sizeof(ai) - 1 : 0);
                if (!rep)
                        return NULL;
                sb = sbuf_make();
       +        sbuf_str(sb, ai);
                sbuf_str(sb, pref);
                sbuf_str(sb, rep);
                last = lastline(sbuf_buf(sb));
                off = uc_slen(sbuf_buf(sb) + last);
       +        if (last)
       +                while (xautoindent && (post[0] == ' ' || post[0] == '\t'))
       +                        post++;
                sbuf_str(sb, post);
                *row = linecount(sbuf_buf(sb)) - 1;
                *col = ren_pos(sbuf_buf(sb) + last, MAX(0, off - 1));
 (DIR) diff --git a/vi.h b/vi.h
       t@@ -110,7 +110,7 @@ void term_commit(void);
        
        /* line-oriented input and output */
        char *led_prompt(char *pref, char *post);
       -char *led_input(char *pref, char *post);
       +char *led_input(char *pref, char *post, char *ai, int ai_max);
        void led_print(char *msg, int row);
        char *led_keymap(int c);
        int led_pos(char *s, int pos);