aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGregory Anders <8965202+gpanders@users.noreply.github.com>2024-07-24 09:04:09 -0500
committerGitHub <noreply@github.com>2024-07-24 09:04:09 -0500
commitb02c83941493db79e4ab7ba23adb665d4528f791 (patch)
treece24a95528e76695a6ee4abaf2c53b54ce13344c
parent862338255da6dc08ae4f4f78db0034c81e3cdf38 (diff)
downloadrneovim-b02c83941493db79e4ab7ba23adb665d4528f791.tar.gz
rneovim-b02c83941493db79e4ab7ba23adb665d4528f791.tar.bz2
rneovim-b02c83941493db79e4ab7ba23adb665d4528f791.zip
fix(tui): set id parameter in OSC 8 sequences (#29840)
The id parameter is used to communicate to the terminal that two URLs are the same. Without an id, the terminal must rely on heuristics to determine which cells belong together to make a single hyperlink. See the relevant section in the spec [1] for more details. [1]: https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda#hover-underlining-and-the-id-parameter
-rw-r--r--src/nvim/tui/tui.c7
-rw-r--r--test/functional/terminal/tui_spec.lua8
2 files changed, 10 insertions, 5 deletions
diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c
index c7ec013b28..0adf0712c0 100644
--- a/src/nvim/tui/tui.c
+++ b/src/nvim/tui/tui.c
@@ -793,7 +793,12 @@ static void update_attrs(TUIData *tui, int attr_id)
if (attrs.url >= 0) {
const char *url = urls.keys[attrs.url];
kv_size(tui->urlbuf) = 0;
- kv_printf(tui->urlbuf, "\x1b]8;;%s\x1b\\", url);
+
+ // Add some fixed offset to the URL ID to deconflict with other
+ // applications which may set their own IDs
+ const uint64_t id = 0xE1EA0000U + (uint32_t)attrs.url;
+
+ kv_printf(tui->urlbuf, "\x1b]8;id=%" PRIu64 ";%s\x1b\\", id, url);
out(tui, tui->urlbuf.items, kv_size(tui->urlbuf));
} else {
out(tui, S_LEN("\x1b]8;;\x1b\\"));
diff --git a/test/functional/terminal/tui_spec.lua b/test/functional/terminal/tui_spec.lua
index 3e0b907ea2..50199bd83d 100644
--- a/test/functional/terminal/tui_spec.lua
+++ b/test/functional/terminal/tui_spec.lua
@@ -1968,9 +1968,9 @@ describe('TUI', function()
if not req then
return
end
- local url = req:match('\027]8;;(.*)$')
- if url ~= nil then
- table.insert(_G.urls, url)
+ local id, url = req:match('\027]8;id=(%d+);(.*)$')
+ if id ~= nil and url ~= nil then
+ table.insert(_G.urls, { id = tonumber(id), url = url })
end
end,
})
@@ -1984,7 +1984,7 @@ describe('TUI', function()
})
]])
retry(nil, 1000, function()
- eq({ 'https://example.com', '' }, exec_lua([[return _G.urls]]))
+ eq({ { id = 0xE1EA0000, url = 'https://example.com' } }, exec_lua([[return _G.urls]]))
end)
end)
end)