tty-link 0.1.1 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|