]> git.neil.brown.name Git - edlib.git/commitdiff
Revise how location-sensitive actions are managed.
authorNeilBrown <neil@brown.name>
Sat, 8 Jul 2023 02:42:51 +0000 (12:42 +1000)
committerNeilBrown <neil@brown.name>
Wed, 12 Jul 2023 22:17:52 +0000 (08:17 +1000)
To create a location-sensitive action, the attribute "action-FOO" must
be set to a command name, for some value of FOO.
Currently only "activate" is effective, and this send on a mouse click.
In the future "menu" may be added, and possibly others such as for
drag-and-drop.

Signed-off-by: NeilBrown <neil@brown.name>
DOC/Developer/06-rendering.md
DOC/render-control
doc-email.c
lib-menu.c
mode-emacs.c
python/lib-url.py
python/module-notmuch.py
render-lines.c

index a49aa5aab581bc667cf841e6d68e35c8d0c661a8..a27fb95b26814361ab96adaaf32b38bf082f43e6 100644 (file)
@@ -205,15 +205,15 @@ document, rather than on its content.
   from the end of the display, a positive number is counted forward from
   the start.  A line number of zero is the centre of the display.
 
-- "Move-CursorXY" does not adjust the display, but moved the point as
+- "Move-CursorXY" does not adjust the display, but moves the point as
   close as possible to the x,y position passed in the message.
-  The num1 argument will report if the message is due to a mouse click
-  (1) or release (2) or motion (3).  If it was "release" then
-  "render-lines" will check if the attribute "active-tag" appears in the
-  markup for that location.  If it does then a message is sent to the
-  stack with a key formed from "Activate:" followed by the value
-  of "active-tag".  "mark" will be a mark at the location, "str1" will be
-  the tag, and "str2" will be all attributes active at that location.
+  The str1 argument can indicate that a context-dependant action, if
+  any,  could be performed.  If the content at the target location has
+  a tag named "action-" followed by the value in str1, then the value of
+  that tag is used as a command name and is sent to the focus with
+  all attributes at that location passed as "str1".  "mark" will be the
+  location that the cursor is about to move to, and "mark2" will be the
+  mark that will be moved.
 
 - "Move-Line" moves the cursor (point) forward or backward some number
   of lines based on the num1 argument.  "render-lines" attempts to keep
index 14dfff69c42ba585659fce6c6e9fd67fae22f2b7..90ffac5ed0fb49f5d8fb64d45720609f0fe4535d 100644 (file)
@@ -132,11 +132,14 @@ Standard attributes are:
            the following line is prefixed with the value of the
            attribute.
 
-  active-tag:$tag If a mouse-click happens on text with this attribute,
-           Activate:$tag is called with:
+  action-$name:$command If a mouse-click happens on text with this attribute,
+           then depending on the name the command will be called with:
               ->mark being a new mark at the location
-              ->str being $tag
-             ->str2 being all attributes active at the location
+             ->mark2 being the point that will be moved there.
+              ->str being all attributes at that location.
+           $name is "activate" for a mouse-1 release.
+           This command can also be triggered by calling "Action"
+           passing the name as ->str.
 
 only on pygtk:
   NN      font size
index d2862b35bdac79e35e5f0bb1459223a42cb2768b..0bbb9483c4e8b1e7459abf4ee681b08a9fd71c26 100644 (file)
@@ -78,7 +78,7 @@ static bool handle_rfc822(struct pane *email safe,
 static bool cond_append(struct buf *b safe, char *txt safe, char *tag safe,
                        int offset, int *pos safe)
 {
-       char *tagf = "active-tag:email-";
+       char *tagf = "action-activate:email-";
        int prelen = 1 + strlen(tagf) + strlen(tag) + 1 + 1;
        int postlen = 1 + 3;
        int len = prelen + strlen(txt) + postlen;
index db98bf097a4b724d1197a1e6adbafcb5e9950a29..3d7f33fd2ff4fb21784f4957e6e01c604d239f00 100644 (file)
@@ -90,7 +90,7 @@ DEF_CMD(menu_attach)
        call("doc:set:autoclose", docp, 1);
        attr_set_str(&docp->attrs, "render-simple", "format");
        attr_set_str(&docp->attrs, "heading", "");
-       attr_set_str(&docp->attrs, "line-format", "<active-tag:menu-select>%name</>");
+       attr_set_str(&docp->attrs, "line-format", "<action-activate:menu-select>%name</>");
        attr_set_str(&docp->attrs, "done-key", ci->str2 ?: "menu-done");
        /* No borders, just a shaded background to make menu stand out */
        attr_set_str(&docp->attrs, "borders", "");
@@ -120,7 +120,7 @@ static void menu_init_map(void)
        key_add(menu_map, "menu-add", &menu_add);
        key_add(menu_map, "K:ESC", &menu_abort);
        key_add(menu_map, "K:Enter", &menu_done);
-       key_add(menu_map, "Activate:menu-select", &menu_done);
+       key_add(menu_map, "menu-select", &menu_done);
 }
 
 void edlib_init(struct pane *ed safe)
index 34f24f498036ef809e74228aba3d9b805e25c753..29e12a7c869f6df2bc71b8b5360f54f6b0645596 100644 (file)
@@ -2514,7 +2514,7 @@ DEF_CMD(emacs_release)
        attr_set_int(&m2->attrs, "emacs:track-selection", 0);
 
        call("Move-CursorXY", ci->focus,
-            2, m, NULL, moved, NULL, NULL, ci->x, ci->y);
+            0, m, "activate", moved, NULL, NULL, ci->x, ci->y);
        /* That action might have closed a pane.  Better check... */
        if (ci->focus->damaged & DAMAGED_CLOSED) {
                /* Do nothing */
index bc313cff3ac1121cd508cf7dfa2b4b84dedb4394..1b7e0b3b08730f046d478c20a8e6bbd34a5f101d 100644 (file)
@@ -8,8 +8,8 @@
 # The "tag" leads to a pane attribute 'url:tag' which hold the full url.
 #
 # "render:url-view" is an overlay pane which:
-#  - responds to map-attr for render:url, adding the active-tag attr
-#  - handles Activate:url to also activate the url
+#  - responds to map-attr for render:url, adding the action-activate attr
+#  - handles Acivate:url to also activate the url
 
 import edlib
 
@@ -70,12 +70,12 @@ class url_view(edlib.Pane):
             if str1 == "render:url-end":
                 leng = -1
             comm2("attr:callback", focus, leng, mark,
-                  "fg:cyan-60,underline,active-tag:url,url-tag="+tg, 120)
+                  "fg:cyan-60,underline,action-activate:Activate:url,url-tag="+tg, 120)
             return 1
 
-    def handle_click(self, key, focus, mark, str2, **a):
+    def handle_click(self, key, focus, mark, str1, **a):
         "handle:Activate:url"
-        a = str2.split(',')
+        a = str1.split(',')
         tag=""
         for w in a:
             if w.startswith("url-tag="):
@@ -100,7 +100,7 @@ class url_view(edlib.Pane):
 
     def handle_enter(self, key, focus, mark, **a):
         "handle:K:Enter"
-        return focus.call("Activate", mark)
+        return focus.call("Action", "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 098e800f5c726b41ae60d2d3976c1bbaa4c71fb1..d9e9f05a7f7d941cb4e43760882b831ed8d62eef 100644 (file)
@@ -3368,15 +3368,15 @@ class notmuch_message_view(edlib.Pane):
         return 1
 
     def handle_toggle_hide(self, key, focus, mark, **a):
-        "handle-list/Activate:email-hide/email:select:hide"
+        "handle-list/email-hide/email:select:hide"
         return self.handle_vis(focus, mark, "hide")
 
     def handle_toggle_full(self, key, focus, mark, **a):
-        "handle-list/Activate:email-full/email:select:full"
+        "handle-list/email-full/email:select:full"
         return self.handle_vis(focus, mark, "full")
 
     def handle_toggle_extras(self, key, focus, mark, **a):
-        "handle-list/Activate:email-extras/email:select:extras/doc:char-X"
+        "handle-list/email-extras/email:select:extras/doc:char-X"
         if not mark:
             # a mark at the first "sep" part will identify the headers
             mark = edlib.Mark(focus)
@@ -3414,7 +3414,7 @@ class notmuch_message_view(edlib.Pane):
         return 1
 
     def handle_save(self, key, focus, mark, **a):
-        "handle-list/Activate:email-save/email:select:save"
+        "handle-list/email-save/email:select:save"
 
         file = focus.call("doc:get-attr", "multipart-prev:email:filename", mark, ret='str')
         if not file:
@@ -3432,7 +3432,7 @@ class notmuch_message_view(edlib.Pane):
         return 1
 
     def handle_external(self, key, focus, mark, **a):
-        "handle-list/Activate:email-external view/email:select:external view"
+        "handle-list/email-external view/email:select:external view"
         type = focus.call("doc:get-attr", "multipart-prev:email:content-type", mark, ret='str')
         prefix = focus.call("doc:get-attr", "multipart-prev:email:prefix", mark, ret='str')
         ext = focus.call("doc:get-attr", "multipart-prev:email:ext", mark, ret='str')
index ec37e8f647ace34f5ccbcdfdffe8936ee5a2e7b7..3a540cae64ff0e560c5ad269c0c7978f7a0deabe 100644 (file)
@@ -1451,32 +1451,38 @@ DEF_CMD(render_lines_move_view)
        return 1;
 }
 
-static char *get_active_tag(const char *a)
+static char *get_action_tag(const char *tag safe, const char *a)
 {
+       int taglen = strlen(tag);
        char *t;
        char *c;
 
        if (!a)
                return NULL;
-       t = strstr(a, ",active-tag:");
-       if (!t)
-               return NULL;
-       t += 12;
+       do {
+               t = strstr(a, ",action-");
+               if (!t)
+                       return NULL;
+               a = t+1;
+       } while (!(strncmp(t+8, tag, taglen) == 0 &&
+                  t[8+taglen] == ':'));
+
+       t += 8 + taglen + 1;
        c = strchr(t, ',');
        return strndup(t, c?c-t: (int)strlen(t));
 }
 
 DEF_CMD(render_lines_set_cursor)
 {
-       /* ->num is
-        * 1 if this resulted from a click
-        * 2 if from a release
-        * 3 if from motion
-        * 0 any other reason.
+       /* ->str gives a context specific action to perform
+        * If the attributes at the location include
+        * action-$str then the value of that attribute
+        * is send as a command
         */
        struct pane *p = ci->home;
        struct pane *focus = ci->focus;
        struct rl_data *rl = p->data;
+       const char *action = ci->str;
        struct mark *m;
        struct mark *m2 = NULL;
        struct xy cih;
@@ -1510,17 +1516,12 @@ DEF_CMD(render_lines_set_cursor)
        if (m2) {
                char *tag, *xyattr;
 
-               if (ci->num == 2) { /* Mouse release */
+               if (action) {
                        xyattr = pane_attr_get(m->mdata, "xyattr");
-                       tag = get_active_tag(xyattr);
-                       if (tag) {
-                               char *c = NULL;
-                               asprintf(&c, "Activate:%s", tag);
-                               if (c)
-                                       call(c, focus, 0, m2, tag,
-                                            0, ci->mark, xyattr);
-                               free(c);
-                       }
+                       tag = get_action_tag(action, xyattr);
+                       if (tag)
+                               call(tag, focus, 0, m2, xyattr,
+                                    0, ci->mark);
                }
                m = m2;
        } else {
@@ -1536,9 +1537,9 @@ DEF_CMD(render_lines_set_cursor)
        return 1;
 }
 
-DEF_CMD(render_lines_activate)
+DEF_CMD(render_lines_action)
 {
-       /* If there is an active-tag: at '->mark', send Activate:tag
+       /* If there is an action-$str: at '->mark', send the command
         * to the focus
         */
        struct mark *m = ci->mark;
@@ -1549,7 +1550,7 @@ DEF_CMD(render_lines_activate)
        int offset;
        char *attr, *tag;
 
-       if (!m)
+       if (!m || !ci->str)
                return Enoarg;
        v = vmark_first(p, rl->typenum, p);
 
@@ -1564,15 +1565,9 @@ DEF_CMD(render_lines_activate)
                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);
-       }
+       tag = get_action_tag(ci->str, attr);
+       if (tag)
+               call(tag, focus, 0, m, attr);
        return 1;
 }
 
@@ -1906,7 +1901,7 @@ 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, "Action", &render_lines_action);
 
        key_add(rl_map, "Close", &render_lines_close);
        key_add(rl_map, "Close:mark", &render_lines_close_mark);