]> git.neil.brown.name Git - edlib.git/commitdiff
renderline: allow a wrap-margin
authorNeilBrown <neil@brown.name>
Sun, 5 Feb 2023 00:56:02 +0000 (11:56 +1100)
committerNeilBrown <neil@brown.name>
Mon, 6 Feb 2023 05:48:19 +0000 (16:48 +1100)
The location of the first wrap-margin tag is remembered, and any
subsequent line wrap is wrapped to that offset.

This is used to wrap subjects for notmuch message summaries.

Signed-off-by: NeilBrown <neil@brown.name>
DOC/Developer/06-rendering.md
DOC/TODO.md
lib-renderline.c
python/module-notmuch.py

index 38c89ad70a11b05740598b732aaf8bc2c90141a3..7fcbc0fa9b9e5f6bd592621814041da1d4dcd2e1 100644 (file)
@@ -325,8 +325,13 @@ display to affect drawing of the text.  Attributes understood by
   If no text has the "wrap" attribute, then wrap will happen after the
   last character that fits.
 
+- "wrap-margin" - mark a location in the line where any subsequent wrap
+                  will cause a margin to be inserted to.  Only the first
+                  location with this tag is remembered.
+
 - "wrap-head:" - The value of this tag is used to start the line after a
-   wrap point.  By default no text is added.
+                 wrap point.  By default no text is added.  This is added
+                 after the wrap-margin.
 
 - "wrap-tail:" - The value of this tag is placed at the end of a line
   just before it is wrapped.  It will be underlined with blue
index d5a4ff7c2a5230ca2f8c388f8b90c86565010c61..3d29ad36b592ce7f587e89e40c8408f31b7207c6 100644 (file)
@@ -592,7 +592,7 @@ Module features
       exist, or not be readable
 - [ ] allow opening drafts in composer on restart.
 - [ ] allow deleting of drafts without posting.  Maybe just 'delete'..
-- [1] option to wrap subjects onto next line - in query view
+- [X] option to wrap subjects onto next line - in query view
 - [ ] When active query changes, highlight on list view doesn't immediately
       follow
 - [ ] TESTS
index da261b0a262bb7b5dbd835b6b3ca35bb7a18c0db..d74b33f50471c45ea80792a683c855ba6bd465c7 100644 (file)
@@ -176,7 +176,7 @@ static char *get_last_attr(const char *attrs safe, const char *attr safe)
 
 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 y, int scale, int wrap_pos, int *wrap_margin safe,
                      const char **xypos, const char **xyattr)
 {
        /* Flush a render_list returning x-space used.
@@ -218,6 +218,9 @@ static int flush_line(struct pane *p safe, struct pane *focus safe, int dodraw,
        for (rl = *rlp; rl && rl != last_wrap; rl = rl->next) {
                int cp = rl->cursorpos;
 
+               if (!*wrap_margin && strstr(rl->attr, "wrap-margin,"))
+                       *wrap_margin = rl->x;
+
                if (wrap_pos &&
                    cp >= (int)strlen(rl->text) + wrap_len)
                        /* Don't want to place cursor at end of line before
@@ -263,24 +266,27 @@ static int flush_line(struct pane *p safe, struct pane *focus safe, int dodraw,
        *rlp = end_wrap;
 
        /* Queue the wrap-head for the next flush */
-       if (wrap_pos && last_rl &&
-           (head = get_last_attr(last_rl->attr, "wrap-head"))) {
-               struct call_return cr =
-                       home_call_ret(all, focus, "Draw:text-size", p,
-                                     p->w, NULL, head,
-                                     scale, NULL, last_rl->attr);
-               rl = calloc(1, sizeof(*rl));
-               rl->text = head;
-               rl->attr = strdup(last_rl->attr); // FIXME underline,fg:blue ???
-               rl->width = cr.x;
-               rl->x = 0;
-               rl->cursorpos = -1;
-               rl->next = *rlp;
-               *rlp = rl;
-               /* 'x' is how much to shift-left remaining rl entries,
-                * Don't want to shift them over the wrap-head
-                */
-               x -= cr.x;
+       if (wrap_pos && last_rl) {
+               head = get_last_attr(last_rl->attr, "wrap-head");
+               if (head) {
+                       struct call_return cr =
+                               home_call_ret(all, focus, "Draw:text-size", p,
+                                             p->w, NULL, head,
+                                             scale, NULL, last_rl->attr);
+                       rl = calloc(1, sizeof(*rl));
+                       rl->text = head;
+                       rl->attr = strdup(last_rl->attr); // FIXME underline,fg:blue ???
+                       rl->width = cr.x;
+                       rl->x = *wrap_margin;
+                       rl->cursorpos = -1;
+                       rl->next = *rlp;
+                       *rlp = rl;
+                       /* 'x' is how much to shift-left remaining rl entries,
+                        * Don't want to shift them over the wrap-head
+                        */
+                       x -= cr.x;
+               }
+               x -= *wrap_margin;
        }
 
        for (rl = tofree; rl && rl != end_wrap; rl = tofree) {
@@ -504,6 +510,7 @@ DEF_CMD(renderline)
        struct buf attr;
        unsigned char ch;
        int wrap_offset = 0; /*number of columns displayed in earlier lines */
+       int wrap_margin = 0; /* left margin for wrap */
        int in_tab = 0;
        int shift_left = atoi(pane_attr_get(focus, "shift_left") ?:"0");
        int wrap = shift_left < 0;
@@ -646,7 +653,7 @@ DEF_CMD(renderline)
                        if (wrap && *line && *line != '\n') {
                                int len = flush_line(p, focus, dodraw, &rlst,
                                                     y+ascent, scale,
-                                                    p->w - mwidth,
+                                                    p->w - mwidth, &wrap_margin,
                                                     &xypos, &xyattr);
                                wrap_offset += len;
                                x -= len;
@@ -758,7 +765,7 @@ DEF_CMD(renderline)
                if (ch == '\n') {
                        xypos = line-1;
                        flush_line(p, focus, dodraw, &rlst, y+ascent, scale, 0,
-                                  &xypos, &xyattr);
+                                  &wrap_margin, &xypos, &xyattr);
                        y += line_height;
                        x = 0;
                        wrap_offset = 0;
@@ -818,7 +825,7 @@ DEF_CMD(renderline)
        }
 
        flush_line(p, focus, dodraw, &rlst, y+ascent, scale, 0,
-                  &xypos, &xyattr);
+                  &wrap_margin, &xypos, &xyattr);
 
        if (want_xypos == 1) {
                rd->xyattr = xyattr ? strdup(xyattr) : NULL;
index c27973c1c180bec803ec61968f4e847754af35b7..298d201a08ebd21c64bdd7d9938fde5a85e4ddf9 100644 (file)
@@ -873,7 +873,7 @@ class notmuch_query(edlib.Doc):
         self["line-format"] = ("<%BG><%TM-hilite>%TM-date_relative</>" +
                                "<tab:130> <fg:blue>%TM-authors</>" +
                                "<tab:350>%TM-size%TM-threadinfo<%TM-hilite>" +
-                               "<fg:red,bold>%TM-flag</> %TM-subject</></>")
+                               "<fg:red,bold>%TM-flag</> <wrap-margin>%TM-subject</></>")
         self.add_notify(self.maindoc, "Notify:Tag")
         self.add_notify(self.maindoc, "Notify:Close")
         self['doc-status'] = ""
@@ -2538,7 +2538,6 @@ class notmuch_list_view(edlib.Pane):
     def __init__(self, focus):
         edlib.Pane.__init__(self, focus)
         self['notmuch:pane'] = 'main'
-        self['render-wrap'] = 'no'
         self['background'] = 'color:#A0FFFF'
         self['line-format'] = '<%fmt>%count%space%name</>'
         self.call("notmuch:set_list_pane")
@@ -3496,6 +3495,7 @@ def notmuch_doc(key, home, focus, comm2, **a):
 def render_query_attach(key, focus, comm2, **a):
     p = notmuch_query_view(focus)
     p = p.call("attach-render-format", ret='pane')
+    p['render-wrap'] = 'yes'
     if comm2:
         comm2("callback", p)
     return 1