tled: highlight the text in the reverse direction - 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 88ed01cab8edeb1c8eb4ea39bba066dac00f161c
 (DIR) parent bdbc8d37c53bd7702979786c58354bbf2ef6990e
 (HTM) Author: Ali Gholami Rudi <ali@rudi.ir>
       Date:   Thu, 28 May 2015 23:25:00 +0430
       
       led: highlight the text in the reverse direction
       
       Diffstat:
         M conf.c                              |       6 ++++++
         M conf.h                              |       5 ++++-
         M led.c                               |      35 +++++++++++++++++++++++++++++++
         M vi.h                                |       1 +
       
       4 files changed, 46 insertions(+), 1 deletion(-)
       ---
 (DIR) diff --git a/conf.c b/conf.c
       t@@ -71,3 +71,9 @@ int conf_filetype(int idx, char **ft, char **pat)
                        *pat = filetypes[idx].pat;
                return 0;
        }
       +
       +int conf_highlight_revdir(int *att)
       +{
       +        *att = SYN_REVDIR;
       +        return 0;
       +}
 (DIR) diff --git a/conf.h b/conf.h
       t@@ -27,7 +27,7 @@ static struct dirmark {
                {+0, +1, 1, "\\\\\\*\\[([^]]+)\\]"},
                {+1, -1, 0, "[" CR2L "][" CNEUT CR2L "]*[" CR2L "]"},
                {-1, +1, 0, "[a-zA-Z0-9_][^" CR2L "\\\\`$']*[a-zA-Z0-9_]"},
       -        {+0, +1, 0, "$([^$]+)\\$"},
       +        {+0, +1, 0, "\\$([^$]+)\\$"},
                {+0, +1, 1, "\\\\[a-zA-Z0-9_]+\\{([^}]+)\\}"},
                {-1, +1, 0, "\\\\[^ \t" CR2L "]+"},
        };
       t@@ -79,3 +79,6 @@ static struct highlight {
                {"tr", SYN_BD, 0, "^\\.SH.*$"},
                {"tr", 4, 0, "^\\.[a-zA-Z0-9]{2}.*$"},
        };
       +
       +/* how to hightlight text in the reverse direction */
       +#define SYN_REVDIR                (SYN_BGMK(7))
 (DIR) diff --git a/led.c b/led.c
       t@@ -36,6 +36,40 @@ static int led_posctx(int dir, int pos)
                return dir >= 0 ? pos : xcols - pos - 1;
        }
        
       +static int led_offdir(char **chrs, int *pos, int i)
       +{
       +        if (pos[i] + ren_cwid(chrs[i], pos[i]) == pos[i + 1])
       +                return +1;
       +        if (pos[i + 1] + ren_cwid(chrs[i + 1], pos[i + 1]) == pos[i])
       +                return -1;
       +        return 0;
       +}
       +
       +static int syn_merge(int old, int new)
       +{
       +        int fg = SYN_FG(new) ? SYN_FG(new) : SYN_FG(old);
       +        int bg = SYN_BG(new) ? SYN_BG(new) : SYN_BG(old);
       +        return fg | SYN_BGMK(bg);
       +}
       +
       +static void led_markrev(int n, char **chrs, int *pos, int *att)
       +{
       +        int i = 0, j;
       +        int hl = 0;
       +        conf_highlight_revdir(&hl);
       +        while (i + 1 < n) {
       +                int dir = led_offdir(chrs, pos, i);
       +                int beg = i;
       +                while (i + 1 < n && led_offdir(chrs, pos, i) == dir)
       +                        i++;
       +                if (dir < 0)
       +                        for (j = beg; j <= i; j++)
       +                                att[j] = syn_merge(att[j], hl);
       +                if (i == beg)
       +                        i++;
       +        }
       +}
       +
        static char *led_render(char *s0)
        {
                int n, maxcol = 0;
       t@@ -63,6 +97,7 @@ static char *led_render(char *s0)
                        }
                }
                att = syn_highlight(xft, s0);
       +        led_markrev(n, chrs, pos, att);
                out = sbuf_make();
                i = 0;
                while (i <= maxcol) {
 (DIR) diff --git a/vi.h b/vi.h
       t@@ -156,6 +156,7 @@ int conf_dircontext(int idx, char **pat, int *ctx);
        int conf_placeholder(int idx, char **s, char **d, int *wid);
        int conf_highlight(int idx, char **ft, int *att, int *grp, char **pat);
        int conf_filetype(int idx, char **ft, char **pat);
       +int conf_highlight_revdir(int *att);
        
        /* global variables */
        #define PATHLEN                512