URI: 
       tShow current mode - 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 991419d13fe4ec01c9898681cd5d9ab708486ed8
   DIR parent 0ac206aa676b56346dd45906fe0379a1e845fb80
  HTML Author: lumidify <nobody@lumidify.org>
       Date:   Sat, 22 May 2021 09:47:27 +0200
       
       Show current mode
       
       Diffstat:
         M Makefile                            |       4 ++--
         M ledit.c                             |      74 +++++++++++++++++++++++++++----
         A util.c                              |      38 +++++++++++++++++++++++++++++++
         A util.h                              |       8 ++++++++
       
       4 files changed, 114 insertions(+), 10 deletions(-)
       ---
   DIR diff --git a/Makefile b/Makefile
       t@@ -9,8 +9,8 @@ MANPREFIX = ${PREFIX}/man
        BIN = ${NAME}
        MAN1 = ${BIN:=.1}
        
       -OBJ = ${BIN:=.o} cache.o buffer.o memory.o
       -HDR = cache.h buffer.h memory.h common.h
       +OBJ = ${BIN:=.o} cache.o buffer.o memory.o util.o
       +HDR = cache.h buffer.h memory.h common.h util.h
        
        CFLAGS_LEDIT = -g -Wall -Wextra -D_POSIX_C_SOURCE=200809L `pkg-config --cflags x11 xkbfile pangoxft xext`
        LDFLAGS_LEDIT = ${LDFLAGS} `pkg-config --libs x11 xkbfile pangoxft xext` -lm
   DIR diff --git a/ledit.c b/ledit.c
       t@@ -29,6 +29,7 @@
        #include "common.h"
        #include "buffer.h"
        #include "cache.h"
       +#include "util.h"
        
        enum key_type {
                KEY_NONE = 0,
       t@@ -42,6 +43,16 @@ enum key_type {
                KEY_ANY = 0xFF
        };
        
       +struct {
       +        /* FIXME: encapsulate layout, width, draw a bit */
       +        PangoLayout *mode;
       +        ledit_draw *mode_draw;
       +        int mode_w, mode_h;
       +        PangoLayout *ruler;
       +        ledit_draw *ruler_draw;
       +        int ruler_w, ruler_h;
       +} bottom_bar;
       +
        struct key {
                char *text;              /* for keys that correspond with text */
                unsigned int mods;       /* modifier mask */
       t@@ -138,6 +149,29 @@ struct {
                char *clipboard;
        } xsel;
        
       +static void
       +set_mode(enum ledit_mode mode) {
       +        state.mode = mode;
       +        switch (mode) {
       +                case NORMAL:
       +                        pango_layout_set_text(bottom_bar.mode, "Normal", -1);
       +                        break;
       +                case VISUAL:
       +                        pango_layout_set_text(bottom_bar.mode, "Visual", -1);
       +                        break;
       +                case INSERT:
       +                        pango_layout_set_text(bottom_bar.mode, "Insert", -1);
       +                        break;
       +                default:
       +                        pango_layout_set_text(bottom_bar.mode, "ledit is buggy", -1);
       +                        break;
       +        }
       +        pango_layout_get_pixel_size(bottom_bar.mode, &bottom_bar.mode_w, &bottom_bar.mode_h);
       +        ledit_grow_draw(&state, bottom_bar.mode_draw, bottom_bar.mode_w, bottom_bar.mode_h);
       +        XftDrawRect(bottom_bar.mode_draw->xftdraw, &state.bg, 0, 0, bottom_bar.mode_w, bottom_bar.mode_h);
       +        pango_xft_render_layout(bottom_bar.mode_draw->xftdraw, &state.fg, bottom_bar.mode, 0, 0);
       +}
       +
        void
        clipcopy(void)
        {
       t@@ -191,7 +225,7 @@ selnotify(XEvent *e)
        {
                unsigned long nitems, ofs, rem;
                int format;
       -        unsigned char *data, *last, *repl;
       +        unsigned char *data;
                Atom type, incratom, property = None;
        
                incratom = XInternAtom(state.dpy, "INCR", 0);
       t@@ -396,7 +430,7 @@ static void
        key_d(void) {
                int num = 0;
                if (delete_selection()) {
       -                state.mode = NORMAL;
       +                set_mode(NORMAL);
                        buffer->cur_index = ledit_get_legal_normal_pos(buffer, buffer->cur_line, buffer->cur_index);
                        ledit_set_line_cursor_attrs(buffer, buffer->cur_line, buffer->cur_index);
                        clear_key_stack();
       t@@ -834,7 +868,11 @@ setup(int argc, char *argv[]) {
                }
                XSetICFocus(state.xic);
        
       -        state.mode = INSERT;
       +        bottom_bar.mode = pango_layout_new(state.context);
       +        pango_layout_set_font_description(bottom_bar.mode, state.font);
       +        /* FIXME: only create "dummy draw" at first and create with proper size when needed */
       +        bottom_bar.mode_draw = ledit_create_draw(&state, 10, 10);
       +        set_mode(INSERT);
        
                XMapWindow(state.dpy, state.win);
        
       t@@ -947,6 +985,18 @@ redraw(void) {
                            state.w - 10, (int)round(scroll_y), 10, (int)round(scroll_h)
                        );
                }
       +        XSetForeground(state.dpy, state.gc, state.bg.pixel);
       +        XFillRectangle(
       +            state.dpy, state.drawable, state.gc,
       +            0, state.h - bottom_bar.mode_h,
       +            state.w - 10, bottom_bar.mode_h
       +        );
       +        XCopyArea(
       +            state.dpy, bottom_bar.mode_draw->pixmap,
       +            state.drawable, state.gc,
       +            0, 0, bottom_bar.mode_w, bottom_bar.mode_h,
       +            state.w - 10 - bottom_bar.mode_w, state.h - bottom_bar.mode_h
       +        );
        
                XdbeSwapInfo swap_info;
                swap_info.swap_window = state.win;
       t@@ -1124,7 +1174,7 @@ button_press(XEvent *event) {
                                        set_selection(l, b, l, b);
                                        if (state.mode == NORMAL) {
                                                ledit_wipe_line_cursor_attrs(buffer, buffer->cur_line);
       -                                        state.mode = VISUAL;
       +                                        set_mode(VISUAL);
                                        }
                                        buffer->cur_line = l;
                                        buffer->cur_index = b;
       t@@ -1379,9 +1429,9 @@ escape_key(void) {
                if (state.mode == INSERT &&
                    (buffer->sel.line1 != buffer->sel.line2 ||
                     buffer->sel.byte1 != buffer->sel.byte2)) {
       -                state.mode = VISUAL;
       +                set_mode(VISUAL);
                } else {
       -                state.mode = NORMAL;
       +                set_mode(NORMAL);
                        clear_key_stack();
                        PangoDirection dir = PANGO_DIRECTION_RTL;
                        int tmp_index = buffer->cur_index;
       t@@ -1395,6 +1445,14 @@ escape_key(void) {
                        } else {
                                cursor_left();
                        }
       +                if (buffer->sel.line1 != buffer->sel.line2) {
       +                        int min = buffer->sel.line1 < buffer->sel.line2 ? buffer->sel.line1 : buffer->sel.line2;
       +                        int max = buffer->sel.line1 > buffer->sel.line2 ? buffer->sel.line1 : buffer->sel.line2;
       +                        for (int i = min; i <= max; i++) {
       +                                ledit_wipe_line_cursor_attrs(buffer, i);
       +                        }
       +                }
       +                /* FIXME: optimize this to avoid first wiping and then setting the attrs */
                        ledit_set_line_cursor_attrs(buffer, buffer->cur_line, buffer->cur_index);
                }
        }
       t@@ -1403,7 +1461,7 @@ static void
        enter_insert(void) {
                if (state.mode == NORMAL)
                        ledit_wipe_line_cursor_attrs(buffer, buffer->cur_line);
       -        state.mode = INSERT;
       +        set_mode(INSERT);
                clear_key_stack();
        }
        
       t@@ -1489,7 +1547,7 @@ cursor_to_beginning(void) {
        
        static void
        enter_visual(void) {
       -        state.mode = VISUAL;
       +        set_mode(VISUAL);
                buffer->sel.line1 = buffer->sel.line2 = buffer->cur_line;
                buffer->sel.byte1 = buffer->sel.byte2 = buffer->cur_index;
                ledit_wipe_line_cursor_attrs(buffer, buffer->cur_line);
   DIR diff --git a/util.c b/util.c
       t@@ -0,0 +1,38 @@
       +#include <X11/Xlib.h>
       +#include <X11/Xutil.h>
       +#include <pango/pangoxft.h>
       +#include <X11/extensions/Xdbe.h>
       +
       +#include "memory.h"
       +#include "common.h"
       +#include "util.h"
       +
       +ledit_draw *
       +ledit_create_draw(ledit_common_state *state, int w, int h) {
       +        ledit_draw *draw = ledit_malloc(sizeof(ledit_draw));
       +        draw->w = w;
       +        draw->h = h;
       +        draw->pixmap = XCreatePixmap(
       +            state->dpy, state->drawable, w, h, state->depth
       +        );
       +        draw->xftdraw = XftDrawCreate(
       +            state->dpy, draw->pixmap, state->vis, state->cm
       +        );
       +        return draw;
       +}
       +
       +void
       +ledit_grow_draw(ledit_common_state *state, ledit_draw *draw, int w, int h) {
       +        /* FIXME: sensible default pixmap sizes here */
       +        /* FIXME: maybe shrink the pixmaps at some point */
       +        if (draw->w < w || draw->h < h) {
       +                draw->w = w > draw->w ? w + 10 : draw->w;
       +                draw->h = h > draw->h ? h + 10 : draw->h;
       +                XFreePixmap(state->dpy, draw->pixmap);
       +                draw->pixmap = XCreatePixmap(
       +                    state->dpy, state->drawable,
       +                    draw->w, draw->h, state->depth
       +                );
       +                XftDrawChange(draw->xftdraw, draw->pixmap);
       +        }
       +}
   DIR diff --git a/util.h b/util.h
       t@@ -0,0 +1,8 @@
       +typedef struct {
       +        XftDraw *xftdraw;
       +        Pixmap pixmap;
       +        int w, h;
       +} ledit_draw;
       +
       +ledit_draw *ledit_create_draw(ledit_common_state *state, int w, int h);
       +void ledit_grow_draw(ledit_common_state *state, ledit_draw *draw, int w, int h);