]> git.neil.brown.name Git - edlib.git/commitdiff
render-lines: improve margin calculations.
authorNeilBrown <neil@brown.name>
Sat, 3 Jul 2021 07:26:28 +0000 (17:26 +1000)
committerNeilBrown <neil@brown.name>
Sat, 3 Jul 2021 08:23:21 +0000 (18:23 +1000)
In particular, find_lines() needs to honour ->margin, and
validate_start() need to allow the cursor inside the margin when start
of file is displayed.

Signed-off-by: NeilBrown <neil@brown.name>
DOC/TODO.md
render-lines.c

index 6ebf850873e1204cd19690dd42e01a421cade59d..1235ec5a15cb0467ba4fd0cdf323a2d54aaf6bfd 100644 (file)
@@ -271,7 +271,7 @@ Module features
 
 ### render-lines
 
-- [1] improve 'margin' to permit cursor in margin at start of file
+- [X] improve 'margin' to permit cursor in margin at start of file
 - [1] improve 'margin' to honour previous view of doc
 - [ ] update_line_height should handle TAB (and any control) - cannot expect
       Draw:text-size to handle it.
@@ -728,6 +728,32 @@ a display pane.  This might result in them running on different hosts.
 The protocol over then should be QUIC if possible as they seems to allow
 mobility nicely.  I'd need to look at how it handles network breaks.
 
+### Remote display
+
+I don't think I'll go with QUIC.  I'll make something focussed, like
+mosh and wireguard do.
+ssh will be used to request a key and 2 nounces - requested over the
+server socket.  Using this key, messages are secured with the "secretbox"
+module of libsodium and sent via UDP - client can send from anywhere and
+server replies to there.
+
+Client sends keystrokes, mouse-action, size report.  Each have an event
+sequence number.
+
+Server sends pane reset/create/destroy/clear/update/done messages.
+These have sequence numbers with a history stored and updates are resent
+if a client message has an old seq number.  If the client seq is too
+old, the server can send a reset, then create and fill each pane.
+
+The client acknowleges server messages with a 'size' update, and also
+reports the size every 5 seconds as a ping.  Server replies with any
+un-acked updates, or with a new 'done' message.
+
+Some day I might need "measure" requests fromt the server which the
+client can reply to, so texts can be measured for variable-sized fonts.
+Server would need to cache results for performance, and would need to
+know if a font is constant-width, so a single measurement will suffice.
+
 ### threaded-panes
 
 An import characteristic of a good editor is low latency.  While you can
index 36da789c1cdd994b24ee02ff97f10f5d163eec82..9bb7e3975f85f342d6e272e4f7bf7e5831166b4a 100644 (file)
@@ -473,8 +473,8 @@ static int consume_space(struct pane *p safe, int y,
  * 'pm' must be displayed, and if vline is not NO_NUMERIC,
  * pm should be displayed on that line of the display, where
  * negative numbers count from the bottom of the page.
- * Otherwise pm should be at least pm->margin from top and bottom.
- * In no case should start-of-file be *after* top of display.
+ * Otherwise pm should be at least rl->margin from top and bottom,
+ * but in no case should start-of-file be *after* top of display.
  * If there is an existing display, move the display as little as
  * possible while complying with the above.
  *
@@ -614,19 +614,17 @@ static void find_lines(struct mark *pm safe, struct pane *p safe,
                         */
                        y_post = 0;
 
-               if (!found_end && bot &&
-                   mark_ordered_not_same(start, bot))
-                       /* Overlap original from below, so prefer to
-                        * maximize that overlap.
-                        */
-                       found_end = True;
-
-               if (!found_end && bot && mark_same(start, bot) &&
-                   y_pre - rl->skip_height >= y_post)
-                       /* No overlap in marks yet, but over-lap in space,
-                        * so same result as above.
-                        */
-                       found_end = True;
+               if (!found_end && bot && lines_below >= rl->margin)
+                       if (mark_ordered_not_same(start, bot) ||
+                           /* Overlap original from below, so prefer to
+                            * maximize that overlap.
+                            */
+                           (mark_same(start, bot) &&
+                            y_pre - rl->skip_height >= y_post))
+                               /* No overlap in marks yet, but over-lap in
+                                * space, so same result as above.
+                                */
+                               found_end = True;
 
                if (!found_end && y_post <= 0)
                        /* step forwards */
@@ -634,12 +632,11 @@ static void find_lines(struct mark *pm safe, struct pane *p safe,
                                              &y_post, &line_height_post);
 
                if (!found_start && top && end &&
-                   mark_ordered_not_same(top, end))
-                       found_start = True;
-
-               if (!found_start && top && end && mark_same(top, end)
-                   && y_post - rl->tail_height >= y_pre)
-                       found_start = True;
+                   lines_above >= rl->margin)
+                       if (mark_ordered_not_same(top, end) ||
+                           (mark_same(top, end) &&
+                            y_post - rl->tail_height >= y_pre))
+                               found_start = True;
 
                y = consume_space(p, y, &y_pre, &y_post,
                                  &lines_above, &lines_below,
@@ -895,6 +892,7 @@ static int revalidate_start(struct rl_data *rl safe,
        bool on_screen = False;
        struct mark *m, *m2;
        bool found_end = False;
+       bool start_of_file;
 
        if (pm && !rl->do_wrap) {
                int prefix_len;
@@ -955,6 +953,7 @@ static int revalidate_start(struct rl_data *rl safe,
                        y = hp->h;
        }
        y -= rl->skip_height;
+       start_of_file = doc_prior(focus, start) == WEOF;
        for (m = start; m && !found_end && y < p->h; m = vmark_next(m)) {
                struct pane *hp;
                if (refresh_all)
@@ -981,7 +980,12 @@ static int revalidate_start(struct rl_data *rl safe,
                        if (offset >= 0) {
                                measure_line(p, focus, m, offset);
                                if (hp->cy >= rl->skip_height + rl->margin)
-                                       /* Cursor is visible on this line */
+                                       /* Cursor is visible on this line
+                                        * and after margin from top.
+                                        */
+                                       on_screen = True;
+                               else if (start_of_file && rl->skip_height == 0)
+                                       /* Cannot make more margin space */
                                        on_screen = True;
                        }
                } else if (pm && y >= p->h && m->seq < pm->seq) {
@@ -1016,7 +1020,8 @@ static int revalidate_start(struct rl_data *rl safe,
                                        lh = attr_find_int(hp->attrs,
                                                           "line-height");
                                        cy = y - hp->h + hp->cy;
-                                       if (cy >= rl->margin && cy <= p->h - rl->margin - lh)
+                                       if (cy >= rl->margin &&
+                                           cy <= p->h - rl->margin - lh)
                                                /* Cursor at least margin from edge */
                                                on_screen = True;
                                }
@@ -1071,7 +1076,7 @@ DEF_CMD(render_lines_revise)
 
        rl->margin = pane_attr_get_int(focus, "render-vmargin", 0);
        if (rl->margin >= p->h/2)
-               rl->margin= p->h/2;
+               rl->margin = p->h/2;
 
        hdr = pane_attr_get(focus, "heading");
        if (hdr && !*hdr)