]> git.neil.brown.name Git - edlib.git/commitdiff
Change "render-line" to return line via a callback.
authorNeilBrown <neil@brown.name>
Wed, 9 Dec 2015 08:38:58 +0000 (19:38 +1100)
committerNeilBrown <neil@brown.name>
Thu, 10 Dec 2015 02:54:09 +0000 (13:54 +1100)
Signed-off-by: NeilBrown <neil@brown.name>
core.h
doc-text.c
render-complete.c
render-format.c
render-hex.c
render-lines.c

diff --git a/core.h b/core.h
index 68ddb24e92fba98da425d37e865e437e2ff7fdc9..2929068293d2f9feb6ba3c5d39952d4a83600669 100644 (file)
--- a/core.h
+++ b/core.h
@@ -477,6 +477,7 @@ struct call_return {
        struct mark *m;
        char *s;
        struct pane *p;
+       int i;
 };
 
 static inline int call_comm(char *key, struct pane *focus, int numeric, struct mark *m,
index 10165ba2e89a0e84ef5b409053e287b2026ae6dd..3b3db46f7aa7198b908731c4e0e71b490051f437 100644 (file)
@@ -1617,6 +1617,7 @@ DEF_CMD(render_line)
        int o = ci->numeric;
        wint_t ch = WEOF;
        int chars = 0;
+       int ret;
 
        if (!m)
                return -1;
@@ -1657,8 +1658,10 @@ DEF_CMD(render_line)
                        buf_concat(&b, "</>");
                chars++;
        }
-       ci->str = buf_final(&b);
-       return 1;
+       ret = comm_call(ci->comm2, "callback:render", ci->focus, 0, NULL,
+                       buf_final(&b), 0);
+       free(b.b);
+       return ret;
 }
 
 void edlib_init(struct editor *ed)
index 4d21f0c392282188c668686a3e08828fff14e100..1c42537678d1a2e05e51a492b325e9b81d9c7370 100644 (file)
@@ -23,6 +23,12 @@ struct complete_data {
        char *prefix;
 };
 
+struct rlcb {
+       struct command c;
+       int keep, plen, cmp;
+       char *prefix, *str;
+};
+
 static char *add_highlight_prefix(char *orig, int plen, char *attr)
 {
        struct buf ret;
@@ -42,6 +48,22 @@ static char *add_highlight_prefix(char *orig, int plen, char *attr)
        return buf_final(&ret);
 }
 
+DEF_CMD(save_highlighted)
+{
+       struct call_return *cr = container_of(ci->comm, struct call_return, c);
+       cr->s = add_highlight_prefix(ci->str, cr->i, "<fg:red>");
+       return 1;
+}
+
+DEF_CMD(rcl_cb)
+{
+       struct rlcb *cb = container_of(ci->comm, struct rlcb, c);
+       if (ci->str == NULL)
+               cb->cmp = 0;
+       else
+               cb->cmp = strncmp(ci->str, cb->prefix, cb->plen);
+       return 1;
+}
 DEF_CMD(render_complete_line)
 {
        /* The first line *must* match the prefix.
@@ -51,6 +73,9 @@ DEF_CMD(render_complete_line)
        struct complete_data *cd = ci->home->data;
        struct doc *d = doc_from_pane(ci->home);
        int plen = strlen(cd->prefix);
+       struct call_return cr;
+       struct rlcb cb;
+       int ret;
 
        if (!d || !ci->mark)
                return -1;
@@ -60,28 +85,48 @@ DEF_CMD(render_complete_line)
        ci2.mark2 = ci->mark2;
        ci2.focus = ci->home->parent;
        ci2.numeric = ci->numeric;
+       cr.c = save_highlighted;
+       cr.i = plen;
+       cr.s = NULL;
+       ci2.comm2 = &cr.c;
        if (key_handle(&ci2) == 0)
                return 0;
-       ci->str = add_highlight_prefix(ci2.str, plen, "<fg:red>");
-       free(ci2.str);
+
+       ret = comm_call(ci->comm2, "callback:render", ci->focus, 0, NULL, cr.s, 0);
        if (ci->numeric != NO_NUMERIC)
-               return 1;
+               return ret;
        /* Need to continue over other matching lines */
        ci2.mark = mark_dup(ci->mark, 1);
        while (1) {
                ci2.numeric = ci->numeric;
                ci2.focus = ci->home->parent;
+               cb.c = rcl_cb;
+               cb.plen = plen;
+               cb.prefix = cd->prefix;
+               cb.cmp = 0;
+               ci2.comm2 = &cb.c;
                key_handle(&ci2);
-               if (ci2.str == NULL ||
-                   strncmp(ci2.str, cd->prefix, plen) == 0)
+               if (cb.cmp == 0)
                        break;
-               /* have a match, so move the mark to here. */
+
+               /* have a non-match, so move the mark over it. */
                mark_to_mark(ci->mark, ci2.mark);
        }
        mark_free(ci2.mark);
-       return 1;
+       return ret;
 }
 
+DEF_CMD(rlcb)
+{
+       struct rlcb *cb = container_of(ci->comm, struct rlcb, c);
+       if (ci->str == NULL)
+               cb->cmp = -1;
+       else
+               cb->cmp = strncmp(ci->str, cb->prefix, cb->plen);
+       if (cb->cmp == 0 && cb->keep && ci->str)
+               cb->str = strdup(ci->str);
+       return 1;
+}
 DEF_CMD(render_complete_prev)
 {
        /* If ->numeric is 0 we just need 'start of line' so use
@@ -90,8 +135,8 @@ DEF_CMD(render_complete_prev)
         * it matches the prefix.
         */
        struct cmd_info ci2 = {0}, ci3 = {0};
+       struct rlcb cb;
        struct complete_data *cd = ci->home->data;
-       int plen = strlen(cd->prefix);
        int ret;
 
        ci2.key = ci->key;
@@ -101,9 +146,12 @@ DEF_CMD(render_complete_prev)
 
        ci3.key = "render-line";
        ci3.focus = ci->home->parent;
+       cb.c = rlcb;
+       cb.str = NULL;
+       cb.prefix = cd->prefix;
+       cb.plen = strlen(cb.prefix);
+       ci3.comm2 = &cb.c;
        while (1) {
-               int cmp;
-
                ret = key_handle(&ci2);
                if (ret <= 0 || ci->numeric == 0)
                        /* Either hit start-of-file, or have what we need */
@@ -115,20 +163,16 @@ DEF_CMD(render_complete_prev)
                        ci2.mark = mark_dup(ci->mark, 1);
                ci3.mark = mark_dup(ci2.mark, 1);
                ci3.numeric = NO_NUMERIC;
-               if (key_handle(&ci3) == 0) {
+               cb.keep = ci2.numeric == 1 && ci->extra == 42;
+               cb.str = NULL;
+               if (key_handle(&ci3) != 1) {
                        mark_free(ci3.mark);
                        break;
                }
                mark_free(ci3.mark);
-               if (ci3.str == NULL)
-                       cmp = -1;
-               else
-                       cmp = strncmp(ci3.str, cd->prefix, plen);
-               if (cmp != 0 || ci2.numeric != 1 || ci->extra != 42)
-                       free(ci3.str);
-               else
-                       ci->str2 = ci3.str;
-               if (cmp == 0 && ci2.numeric == 1)
+               ci->str2 = cb.str;
+
+               if (cb.cmp == 0 && ci2.numeric == 1)
                        /* This is a valid new start-of-line */
                        break;
                /* step back once more */
@@ -174,6 +218,12 @@ DEF_CMD(complete_nomove)
        return 1;
 }
 
+DEF_CMD(eol_cb)
+{
+       /* don't save anything */
+       return 1;
+}
+
 DEF_CMD(complete_eol)
 {
        int rpt = RPT_NUM(ci);
@@ -194,15 +244,16 @@ DEF_CMD(complete_eol)
        }
        while (rpt > 1) {
                struct cmd_info ci2 = {0};
+               struct call_return cr;
                ci2.key = "render-line";
                ci2.numeric = NO_NUMERIC;
                ci2.mark = ci->mark;
                ci2.focus = ci->focus;
                ci2.home = ci->home;
-               if (render_complete_line_func(&ci2) < 0)
+               cr.c = eol_cb;
+               ci2.comm2 = &cr.c;
+               if (render_complete_line_func(&ci2) <= 0)
                        rpt = 1;
-               else
-                       free(ci2.str);
                rpt -= 1;
        }
        return 1;
@@ -264,13 +315,20 @@ DEF_CMD(complete_set_prefix)
        return cnt + 1;
 }
 
+DEF_CMD(save_str)
+{
+       struct call_return *cr = container_of(ci->comm, struct call_return, c);
+       cr->s = ci->str ? strdup(ci->str) : NULL;
+       return 1;
+}
+
 DEF_CMD(complete_return)
 {
        /* submit the selected entry to the popup */
        struct pane *p = ci->home;
        struct complete_data *cd = p->data;
        struct cmd_info ci2 = {0};
-       char *str;
+       struct call_return cr;
        int l;
        char *c1, *c2;
 
@@ -279,14 +337,16 @@ DEF_CMD(complete_return)
        ci2.home = ci->home;
        ci2.mark = ci->mark;
        ci2.numeric = NO_NUMERIC;
+       cr.c = save_str;
+       cr.s = NULL;
+       ci2.comm2 = &cr.c;
        render_complete_line_func(&ci2);
-       str = ci2.str;
-       if (!str)
+       if (!cr.s)
                return 1;
-       l = strlen(str);
-       if (l && str[l-1] == '\n')
-               str[l-1] = 0;
-       c1 = c2 = str;
+       l = strlen(cr.s);
+       if (l && cr.s[l-1] == '\n')
+               cr.s[l-1] = 0;
+       c1 = c2 = cr.s;
        while (*c2) {
                if (*c2 != '<') {
                        *c1++ = *c2++;
@@ -305,10 +365,10 @@ DEF_CMD(complete_return)
        memset(&ci2, 0, sizeof(ci2));
        ci2.key = ci->key;
        ci2.focus = ci->home->parent;
-       ci2.str = str + strlen(cd->prefix);
+       ci2.str = cr.s + strlen(cd->prefix);
        ci2.numeric = NO_NUMERIC;
        key_handle(&ci2);
-       free(str);
+       free(cr.s);
        return 1;
 }
 
index 1666e9ac42e1e166187c08e7b044d6111e77df5f..73516b4686330e394dec487d9e36e2edea348e93 100644 (file)
@@ -32,6 +32,7 @@ DEF_CMD(render_line)
        wint_t ch;
        int home;
        int field = 0;
+       int rv;
 
        if (!d || !ci->mark)
                return -1;
@@ -39,10 +40,8 @@ DEF_CMD(render_line)
        if (pm && !mark_same(d, pm, m))
                pm = NULL;
        ch = doc_following(d, m);
-       if (ch == WEOF) {
-               ci->str = NULL;
+       if (ch == WEOF)
                return 1;
-       }
        buf_init(&ret);
 
        if (!body)
@@ -149,8 +148,10 @@ endwhile:
                        mark_next(d, m);
                }
        }
-       ci->str = buf_final(&ret);
-       return 1;
+       rv = comm_call(ci->comm2, "callback:render", ci->focus, 0, NULL,
+                      buf_final(&ret), 0);
+       free(ret.b);
+       return rv;
 }
 
 DEF_CMD(render_line_prev)
index c98c79349b4b905519fc8b236873bf5f661ee307..92ac80a11c0e43fbc5fb63e37da68fc69d7e10ac 100644 (file)
@@ -127,6 +127,7 @@ DEF_CMD(render_line)
        int pos;
        int i;
        char buf[10];
+       int rv;
 
        if (!d || !ci->mark)
                return -1;
@@ -181,8 +182,10 @@ DEF_CMD(render_line)
 done:
        if (m)
                mark_free(m);
-       ci->str = buf_final(&ret);
-       return 1;
+       rv = comm_call(ci->comm2, "callback:render", ci->focus, 0, NULL,
+                      buf_final(&ret), 0);
+       free(ret.b);
+       return rv;
 }
 
 DEF_CMD(render_line_prev)
index 8489f9bf01b70f88ca1889a8b6a7007ad48d498d..baca51570314f96587032000dc5f24aa414fc258 100644 (file)
@@ -287,15 +287,26 @@ static struct mark *call_render_line_prev(struct pane *p,
        return m;
 }
 
+DEF_CMD(save_str)
+{
+       struct call_return *cr = container_of(ci->comm, struct call_return, c);
+       cr->s = ci->str ? strdup(ci->str) : NULL;
+       return 1;
+}
+
 static struct mark *call_render_line(struct pane *p, struct mark *start)
 {
        struct cmd_info ci = {0};
+       struct call_return cr;
        struct mark *m, *m2;
 
        ci.key = "render-line";
        ci.focus = p;
        ci.mark = mark_dup(start, 0);
        ci.numeric = NO_NUMERIC;
+       cr.c = save_str;
+       cr.s = NULL;
+       ci.comm2 = &cr.c;
        /* Allow for filling the rest of the pane, given that
         * some has been used.
         * 'used' can be negative if the mark is before the start
@@ -308,7 +319,7 @@ static struct mark *call_render_line(struct pane *p, struct mark *start)
 
        if (start->mdata)
                free(start->mdata);
-       start->mdata = ci.str;
+       start->mdata = cr.s;
 
        m = vmark_matching(p, ci.mark);
        if (m)
@@ -327,6 +338,11 @@ static struct mark *call_render_line(struct pane *p, struct mark *start)
        return m;
 }
 
+DEF_CMD(no_save)
+{
+       return 1;
+}
+
 static struct mark *call_render_line_offset(struct pane *p,
                                            struct mark *start, int offset)
 {
@@ -336,14 +352,22 @@ static struct mark *call_render_line_offset(struct pane *p,
        ci.focus = p;
        ci.mark = mark_dup(start, 0);
        ci.numeric = offset;
+       ci.comm2 = &no_save;
        if (key_handle(&ci) == 0) {
                mark_free(ci.mark);
                return NULL;
        }
-       free(ci.str);
        return ci.mark;
 }
 
+DEF_CMD(get_len)
+{
+       if (ci->str)
+               return strlen(ci->str) + 1;
+       else
+               return 1;
+}
+
 static int call_render_line_to_point(struct pane *p, struct mark *pm,
                                     struct mark *start)
 {
@@ -355,16 +379,14 @@ static int call_render_line_to_point(struct pane *p, struct mark *pm,
        ci.mark2 = pm;
        ci.mark = mark_dup(start, 0);
        ci.numeric = -1;
-       if (key_handle(&ci) == 0) {
+       ci.comm2 = &get_len;
+       len = key_handle(&ci);
+       if (len <= 0) {
                mark_free(ci.mark);
                return 0;
        }
+       len -= 1;
        mark_free(ci.mark);
-       if (ci.str) {
-               len = strlen(ci.str);
-               free(ci.str);
-       } else
-               len = 0;
        return len;
 }