tty-link 0.1.1 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +24 -0
- data/LICENSE.txt +1 -1
- data/README.md +279 -28
- data/lib/tty/link/ansi_link.rb +105 -0
- data/lib/tty/link/errors.rb +77 -0
- data/lib/tty/link/hyperlink_parameter.rb +95 -0
- data/lib/tty/link/plain_link.rb +52 -0
- data/lib/tty/link/semantic_version.rb +204 -0
- data/lib/tty/link/terminals/abstract.rb +189 -0
- data/lib/tty/link/terminals/alacritty.rb +50 -0
- data/lib/tty/link/terminals/contour.rb +96 -0
- data/lib/tty/link/terminals/domterm.rb +107 -0
- data/lib/tty/link/terminals/foot.rb +50 -0
- data/lib/tty/link/terminals/hyper.rb +54 -0
- data/lib/tty/link/terminals/iterm.rb +54 -0
- data/lib/tty/link/terminals/jediterm.rb +71 -0
- data/lib/tty/link/terminals/kitty.rb +48 -0
- data/lib/tty/link/terminals/konsole.rb +65 -0
- data/lib/tty/link/terminals/mintty.rb +54 -0
- data/lib/tty/link/terminals/rio.rb +54 -0
- data/lib/tty/link/terminals/tabby.rb +50 -0
- data/lib/tty/link/terminals/terminology.rb +54 -0
- data/lib/tty/link/terminals/vscode.rb +54 -0
- data/lib/tty/link/terminals/vte.rb +65 -0
- data/lib/tty/link/terminals/wezterm.rb +71 -0
- data/lib/tty/link/terminals/wt.rb +63 -0
- data/lib/tty/link/terminals.rb +71 -0
- data/lib/tty/link/version.rb +2 -2
- data/lib/tty/link.rb +279 -40
- data/lib/tty-link.rb +2 -0
- metadata +39 -26
@@ -0,0 +1,52 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module TTY
|
4
|
+
class Link
|
5
|
+
# Responsible for converting a URL to a plain terminal link
|
6
|
+
#
|
7
|
+
# @api private
|
8
|
+
class PlainLink
|
9
|
+
# The replacement tokens pattern
|
10
|
+
#
|
11
|
+
# @return [Regexp]
|
12
|
+
#
|
13
|
+
# @api private
|
14
|
+
REPLACEMENT_TOKENS_PATTERN = /:(name|url)/i.freeze
|
15
|
+
private_constant :REPLACEMENT_TOKENS_PATTERN
|
16
|
+
|
17
|
+
# Create a {TTY::Link::PlainLink} instance
|
18
|
+
#
|
19
|
+
# @example
|
20
|
+
# plain_link = TTY::Link::PlainLink.new(
|
21
|
+
# "TTY Toolkit", "https://ttytoolkit.org", ":name (:url)")
|
22
|
+
#
|
23
|
+
# @param [String] name
|
24
|
+
# the URL name
|
25
|
+
# @param [String] url
|
26
|
+
# the URL target
|
27
|
+
# @param [String] template
|
28
|
+
# the URL replacement template
|
29
|
+
#
|
30
|
+
# @api public
|
31
|
+
def initialize(name, url, template)
|
32
|
+
@name = name
|
33
|
+
@url = url
|
34
|
+
@template = template
|
35
|
+
end
|
36
|
+
|
37
|
+
# Convert this link to a plain string
|
38
|
+
#
|
39
|
+
# @example
|
40
|
+
# plain_link.to_s
|
41
|
+
# # => "TTY Toolkit (https://ttytoolkit.org)"
|
42
|
+
#
|
43
|
+
# @return [String]
|
44
|
+
#
|
45
|
+
# @api public
|
46
|
+
def to_s
|
47
|
+
replacements = {":name" => @name, ":url" => @url}
|
48
|
+
@template.gsub(REPLACEMENT_TOKENS_PATTERN, replacements)
|
49
|
+
end
|
50
|
+
end # PlainLink
|
51
|
+
end # Link
|
52
|
+
end # TTY
|
@@ -0,0 +1,204 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module TTY
|
4
|
+
class Link
|
5
|
+
# Responsible for comparing terminal release versions
|
6
|
+
#
|
7
|
+
# @api private
|
8
|
+
class SemanticVersion
|
9
|
+
include Comparable
|
10
|
+
|
11
|
+
# The unseparated version pattern
|
12
|
+
#
|
13
|
+
# @return [Regexp]
|
14
|
+
#
|
15
|
+
# @api private
|
16
|
+
UNSEPARATED_VERSION_PATTERN = /^(\d{1,2})(\d{2})$/.freeze
|
17
|
+
private_constant :UNSEPARATED_VERSION_PATTERN
|
18
|
+
|
19
|
+
# The version separator
|
20
|
+
#
|
21
|
+
# @return [String]
|
22
|
+
#
|
23
|
+
# @api private
|
24
|
+
VERSION_SEPARATOR = "."
|
25
|
+
private_constant :VERSION_SEPARATOR
|
26
|
+
|
27
|
+
# The zero number
|
28
|
+
#
|
29
|
+
# @return [String]
|
30
|
+
#
|
31
|
+
# @api private
|
32
|
+
ZERO_NUMBER = "0"
|
33
|
+
private_constant :ZERO_NUMBER
|
34
|
+
|
35
|
+
# Create a {TTY::Link::SemanticVersion} instance from a version value
|
36
|
+
#
|
37
|
+
# @example
|
38
|
+
# TTY::Link::SemanticVersion.from(1, 2, 3)
|
39
|
+
#
|
40
|
+
# @example
|
41
|
+
# TTY::Link::SemanticVersion[1, 2, 3]
|
42
|
+
#
|
43
|
+
# @example
|
44
|
+
# TTY::Link::SemanticVersion.from("1234")
|
45
|
+
#
|
46
|
+
# @example
|
47
|
+
# TTY::Link::SemanticVersion.from("1.2.3")
|
48
|
+
#
|
49
|
+
# @example
|
50
|
+
# TTY::Link::SemanticVersion.from("1-2-3", separator: "-")
|
51
|
+
#
|
52
|
+
# @param [Array<Integer, String>] version
|
53
|
+
# the version to convert to a semantic version
|
54
|
+
# @param [String] separator
|
55
|
+
# the version separator
|
56
|
+
#
|
57
|
+
# @return [TTY::Link::SemanticVersion]
|
58
|
+
#
|
59
|
+
# @api public
|
60
|
+
def self.from(*version, separator: VERSION_SEPARATOR)
|
61
|
+
major, minor, patch =
|
62
|
+
if version.size == 1 && version[0].respond_to?(:split)
|
63
|
+
convert_to_array(version[0], separator: separator)
|
64
|
+
else
|
65
|
+
version
|
66
|
+
end
|
67
|
+
new(major.to_i, minor.to_i, patch.to_i)
|
68
|
+
end
|
69
|
+
singleton_class.send(:alias_method, :[], :from)
|
70
|
+
|
71
|
+
# Convert a string version to an array
|
72
|
+
#
|
73
|
+
# @example
|
74
|
+
# TTY::Link::SemanticVersion.from("1234")
|
75
|
+
# # => ["0", "12", "34"]
|
76
|
+
#
|
77
|
+
# @example
|
78
|
+
# TTY::Link::SemanticVersion.convert_to_array("1.2.3")
|
79
|
+
# # => ["1", "2", "3"]
|
80
|
+
#
|
81
|
+
# @example
|
82
|
+
# TTY::Link::SemanticVersion.convert_to_array("1-2-3", separator: "-")
|
83
|
+
# # => ["1", "2", "3"]
|
84
|
+
#
|
85
|
+
# @param [String] version
|
86
|
+
# the version to convert to an array
|
87
|
+
# @param [String] separator
|
88
|
+
# the version separator
|
89
|
+
#
|
90
|
+
# @return [Array<String>]
|
91
|
+
#
|
92
|
+
# @api private
|
93
|
+
def self.convert_to_array(version, separator: VERSION_SEPARATOR)
|
94
|
+
if (matches = version.match(UNSEPARATED_VERSION_PATTERN))
|
95
|
+
[ZERO_NUMBER, matches[1], matches[2]]
|
96
|
+
else
|
97
|
+
version.split(separator)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
private_class_method :convert_to_array
|
101
|
+
|
102
|
+
# The major number
|
103
|
+
#
|
104
|
+
# @example
|
105
|
+
# semantic_version.major
|
106
|
+
#
|
107
|
+
# @return [Integer]
|
108
|
+
#
|
109
|
+
# @api public
|
110
|
+
attr_reader :major
|
111
|
+
|
112
|
+
# The minor number
|
113
|
+
#
|
114
|
+
# @example
|
115
|
+
# semantic_version.minor
|
116
|
+
#
|
117
|
+
# @return [Integer]
|
118
|
+
#
|
119
|
+
# @api public
|
120
|
+
attr_reader :minor
|
121
|
+
|
122
|
+
# The patch number
|
123
|
+
#
|
124
|
+
# @example
|
125
|
+
# semantic_version.patch
|
126
|
+
#
|
127
|
+
# @return [Integer]
|
128
|
+
#
|
129
|
+
# @api public
|
130
|
+
attr_reader :patch
|
131
|
+
|
132
|
+
# Create a {TTY::Link::SemanticVersion} instance
|
133
|
+
#
|
134
|
+
# @example
|
135
|
+
# TTY::Link::SemanticVersion.new(1, 2, 3)
|
136
|
+
#
|
137
|
+
# @param [Integer] major
|
138
|
+
# the major number
|
139
|
+
# @param [Integer] minor
|
140
|
+
# the minor number
|
141
|
+
# @param [Integer] patch
|
142
|
+
# the patch number
|
143
|
+
#
|
144
|
+
# @api private
|
145
|
+
def initialize(major, minor, patch)
|
146
|
+
@major = major
|
147
|
+
@minor = minor
|
148
|
+
@patch = patch
|
149
|
+
end
|
150
|
+
private_class_method :new
|
151
|
+
|
152
|
+
# Compare this semantic version with another object
|
153
|
+
#
|
154
|
+
# @example
|
155
|
+
# semantic_version >= other
|
156
|
+
#
|
157
|
+
# @param [Object] other
|
158
|
+
# the other object to compare with
|
159
|
+
#
|
160
|
+
# @return [Integer, nil]
|
161
|
+
# Return negative, zero, or positive number when
|
162
|
+
# this semantic version is less than, equal to, or
|
163
|
+
# greater than other semantic version. Return nil
|
164
|
+
# when the other object is not a semantic version.
|
165
|
+
#
|
166
|
+
# @api public
|
167
|
+
def <=>(other)
|
168
|
+
return unless other.is_a?(self.class)
|
169
|
+
|
170
|
+
major_comparison = @major <=> other.major
|
171
|
+
return major_comparison unless major_comparison.zero?
|
172
|
+
|
173
|
+
minor_comparison = @minor <=> other.minor
|
174
|
+
return minor_comparison unless minor_comparison.zero?
|
175
|
+
|
176
|
+
@patch <=> other.patch
|
177
|
+
end
|
178
|
+
|
179
|
+
# Generate hash value for this semantic version
|
180
|
+
#
|
181
|
+
# @example
|
182
|
+
# semantic_version.hash
|
183
|
+
#
|
184
|
+
# @return [Integer]
|
185
|
+
#
|
186
|
+
# @api public
|
187
|
+
def hash
|
188
|
+
[self.class, @major, @minor, @patch].hash
|
189
|
+
end
|
190
|
+
|
191
|
+
# Convert this semantic version to a string
|
192
|
+
#
|
193
|
+
# @example
|
194
|
+
# semantic_version.inspect
|
195
|
+
#
|
196
|
+
# @return [String]
|
197
|
+
#
|
198
|
+
# @api public
|
199
|
+
def inspect
|
200
|
+
[@major, @minor, @patch].join(VERSION_SEPARATOR)
|
201
|
+
end
|
202
|
+
end # SemanticVersion
|
203
|
+
end # Link
|
204
|
+
end # TTY
|
@@ -0,0 +1,189 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "../errors"
|
4
|
+
|
5
|
+
module TTY
|
6
|
+
class Link
|
7
|
+
module Terminals
|
8
|
+
# Responsible for providing common terminal detection
|
9
|
+
#
|
10
|
+
# @abstract Override {#name?} and {#version?} to implement
|
11
|
+
# terminal hyperlinks detection
|
12
|
+
#
|
13
|
+
# @api private
|
14
|
+
class Abstract
|
15
|
+
# The term environment variable name
|
16
|
+
#
|
17
|
+
# @return [String]
|
18
|
+
#
|
19
|
+
# @api private
|
20
|
+
TERM = "TERM"
|
21
|
+
private_constant :TERM
|
22
|
+
|
23
|
+
# The term program environment variable name
|
24
|
+
#
|
25
|
+
# @return [String]
|
26
|
+
#
|
27
|
+
# @api private
|
28
|
+
TERM_PROGRAM = "TERM_PROGRAM"
|
29
|
+
private_constant :TERM_PROGRAM
|
30
|
+
|
31
|
+
# The term program version environment variable name
|
32
|
+
#
|
33
|
+
# @return [String]
|
34
|
+
#
|
35
|
+
# @api private
|
36
|
+
TERM_PROGRAM_VERSION = "TERM_PROGRAM_VERSION"
|
37
|
+
private_constant :TERM_PROGRAM_VERSION
|
38
|
+
|
39
|
+
# Register a terminal class with terminals
|
40
|
+
#
|
41
|
+
# @param [TTY::Link::Terminal::Abstract] terminal_class
|
42
|
+
# the terminal class to register
|
43
|
+
#
|
44
|
+
# @return [void]
|
45
|
+
#
|
46
|
+
# @api private
|
47
|
+
def self.inherited(terminal_class)
|
48
|
+
super
|
49
|
+
Terminals.register(terminal_class)
|
50
|
+
end
|
51
|
+
private_class_method :inherited
|
52
|
+
|
53
|
+
# Create an {TTY::Link::Terminals::Abstract} instance
|
54
|
+
#
|
55
|
+
# @example
|
56
|
+
# terminal = TTY::Link::Terminals::Abstract.new(SemanticVersion, ENV)
|
57
|
+
#
|
58
|
+
# @param [TTY::Link::SemanticVersion] semantic_version
|
59
|
+
# the semantic version creator
|
60
|
+
# @param [ENV, Hash{String => String}] env
|
61
|
+
# the environment variables
|
62
|
+
#
|
63
|
+
# @api public
|
64
|
+
def initialize(semantic_version, env)
|
65
|
+
@semantic_version = semantic_version
|
66
|
+
@env = env
|
67
|
+
end
|
68
|
+
|
69
|
+
# Detect a terminal hyperlink support
|
70
|
+
#
|
71
|
+
# @example
|
72
|
+
# terminal.link?
|
73
|
+
# # => true
|
74
|
+
#
|
75
|
+
# @return [Boolean]
|
76
|
+
#
|
77
|
+
# @api public
|
78
|
+
def link?
|
79
|
+
name? && version?
|
80
|
+
end
|
81
|
+
|
82
|
+
protected
|
83
|
+
|
84
|
+
# Detect a terminal name
|
85
|
+
#
|
86
|
+
# @example
|
87
|
+
# terminal.name?
|
88
|
+
#
|
89
|
+
# @raise [TTY::Link::AbstractMethodError]
|
90
|
+
# the class doesn't implement the name? method
|
91
|
+
#
|
92
|
+
# @abstract
|
93
|
+
#
|
94
|
+
# @api private
|
95
|
+
def name?
|
96
|
+
raise AbstractMethodError.new(self.class.name, __method__)
|
97
|
+
end
|
98
|
+
|
99
|
+
# Detect whether a terminal version supports terminal hyperlinks
|
100
|
+
#
|
101
|
+
# @example
|
102
|
+
# terminal.version?
|
103
|
+
#
|
104
|
+
# @raise [TTY::Link::AbstractMethodError]
|
105
|
+
# the class doesn't implement the version? method
|
106
|
+
#
|
107
|
+
# @abstract
|
108
|
+
#
|
109
|
+
# @api private
|
110
|
+
def version?
|
111
|
+
raise AbstractMethodError.new(self.class.name, __method__)
|
112
|
+
end
|
113
|
+
|
114
|
+
# The environment variables
|
115
|
+
#
|
116
|
+
# @example
|
117
|
+
# terminal.env
|
118
|
+
#
|
119
|
+
# @return [ENV, Hash{String => String}]
|
120
|
+
#
|
121
|
+
# @api private
|
122
|
+
attr_reader :env
|
123
|
+
|
124
|
+
# Create a {TTY::Link::SemanticVersion} instance from a version value
|
125
|
+
#
|
126
|
+
# @example
|
127
|
+
# terminal.semantic_version(1, 2, 3)
|
128
|
+
#
|
129
|
+
# @example
|
130
|
+
# terminal.semantic_version("1.2.3")
|
131
|
+
#
|
132
|
+
# @param [Array<Integer, String>] version
|
133
|
+
# the version to convert to a semantic version
|
134
|
+
# @param [Hash{Symbol => String}] options
|
135
|
+
# the options to convert to a semantic version
|
136
|
+
# @option options [String] :separator
|
137
|
+
# the version separator
|
138
|
+
#
|
139
|
+
# @return [TTY::Link::SemanticVersion]
|
140
|
+
#
|
141
|
+
# @see SemanticVersion#from
|
142
|
+
#
|
143
|
+
# @api private
|
144
|
+
def semantic_version(*version, **options)
|
145
|
+
@semantic_version.from(*version, **options)
|
146
|
+
end
|
147
|
+
|
148
|
+
# Read the term environment variable
|
149
|
+
#
|
150
|
+
# @example
|
151
|
+
# terminal.term
|
152
|
+
# # => "alacritty"
|
153
|
+
#
|
154
|
+
# @return [String, nil]
|
155
|
+
#
|
156
|
+
# @api private
|
157
|
+
def term
|
158
|
+
env[TERM]
|
159
|
+
end
|
160
|
+
|
161
|
+
# Read the term program environment variable
|
162
|
+
#
|
163
|
+
# @example
|
164
|
+
# terminal.term_program
|
165
|
+
# # => "iTerm.app"
|
166
|
+
#
|
167
|
+
# @return [String, nil]
|
168
|
+
#
|
169
|
+
# @api private
|
170
|
+
def term_program
|
171
|
+
env[TERM_PROGRAM]
|
172
|
+
end
|
173
|
+
|
174
|
+
# Read the term program version environment variable
|
175
|
+
#
|
176
|
+
# @example
|
177
|
+
# terminal.term_program_version
|
178
|
+
# # => "1.2.3"
|
179
|
+
#
|
180
|
+
# @return [String, nil]
|
181
|
+
#
|
182
|
+
# @api private
|
183
|
+
def term_program_version
|
184
|
+
env[TERM_PROGRAM_VERSION]
|
185
|
+
end
|
186
|
+
end # Abstract
|
187
|
+
end # Terminals
|
188
|
+
end # Link
|
189
|
+
end # TTY
|
@@ -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 Alacritty terminal
|
9
|
+
#
|
10
|
+
# @api private
|
11
|
+
class Alacritty < Abstract
|
12
|
+
# The Alacritty terminal name pattern
|
13
|
+
#
|
14
|
+
# @return [Regexp]
|
15
|
+
#
|
16
|
+
# @api private
|
17
|
+
ALACRITTY = /alacritty/i.freeze
|
18
|
+
private_constant :ALACRITTY
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
# Detect Alacritty terminal
|
23
|
+
#
|
24
|
+
# @example
|
25
|
+
# alacritty.name?
|
26
|
+
# # => true
|
27
|
+
#
|
28
|
+
# @return [Boolean]
|
29
|
+
#
|
30
|
+
# @api private
|
31
|
+
def name?
|
32
|
+
!(term =~ ALACRITTY).nil?
|
33
|
+
end
|
34
|
+
|
35
|
+
# Detect any Alacritty version to support terminal hyperlinks
|
36
|
+
#
|
37
|
+
# @example
|
38
|
+
# alacritty.version?
|
39
|
+
# # => true
|
40
|
+
#
|
41
|
+
# @return [Boolean]
|
42
|
+
#
|
43
|
+
# @api private
|
44
|
+
def version?
|
45
|
+
true
|
46
|
+
end
|
47
|
+
end # Alacritty
|
48
|
+
end # Terminals
|
49
|
+
end # Link
|
50
|
+
end # TTY
|
@@ -0,0 +1,96 @@
|
|
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 Contour terminal
|
9
|
+
#
|
10
|
+
# @api private
|
11
|
+
class Contour < Abstract
|
12
|
+
# The Contour terminal name pattern
|
13
|
+
#
|
14
|
+
# @return [Regexp]
|
15
|
+
#
|
16
|
+
# @api private
|
17
|
+
CONTOUR = /contour/i.freeze
|
18
|
+
private_constant :CONTOUR
|
19
|
+
|
20
|
+
# The terminal name environment variable name
|
21
|
+
#
|
22
|
+
# @return [String]
|
23
|
+
#
|
24
|
+
# @api private
|
25
|
+
TERMINAL_NAME = "TERMINAL_NAME"
|
26
|
+
private_constant :TERMINAL_NAME
|
27
|
+
|
28
|
+
# The terminal version triple environment variable name
|
29
|
+
#
|
30
|
+
# @return [String]
|
31
|
+
#
|
32
|
+
# @api private
|
33
|
+
TERMINAL_VERSION_TRIPLE = "TERMINAL_VERSION_TRIPLE"
|
34
|
+
private_constant :TERMINAL_VERSION_TRIPLE
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
# Detect Contour terminal
|
39
|
+
#
|
40
|
+
# @example
|
41
|
+
# contour.name?
|
42
|
+
# # => true
|
43
|
+
#
|
44
|
+
# @return [Boolean]
|
45
|
+
#
|
46
|
+
# @api private
|
47
|
+
def name?
|
48
|
+
!(terminal_name =~ CONTOUR).nil?
|
49
|
+
end
|
50
|
+
|
51
|
+
# Detect whether the Contour version supports terminal hyperlinks
|
52
|
+
#
|
53
|
+
# @example
|
54
|
+
# contour.version?
|
55
|
+
# # => true
|
56
|
+
#
|
57
|
+
# @return [Boolean]
|
58
|
+
#
|
59
|
+
# @api private
|
60
|
+
def version?
|
61
|
+
return false unless terminal_version_triple
|
62
|
+
|
63
|
+
current_semantic_version = semantic_version(terminal_version_triple)
|
64
|
+
|
65
|
+
current_semantic_version >= semantic_version(0, 1, 0)
|
66
|
+
end
|
67
|
+
|
68
|
+
# Read the terminal name environment variable
|
69
|
+
#
|
70
|
+
# @example
|
71
|
+
# contour.terminal_name
|
72
|
+
# # => "contour"
|
73
|
+
#
|
74
|
+
# @return [String, nil]
|
75
|
+
#
|
76
|
+
# @api private
|
77
|
+
def terminal_name
|
78
|
+
env[TERMINAL_NAME]
|
79
|
+
end
|
80
|
+
|
81
|
+
# Read the terminal version triple environment variable
|
82
|
+
#
|
83
|
+
# @example
|
84
|
+
# contour.terminal_version_triple
|
85
|
+
# # => "1.2.3"
|
86
|
+
#
|
87
|
+
# @return [String, nil]
|
88
|
+
#
|
89
|
+
# @api private
|
90
|
+
def terminal_version_triple
|
91
|
+
env[TERMINAL_VERSION_TRIPLE]
|
92
|
+
end
|
93
|
+
end # Contour
|
94
|
+
end # Terminals
|
95
|
+
end # Link
|
96
|
+
end # TTY
|
@@ -0,0 +1,107 @@
|
|
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 DomTerm terminal
|
9
|
+
#
|
10
|
+
# @api private
|
11
|
+
class Domterm < Abstract
|
12
|
+
# The domterm environment variable name
|
13
|
+
#
|
14
|
+
# @return [String]
|
15
|
+
#
|
16
|
+
# @api private
|
17
|
+
DOMTERM = "DOMTERM"
|
18
|
+
private_constant :DOMTERM
|
19
|
+
|
20
|
+
# The key and value separator
|
21
|
+
#
|
22
|
+
# @return [String]
|
23
|
+
#
|
24
|
+
# @api private
|
25
|
+
KEY_VAL_SEP = "="
|
26
|
+
private_constant :KEY_VAL_SEP
|
27
|
+
|
28
|
+
# The parameter separator
|
29
|
+
#
|
30
|
+
# @return [String]
|
31
|
+
#
|
32
|
+
# @api private
|
33
|
+
PARAM_SEP = ";"
|
34
|
+
private_constant :PARAM_SEP
|
35
|
+
|
36
|
+
# The version parameter pattern
|
37
|
+
#
|
38
|
+
# @return [Regexp]
|
39
|
+
#
|
40
|
+
# @api private
|
41
|
+
VERSION_PARAM = /version/i.freeze
|
42
|
+
private_constant :VERSION_PARAM
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
# Detect DomTerm terminal
|
47
|
+
#
|
48
|
+
# @example
|
49
|
+
# domterm.name?
|
50
|
+
# # => true
|
51
|
+
#
|
52
|
+
# @return [Boolean]
|
53
|
+
#
|
54
|
+
# @api private
|
55
|
+
def name?
|
56
|
+
!domterm.nil?
|
57
|
+
end
|
58
|
+
|
59
|
+
# Detect whether the DomTerm version supports terminal hyperlinks
|
60
|
+
#
|
61
|
+
# @example
|
62
|
+
# domterm.version?
|
63
|
+
# # => true
|
64
|
+
#
|
65
|
+
# @return [Boolean]
|
66
|
+
#
|
67
|
+
# @api private
|
68
|
+
def version?
|
69
|
+
return false unless domterm_version
|
70
|
+
|
71
|
+
current_semantic_version = semantic_version(domterm_version)
|
72
|
+
|
73
|
+
current_semantic_version >= semantic_version(1, 0, 2)
|
74
|
+
end
|
75
|
+
|
76
|
+
# Read the domterm environment variable
|
77
|
+
#
|
78
|
+
# @example
|
79
|
+
# domterm.domterm
|
80
|
+
# # => "version=1.2.3;tty=/dev/pts/1"
|
81
|
+
#
|
82
|
+
# @return [String, nil]
|
83
|
+
#
|
84
|
+
# @api private
|
85
|
+
def domterm
|
86
|
+
env[DOMTERM]
|
87
|
+
end
|
88
|
+
|
89
|
+
# Read the version from the domterm environment variable
|
90
|
+
#
|
91
|
+
# @example
|
92
|
+
# domterm.domterm_version
|
93
|
+
# # => "1.2.3"
|
94
|
+
#
|
95
|
+
# @return [String, nil]
|
96
|
+
#
|
97
|
+
# @api private
|
98
|
+
def domterm_version
|
99
|
+
version_pair = domterm.split(PARAM_SEP).grep(VERSION_PARAM)[0]
|
100
|
+
return unless version_pair
|
101
|
+
|
102
|
+
version_pair.split(KEY_VAL_SEP)[1]
|
103
|
+
end
|
104
|
+
end # Domterm
|
105
|
+
end # Terminals
|
106
|
+
end # Link
|
107
|
+
end # TTY
|