From ca1080d01edca48cd5c51d6f8b7aad0a96d08ab2 Mon Sep 17 00:00:00 2001 From: nicm Date: Tue, 27 Aug 2024 07:49:07 +0000 Subject: [PATCH] Display hyperlinks in copy mode and add copy_cursor_hyperlink format to get the hyperlink under the cursor. --- usr.bin/tmux/hyperlinks.c | 18 +++++++++++++++--- usr.bin/tmux/tmux.1 | 3 ++- usr.bin/tmux/tmux.h | 3 ++- usr.bin/tmux/window-copy.c | 21 +++++++++++++++++++-- 4 files changed, 38 insertions(+), 7 deletions(-) diff --git a/usr.bin/tmux/hyperlinks.c b/usr.bin/tmux/hyperlinks.c index ea0e7db735d..4f3ed7348c1 100644 --- a/usr.bin/tmux/hyperlinks.c +++ b/usr.bin/tmux/hyperlinks.c @@ -1,4 +1,4 @@ -/* $OpenBSD: hyperlinks.c,v 1.3 2023/06/30 13:19:32 nicm Exp $ */ +/* $OpenBSD: hyperlinks.c,v 1.4 2024/08/27 07:49:07 nicm Exp $ */ /* * Copyright (c) 2021 Will @@ -69,6 +69,7 @@ struct hyperlinks { u_int next_inner; struct hyperlinks_by_inner_tree by_inner; struct hyperlinks_by_uri_tree by_uri; + u_int references; }; static int @@ -206,6 +207,15 @@ hyperlinks_init(void) hl->next_inner = 1; RB_INIT(&hl->by_uri); RB_INIT(&hl->by_inner); + hl->references = 1; + return (hl); +} + +/* Copy hyperlink set. */ +struct hyperlinks * +hyperlinks_copy(struct hyperlinks *hl) +{ + hl->references++; return (hl); } @@ -223,6 +233,8 @@ hyperlinks_reset(struct hyperlinks *hl) void hyperlinks_free(struct hyperlinks *hl) { - hyperlinks_reset(hl); - free(hl); + if (--hl->references == 0) { + hyperlinks_reset(hl); + free(hl); + } } diff --git a/usr.bin/tmux/tmux.1 b/usr.bin/tmux/tmux.1 index eea5747ae70..9165234df21 100644 --- a/usr.bin/tmux/tmux.1 +++ b/usr.bin/tmux/tmux.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: tmux.1,v 1.953 2024/08/27 07:31:26 nicm Exp $ +.\" $OpenBSD: tmux.1,v 1.954 2024/08/27 07:49:07 nicm Exp $ .\" .\" Copyright (c) 2007 Nicholas Marriott .\" @@ -5498,6 +5498,7 @@ The following variables are available, where appropriate: .It Li "command_list_name" Ta "" Ta "Command name if listing commands" .It Li "command_list_usage" Ta "" Ta "Command usage if listing commands" .It Li "config_files" Ta "" Ta "List of configuration files loaded" +.It Li "copy_cursor_hyperlink" Ta "" Ta "Hyperlink under cursor in copy mode" .It Li "copy_cursor_line" Ta "" Ta "Line the cursor is on in copy mode" .It Li "copy_cursor_word" Ta "" Ta "Word under cursor in copy mode" .It Li "copy_cursor_x" Ta "" Ta "Cursor X position in copy mode" diff --git a/usr.bin/tmux/tmux.h b/usr.bin/tmux/tmux.h index f8e7c5275db..99f5343b5f8 100644 --- a/usr.bin/tmux/tmux.h +++ b/usr.bin/tmux/tmux.h @@ -1,4 +1,4 @@ -/* $OpenBSD: tmux.h,v 1.1225 2024/08/26 07:30:46 nicm Exp $ */ +/* $OpenBSD: tmux.h,v 1.1226 2024/08/27 07:49:07 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -3434,6 +3434,7 @@ u_int hyperlinks_put(struct hyperlinks *, const char *, int hyperlinks_get(struct hyperlinks *, u_int, const char **, const char **, const char **); struct hyperlinks *hyperlinks_init(void); +struct hyperlinks *hyperlinks_copy(struct hyperlinks *); void hyperlinks_reset(struct hyperlinks *); void hyperlinks_free(struct hyperlinks *); diff --git a/usr.bin/tmux/window-copy.c b/usr.bin/tmux/window-copy.c index 697b7b56aea..eb830948dc0 100644 --- a/usr.bin/tmux/window-copy.c +++ b/usr.bin/tmux/window-copy.c @@ -1,4 +1,4 @@ -/* $OpenBSD: window-copy.c,v 1.352 2024/08/27 07:31:26 nicm Exp $ */ +/* $OpenBSD: window-copy.c,v 1.353 2024/08/27 07:49:07 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -450,6 +450,8 @@ window_copy_init(struct window_mode_entry *wme, data->scroll_exit = args_has(args, 'e'); data->hide_position = args_has(args, 'H'); + if (base->hyperlinks != NULL) + data->screen.hyperlinks = hyperlinks_copy(base->hyperlinks); data->screen.cx = data->cx; data->screen.cy = data->cy; data->mx = data->cx; @@ -764,6 +766,18 @@ window_copy_get_line(struct window_pane *wp, u_int y) return (format_grid_line(gd, gd->hsize + y)); } +static void * +window_copy_cursor_hyperlink_cb(struct format_tree *ft) +{ + struct window_pane *wp = format_get_pane(ft); + struct window_mode_entry *wme = TAILQ_FIRST(&wp->modes); + struct window_copy_mode_data *data = wme->data; + struct grid *gd = data->screen.grid; + + return (format_grid_hyperlink(gd, data->cx, gd->hsize + data->cy, + &data->screen)); +} + static void * window_copy_cursor_word_cb(struct format_tree *ft) { @@ -833,6 +847,8 @@ window_copy_formats(struct window_mode_entry *wme, struct format_tree *ft) format_add_cb(ft, "copy_cursor_word", window_copy_cursor_word_cb); format_add_cb(ft, "copy_cursor_line", window_copy_cursor_line_cb); + format_add_cb(ft, "copy_cursor_hyperlink", + window_copy_cursor_hyperlink_cb); } static void @@ -2486,7 +2502,8 @@ window_copy_cmd_refresh_from_pane(struct window_copy_cmd_state *cs) screen_free(data->backing); free(data->backing); - data->backing = window_copy_clone_screen(&wp->base, &data->screen, NULL, NULL, wme->swp != wme->wp); + data->backing = window_copy_clone_screen(&wp->base, &data->screen, NULL, + NULL, wme->swp != wme->wp); window_copy_size_changed(wme); return (WINDOW_COPY_CMD_REDRAW); -- 2.20.1