edo

Experimental text editor.
Log | Files | Refs | LICENSE

commit a1dc959104b9f6d69d7917a23d514a535401d062
parent 10ba804f935c024ffe37b59689c888ef34044f1d
Author: Claudio Alessi <smoppy@gmail.com>
Date:   Wed, 21 Jan 2026 23:09:43 +0100

Simplify TUI drawing and disable ZWNJ hack.

ZWNJ rendering hack has been disabled. Basic logic seems easy:

if(IS_RIS(cp))
	ab_write(&frame, ZWNJ, sizeof ZWNJ - 1);

However make it works on different terminals required an excessive
amount of debugging time, far exceeding the feature actual value.

Inconsistences between VTs proved too challenging. I may decide to try
again in the future but for now I removed the feature to focus on more
productive stuff.

Diffstat:
Mtui.c | 53++++++++++++++++++++++-------------------------------
Mui.h | 1-
Mutf8.c | 2--
3 files changed, 22 insertions(+), 34 deletions(-)

diff --git a/tui.c b/tui.c @@ -34,7 +34,6 @@ struct termios origti; struct winsize ws; Abuf frame; int compat_mode; -int split_ris; /* split RIS characters in-between with a ZWNJ */ /* TODO: edo.h? */ extern void *ecalloc(size_t nmemb, size_t size); @@ -214,7 +213,7 @@ tui_draw_line_compat(UI *ui, int x, int y, Cell *cells, int count) { while(o < cells[i].len) { int step = utf8_decode(txt + o, cells[i].len - o, &cp); int cw = cells[i].width; - int neederase = cells[i].len > 1 && (cells[i].width == 1 || IS_RIS(cp)); + int neederase = cells[i].len > 1 && (cells[i].width == 1); switch(cp) { case '\t': @@ -223,7 +222,6 @@ tui_draw_line_compat(UI *ui, int x, int y, Cell *cells, int count) { break; default: cw = wcwidth(cp); - //cw = tui_text_width(txt + o, cells[i].len - o, x); if(cw < 0) break; if(!cw) { @@ -260,16 +258,12 @@ tui_draw_line_compat(UI *ui, int x, int y, Cell *cells, int count) { } ab_write(&frame, txt + o, step); - +#if 0 /* to preserve coherence between terminals always split RIS - * so that we can see individual components. This is needed - * to ensure cursor synchronization between terminals that - * renders the same glyph with 2 different widths. */ - if(split_ris && IS_RIS(cp)) { + * so that we can see individual components. */ + if(IS_RIS(cp)) ab_write(&frame, ZWNJ, sizeof ZWNJ - 1); - ++cw; - } - +#endif if(neederase) { const char t[] = ESC"[0m"; ab_write(&frame, t, sizeof t - 1); @@ -278,7 +272,6 @@ tui_draw_line_compat(UI *ui, int x, int y, Cell *cells, int count) { } vw += cw; - /* stop processing after truncation */ if(cells[i].flags & (CELL_TRUNC_L | CELL_TRUNC_R)) break; @@ -288,7 +281,7 @@ tui_draw_line_compat(UI *ui, int x, int y, Cell *cells, int count) { o += step; } - /* pad clusters having unexpected width */ + /* pad glyph having unexpected width */ if(vw < cells[i].width) while(vw++ < cells[i].width) ab_write(&frame, " ", 1); @@ -298,7 +291,6 @@ tui_draw_line_compat(UI *ui, int x, int y, Cell *cells, int count) { if(x < ws.ws_col) ab_write(&frame, CLEARRIGHT, strlen(CLEARRIGHT)); } -/* TODO: add support for cell flags */ void tui_draw_line(UI *ui, int x, int y, Cell *cells, int count) { assert(x < ws.ws_col && y < ws.ws_row); @@ -319,23 +311,23 @@ tui_draw_line(UI *ui, int x, int y, Cell *cells, int count) { /* TODO: temp code for testing, we'll se how to deal with this later */ if(txt[0] == '\t') { ab_printf(&frame, "%*s", cells[i].width, " "); - } else { - - if(cells[i].flags & CELL_TRUNC_L) { - ab_write(&frame, "<", 1); - for(int j = 1; j < cells[i].width; ++j) - ab_write(&frame, ".", 1); - continue; - } - if(cells[i].flags & CELL_TRUNC_R) { - ab_write(&frame, ">", 1); - for(int j = 1; j < cells[i].width; ++j) - ab_write(&frame, ".", 1); - continue; - } + continue; + } - ab_write(&frame, txt, cells[i].len); + if(cells[i].flags & CELL_TRUNC_L) { + ab_write(&frame, "<", 1); + for(int j = 1; j < cells[i].width; ++j) + ab_write(&frame, ".", 1); + continue; } + if(cells[i].flags & CELL_TRUNC_R) { + ab_write(&frame, ">", 1); + for(int j = 1; j < cells[i].width; ++j) + ab_write(&frame, ".", 1); + continue; + } + + ab_write(&frame, txt, cells[i].len); } ab_write(&frame, CLEARRIGHT, strlen(CLEARRIGHT)); } @@ -374,8 +366,7 @@ tui_init(void) { setbuf(stdout, NULL); ioctl(0, TIOCGWINSZ, &ws); - compat_mode = 0; /* TODO: auto-detect */ - split_ris = compat_mode && 0; /* split RIS clusters */ + compat_mode = 1; /* TODO: auto-detect but toggable (upward only) */ } int diff --git a/ui.h b/ui.h @@ -28,7 +28,6 @@ typedef struct { } TextPool; enum CellFlags { - CELL_DEFAULT, CELL_TRUNC_L, CELL_TRUNC_R }; diff --git a/utf8.c b/utf8.c @@ -11,11 +11,9 @@ utf8_len_compat(char *buf, int len) { int step, i; i = step = utf8_decode(buf, len, &cp); - //if(wcwidth(cp) >= 0) return step; if(!utf8_is_combining(cp) && wcwidth(cp) < 0) return step; while(i < len) { step = utf8_decode(buf + i, len - i, &cp); - //if(wcwidth(cp) >= 0) break; if(!utf8_is_combining(cp) || wcwidth(cp)) break; i += step; }