From f91073c362d55ba82c64e977300a1230be076ffd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Sat, 16 Nov 2019 10:54:21 +0100 Subject: [PATCH 1/8] term: add tab-stop list to terminal struct This list is intended to store tab stop columns --- terminal.c | 2 ++ terminal.h | 2 ++ 2 files changed, 4 insertions(+) diff --git a/terminal.c b/terminal.c index 2be46130..8b7d6fa2 100644 --- a/terminal.c +++ b/terminal.c @@ -504,6 +504,7 @@ term_init(const struct config *conf, struct fdm *fdm, struct wayland *wayl, .normal = {.damage = tll_init(), .scroll_damage = tll_init()}, .alt = {.damage = tll_init(), .scroll_damage = tll_init()}, .grid = &term->normal, + .tab_stops = tll_init(), .wl = wayl, .render = { .scrollback_lines = conf->scrollback_lines, @@ -727,6 +728,7 @@ term_destroy(struct terminal *term) tll_foreach(term->ptmx_buffer, it) free(it->item.data); tll_free(term->ptmx_buffer); + tll_free(term->tab_stops); int ret = EXIT_SUCCESS; diff --git a/terminal.h b/terminal.h index 5339d367..11cfd495 100644 --- a/terminal.h +++ b/terminal.h @@ -262,6 +262,8 @@ struct terminal { int max_x_advance; } fextents; + tll(int) tab_stops; + struct wayland *wl; struct wl_window *window; From 37139fc4faea37833e0b9d5be7c55f1c5db410cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Sat, 16 Nov 2019 10:54:56 +0100 Subject: [PATCH 2/8] render: configure default tab stops when resizing the terminal --- render.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/render.c b/render.c index 0b0c6d5b..f688a08f 100644 --- a/render.c +++ b/render.c @@ -911,6 +911,11 @@ render_resize(struct terminal *term, int width, int height) grid_row_free(term->alt.rows[r]); free(term->alt.rows); + /* Reset tab stops */ + tll_free(term->tab_stops); + for (int c = 0; c < new_cols; c += 8) + tll_push_back(term->tab_stops, c); + term->cols = new_cols; term->rows = new_rows; From 69e0e454fa20b7f80b2012c27cc9edc40f659360 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Sat, 16 Nov 2019 10:55:14 +0100 Subject: [PATCH 3/8] vt: remove commented out code --- vt.c | 37 ------------------------------------- 1 file changed, 37 deletions(-) diff --git a/vt.c b/vt.c index e7336dc6..564c14e3 100644 --- a/vt.c +++ b/vt.c @@ -608,43 +608,6 @@ esc_dispatch(struct terminal *term, uint8_t final) term_reset(term, true); break; -#if 0 - case '0': { - /* Configure G0-G3 to use special chars + line drawing */ - char param = term->vt.private[0] != 0 ? term->vt.private[0] : 0; - - switch (param) { - case '(': term->charset[0] = CHARSET_GRAPHIC; break; - case ')': term->charset[1] = CHARSET_GRAPHIC; break; - case '*': term->charset[2] = CHARSET_GRAPHIC; break; - case '+': term->charset[3] = CHARSET_GRAPHIC; break; - case 0: break; - - default: - UNHANDLED(); - break; - } - break; - } - - case 'B': { - /* Configure G0-G3 to use ASCII */ - char param = term->vt.private[0] != 0 ? term->vt.private[0] : 0; - - switch (param) { - case '(': term->charset[0] = CHARSET_ASCII; break; - case ')': term->charset[1] = CHARSET_ASCII; break; - case '*': term->charset[2] = CHARSET_ASCII; break; - case '+': term->charset[3] = CHARSET_ASCII; break; - case 0: break; - - default: - UNHANDLED(); - break; - } - break; - } -#endif case 'D': term_linefeed(term); break; From 98402911000414916f4b0cdfe9f9f1b07342b7f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Sat, 16 Nov 2019 10:55:28 +0100 Subject: [PATCH 4/8] csi: implement CSI 0g and CSI 3g * 0g - clear tab stop at current column * 3g - clear all tab stops --- csi.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/csi.c b/csi.c index 13a31069..c39653e1 100644 --- a/csi.c +++ b/csi.c @@ -357,6 +357,32 @@ csi_dispatch(struct terminal *term, uint8_t final) term_cursor_left(term, vt_param_get(term, 0, 1)); break; + case 'g': { + int param = vt_param_get(term, 0, 0); + switch (param) { + case 0: + /* Clear tab stop at *current* column */ + tll_foreach(term->tab_stops, it) { + if (it->item == term->cursor.col) + tll_remove(term->tab_stops, it); + else if (it->item > term->cursor.col) + break; + } + + break; + + case 3: + /* Clear *all* tabs */ + tll_free(term->tab_stops); + break; + + default: + UNHANDLED(); + break; + } + break; + } + case 'G': { /* Cursor horizontal absolute */ struct coord new_cursor = term_cursor_rel_to_abs( From b31c18c7413222480c6d33ee2aa5ee4025902a35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Sat, 16 Nov 2019 10:56:10 +0100 Subject: [PATCH 5/8] selection: buffer may be empty if only empty cells where selected --- selection.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/selection.c b/selection.c index 2a05b853..23eb4450 100644 --- a/selection.c +++ b/selection.c @@ -108,6 +108,12 @@ extract_selection(const struct terminal *term) start_col = 0; } + if (idx == 0) { + /* Selection of empty cells only */ + buf[idx] = '\0'; + return buf; + } + assert(idx > 0); assert(idx < buf_size); if (buf[idx - 1] == '\n') From 13204d93376d3986221fd7d0e71e3a5d975fb7fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Sat, 16 Nov 2019 10:56:28 +0100 Subject: [PATCH 6/8] tllist: update to latest In particular, pull in tll_insert_{before,after} --- tllist.h | 77 ++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 50 insertions(+), 27 deletions(-) diff --git a/tllist.h b/tllist.h index acd0ab47..ec2fd41c 100644 --- a/tllist.h +++ b/tllist.h @@ -38,38 +38,21 @@ #define tll_length(list) (list).length /* Adds a new item to the back of the list */ -#define tll_push_back(list, new_item) \ - do { \ - __typeof__((list).head) __e = malloc(sizeof(*__e)); \ - __e->item = (new_item); \ - __e->prev = (list).tail; \ - __e->next = NULL; \ - if ((list).head == NULL) \ - (list).head = (list).tail = __e; \ - else { \ - (list).tail->next = __e; \ - (list).tail = __e; \ - } \ - (list).length++; \ +#define tll_push_back(list, new_item) \ + do { \ + tll_insert_after(list, (list).tail, new_item); \ + if ((list).head == NULL) \ + (list).head = (list).tail; \ } while (0) /* Adds a new item to the front of the list */ -#define tll_push_front(list, new_item) \ - do { \ - __typeof__((list).head) __e = malloc(sizeof(*__e)); \ - __e->item = (new_item); \ - __e->prev = NULL; \ - __e->next = (list).head; \ - if ((list).head == NULL) \ - (list).head = (list).tail = __e; \ - else { \ - (list).head->prev = __e; \ - (list).head = __e; \ - } \ - (list).length++; \ +#define tll_push_front(list, new_item) \ + do { \ + tll_insert_before(list, (list).head, new_item); \ + if ((list).tail == NULL) \ + (list).tail = (list).head; \ } while (0) - /* * Iterates the list. is an iterator pointer. You can access the * list item with ->item: @@ -96,6 +79,46 @@ it = it_prev, \ it_prev = it_prev != NULL ? it_prev->prev : NULL) +/* + * Inserts a new item after , which is an iterator. I.e. you can + * only call this from inside a tll_foreach() or tll_rforeach() loop. + */ +#define tll_insert_after(list, it, new_item) \ + do { \ + __typeof__((list).head) __e = malloc(sizeof(*__e)); \ + __e->item = (new_item); \ + __e->prev = (it); \ + __e->next = (it) != NULL ? (it)->next : NULL; \ + if ((it) != NULL) { \ + if ((it)->next != NULL) \ + (it)->next->prev = __e; \ + (it)->next = __e; \ + } \ + if ((it) == (list).tail) \ + (list).tail = __e; \ + (list).length++; \ + } while (0) + +/* + * Inserts a new item before , which is an iterator. I.e. you can + * only call this from inside a tll_foreach() or tll_rforeach() loop. + */ +#define tll_insert_before(list, it, new_item) \ + do { \ + __typeof__((list).head) __e = malloc(sizeof(*__e)); \ + __e->item = (new_item); \ + __e->prev = (it) != NULL ? (it)->prev : NULL; \ + __e->next = (it); \ + if ((it) != NULL) { \ + if ((it)->prev != NULL) \ + (it)->prev->next = __e; \ + (it)->prev = __e; \ + } \ + if ((it) == (list).head) \ + (list).head = __e; \ + (list).length++; \ + } while (0) + /* * Removes an entry from the list. is an iterator. I.e. you can * only call this from inside a tll_foreach() or tll_rforeach() loop. From 9ff48c2015c6bcd7fce8a4e64a51db593b28884c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Sat, 16 Nov 2019 10:57:11 +0100 Subject: [PATCH 7/8] vt: implement ESC H - set tab stop at current column --- vt.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/vt.c b/vt.c index 564c14e3..73bc6262 100644 --- a/vt.c +++ b/vt.c @@ -617,6 +617,17 @@ esc_dispatch(struct terminal *term, uint8_t final) term_cursor_left(term, term->cursor.col); break; + case 'H': + tll_foreach(term->tab_stops, it) { + if (it->item >= term->cursor.col) { + tll_insert_before(term->tab_stops, it, term->cursor.col); + break; + } + } + + tll_push_back(term->tab_stops, term->cursor.col); + break; + case 'M': term_reverse_index(term); break; From 65ff3656f70735f6fcaee05c652004f1d4c717e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Sat, 16 Nov 2019 10:57:39 +0100 Subject: [PATCH 8/8] vt: execute: \t: use tab stops from tab stop list Instead of assuming hardcoded 8-width tab stops, use the tab stops from the tab stop list. --- vt.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/vt.c b/vt.c index 73bc6262..79e9871e 100644 --- a/vt.c +++ b/vt.c @@ -866,9 +866,14 @@ action(struct terminal *term, enum action _action, uint8_t c) case '\x09': { /* HT - horizontal tab */ - int col = term->cursor.col; - col = (col + 8) / 8 * 8; - term_cursor_right(term, col - term->cursor.col); + int new_col = term->cursor.col; + tll_foreach(term->tab_stops, it) { + if (it->item >= term->cursor.col) { + new_col = it->item; + break; + } + } + term_cursor_right(term, new_col - term->cursor.col); break; }