mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-02-05 04:06:08 -05:00
terminal: add term_osc8_{open,close} functions
These functions update the OSC-8 URI state in the terminal. term_osc8_open() tracks the beginning of an URL, by storing the start coordinate (i.e. the current cursor location), along with the URL itself. Note that term_osc8_open() may not be called with an empty URL. This is important to notice, since the way OSC-8 works, applications close an URL by “opening” a new, empty one: \E]8;;https://foo.bar\e\\this is an OSC-8 URL\E]8;;\e\\ It is up to the caller to check for this, and call term_osc8_close() instead of term_osc8_open() when the URL is empty. However, it is *also* valid to switch directly from one URL to another: \E]8;;http://123\e\\First URL\E]8;;http//456\e\\Second URL\E]8;;\e\\ This use-case *is* handled by term_osc8_open(). term_osc8_close() uses the information from term_osc8_open() to add per-row URL data (using the new ‘extra’ row data).
This commit is contained in:
parent
841e5f0e50
commit
682494d45a
2 changed files with 57 additions and 0 deletions
54
terminal.c
54
terminal.c
|
|
@ -3015,3 +3015,57 @@ term_ime_set_cursor_rect(struct terminal *term, int x, int y, int width,
|
|||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
term_osc8_open(struct terminal *term, const char *uri)
|
||||
{
|
||||
if (unlikely(term->vt.osc8.begin.row < 0)) {
|
||||
/* It’s valid to switch from one URI to another without
|
||||
* closing the first one */
|
||||
term_osc8_close(term);
|
||||
}
|
||||
|
||||
term->vt.osc8.begin = (struct coord){
|
||||
.col = term->grid->cursor.point.col,
|
||||
.row = grid_row_absolute(term->grid, term->grid->cursor.point.row),
|
||||
};
|
||||
term->vt.osc8.uri = xstrdup(uri);
|
||||
}
|
||||
|
||||
void
|
||||
term_osc8_close(struct terminal *term)
|
||||
{
|
||||
if (term->vt.osc8.begin.row < 0)
|
||||
return;
|
||||
|
||||
if (term->vt.osc8.uri[0] == '\0')
|
||||
goto done;
|
||||
|
||||
struct coord start = term->vt.osc8.begin;
|
||||
struct coord end = (struct coord){
|
||||
.col = term->grid->cursor.point.col,
|
||||
.row = grid_row_absolute(term->grid, term->grid->cursor.point.row),
|
||||
};
|
||||
|
||||
int r = start.row;
|
||||
int start_col = start.col;
|
||||
do {
|
||||
int end_col = r == end.row ? end.col : term->cols - 1;
|
||||
|
||||
struct row *row = term->grid->rows[r];
|
||||
if (row->extra == NULL)
|
||||
row->extra = xcalloc(1, sizeof(*row->extra));
|
||||
|
||||
struct row_uri_range range = {
|
||||
.start = start_col,
|
||||
.end = end_col,
|
||||
.uri = xstrdup(term->vt.osc8.uri),
|
||||
};
|
||||
tll_push_back(row->extra->uri_ranges, range);
|
||||
start_col = 0;
|
||||
} while (r++ != end.row);
|
||||
|
||||
done:
|
||||
free(term->vt.osc8.uri);
|
||||
term->vt.osc8.uri = NULL;
|
||||
term->vt.osc8.begin = (struct coord){-1, -1};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -689,3 +689,6 @@ void term_ime_set_cursor_rect(
|
|||
|
||||
void term_urls_reset(struct terminal *term);
|
||||
void term_collect_urls(struct terminal *term);
|
||||
|
||||
void term_osc8_open(struct terminal *term, const char *uri);
|
||||
void term_osc8_close(struct terminal *term);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue