Skip to content

Commit 33e1270

Browse files
committed
Add Ghostty terminal hyperlink support
1 parent 28ae207 commit 33e1270

File tree

5 files changed

+131
-0
lines changed

5 files changed

+131
-0
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Change log
22

3+
## Unreleased
4+
5+
* Add hyperlinks support detection in Ghostty Terminal
6+
37
## [v0.2.0] - 2024-11-03
48

59
### Added

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,7 @@ The **TTY::Link** supports hyperlink generation in the following terminals:
279279
* `Contour`
280280
* `DomTerm`
281281
* `foot`
282+
* `Ghostty`
282283
* `Hyper`
283284
* `iTerm2`
284285
* `JediTerm`

lib/tty/link/terminals/ghostty.rb

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# frozen_string_literal: true
2+
3+
require_relative "abstract"
4+
5+
module TTY
6+
class Link
7+
module Terminals
8+
# Responsible for detecting hyperlink support in the Ghostty terminal
9+
#
10+
# @api private
11+
class Ghostty < Abstract
12+
# The Ghostty terminal name pattern
13+
#
14+
# @return [Regexp]
15+
#
16+
# @api private
17+
GHOSTTY = /ghostty/i.freeze
18+
private_constant :GHOSTTY
19+
20+
private
21+
22+
# Detect Ghostty terminal
23+
#
24+
# @example
25+
# ghostty.name?
26+
# # => true
27+
#
28+
# @return [Boolean]
29+
#
30+
# @api private
31+
def name?
32+
!(term_program =~ GHOSTTY).nil?
33+
end
34+
35+
# Detect any Ghostty terminal version to support terminal hyperlinks
36+
#
37+
# @example
38+
# ghostty.version?
39+
# # => true
40+
#
41+
# @return [Boolean]
42+
#
43+
# @api private
44+
def version?
45+
true
46+
end
47+
end # Ghostty
48+
end # Terminals
49+
end # Link
50+
end # TTY

spec/unit/link_spec.rb

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,15 @@
8484
end
8585
end
8686

87+
context "when Ghostty" do
88+
it "supports links on any version" do
89+
env = {"TERM_PROGRAM" => "ghostty"}
90+
link = described_class.new(env: env, output: output)
91+
92+
expect(link.link?).to eq(true)
93+
end
94+
end
95+
8796
context "when Hyper" do
8897
it "supports links above the 2.0.0 version" do
8998
env = {
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
# frozen_string_literal: true
2+
3+
RSpec.describe TTY::Link::Terminals::Ghostty, "#link?" do
4+
let(:env_with_name) { {"TERM_PROGRAM" => "ghostty"} }
5+
let(:semantic_version) { TTY::Link::SemanticVersion }
6+
7+
it "doesn't support links without the term program environment variable" do
8+
ghostty = described_class.new(semantic_version, {})
9+
10+
expect(ghostty.link?).to eq(false)
11+
end
12+
13+
it "doesn't support links without a terminal program name" do
14+
env = {"TERM_PROGRAM" => nil}
15+
ghostty = described_class.new(semantic_version, env)
16+
17+
expect(ghostty.link?).to eq(false)
18+
end
19+
20+
it "doesn't support links with a non-Ghostty program name" do
21+
env = {"TERM_PROGRAM" => "other-terminal"}
22+
ghostty = described_class.new(semantic_version, env)
23+
24+
expect(ghostty.link?).to eq(false)
25+
end
26+
27+
it "supports links with the Ghostty program name" do
28+
env = {"TERM_PROGRAM" => "ghostty"}
29+
ghostty = described_class.new(semantic_version, env)
30+
31+
expect(ghostty.link?).to eq(true)
32+
end
33+
34+
it "supports links with the Ghostty program name in uppercase" do
35+
env = {"TERM_PROGRAM" => "GHOSTTY"}
36+
ghostty = described_class.new(semantic_version, env)
37+
38+
expect(ghostty.link?).to eq(true)
39+
end
40+
41+
it "supports links with the Ghostty program name in mixed case" do
42+
env = {"TERM_PROGRAM" => "Ghostty"}
43+
ghostty = described_class.new(semantic_version, env)
44+
45+
expect(ghostty.link?).to eq(true)
46+
end
47+
48+
it "supports links without a version" do
49+
env = env_with_name.merge({"TERM_PROGRAM_VERSION" => nil})
50+
ghostty = described_class.new(semantic_version, env)
51+
52+
expect(ghostty.link?).to eq(true)
53+
end
54+
55+
it "supports links without the term program version env variable" do
56+
ghostty = described_class.new(semantic_version, env_with_name)
57+
58+
expect(ghostty.link?).to eq(true)
59+
end
60+
61+
it "supports links with any version" do
62+
env = env_with_name.merge({"TERM_PROGRAM_VERSION" => "1.0.0"})
63+
ghostty = described_class.new(semantic_version, env)
64+
65+
expect(ghostty.link?).to eq(true)
66+
end
67+
end

0 commit comments

Comments
 (0)