]> git.neil.brown.name Git - edlib.git/commitdiff
render-lines: add "Activate" support.
authorNeilBrown <neil@brown.name>
Wed, 7 Jun 2023 22:30:58 +0000 (08:30 +1000)
committerNeilBrown <neil@brown.name>
Wed, 28 Jun 2023 05:40:21 +0000 (15:40 +1000)
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 <neil@brown.name>
DOC/TODO.md
doc-email.c
lib-renderline.c
python/lib-url.py
python/module-notmuch.py
render-lines.c

index f40c93be9a38d06110d5230b7f23ec4fc1c7fa7c..03c3ec9b8deab580db47ed385efd09bbedb54ab5 100644 (file)
@@ -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.
index b5428c401d802ec1b7f80a7ab10b7f107aa65fa6..6204b8a87d889e36b9ea4e61fa69526f1d1f1357 100644 (file)
@@ -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);
index e926d383fe754f87012f643fc75e43b12e8c5520..17be787a3cd7c089d8f87bbcb0d3d947a58b8467 100644 (file)
@@ -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;
 
index 1fc272e65b28151b7cb91832e62992518d9d2be6..46ff789f65bc8144f1cd4791e1d1a74e02610145 100644 (file)
@@ -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)
index 1d268b9b707230a9c4b5c06b5403ad946363df4f..80a6ab8b405c24ad7607ad4abd76632733d73191 100644 (file)
@@ -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)
index 4209b02d9984ea63b04da9346095af741f31d25d..2c1ecb7efbdf89cc35c8d022309d0ae98170d845 100644 (file)
@@ -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);