From: NeilBrown Date: Wed, 7 Jun 2023 22:30:58 +0000 (+1000) Subject: render-lines: add "Activate" support. X-Git-Url: http://git.neil.brown.name/?a=commitdiff_plain;h=484325cb4a9eaa8fa04a92ee8b0049eee3a8935d;p=edlib.git render-lines: add "Activate" support. When render-lines gets "Activate" it looks up the attrs at the mark and if there is an active-tag, it calls "Activate:tag". This makes email:select unnecessary. lib-url uses Activate to respond to K:Enter Signed-off-by: NeilBrown --- diff --git a/DOC/TODO.md b/DOC/TODO.md index f40c93be..03c3ec9b 100644 --- a/DOC/TODO.md +++ b/DOC/TODO.md @@ -737,7 +737,7 @@ Module features - [X] command to mark-up all URLs in a document - [X] handlers for that markup. xdg-open for links, maybe signal register email client for mailto: links. -- [ ] easy way for K:Enter on a link to do just like mouse-click +- [X] easy way for K:Enter on a link to do just like mouse-click - [ ] email: urls should not be followed unless they are visible. Maybe display in the message window, which might be made larger just for this purpose. diff --git a/doc-email.c b/doc-email.c index b5428c40..6204b8a8 100644 --- a/doc-email.c +++ b/doc-email.c @@ -276,44 +276,6 @@ DEF_CMD(email_image) return ret; } -DEF_CMD(email_select) -{ - /* If mark is on a button, press it... */ - struct mark *m = ci->mark; - char *a, *e, *cmd = NULL; - wint_t ch; - int p; - int b; - - if (!m) - return Enoarg; - p = get_part(ci->home, m); - if (!is_spacer(p)) - return Efallthrough; - ch = doc_following(ci->home, m); - if (ch == WEOF || !isdigit(ch)) - return 1; - b = ch - '0'; - a = pane_mark_attr(ci->focus, m, "multipart-prev:email:actions"); - if (!a) - a = "hide"; - while (b > 0 && a) { - a = strchr(a, ':'); - if (a) - a += 1; - b -= 1; - } - if (!a) - return 1; - e = strchr(a, ':'); - if (!e) - e = a + strlen(a); - asprintf(&cmd, "email:select:%.*s", (int)(e-a), a); - if (!cmd) - return Efail; - return call(cmd, ci->focus, 0, m); -} - DEF_CMD(email_select_hide) { int vis = 1; @@ -1323,7 +1285,6 @@ static void email_init_map(void) key_add(email_view_map, "doc:get-attr", &email_view_get_attr); key_add(email_view_map, "doc:email:render-spacer", &email_spacer); key_add(email_view_map, "doc:email:render-image", &email_image); - key_add(email_view_map, "doc:email:select", &email_select); key_add(email_view_map, "email:select:hide", &email_select_hide); key_add(email_view_map, "email:select:full", &email_select_full); key_add(email_view_map, "email:select:extras", &email_select_extras); diff --git a/lib-renderline.c b/lib-renderline.c index e926d383..17be787a 100644 --- a/lib-renderline.c +++ b/lib-renderline.c @@ -43,6 +43,7 @@ struct render_list { struct rline_data { short prefix_len; const char *xyattr; + const char *cursattr; short curs_width; int scale; const char *line; @@ -188,7 +189,7 @@ static int flush_line(struct pane *p safe, struct pane *focus safe, int dodraw, struct render_list **rlp safe, int y, int scale, int wrap_pos, int *wrap_margin safe, int *wrap_prefix_sizep, - const char **xypos, const char **xyattr) + const char **xypos, const char **xyattr, const char **cursattr) { /* Flush a render_list returning x-space used. * If wrap_pos is > 0, stop rendering before last entry with the @@ -252,6 +253,8 @@ static int flush_line(struct pane *p safe, struct pane *focus safe, int dodraw, if (xyattr) *xyattr = strsave(p, rl->attr); } + if (cp >= 0 && cursattr) + *cursattr = strsave(p, rl->attr); } /* Draw the wrap text if it contains the cursor */ for (; rl && rl != end_wrap; rl = rl->next) { @@ -665,6 +668,7 @@ DEF_CMD(renderline) const char *xypos = NULL; const char *ret_xypos = NULL; const char *xyattr = NULL; + const char *cursattr = NULL; /* want_xypos becomes 2 when the pos is found */ int want_xypos = strcmp(ci->key, "render-line:findxy") == 0; struct xy xyscale = pane_scale(focus); @@ -796,7 +800,7 @@ DEF_CMD(renderline) y+ascent, scale, p->w - mwidth, &wrap_margin, &wrap_prefix_size, - &xypos, &xyattr); + &xypos, &xyattr, &cursattr); if (len + wrap_prefix_size <= cx && cy == y) { cx -= len; cy += line_height; @@ -947,7 +951,7 @@ DEF_CMD(renderline) if (ch == '\n') { xypos = line-1; flush_line(p, focus, dodraw, &rlst, y+ascent, scale, 0, - &wrap_margin, NULL, &xypos, &xyattr); + &wrap_margin, NULL, &xypos, &xyattr, &cursattr); y += line_height; x = 0; wrap_offset = 0; @@ -1010,13 +1014,17 @@ DEF_CMD(renderline) } flush_line(p, focus, dodraw, &rlst, y+ascent, scale, 0, - &wrap_margin, NULL, &xypos, &xyattr); + &wrap_margin, NULL, &xypos, &xyattr, &cursattr); if (want_xypos == 1) { rd->xyattr = xyattr ? strdup(xyattr) : NULL; ret_xypos = xypos ?: line; want_xypos = 2; } + if (cursattr) { + free((void*)rd->cursattr); + rd->cursattr = strdup(cursattr); + } if (offset >= 0 && line - line_start <= offset) { if (y >= 0 && (y == 0 || y + line_height <= p->h)) { @@ -1070,6 +1078,8 @@ DEF_CMD(renderline_get) snprintf(buf, sizeof(buf), "%d", rd->curs_width); else if (strcmp(ci->str, "xyattr") == 0) val = rd->xyattr; + else if (strcmp(ci->str, "cursattr") == 0) + val = rd->cursattr; else return Einval; diff --git a/python/lib-url.py b/python/lib-url.py index 1fc272e6..46ff789f 100644 --- a/python/lib-url.py +++ b/python/lib-url.py @@ -95,5 +95,9 @@ class url_view(edlib.Pane): focus.call("Message", "URL tag %s not found" % tag) return 1 + def handle_enter(self, key, focus, mark, **a): + "handle:K:Enter" + return focus.call("Activate", mark) + edlib.editor.call("global-set-command", "url:mark-up", mark_urls) edlib.editor.call("global-set-command", "attach-render-url-view", attach_url) diff --git a/python/module-notmuch.py b/python/module-notmuch.py index 1d268b9b..80a6ab8b 100644 --- a/python/module-notmuch.py +++ b/python/module-notmuch.py @@ -3354,9 +3354,6 @@ class notmuch_message_view(edlib.Pane): self.leaf.call("view:changed", m, m.next()) return 1 - focus.call("doc:email:select", mark) - return 1 - def handle_vis(self, focus, mark, which): v = focus.call("doc:get-attr", mark, "email:visible", ret='str') self.parent.call("email:select:" + which, focus, mark) diff --git a/render-lines.c b/render-lines.c index 4209b02d..2c1ecb7e 100644 --- a/render-lines.c +++ b/render-lines.c @@ -1414,6 +1414,46 @@ DEF_CMD(render_lines_set_cursor) return 1; } +DEF_CMD(render_lines_activate) +{ + /* If there is an active-tag: at '->mark', send Activate:tag + * to the focus + */ + struct mark *m = ci->mark; + struct pane *p = ci->home; + struct rl_data *rl = p->data; + struct pane *focus = ci->focus; + struct mark *v, *n; + int offset; + char *attr, *tag; + + if (!m) + return Enoarg; + v = vmark_first(p, rl->typenum, p); + + while (v && v->mdata && (n = vmark_next(v)) && + mark_ordered_or_same(n, m)) + v = n; + + if (!v || !v->mdata || !mark_ordered_or_same(v, m)) + return Efallthrough; + offset = call_render_line_to_point(focus, m, v); + if (offset < 0) + return Efallthrough; + measure_line(p, focus, v, offset); + attr = pane_attr_get(v->mdata, "cursattr"); + tag = get_active_tag(attr); + if (tag) { + char *c = NULL; + asprintf(&c, "Activate:%s", tag); + if (c) + call(c, focus, 0, m, tag, + 0, NULL, attr); + free(c); + } + return 1; +} + DEF_CMD(render_lines_move_pos) { struct pane *p = ci->home; @@ -1744,6 +1784,8 @@ static void render_lines_register_map(void) /* Make it easy to stop ignoring point */ key_add(rl_map, "Abort", &render_lines_abort); + key_add(rl_map, "Activate", &render_lines_activate); + key_add(rl_map, "Close", &render_lines_close); key_add(rl_map, "Close:mark", &render_lines_close_mark); key_add(rl_map, "Free", &edlib_do_free);