#ifndef CST_TEXTSEL_H #define CST_TEXTSEL_H #include #include /* UTF-8 / ANSI helpers shared by the TUI renderer and mouse selection, so both * agree on which character occupies each column. */ int cst_utf8_decode(const char *s, size_t avail, wchar_t *wc, size_t *eaten); /* wcwidth(), with an East-Asian / ASCII heuristic on Windows. */ int cst_wcwidth(wchar_t wc); /* Columns of wc; 1 for non-printing characters. */ int cst_utf8_width(wchar_t wc); /* Length of the escape sequence at s (CSI or two-byte ESC), 0 if none. */ size_t cst_ansi_skip(const char *s, size_t n); typedef struct { char *s; /* NUL-terminated once anything was appended */ size_t n, cap; } cst_selbuf_t; void cst_selbuf_free(cst_selbuf_t *b); int cst_selbuf_putc(cst_selbuf_t *b, char c); /* Appends the text drawn in columns [c1, c2] of a row whose content `line` * (ANSI escapes allowed) starts at column `indent`; c2 < 0 means the end of * the row. A wide character is taken whole when either of its cells is in * range. With `trim`, trailing spaces of the appended part are dropped. * Returns 0, or -1 when out of memory. */ int cst_textsel_append(cst_selbuf_t *b, const char *line, int indent, int c1, int c2, int trim); /* Column span [*c1, *c2] of the word under column `col`; just that cell (or * both cells of a wide character) when it is not on a word character. */ void cst_textsel_word(const char *line, int indent, int col, int *c1, int *c2); /* Widens [*c1, *c2] so that neither end splits a wide character; highlighting * half of one desynchronizes curses from the terminal. *c2 < 0 is left as is. */ void cst_textsel_snap(const char *line, int indent, int *c1, int *c2); #endif