fix(tui): forward OSC 8 hyperlinks under tmux when the client supports them
detectCapabilities previously disabled hyperlinks under tmux unconditionally. tmux re-emits OSC 8 to the outer terminal only when the attached client advertises the 'hyperlinks' feature in client_termfeatures, and strips them otherwise.
Probe the running server with 'tmux display-message -p #{client_termfeatures}' and enable hyperlinks only when the feature is listed. The probe fails closed: any error (no tmux/server, timeout, old tmux) yields false. images stays null; only the hyperlink decision changed. The probe is injected into detectCapabilities so it stays testable without spawning a process.
This commit is contained in:
@@ -207,19 +207,30 @@ describe("detectCapabilities", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("forces hyperlinks: false under tmux even if outer terminal supports OSC 8", () => {
|
||||
it("enables hyperlinks under tmux when the client forwards them", () => {
|
||||
withEnv({ TMUX: "/tmp/tmux-1000/default,1234,0", TERM_PROGRAM: "ghostty" }, () => {
|
||||
const caps = detectCapabilities();
|
||||
const caps = detectCapabilities(() => true);
|
||||
assert.strictEqual(caps.hyperlinks, true);
|
||||
assert.strictEqual(caps.images, null);
|
||||
});
|
||||
});
|
||||
|
||||
it("disables hyperlinks under tmux when the client does not forward them", () => {
|
||||
withEnv({ TMUX: "/tmp/tmux-1000/default,1234,0", TERM_PROGRAM: "ghostty" }, () => {
|
||||
const caps = detectCapabilities(() => false);
|
||||
assert.strictEqual(caps.hyperlinks, false);
|
||||
assert.strictEqual(caps.images, null);
|
||||
});
|
||||
});
|
||||
|
||||
it("forces hyperlinks: false when TERM starts with 'tmux'", () => {
|
||||
it("checks tmux capability when TERM starts with 'tmux'", () => {
|
||||
withEnv({ TERM: "tmux-256color", TERM_PROGRAM: "iterm.app" }, () => {
|
||||
const caps = detectCapabilities();
|
||||
assert.strictEqual(caps.hyperlinks, false);
|
||||
const caps = detectCapabilities(() => true);
|
||||
assert.strictEqual(caps.hyperlinks, true);
|
||||
assert.strictEqual(caps.images, null);
|
||||
|
||||
const caps2 = detectCapabilities(() => false);
|
||||
assert.strictEqual(caps2.hyperlinks, false);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -294,7 +305,7 @@ describe("detectCapabilities", () => {
|
||||
|
||||
it("does not inherit Windows Terminal truecolor through tmux", () => {
|
||||
withEnv({ WT_SESSION: "session", TMUX: "/tmp/tmux-1000/default,1234,0", TERM: "tmux-256color" }, () => {
|
||||
const caps = detectCapabilities();
|
||||
const caps = detectCapabilities(() => false);
|
||||
assert.strictEqual(caps.trueColor, false);
|
||||
assert.strictEqual(caps.hyperlinks, false);
|
||||
assert.strictEqual(caps.images, null);
|
||||
@@ -303,7 +314,7 @@ describe("detectCapabilities", () => {
|
||||
|
||||
it("trusts explicit truecolor hints through tmux", () => {
|
||||
withEnv({ COLORTERM: "truecolor", TMUX: "/tmp/tmux-1000/default,1234,0", TERM: "tmux-256color" }, () => {
|
||||
const caps = detectCapabilities();
|
||||
const caps = detectCapabilities(() => false);
|
||||
assert.strictEqual(caps.trueColor, true);
|
||||
assert.strictEqual(caps.hyperlinks, false);
|
||||
assert.strictEqual(caps.images, null);
|
||||
|
||||
Reference in New Issue
Block a user