mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-03-14 05:33:59 -04:00
Merge branch 'tab-stop'
This commit is contained in:
commit
aee22dd4b6
7 changed files with 110 additions and 67 deletions
26
csi.c
26
csi.c
|
|
@ -357,6 +357,32 @@ csi_dispatch(struct terminal *term, uint8_t final)
|
||||||
term_cursor_left(term, vt_param_get(term, 0, 1));
|
term_cursor_left(term, vt_param_get(term, 0, 1));
|
||||||
break;
|
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': {
|
case 'G': {
|
||||||
/* Cursor horizontal absolute */
|
/* Cursor horizontal absolute */
|
||||||
struct coord new_cursor = term_cursor_rel_to_abs(
|
struct coord new_cursor = term_cursor_rel_to_abs(
|
||||||
|
|
|
||||||
5
render.c
5
render.c
|
|
@ -911,6 +911,11 @@ render_resize(struct terminal *term, int width, int height)
|
||||||
grid_row_free(term->alt.rows[r]);
|
grid_row_free(term->alt.rows[r]);
|
||||||
free(term->alt.rows);
|
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->cols = new_cols;
|
||||||
term->rows = new_rows;
|
term->rows = new_rows;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -108,6 +108,12 @@ extract_selection(const struct terminal *term)
|
||||||
start_col = 0;
|
start_col = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (idx == 0) {
|
||||||
|
/* Selection of empty cells only */
|
||||||
|
buf[idx] = '\0';
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
assert(idx > 0);
|
assert(idx > 0);
|
||||||
assert(idx < buf_size);
|
assert(idx < buf_size);
|
||||||
if (buf[idx - 1] == '\n')
|
if (buf[idx - 1] == '\n')
|
||||||
|
|
|
||||||
|
|
@ -504,6 +504,7 @@ term_init(const struct config *conf, struct fdm *fdm, struct wayland *wayl,
|
||||||
.normal = {.damage = tll_init(), .scroll_damage = tll_init()},
|
.normal = {.damage = tll_init(), .scroll_damage = tll_init()},
|
||||||
.alt = {.damage = tll_init(), .scroll_damage = tll_init()},
|
.alt = {.damage = tll_init(), .scroll_damage = tll_init()},
|
||||||
.grid = &term->normal,
|
.grid = &term->normal,
|
||||||
|
.tab_stops = tll_init(),
|
||||||
.wl = wayl,
|
.wl = wayl,
|
||||||
.render = {
|
.render = {
|
||||||
.scrollback_lines = conf->scrollback_lines,
|
.scrollback_lines = conf->scrollback_lines,
|
||||||
|
|
@ -727,6 +728,7 @@ term_destroy(struct terminal *term)
|
||||||
tll_foreach(term->ptmx_buffer, it)
|
tll_foreach(term->ptmx_buffer, it)
|
||||||
free(it->item.data);
|
free(it->item.data);
|
||||||
tll_free(term->ptmx_buffer);
|
tll_free(term->ptmx_buffer);
|
||||||
|
tll_free(term->tab_stops);
|
||||||
|
|
||||||
int ret = EXIT_SUCCESS;
|
int ret = EXIT_SUCCESS;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -262,6 +262,8 @@ struct terminal {
|
||||||
int max_x_advance;
|
int max_x_advance;
|
||||||
} fextents;
|
} fextents;
|
||||||
|
|
||||||
|
tll(int) tab_stops;
|
||||||
|
|
||||||
struct wayland *wl;
|
struct wayland *wl;
|
||||||
struct wl_window *window;
|
struct wl_window *window;
|
||||||
|
|
||||||
|
|
|
||||||
77
tllist.h
77
tllist.h
|
|
@ -38,38 +38,21 @@
|
||||||
#define tll_length(list) (list).length
|
#define tll_length(list) (list).length
|
||||||
|
|
||||||
/* Adds a new item to the back of the list */
|
/* Adds a new item to the back of the list */
|
||||||
#define tll_push_back(list, new_item) \
|
#define tll_push_back(list, new_item) \
|
||||||
do { \
|
do { \
|
||||||
__typeof__((list).head) __e = malloc(sizeof(*__e)); \
|
tll_insert_after(list, (list).tail, new_item); \
|
||||||
__e->item = (new_item); \
|
if ((list).head == NULL) \
|
||||||
__e->prev = (list).tail; \
|
(list).head = (list).tail; \
|
||||||
__e->next = NULL; \
|
|
||||||
if ((list).head == NULL) \
|
|
||||||
(list).head = (list).tail = __e; \
|
|
||||||
else { \
|
|
||||||
(list).tail->next = __e; \
|
|
||||||
(list).tail = __e; \
|
|
||||||
} \
|
|
||||||
(list).length++; \
|
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
/* Adds a new item to the front of the list */
|
/* Adds a new item to the front of the list */
|
||||||
#define tll_push_front(list, new_item) \
|
#define tll_push_front(list, new_item) \
|
||||||
do { \
|
do { \
|
||||||
__typeof__((list).head) __e = malloc(sizeof(*__e)); \
|
tll_insert_before(list, (list).head, new_item); \
|
||||||
__e->item = (new_item); \
|
if ((list).tail == NULL) \
|
||||||
__e->prev = NULL; \
|
(list).tail = (list).head; \
|
||||||
__e->next = (list).head; \
|
|
||||||
if ((list).head == NULL) \
|
|
||||||
(list).head = (list).tail = __e; \
|
|
||||||
else { \
|
|
||||||
(list).head->prev = __e; \
|
|
||||||
(list).head = __e; \
|
|
||||||
} \
|
|
||||||
(list).length++; \
|
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Iterates the list. <it> is an iterator pointer. You can access the
|
* Iterates the list. <it> is an iterator pointer. You can access the
|
||||||
* list item with ->item:
|
* list item with ->item:
|
||||||
|
|
@ -96,6 +79,46 @@
|
||||||
it = it_prev, \
|
it = it_prev, \
|
||||||
it_prev = it_prev != NULL ? it_prev->prev : NULL)
|
it_prev = it_prev != NULL ? it_prev->prev : NULL)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Inserts a new item after <it>, 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 <it>, 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. <it> is an iterator. I.e. you can
|
* Removes an entry from the list. <it> is an iterator. I.e. you can
|
||||||
* only call this from inside a tll_foreach() or tll_rforeach() loop.
|
* only call this from inside a tll_foreach() or tll_rforeach() loop.
|
||||||
|
|
|
||||||
59
vt.c
59
vt.c
|
|
@ -608,43 +608,6 @@ esc_dispatch(struct terminal *term, uint8_t final)
|
||||||
term_reset(term, true);
|
term_reset(term, true);
|
||||||
break;
|
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':
|
case 'D':
|
||||||
term_linefeed(term);
|
term_linefeed(term);
|
||||||
break;
|
break;
|
||||||
|
|
@ -654,6 +617,17 @@ esc_dispatch(struct terminal *term, uint8_t final)
|
||||||
term_cursor_left(term, term->cursor.col);
|
term_cursor_left(term, term->cursor.col);
|
||||||
break;
|
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':
|
case 'M':
|
||||||
term_reverse_index(term);
|
term_reverse_index(term);
|
||||||
break;
|
break;
|
||||||
|
|
@ -892,9 +866,14 @@ action(struct terminal *term, enum action _action, uint8_t c)
|
||||||
|
|
||||||
case '\x09': {
|
case '\x09': {
|
||||||
/* HT - horizontal tab */
|
/* HT - horizontal tab */
|
||||||
int col = term->cursor.col;
|
int new_col = term->cursor.col;
|
||||||
col = (col + 8) / 8 * 8;
|
tll_foreach(term->tab_stops, it) {
|
||||||
term_cursor_right(term, col - term->cursor.col);
|
if (it->item >= term->cursor.col) {
|
||||||
|
new_col = it->item;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
term_cursor_right(term, new_col - term->cursor.col);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue