From: NeilBrown Date: Wed, 9 Dec 2015 08:38:58 +0000 (+1100) Subject: Change "render-line" to return line via a callback. X-Git-Tag: lca2016~100 X-Git-Url: http://git.neil.brown.name/?a=commitdiff_plain;h=f1087cecc9a02fb4f96142fb0136b544f8c94ddb;p=edlib.git Change "render-line" to return line via a callback. Signed-off-by: NeilBrown --- diff --git a/core.h b/core.h index 68ddb24e..29290682 100644 --- 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, diff --git a/doc-text.c b/doc-text.c index 10165ba2..3b3db46f 100644 --- a/doc-text.c +++ b/doc-text.c @@ -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) diff --git a/render-complete.c b/render-complete.c index 4d21f0c3..1c425376 100644 --- a/render-complete.c +++ b/render-complete.c @@ -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, ""); + 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, ""); - 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; } diff --git a/render-format.c b/render-format.c index 1666e9ac..73516b46 100644 --- a/render-format.c +++ b/render-format.c @@ -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) diff --git a/render-hex.c b/render-hex.c index c98c7934..92ac80a1 100644 --- a/render-hex.c +++ b/render-hex.c @@ -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) diff --git a/render-lines.c b/render-lines.c index 8489f9bf..baca5157 100644 --- a/render-lines.c +++ b/render-lines.c @@ -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; }