Skip to content

Commit

Permalink
Apply OSC 8 hyperlinks patch
Browse files Browse the repository at this point in the history
  • Loading branch information
dandavison committed Jul 22, 2020
1 parent a10c4c6 commit 31ae4ab
Show file tree
Hide file tree
Showing 8 changed files with 116 additions and 5 deletions.
9 changes: 7 additions & 2 deletions grid.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,12 @@

/* Default grid cell data. */
const struct grid_cell grid_default_cell = {
{ { ' ' }, 0, 1, 1 }, 0, 0, 8, 8, 0
{ { ' ' }, 0, 1, 1 }, 0, 0, 8, 8, 0, 0
};

/* Cleared grid cell data. */
const struct grid_cell grid_cleared_cell = {
{ { ' ' }, 0, 1, 1 }, 0, GRID_FLAG_CLEARED, 8, 8, 0
{ { ' ' }, 0, 1, 1 }, 0, GRID_FLAG_CLEARED, 8, 8, 0, 0
};
static const struct grid_cell_entry grid_cleared_entry = {
GRID_FLAG_CLEARED, { .data = { 0, 8, 8, ' ' } }
Expand Down Expand Up @@ -84,6 +84,8 @@ grid_need_extended_cell(const struct grid_cell_entry *gce,
return (1);
if (gc->us != 0) /* only supports 256 or RGB */
return (1);
if (gc->link != 0)
return (1);
return (0);
}

Expand Down Expand Up @@ -221,6 +223,8 @@ grid_cells_equal(const struct grid_cell *gca, const struct grid_cell *gcb)
return (0);
if (gca->attr != gcb->attr || gca->flags != gcb->flags)
return (0);
if (gca->link != gcb->link)
return (0);
if (gca->data.width != gcb->data.width)
return (0);
if (gca->data.size != gcb->data.size)
Expand Down Expand Up @@ -479,6 +483,7 @@ grid_get_cell1(struct grid_line *gl, u_int px, struct grid_cell *gc)
gc->bg |= COLOUR_FLAG_256;
gc->us = 0;
utf8_set(&gc->data, gce->data.data);
gc->link = 0;
}

/* Get cell for reading. */
Expand Down
36 changes: 36 additions & 0 deletions input.c
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ static void input_set_state(struct window_pane *,
static void input_reset_cell(struct input_ctx *);

static void input_osc_4(struct input_ctx *, const char *);
static void input_osc_8(struct input_ctx *, const char *);
static void input_osc_10(struct input_ctx *, const char *);
static void input_osc_11(struct input_ctx *, const char *);
static void input_osc_52(struct input_ctx *, const char *);
Expand Down Expand Up @@ -2225,6 +2226,9 @@ input_exit_osc(struct input_ctx *ictx)
server_status_window(ictx->wp->window);
}
break;
case 8:
input_osc_8(ictx, p);
break;
case 10:
input_osc_10(ictx, p);
break;
Expand Down Expand Up @@ -2433,6 +2437,38 @@ input_osc_4(struct input_ctx *ictx, const char *p)
free(copy);
}

/* Handle the OSC 8 sequence for writing hyperlinks. */
static void
input_osc_8(struct input_ctx *ictx, const char *p)
{
struct grid_cell *gc = &ictx->cell.cell;
char *end;
struct hyperlink *hl;

if ((end = strchr(p, ';')) == NULL)
goto bad;
end++;
if (*end == '\0') {
gc->link = 0;
return;
}

/* XXX parse ID and check pane tree, reuse entry if present */

hl = xcalloc(1, sizeof *hl);
hl->id = ++next_hyperlink;
hl->link = xstrdup(end);
RB_INSERT (hyperlinks, &hyperlinks, hl);

log_debug("hyperlink %u = %s", hl->id, hl->link);

gc->link = hl->id;
return;

bad:
log_debug("bad OSC 8 %s", p);
}

/* Handle the OSC 10 sequence for setting foreground colour. */
static void
input_osc_10(struct input_ctx *ictx, const char *p)
Expand Down
2 changes: 1 addition & 1 deletion screen-write.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ static const struct grid_cell *screen_write_combine(struct screen_write_ctx *,
const struct utf8_data *, u_int *);

static const struct grid_cell screen_write_pad_cell = {
{ { 0 }, 0, 0, 0 }, 0, GRID_FLAG_PADDING, 0, 8, 8
{ { 0 }, 0, 0, 0 }, 0, GRID_FLAG_PADDING, 0, 8, 8, 0
};

struct screen_write_collect_item {
Expand Down
22 changes: 22 additions & 0 deletions server.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@

struct clients clients;

struct hyperlinks hyperlinks = RB_INITIALIZER();
u_int next_hyperlink;

struct tmuxproc *server_proc;
static int server_fd = -1;
static int server_exit;
Expand All @@ -57,6 +60,25 @@ static void server_child_signal(void);
static void server_child_exited(pid_t, int);
static void server_child_stopped(pid_t, int);

RB_GENERATE(hyperlinks, hyperlink, entry, server_cmp_hyperlink);

/* Compare two hyperlinks. */
int
server_cmp_hyperlink(struct hyperlink *hl1, struct hyperlink *hl2)
{
return (hl1->id - hl2->id);
}

/* Get hyperlink. */
struct hyperlink *
server_get_hyperlink(u_int id)
{
struct hyperlink hl;

hl.id = id;
return (RB_FIND(hyperlinks, &hyperlinks, &hl));
}

/* Set marked pane. */
void
server_set_marked(struct session *s, struct winlink *wl, struct window_pane *wp)
Expand Down
2 changes: 1 addition & 1 deletion style.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@

/* Default style. */
static struct style style_default = {
{ { { ' ' }, 0, 1, 1 }, 0, 0, 8, 8, 0 },
{ { { ' ' }, 0, 1, 1 }, 0, 0, 8, 8, 0, 0 },

8,
STYLE_ALIGN_DEFAULT,
Expand Down
16 changes: 16 additions & 0 deletions tmux.h
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,8 @@ enum tty_code_code {
TTYC_EL1,
TTYC_ENACS,
TTYC_FSL,
TTYC_HLS,
TTYC_HLR,
TTYC_HOME,
TTYC_HPA,
TTYC_ICH,
Expand Down Expand Up @@ -636,6 +638,7 @@ struct grid_cell {
int fg;
int bg;
int us;
u_int link;
} __packed;
struct grid_cell_entry {
u_char flags;
Expand Down Expand Up @@ -677,6 +680,14 @@ struct grid {
struct grid_line *linedata;
};

/* Hyperlink tree entry. */
struct hyperlink {
u_int id;
const char *link;
RB_ENTRY(hyperlink) entry;
};
RB_HEAD(hyperlinks, hyperlink);

/* Style alignment. */
enum style_align {
STYLE_ALIGN_DEFAULT,
Expand Down Expand Up @@ -2197,6 +2208,11 @@ void file_push(struct client_file *);
extern struct tmuxproc *server_proc;
extern struct clients clients;
extern struct cmd_find_state marked_pane;
extern struct hyperlinks hyperlinks;
extern u_int next_hyperlink;
int server_cmp_hyperlink(struct hyperlink *, struct hyperlink *);
struct hyperlink *server_get_hyperlink(u_int);
RB_PROTOTYPE(hyperlinks, hyperlink, entry, server_cmp_hyperlink);
void server_set_marked(struct session *, struct winlink *,
struct window_pane *);
void server_clear_marked(void);
Expand Down
2 changes: 2 additions & 0 deletions tty-term.c
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,8 @@ static const struct tty_term_code_entry tty_term_codes[] = {
[TTYC_EL] = { TTYCODE_STRING, "el" },
[TTYC_ENACS] = { TTYCODE_STRING, "enacs" },
[TTYC_FSL] = { TTYCODE_STRING, "fsl" },
[TTYC_HLS] = { TTYCODE_STRING, "Hls" },
[TTYC_HLR] = { TTYCODE_STRING, "Hlr" },
[TTYC_HOME] = { TTYCODE_STRING, "home" },
[TTYC_HPA] = { TTYCODE_STRING, "hpa" },
[TTYC_ICH1] = { TTYCODE_STRING, "ich1" },
Expand Down
32 changes: 31 additions & 1 deletion tty.c
Original file line number Diff line number Diff line change
Expand Up @@ -1329,6 +1329,7 @@ tty_draw_line(struct tty *tty, struct window_pane *wp, struct screen *s,
gcp->fg != last.fg ||
gcp->bg != last.bg ||
gcp->us != last.us ||
gcp->link != last.link ||
ux + width + gcp->data.width > nx ||
(sizeof buf) - len < gcp->data.size)) {
tty_attributes(tty, &last, wp);
Expand Down Expand Up @@ -1927,6 +1928,8 @@ tty_reset(struct tty *tty)
struct grid_cell *gc = &tty->cell;

if (!grid_cells_equal(gc, &grid_default_cell)) {
if (gc->link != 0)
tty_putcode(tty, TTYC_HLR);
if ((gc->attr & GRID_ATTR_CHARSET) && tty_acs_needed(tty))
tty_putcode(tty, TTYC_RMACS);
tty_putcode(tty, TTYC_SGR0);
Expand Down Expand Up @@ -2209,6 +2212,29 @@ tty_cursor(struct tty *tty, u_int cx, u_int cy)
tty->cy = cy;
}

static void
tty_hyperlink(struct tty *tty, const struct grid_cell *gc)
{
struct hyperlink *hl;
char s[16];

if (gc->link == tty->cell.link)
return;
tty->cell.link = gc->link;

if (gc->link == 0)
tty_putcode(tty, TTYC_HLR);
else {
hl = server_get_hyperlink(gc->link);
if (hl == NULL)
tty_putcode(tty, TTYC_HLR);
else {
snprintf(s, sizeof s, "%u", hl->id);
tty_putcode_ptr2(tty, TTYC_HLS, s, hl->link);
}
}
}

void
tty_attributes(struct tty *tty, const struct grid_cell *gc,
struct window_pane *wp)
Expand All @@ -2223,7 +2249,8 @@ tty_attributes(struct tty *tty, const struct grid_cell *gc,
gc->attr == tty->last_cell.attr &&
gc->fg == tty->last_cell.fg &&
gc->bg == tty->last_cell.bg &&
gc->us == tty->last_cell.us)
gc->us == tty->last_cell.us &&
gc->link == tty->last_cell.link)
return;
tty->last_wp = (wp != NULL ? (int)wp->id : -1);
memcpy(&tty->last_cell, gc, sizeof tty->last_cell);
Expand Down Expand Up @@ -2306,6 +2333,9 @@ tty_attributes(struct tty *tty, const struct grid_cell *gc,
tty_putcode(tty, TTYC_SMOL);
if ((changed & GRID_ATTR_CHARSET) && tty_acs_needed(tty))
tty_putcode(tty, TTYC_SMACS);

/* Set hyperlink if any. */
tty_hyperlink(tty, gc);
}

static void
Expand Down

0 comments on commit 31ae4ab

Please sign in to comment.