-
Notifications
You must be signed in to change notification settings - Fork 49
/
widgets.rb
96 lines (81 loc) · 2.45 KB
/
widgets.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# typed: true
require('cli/ui')
module CLI
module UI
# Widgets are formatter objects with more custom implementations than the
# other features, which all center around formatting text with colours,
# etc.
#
# If you want to extend CLI::UI with your own widgets, you may want to do
# something like this:
#
# require('cli/ui')
# class MyWidget < CLI::UI::Widgets::Base
# # ...
# end
# CLI::UI::Widgets.register('my-widget') { MyWidget }
# puts(CLI::UI.fmt("{{@widget/my-widget:args}}"))
module Widgets
extend T::Sig
MAP = {}
autoload(:Base, 'cli/ui/widgets/base')
autoload(:Status, 'cli/ui/widgets/status')
class << self
extend T::Sig
sig { params(name: String, cb: T.proc.returns(T.class_of(Widgets::Base))).void }
def register(name, &cb)
MAP[name] = cb
end
# Looks up a widget by handle
#
# ==== Raises
# Raises InvalidWidgetHandle if the widget is not available.
#
# ==== Returns
# A callable widget, to be invoked like `.call(argstring)`
#
sig { params(handle: String).returns(T.class_of(Widgets::Base)) }
def lookup(handle)
MAP.fetch(handle).call
rescue KeyError, NameError
raise(InvalidWidgetHandle, handle)
end
# All available widgets by name
#
sig { returns(T::Array[String]) }
def available
MAP.keys
end
end
register('status') { Widgets::Status }
class InvalidWidgetHandle < ArgumentError
extend T::Sig
sig { params(handle: String).void }
def initialize(handle)
super
@handle = handle
end
sig { returns(String) }
def message
keys = Widgets.available.join(',')
"invalid widget handle: #{@handle} " \
"-- must be one of CLI::UI::Widgets.available (#{keys})"
end
end
class InvalidWidgetArguments < ArgumentError
extend T::Sig
sig { params(argstring: String, pattern: Regexp).void }
def initialize(argstring, pattern)
super(nil)
@argstring = argstring
@pattern = pattern
end
sig { returns(String) }
def message
"invalid widget arguments: #{@argstring} " \
"-- must match pattern: #{@pattern.inspect}"
end
end
end
end
end