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 7f10c769894b662194bf2fd54bc159647e012bf9
parent f12812ad75c528b59aaf96791c48e3940c9e888c
Author: lumidify <nobody@lumidify.org>
Date:   Tue,  2 Nov 2021 10:27:50 +0100

Slightly change behavior of moving to end of line; change drawing of spaces at the end of soft lines

Diffstat:
A.buffer.c.swp | 0
A.keys_basic.c.swp | 0
MMakefile | 6++++--
Mbuffer.c | 23+++++++++++++++++++++--
Mkeys_basic.c | 66+++++++-----------------------------------------------------------
Apango-compat.c | 58++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Apango-compat.h | 3+++
7 files changed, 93 insertions(+), 63 deletions(-)

diff --git a/.buffer.c.swp b/.buffer.c.swp Binary files differ. diff --git a/.keys_basic.c.swp b/.keys_basic.c.swp Binary files differ. diff --git a/Makefile b/Makefile @@ -22,7 +22,8 @@ OBJ = \ txtbuf.o \ undo.o \ util.o \ - window.o + window.o \ + pango-compat.o HDR = \ action.h \ @@ -38,7 +39,8 @@ HDR = \ txtbuf.h \ undo.h \ util.h \ - window.h + window.h \ + pango-compat.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/buffer.c b/buffer.c @@ -1728,16 +1728,35 @@ ledit_buffer_redraw(ledit_buffer *buffer) { /* Seriously, which of the pango folks though it would be a good idea to not highlight spaces at the end of soft lines? That is an utterly horrible idea. Or am I just too stupid to use it properly? */ + /* FIXME: properly document what is happening here */ + + int box_x = strong.x / PANGO_SCALE; + int box_w = 10; + /* determine where the box should be drawn */ + PangoDirection dir = PANGO_DIRECTION_RTL; + int tmp_index = buffer->cur_index; + if (buffer->cur_index >= cur_line->len) + tmp_index = cur_line->len - 1; + if (tmp_index >= 0) + dir = pango_layout_get_direction(cur_line->layout, tmp_index); + int x, sli; pango_layout_index_to_line_x(cur_line->layout, buffer->cur_index, 0, &sli, &x); PangoLayoutLine *sl = pango_layout_get_line_readonly(cur_line->layout, sli); + if (dir != sl->resolved_dir) { + box_w = 3; + } + if (dir == PANGO_DIRECTION_RTL || dir == PANGO_DIRECTION_WEAK_RTL) { + box_x = box_x - box_w; + } + if (buffer->cur_index == cur_line->len || (cur_line->text[buffer->cur_index] == ' ' && buffer->cur_index == sl->start_index + sl->length - 1)) { XFillRectangle( buffer->common->dpy, buffer->window->drawable, buffer->window->gc, - strong.x / PANGO_SCALE, cursor_y, - 10, strong.height / PANGO_SCALE + box_x, cursor_y, + box_w, strong.height / PANGO_SCALE ); } } else if (buffer->common->mode == INSERT || buffer->common->mode == VISUAL) { diff --git a/keys_basic.c b/keys_basic.c @@ -14,6 +14,7 @@ #include <X11/XF86keysym.h> #include <X11/cursorfont.h> +#include "pango-compat.h" #include "memory.h" #include "common.h" #include "txtbuf.h" @@ -1022,8 +1023,12 @@ move_to_eol(ledit_buffer *buffer, char *text, int len) { if (buffer->common->mode == VISUAL) { ledit_buffer_set_selection(buffer, buffer->sel.line1, buffer->sel.byte1, new_line, end_index); } else { - /* FIXME: this is still kind of weird with mixed bidi text */ - move_cursor_in_line_dir(buffer, -1, 0); + /* FIXME: this is weird because the cursor is actually on the + next soft line, but the alternative has too many weird effects + with bidi text */ + buffer->cur_index = ledit_buffer_get_legal_normal_pos( + buffer, buffer->cur_line, buffer->cur_index + ); } } ledit_buffer_set_line_cursor_attrs(buffer, buffer->cur_line, buffer->cur_index); @@ -1136,63 +1141,6 @@ return_key(ledit_buffer *buffer, char *text, int len) { return (struct action){ACTION_NONE, NULL}; } -/* FIXME: Is this illegal due to different licenses? */ -/* FIXME: Check earliest version of other used functions to get minimum pango version - for ledit as a whole */ -/* FIXME: This is just copied from the newer version of pango. It *seems* like - the structs used are public (they're in the documentation), but it does seem - a bit dirty to do this here */ -#if !PANGO_VERSION_CHECK(1, 46, 0) -static PangoLayoutRun * -pango_layout_line_get_run(PangoLayoutLine *line, int index) { - GSList *run_list; - - run_list = line->runs; - while (run_list) { - PangoLayoutRun *run = run_list->data; - - if (run->item->offset <= index && run->item->offset + run->item->length > index) - return run; - - run_list = run_list->next; - } - - return NULL; -} - -static int -pango_layout_line_get_char_level(PangoLayoutLine *line, int index) { - PangoLayoutRun *run; - - run = pango_layout_line_get_run(line, index); - - if (run) - return run->item->analysis.level; - - return 0; -} - -static PangoDirection -pango_layout_line_get_char_direction(PangoLayoutLine *layout_line, int index) { - return pango_layout_line_get_char_level(layout_line, index) % 2 - ? PANGO_DIRECTION_RTL - : PANGO_DIRECTION_LTR; -} - -static PangoDirection -pango_layout_get_direction(PangoLayout *layout, int index) { - int lineno, x; - PangoLayoutLine *line; - pango_layout_index_to_line_x(layout, index, 0, &lineno, &x); - line = pango_layout_get_line_readonly(layout, lineno); - - if (line) - return pango_layout_line_get_char_direction(line, index); - - return PANGO_DIRECTION_LTR; -} -#endif - static void move_cursor_in_line_dir(ledit_buffer *buffer, int movement_dir, int allow_illegal_index) { PangoDirection dir; diff --git a/pango-compat.c b/pango-compat.c @@ -0,0 +1,58 @@ +#include <pango/pangoxft.h> + +/* FIXME: Is this illegal due to different licenses? */ +/* FIXME: Check earliest version of other used functions to get minimum pango version + for ledit as a whole */ +/* FIXME: This is just copied from the newer version of pango. It *seems* like + the structs used are public (they're in the documentation), but it does seem + a bit dirty to do this here */ +#if !PANGO_VERSION_CHECK(1, 46, 0) +static PangoLayoutRun * +pango_layout_line_get_run(PangoLayoutLine *line, int index) { + GSList *run_list; + + run_list = line->runs; + while (run_list) { + PangoLayoutRun *run = run_list->data; + + if (run->item->offset <= index && run->item->offset + run->item->length > index) + return run; + + run_list = run_list->next; + } + + return NULL; +} + +static int +pango_layout_line_get_char_level(PangoLayoutLine *line, int index) { + PangoLayoutRun *run; + + run = pango_layout_line_get_run(line, index); + + if (run) + return run->item->analysis.level; + + return 0; +} + +static PangoDirection +pango_layout_line_get_char_direction(PangoLayoutLine *layout_line, int index) { + return pango_layout_line_get_char_level(layout_line, index) % 2 + ? PANGO_DIRECTION_RTL + : PANGO_DIRECTION_LTR; +} + +PangoDirection +pango_layout_get_direction(PangoLayout *layout, int index) { + int lineno, x; + PangoLayoutLine *line; + pango_layout_index_to_line_x(layout, index, 0, &lineno, &x); + line = pango_layout_get_line_readonly(layout, lineno); + + if (line) + return pango_layout_line_get_char_direction(line, index); + + return PANGO_DIRECTION_LTR; +} +#endif diff --git a/pango-compat.h b/pango-compat.h @@ -0,0 +1,3 @@ +#if !PANGO_VERSION_CHECK(1, 46, 0) +PangoDirection pango_layout_get_direction(PangoLayout *layout, int index); +#endif