tShow current mode - ledit - Text editor (WIP) | |
git clone git://lumidify.org/ledit.git (fast, but not encrypted) | |
git clone https://lumidify.org/git/ledit.git (encrypted, but very slow) | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
commit 991419d13fe4ec01c9898681cd5d9ab708486ed8 | |
parent 0ac206aa676b56346dd45906fe0379a1e845fb80 | |
Author: lumidify <[email protected]> | |
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 | |
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… | |
LDFLAGS_LEDIT = ${LDFLAGS} `pkg-config --libs x11 xkbfile pangoxft xext` -lm | |
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… | |
+ break; | |
+ } | |
+ pango_layout_get_pixel_size(bottom_bar.mode, &bottom_bar.mode_w, &bott… | |
+ ledit_grow_draw(&state, bottom_bar.mode_draw, bottom_bar.mode_w, botto… | |
+ XftDrawRect(bottom_bar.mode_draw->xftdraw, &state.bg, 0, 0, bottom_bar… | |
+ pango_xft_render_layout(bottom_bar.mode_draw->xftdraw, &state.fg, bott… | |
+} | |
+ | |
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-… | |
ledit_set_line_cursor_attrs(buffer, buffer->cur_line, buffer->… | |
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 siz… | |
+ 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_… | |
); | |
} | |
+ 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, b… | |
- 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 ? buff… | |
+ int max = buffer->sel.line1 > buffer->sel.line2 ? buff… | |
+ for (int i = min; i <= max; i++) { | |
+ ledit_wipe_line_cursor_attrs(buffer, i); | |
+ } | |
+ } | |
+ /* FIXME: optimize this to avoid first wiping and then setting… | |
ledit_set_line_cursor_attrs(buffer, buffer->cur_line, buffer->… | |
} | |
} | |
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); | |
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); | |
+ } | |
+} | |
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… |