commit 991419d13fe4ec01c9898681cd5d9ab708486ed8
parent 0ac206aa676b56346dd45906fe0379a1e845fb80
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(-)
diff --git a/Makefile b/Makefile
@@ -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
diff --git a/ledit.c b/ledit.c
@@ -29,6 +29,7 @@
#include "common.h"
#include "buffer.h"
#include "cache.h"
+#include "util.h"
enum key_type {
KEY_NONE = 0,
@@ -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 */
@@ -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)
{
@@ -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);
@@ -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();
@@ -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);
@@ -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;
@@ -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;
@@ -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;
@@ -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);
}
}
@@ -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();
}
@@ -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);
diff --git a/util.c b/util.c
@@ -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);
+ }
+}
diff --git a/util.h b/util.h
@@ -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);