URI: 
       tMove viewport with text cursor - ledit - Text editor (WIP)
  HTML git clone git://lumidify.org/ledit.git (fast, but not encrypted)
  HTML git clone https://lumidify.org/git/ledit.git (encrypted, but very slow)
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
   DIR commit 155d5f07022e7d2fa4de2374b4ba6c1e9023e124
   DIR parent 1e24e8b24d8dd6676dab036a858e5404c2dfdb10
  HTML Author: lumidify <nobody@lumidify.org>
       Date:   Thu,  1 Apr 2021 21:50:19 +0200
       
       Move viewport with text cursor
       
       Diffstat:
         M ledit.c                             |      32 ++++++++++++++++++++++++++++++-
       
       1 file changed, 31 insertions(+), 1 deletion(-)
       ---
   DIR diff --git a/ledit.c b/ledit.c
       t@@ -242,6 +242,8 @@ mainloop(void) {
        
                XftColorAllocName(state.dpy, state.vis, state.cm, "#000000", &state.fg);
                XftColorAllocName(state.dpy, state.vis, state.cm, "#FFFFFF", &state.bg);
       +        XftColor scroll_bg;
       +        XftColorAllocName(state.dpy, state.vis, state.cm, "#CCCCCC", &scroll_bg);
                int need_redraw = 0;
                redraw();
        
       t@@ -394,7 +396,7 @@ mainloop(void) {
                                }
                                need_redraw = 0;
        
       -                        XSetForeground(state.dpy, state.gc, BlackPixel(state.dpy, state.screen));
       +                        XSetForeground(state.dpy, state.gc, state.fg.pixel);
                                PangoRectangle strong, weak;
                                pango_layout_get_cursor_pos(lines[cur_line].layout, cur_index, &strong, &weak);
                                int cursor_y = strong.y / PANGO_SCALE + cur_line_y;
       t@@ -414,6 +416,9 @@ mainloop(void) {
                                        }
                                }
                                if (total_height > state.h) {
       +                                XSetForeground(state.dpy, state.gc, scroll_bg.pixel);
       +                                XFillRectangle(state.dpy, state.back_buf, state.gc, state.w - 10, 0, 10, state.h);
       +                                XSetForeground(state.dpy, state.gc, state.fg.pixel);
                                        double scroll_h, scroll_y;
                                        get_scroll_pos_height(&scroll_y, &scroll_h);
                                        XFillRectangle(state.dpy, state.back_buf, state.gc, state.w - 10, (int)round(scroll_y), 10, (int)round(scroll_h));
       t@@ -537,6 +542,30 @@ button_release(void) {
        }
        
        static void
       +ensure_cursor_shown(void) {
       +        int cur_line_y = -1;
       +        int h = 0;
       +        /* FIXME: cache this to avoid useless recalculation */
       +        for (int i = 0; i < lines_num; i++) {
       +                if (cur_line == i) {
       +                        cur_line_y = h;
       +                        break;
       +                }
       +                h += lines[i].h;
       +        }
       +        if (cur_line_y < 0)
       +                return;
       +        PangoRectangle strong, weak;
       +        pango_layout_get_cursor_pos(lines[cur_line].layout, cur_index, &strong, &weak);
       +        int cursor_y = strong.y / PANGO_SCALE + cur_line_y;
       +        if (cursor_y < cur_display_offset) {
       +                cur_display_offset = cursor_y;
       +        } else if (cursor_y + strong.height / PANGO_SCALE > cur_display_offset + state.h) {
       +                cur_display_offset = cursor_y - state.h + strong.height / PANGO_SCALE;
       +        }
       +}
       +
       +static void
        recalc_height(void) {
                /*
                int w, h;
       t@@ -896,4 +925,5 @@ key_press(XEvent event) {
                        insert_text(&lines[cur_line], cur_index, buf, n);
                        cur_index += n;
                }
       +        ensure_cursor_shown();
        }