~sircmpwn/imrsh

fd5f2506aa18afda6c5a160b3b2cd56d755df145 — Drew DeVault 3 years ago 44858a3
imrsh_move: handle UTF-8 properly

Several other functions remain to be addressed
2 files changed, 53 insertions(+), 16 deletions(-)

M include/interactive.h
M src/interactive.c
M include/interactive.h => include/interactive.h +1 -1
@@ 13,7 13,7 @@ struct imrsh_interactive {
	struct mrsh_buffer *read_buffer;
	struct mrsh_state *state;
	bool commit;
	size_t cur;
	size_t cur, col, graph;

	TickitTerm *tt;
	struct {

M src/interactive.c => src/interactive.c +52 -15
@@ 27,8 27,10 @@ imrsh_print_from_cursor(struct imrsh_interactive *imrsh, int pad)
	for (int i = 0; i < pad; ++i) {
		tickit_term_print(imrsh->tt, " ");
	}
	/* TODO: Account for unicode */
	tickit_term_move(imrsh->tt, 0, -strlen(s) - pad);
	TickitStringPos limits = { -1, -1, -1, -1 };
	TickitStringPos pos = { 0 };
	tickit_utf8_count(s, &pos, &limits);
	tickit_term_move(imrsh->tt, 0, -pos.columns - pad);
	--imrsh->read_buffer->len;
}



@@ 38,19 40,42 @@ imrsh_commit(struct imrsh_interactive *imrsh)
	tickit_term_printf(imrsh->tt, "\n");
	mrsh_buffer_append_char(imrsh->read_buffer, '\0');
	imrsh->commit = true;
	imrsh->cur = 0;
	imrsh->cur = imrsh->col = imrsh->graph = 0;
}

static void
imrsh_move_delta(struct imrsh_interactive *imrsh, int d)
{
	if ((int)imrsh->cur + d < 0
			|| imrsh->cur + d > imrsh->read_buffer->len) {
	if ((int)imrsh->cur + d < 0) {
		return;
	}
	/* TODO: Account for unicode */
	tickit_term_move(imrsh->tt, 0, d);
	imrsh->cur += d;

	char *s = imrsh->read_buffer->data;
	size_t nbytes = 0, ncols = 0, ngraphs = 0;
	do {
		if (imrsh->graph + d == ngraphs) {
			tickit_term_move(imrsh->tt, 0,
					(int)ncols - (int)imrsh->col);
			imrsh->cur = nbytes;
			imrsh->col = ncols;
			imrsh->graph = ngraphs;
			return;
		}
		TickitStringPos limits = { -1, -1, 1, -1 };
		TickitStringPos pos = { 0 };
		/* TODO: What to do on invalid UTF-8? */
		tickit_utf8_ncount(&s[nbytes],
				imrsh->read_buffer->len - nbytes,
				&pos, &limits);
		nbytes += pos.bytes;
		ncols += pos.columns;
		ngraphs += pos.graphemes;
	} while (nbytes < imrsh->read_buffer->len);

	tickit_term_move(imrsh->tt, 0, (int)ncols - (int)imrsh->col);
	imrsh->cur = nbytes;
	imrsh->col = ncols;
	imrsh->col = ngraphs;
}

static void


@@ 63,6 88,7 @@ imrsh_move(struct imrsh_interactive *imrsh, int i)
static int
imrsh_find_prev_word(struct imrsh_interactive *imrsh)
{
	/* TODO: UTF-8 */
	int n = 0;
	int c = imrsh->cur - 1;
	while (isspace(imrsh->read_buffer->data[c]) && c > 0) {


@@ 80,6 106,7 @@ imrsh_find_prev_word(struct imrsh_interactive *imrsh)
static int
imrsh_find_next_word(struct imrsh_interactive *imrsh)
{
	/* TODO: UTF-8 */
	int n = 0;
	int c = imrsh->cur;
	while (isspace(imrsh->read_buffer->data[c])


@@ 98,6 125,7 @@ imrsh_find_next_word(struct imrsh_interactive *imrsh)
static void
imrsh_backspace(struct imrsh_interactive *imrsh, int n)
{
	/* TODO: UTF-8 */
	if (n <= 0 || (int)imrsh->cur - n < 0) {
		return;
	}


@@ 107,7 135,6 @@ imrsh_backspace(struct imrsh_interactive *imrsh, int n)
			imrsh->read_buffer->len - cur);
	imrsh->cur = cur;
	imrsh->read_buffer->len -= n;
	/* TODO: Account for unicode */
	tickit_term_move(imrsh->tt, 0, -n);
	imrsh_print_from_cursor(imrsh, n);
}


@@ 127,6 154,7 @@ imrsh_backspace_all(struct imrsh_interactive *imrsh)
static void
imrsh_delete(struct imrsh_interactive *imrsh, int n)
{
	/* TODO: UTF-8 */
	if (n <= 0 || imrsh->cur + n > imrsh->read_buffer->len) {
		return;
	}


@@ 146,6 174,7 @@ imrsh_delete_all(struct imrsh_interactive *imrsh)
static void
imrsh_swap(struct imrsh_interactive *imrsh)
{
	/* TODO: UTF-8 */
	if (imrsh->cur <= 1) {
		return;
	}


@@ 186,6 215,7 @@ imrsh_exit(struct imrsh_interactive *imrsh)
static void
imrsh_set_cmd(struct imrsh_interactive *imrsh, const char *cmd)
{
	/* TODO: UTF-8 */
	size_t l = strlen(cmd), _l = imrsh->read_buffer->len;
	imrsh_move(imrsh, 0);
	if (imrsh->read_buffer->len < l + 1) {


@@ 281,16 311,23 @@ imrsh_process_text(struct imrsh_interactive *imrsh, TickitKeyEventInfo *info)
	assert(info->type == TICKIT_KEYEV_TEXT);
	tickit_term_setpen(imrsh->tt, imrsh->pens._default);
	tickit_term_printf(imrsh->tt, "%s", info->str);
	size_t l = strlen(info->str);

	TickitStringPos limits = { -1, -1, -1, -1 };
	TickitStringPos pos = { 0 };
	tickit_utf8_count(info->str, &pos, &limits);

	if (imrsh->cur == imrsh->read_buffer->len) {
		mrsh_buffer_append(imrsh->read_buffer, info->str, l);
		imrsh->cur += l;
		mrsh_buffer_append(imrsh->read_buffer, info->str, pos.bytes);
		imrsh->cur += pos.bytes;
	} else {
		char *b = buffer_insert(imrsh->read_buffer, imrsh->cur, l);
		memcpy(b, info->str, l);
		imrsh->cur += l;
		char *b = buffer_insert(imrsh->read_buffer,
				imrsh->cur, pos.bytes);
		memcpy(b, info->str, pos.bytes);
		imrsh->cur += pos.bytes;
		imrsh_print_from_cursor(imrsh, 0);
	}
	imrsh->col += pos.columns;
	imrsh->graph += pos.graphemes;
}

static int