diff --git a/src/Surface.zig b/src/Surface.zig index d9d6a3012..9cc846865 100644 --- a/src/Surface.zig +++ b/src/Surface.zig @@ -270,6 +270,7 @@ const DerivedConfig = struct { title: ?[:0]const u8, title_report: bool, links: []Link, + link_previews: configpkg.LinkPreviews, const Link = struct { regex: oni.Regex, @@ -336,6 +337,7 @@ const DerivedConfig = struct { .title = config.title, .title_report = config.@"title-report", .links = links, + .link_previews = config.@"link-previews", // Assignments happen sequentially so we have to do this last // so that the memory is captured from allocs above. @@ -1242,7 +1244,7 @@ fn mouseRefreshLinks( // Get our link at the current position. This returns null if there // isn't a link OR if we shouldn't be showing links for some reason // (see further comments for cases). - const link_: ?apprt.action.MouseOverLink = link: { + const link_: ?apprt.action.MouseOverLink, const preview: bool = link: { // If we clicked and our mouse moved cells then we never // highlight links until the mouse is unclicked. This follows // standard macOS and Linux behavior where a click and drag cancels @@ -1257,18 +1259,21 @@ fn mouseRefreshLinks( if (!click_pt.coord().eql(pos_vp)) { log.debug("mouse moved while left click held, ignoring link hover", .{}); - break :link null; + break :link .{ null, false }; } } - const link = (try self.linkAtPos(pos)) orelse break :link null; + const link = (try self.linkAtPos(pos)) orelse break :link .{ null, false }; switch (link[0]) { .open => { const str = try self.io.terminal.screen.selectionString(alloc, .{ .sel = link[1], .trim = false, }); - break :link .{ .url = str }; + break :link .{ + .{ .url = str }, + self.config.link_previews == .true, + }; }, ._open_osc8 => { @@ -1276,9 +1281,14 @@ fn mouseRefreshLinks( const pin = link[1].start(); const uri = self.osc8URI(pin) orelse { log.warn("failed to get URI for OSC8 hyperlink", .{}); - break :link null; + break :link .{ null, false }; + }; + break :link .{ + .{ + .url = uri, + }, + self.config.link_previews != .false, }; - break :link .{ .url = uri }; }, } }; @@ -1294,11 +1304,15 @@ fn mouseRefreshLinks( .mouse_shape, .pointer, ); - _ = try self.rt_app.performAction( - .{ .surface = self }, - .mouse_over_link, - link, - ); + + if (preview) { + _ = try self.rt_app.performAction( + .{ .surface = self }, + .mouse_over_link, + link, + ); + } + try self.queueRender(); return; } diff --git a/src/config.zig b/src/config.zig index ac38eb89c..b6fecde4e 100644 --- a/src/config.zig +++ b/src/config.zig @@ -37,6 +37,7 @@ pub const ShellIntegrationFeatures = Config.ShellIntegrationFeatures; pub const WindowPaddingColor = Config.WindowPaddingColor; pub const BackgroundImagePosition = Config.BackgroundImagePosition; pub const BackgroundImageFit = Config.BackgroundImageFit; +pub const LinkPreviews = Config.LinkPreviews; // Alternate APIs pub const CAPI = @import("config/CAPI.zig"); diff --git a/src/config/Config.zig b/src/config/Config.zig index be76820d2..f9454bf98 100644 --- a/src/config/Config.zig +++ b/src/config/Config.zig @@ -1046,6 +1046,14 @@ link: RepeatableLink = .{}, /// `link`). If you want to customize URL matching, use `link` and disable this. @"link-url": bool = true, +/// Show link previews for a matched URL. +/// +/// When true, link previews are shown for all matched URLs. When false, link +/// previews are never shown. When set to "osc8", link previews are only shown +/// for hyperlinks created with the OSC 8 sequence (in this case, the link text +/// can differ from the link destination). +@"link-previews": LinkPreviews = .true, + /// Whether to start the window in a maximized state. This setting applies /// to new windows and does not apply to tabs, splits, etc. However, this setting /// will apply to all new windows, not just the first one. @@ -4326,6 +4334,12 @@ pub const WindowSubtitle = enum { @"working-directory", }; +pub const LinkPreviews = enum { + false, + true, + osc8, +}; + /// Color represents a color using RGB. /// /// This is a packed struct so that the C API to read color values just