Display hyperlinks in copy mode and add copy_cursor_hyperlink format to
authornicm <nicm@openbsd.org>
Tue, 27 Aug 2024 07:49:07 +0000 (07:49 +0000)
committernicm <nicm@openbsd.org>
Tue, 27 Aug 2024 07:49:07 +0000 (07:49 +0000)
get the hyperlink under the cursor.

usr.bin/tmux/hyperlinks.c
usr.bin/tmux/tmux.1
usr.bin/tmux/tmux.h
usr.bin/tmux/window-copy.c

index ea0e7db..4f3ed73 100644 (file)
@@ -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 <author@will.party>
@@ -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);
+       }
 }
index eea5747..9165234 100644 (file)
@@ -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 <nicholas.marriott@gmail.com>
 .\"
@@ -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"
index f8e7c52..99f5343 100644 (file)
@@ -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 <nicholas.marriott@gmail.com>
@@ -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 *);
 
index 697b7b5..eb83094 100644 (file)
@@ -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 <nicholas.marriott@gmail.com>
@@ -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);