fatty 0.99.8 → 0.99.8.2
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/README.md +316 -211
- data/README.org +94 -0
- data/exe/fatty +58 -9
- data/exe/themer +273 -0
- data/lib/fatty/ansi/renderer.rb +17 -7
- data/lib/fatty/api/output.rb +4 -15
- data/lib/fatty/api/suspend.rb +9 -0
- data/lib/fatty/api.rb +1 -0
- data/lib/fatty/callback_environment.rb +1 -0
- data/lib/fatty/config_files/themes/capuchin_monk.yml +4 -8
- data/lib/fatty/config_files/themes/catppuccin_latte.yml +4 -8
- data/lib/fatty/config_files/themes/catppuccin_mocha.yml +4 -8
- data/lib/fatty/config_files/themes/cyberpunk.yml +4 -8
- data/lib/fatty/config_files/themes/dracula.yml +4 -8
- data/lib/fatty/config_files/themes/everforest_dark.yml +4 -8
- data/lib/fatty/config_files/themes/gruvbox_dark.yml +4 -8
- data/lib/fatty/config_files/themes/gruvbox_light.yml +4 -8
- data/lib/fatty/config_files/themes/mono.yml +6 -10
- data/lib/fatty/config_files/themes/monokai.yml +4 -8
- data/lib/fatty/config_files/themes/nordic.yml +16 -8
- data/lib/fatty/config_files/themes/onedark.yml +4 -8
- data/lib/fatty/config_files/themes/solarized_dark.yml +4 -8
- data/lib/fatty/config_files/themes/solarized_light.yml +4 -8
- data/lib/fatty/config_files/themes/terminal.yml +8 -12
- data/lib/fatty/config_files/themes/tokyo_night.yml +4 -8
- data/lib/fatty/config_files/themes/wordperfect.yml +1 -5
- data/lib/fatty/log_formats/json.rb +1 -1
- data/lib/fatty/log_formats/text.rb +1 -2
- data/lib/fatty/output_buffer.rb +40 -5
- data/lib/fatty/renderer/curses.rb +60 -8
- data/lib/fatty/renderer/truecolor.rb +46 -10
- data/lib/fatty/session/output_session.rb +25 -9
- data/lib/fatty/terminal.rb +12 -0
- data/lib/fatty/themes/manager.rb +12 -3
- data/lib/fatty/themes/resolver.rb +1 -1
- data/lib/fatty/version.rb +1 -1
- metadata +4 -1
data/README.org
CHANGED
|
@@ -773,6 +773,24 @@ If you want a value associated with the user's cancellation of the chooser
|
|
|
773
773
|
with C-c or C-g, set =cancel_value:= to that value.
|
|
774
774
|
|
|
775
775
|
|
|
776
|
+
*** =suspend(&block)=
|
|
777
|
+
|
|
778
|
+
The =suspend= method temporarily gives control of the terminal to the
|
|
779
|
+
application while the supplied block runs. When the block finishes, Fatty
|
|
780
|
+
restores its terminal state and redraws the interface.
|
|
781
|
+
|
|
782
|
+
This is useful for running interactive terminal programs such as editors,
|
|
783
|
+
debuggers, shells, or other programs that need direct access to the terminal.
|
|
784
|
+
|
|
785
|
+
#+begin_src ruby :tangle no
|
|
786
|
+
env.suspend do
|
|
787
|
+
system(ENV.fetch("EDITOR", "vi"), filename)
|
|
788
|
+
end
|
|
789
|
+
#+end_src
|
|
790
|
+
|
|
791
|
+
The value of the block is returned by =suspend=. Terminal state is restored
|
|
792
|
+
even if the block exits by raising an exception.
|
|
793
|
+
|
|
776
794
|
*** =environment=
|
|
777
795
|
This returns a =Hash= of runtime conditions detected by =Fatty=:
|
|
778
796
|
|
|
@@ -806,6 +824,10 @@ The environment report also includes a nested =:curses= hash:
|
|
|
806
824
|
| =:color_pairs= | Number of color pairs available to curses |
|
|
807
825
|
| =:can_change_color= | Whether curses can redefine color values |
|
|
808
826
|
|
|
827
|
+
** Terminal Methods
|
|
828
|
+
*** =Teminal#suspend(&block)=
|
|
829
|
+
Return control to the launching terminal, execute the given block, and return.
|
|
830
|
+
|
|
809
831
|
* Default Interaction
|
|
810
832
|
** Parts of the Screen
|
|
811
833
|
*** Input Field
|
|
@@ -2134,3 +2156,75 @@ Or you can group them under =markdown= without the =markdown_= prefix:
|
|
|
2134
2156
|
bg: navy
|
|
2135
2157
|
attrs: [underline]
|
|
2136
2158
|
#+end_src
|
|
2159
|
+
|
|
2160
|
+
*** The =themer= helper
|
|
2161
|
+
|
|
2162
|
+
Choosing readable colors for the semantic roles---=good=, =info=, =warn=, and
|
|
2163
|
+
=error=---is not trivial. The =themer= utility can suggest suitable foreground
|
|
2164
|
+
colors based on a theme's output background.
|
|
2165
|
+
|
|
2166
|
+
For an existing theme, =themer= also reports the contrast of the current role
|
|
2167
|
+
colors and flags those that fall below its target contrast.
|
|
2168
|
+
|
|
2169
|
+
Pass it either the name of an existing theme:
|
|
2170
|
+
|
|
2171
|
+
#+begin_src sh :tangle no
|
|
2172
|
+
themer nordic
|
|
2173
|
+
#+end_src
|
|
2174
|
+
|
|
2175
|
+
#+begin_example
|
|
2176
|
+
Theme: nordic
|
|
2177
|
+
Output background: #2e3440
|
|
2178
|
+
|
|
2179
|
+
Current semantic roles:
|
|
2180
|
+
|
|
2181
|
+
good #22ee00 contrast 7.91 OK
|
|
2182
|
+
info #33deff contrast 7.75 OK
|
|
2183
|
+
warn #d78700 contrast 4.37 LOW
|
|
2184
|
+
error #d700af contrast 2.68 LOW
|
|
2185
|
+
|
|
2186
|
+
Suggested semantic roles:
|
|
2187
|
+
|
|
2188
|
+
good #28bd41 contrast 5.02
|
|
2189
|
+
info #74abe2 contrast 5.15
|
|
2190
|
+
warn #caa22b contrast 5.18
|
|
2191
|
+
error #e78d8d contrast 5.11
|
|
2192
|
+
#+end_example
|
|
2193
|
+
|
|
2194
|
+
or a hexadecimal background color when developing a new theme:
|
|
2195
|
+
|
|
2196
|
+
#+begin_src sh :tangle no
|
|
2197
|
+
themer '#2e3440'
|
|
2198
|
+
#+end_src
|
|
2199
|
+
|
|
2200
|
+
#+begin_example
|
|
2201
|
+
Background: #2e3440
|
|
2202
|
+
Output background: #2e3440
|
|
2203
|
+
|
|
2204
|
+
Suggested semantic roles:
|
|
2205
|
+
|
|
2206
|
+
good #28bd41 contrast 5.02
|
|
2207
|
+
info #74abe2 contrast 5.15
|
|
2208
|
+
warn #caa22b contrast 5.18
|
|
2209
|
+
error #e78d8d contrast 5.11
|
|
2210
|
+
#+end_example
|
|
2211
|
+
|
|
2212
|
+
You can get the suggestions in YAML form by giving the =--yaml= flag:
|
|
2213
|
+
|
|
2214
|
+
#+begin_src sh :tangle no
|
|
2215
|
+
themer --yaml '#2e3440'
|
|
2216
|
+
#+end_src
|
|
2217
|
+
|
|
2218
|
+
#+begin_example
|
|
2219
|
+
good:
|
|
2220
|
+
fg: "#28bd41"
|
|
2221
|
+
|
|
2222
|
+
info:
|
|
2223
|
+
fg: "#74abe2"
|
|
2224
|
+
|
|
2225
|
+
warn:
|
|
2226
|
+
fg: "#caa22b"
|
|
2227
|
+
|
|
2228
|
+
error:
|
|
2229
|
+
fg: "#e78d8d"
|
|
2230
|
+
#+end_example
|
data/exe/fatty
CHANGED
|
@@ -11,6 +11,15 @@ using Fatty::CoreExt::String
|
|
|
11
11
|
|
|
12
12
|
prompt = Fatty::Prompt.new { "#{Dir.pwd}> " }
|
|
13
13
|
history_ctx_proc = -> { { pwd: Dir.pwd } }
|
|
14
|
+
append_text = lambda do |args|
|
|
15
|
+
if args.length == 1 && File.file?(File.expand_path(args.first))
|
|
16
|
+
File.read(File.expand_path(args.first))
|
|
17
|
+
elsif args.empty?
|
|
18
|
+
"Fatty output role test\n"
|
|
19
|
+
else
|
|
20
|
+
"#{args.join(' ')}\n"
|
|
21
|
+
end
|
|
22
|
+
end
|
|
14
23
|
|
|
15
24
|
on_accept_proc = lambda do |line, env|
|
|
16
25
|
cmd, *args = Shellwords.split(line)
|
|
@@ -107,17 +116,17 @@ on_accept_proc = lambda do |line, env|
|
|
|
107
116
|
"Demo menu",
|
|
108
117
|
choices: {
|
|
109
118
|
"Write to output pane" => proc { |env|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
119
|
+
env.append("menu: wrote this from MenuEnv#output\n")
|
|
120
|
+
:output_written
|
|
121
|
+
},
|
|
113
122
|
"Show status message" => proc { |env|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
123
|
+
env.status("menu: status set from MenuEnv#status")
|
|
124
|
+
:status_written
|
|
125
|
+
},
|
|
117
126
|
"Show markdown" => proc { |env|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
127
|
+
env.markdown("\# Your Choices\n\n- one\n- two\n- three\n")
|
|
128
|
+
:markdown_written
|
|
129
|
+
},
|
|
121
130
|
},
|
|
122
131
|
)
|
|
123
132
|
if result.nil?
|
|
@@ -125,6 +134,34 @@ on_accept_proc = lambda do |line, env|
|
|
|
125
134
|
else
|
|
126
135
|
env.append("menu: result #{result.inspect}\n")
|
|
127
136
|
end
|
|
137
|
+
when "append", "append_good", "append_info", "append_warn", "append_error",
|
|
138
|
+
"append_now", "append_now_good", "append_now_info", "append_now_warn", "append_now_error"
|
|
139
|
+
role =
|
|
140
|
+
case cmd
|
|
141
|
+
when /_good\z/ then :good
|
|
142
|
+
when /_info\z/ then :info
|
|
143
|
+
when /_warn\z/ then :warn
|
|
144
|
+
when /_error\z/ then :error
|
|
145
|
+
end
|
|
146
|
+
text = append_text.call(args)
|
|
147
|
+
if cmd.start_with?("append_now")
|
|
148
|
+
env.append_now(text, role: role)
|
|
149
|
+
else
|
|
150
|
+
env.append(text, role: role)
|
|
151
|
+
end
|
|
152
|
+
nil
|
|
153
|
+
when "append_roles"
|
|
154
|
+
env.append("GOOD\n", role: :good)
|
|
155
|
+
env.append("INFO\n", role: :info)
|
|
156
|
+
env.append("WARN\n", role: :warn)
|
|
157
|
+
env.append("ERROR\n", role: :error)
|
|
158
|
+
nil
|
|
159
|
+
when "append_now_roles"
|
|
160
|
+
env.append_now("GOOD\n", role: :good)
|
|
161
|
+
env.append_now("INFO\n", role: :info)
|
|
162
|
+
env.append_now("WARN\n", role: :warn)
|
|
163
|
+
env.append_now("ERROR\n", role: :error)
|
|
164
|
+
nil
|
|
128
165
|
when "info"
|
|
129
166
|
message = args.empty? ? "Information message" : args.join(" ")
|
|
130
167
|
message = message.gsub(/ ?~~ ?/, "\n")
|
|
@@ -386,6 +423,18 @@ end
|
|
|
386
423
|
cutes = cutes.compact.sort_by(&:downcase).uniq
|
|
387
424
|
|
|
388
425
|
builtins = %w[
|
|
426
|
+
append
|
|
427
|
+
append_good
|
|
428
|
+
append_info
|
|
429
|
+
append_now
|
|
430
|
+
append_now_error
|
|
431
|
+
append_now_good
|
|
432
|
+
append_now_info
|
|
433
|
+
append_now_roles
|
|
434
|
+
append_now_warn
|
|
435
|
+
append_error
|
|
436
|
+
append_roles
|
|
437
|
+
append_warn
|
|
389
438
|
cd
|
|
390
439
|
choose
|
|
391
440
|
choosevals
|
data/exe/themer
ADDED
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# -*- mode: ruby -*-
|
|
3
|
+
|
|
4
|
+
# frozen_string_literal: true
|
|
5
|
+
|
|
6
|
+
require "optparse"
|
|
7
|
+
require "fatty"
|
|
8
|
+
|
|
9
|
+
ROLE_HUES = {
|
|
10
|
+
good: 130.0,
|
|
11
|
+
info: 210.0,
|
|
12
|
+
warn: 45.0,
|
|
13
|
+
error: 0.0,
|
|
14
|
+
}.freeze
|
|
15
|
+
|
|
16
|
+
TARGET_CONTRAST = 5.0
|
|
17
|
+
|
|
18
|
+
def normalize_hex(value)
|
|
19
|
+
hex = value.to_s.delete_prefix("#")
|
|
20
|
+
raise ArgumentError, "invalid RGB color: #{value.inspect}" unless hex.match?(/\A[0-9a-fA-F]{6}\z/)
|
|
21
|
+
|
|
22
|
+
"##{hex.downcase}"
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def hex_color?(value)
|
|
26
|
+
value.to_s.match?(/\A#?[0-9a-fA-F]{6}\z/)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def hex_to_rgb(hex)
|
|
30
|
+
hex = normalize_hex(hex).delete_prefix("#")
|
|
31
|
+
[
|
|
32
|
+
hex[0, 2].to_i(16),
|
|
33
|
+
hex[2, 2].to_i(16),
|
|
34
|
+
hex[4, 2].to_i(16),
|
|
35
|
+
]
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def rgb_to_hex(rgb)
|
|
39
|
+
format("#%02x%02x%02x", *rgb)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def srgb_component(value)
|
|
43
|
+
value /= 255.0
|
|
44
|
+
|
|
45
|
+
if value <= 0.04045
|
|
46
|
+
value / 12.92
|
|
47
|
+
else
|
|
48
|
+
((value + 0.055) / 1.055)**2.4
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def luminance(rgb)
|
|
53
|
+
red, green, blue = rgb.map { |value| srgb_component(value) }
|
|
54
|
+
|
|
55
|
+
(0.2126 * red) +
|
|
56
|
+
(0.7152 * green) +
|
|
57
|
+
(0.0722 * blue)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def contrast_ratio(first, second)
|
|
61
|
+
first_luminance = luminance(first)
|
|
62
|
+
second_luminance = luminance(second)
|
|
63
|
+
|
|
64
|
+
light, dark = [first_luminance, second_luminance].max,
|
|
65
|
+
[first_luminance, second_luminance].min
|
|
66
|
+
|
|
67
|
+
(light + 0.05) / (dark + 0.05)
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def hsl_to_rgb(hue, saturation, lightness)
|
|
71
|
+
chroma = (1 - (2 * lightness - 1).abs) * saturation
|
|
72
|
+
section = hue / 60.0
|
|
73
|
+
intermediate = chroma * (1 - ((section % 2) - 1).abs)
|
|
74
|
+
|
|
75
|
+
red, green, blue =
|
|
76
|
+
case section
|
|
77
|
+
when 0...1 then [chroma, intermediate, 0]
|
|
78
|
+
when 1...2 then [intermediate, chroma, 0]
|
|
79
|
+
when 2...3 then [0, chroma, intermediate]
|
|
80
|
+
when 3...4 then [0, intermediate, chroma]
|
|
81
|
+
when 4...5 then [intermediate, 0, chroma]
|
|
82
|
+
else [chroma, 0, intermediate]
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
offset = lightness - chroma / 2
|
|
86
|
+
|
|
87
|
+
[red, green, blue].map do |value|
|
|
88
|
+
((value + offset) * 255).round.clamp(0, 255)
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def suggested_color(background, hue, target: TARGET_CONTRAST)
|
|
93
|
+
background_rgb = hex_to_rgb(background)
|
|
94
|
+
background_luminance = luminance(background_rgb)
|
|
95
|
+
saturation = 0.65
|
|
96
|
+
|
|
97
|
+
lightness_values =
|
|
98
|
+
if background_luminance < 0.5
|
|
99
|
+
(35..90).map { |value| value / 100.0 }
|
|
100
|
+
else
|
|
101
|
+
(65).downto(10).map { |value| value / 100.0 }
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
best_rgb = nil
|
|
105
|
+
best_ratio = 0.0
|
|
106
|
+
|
|
107
|
+
lightness_values.each do |lightness|
|
|
108
|
+
rgb = hsl_to_rgb(hue, saturation, lightness)
|
|
109
|
+
ratio = contrast_ratio(rgb, background_rgb)
|
|
110
|
+
|
|
111
|
+
if ratio > best_ratio
|
|
112
|
+
best_rgb = rgb
|
|
113
|
+
best_ratio = ratio
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
return [rgb_to_hex(rgb), ratio] if ratio >= target
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
[rgb_to_hex(best_rgb), best_ratio]
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def theme_background(name)
|
|
123
|
+
theme = Fatty::Themes::Manager.fetch(name)
|
|
124
|
+
background = theme.dig(:roles, :output, :bg)
|
|
125
|
+
|
|
126
|
+
unless background
|
|
127
|
+
raise ArgumentError,
|
|
128
|
+
"theme #{name.inspect} has no resolved output background"
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
rgb = Fatty::Color.rgb(background)
|
|
132
|
+
|
|
133
|
+
unless rgb
|
|
134
|
+
raise ArgumentError,
|
|
135
|
+
"cannot resolve output background #{background.inspect} for theme #{name.inspect}"
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
rgb_to_hex(rgb)
|
|
139
|
+
rescue Fatty::Themes::ResolveError => e
|
|
140
|
+
raise ArgumentError, e.message
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
def current_roles(name, background)
|
|
144
|
+
theme = Fatty::Themes::Manager.fetch(name)
|
|
145
|
+
background_rgb = hex_to_rgb(background)
|
|
146
|
+
|
|
147
|
+
ROLE_HUES.keys.to_h do |role|
|
|
148
|
+
foreground = theme.dig(:roles, role, :fg)
|
|
149
|
+
rgb = Fatty::Color.rgb(foreground)
|
|
150
|
+
|
|
151
|
+
data =
|
|
152
|
+
if rgb
|
|
153
|
+
ratio = contrast_ratio(rgb, background_rgb)
|
|
154
|
+
|
|
155
|
+
{
|
|
156
|
+
hex: rgb_to_hex(rgb),
|
|
157
|
+
contrast: ratio,
|
|
158
|
+
status: ratio >= TARGET_CONTRAST ? "OK" : "LOW",
|
|
159
|
+
}
|
|
160
|
+
else
|
|
161
|
+
{
|
|
162
|
+
hex: foreground.to_s,
|
|
163
|
+
contrast: nil,
|
|
164
|
+
status: "UNKNOWN",
|
|
165
|
+
}
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
[role, data]
|
|
169
|
+
end
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
def print_yaml(suggestions)
|
|
173
|
+
suggestions.each do |role, data|
|
|
174
|
+
puts "#{role}:"
|
|
175
|
+
puts " fg: #{data[:hex].inspect}\n\n"
|
|
176
|
+
end
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
def print_roles(title, roles, status: false)
|
|
180
|
+
puts title
|
|
181
|
+
puts
|
|
182
|
+
|
|
183
|
+
roles.each do |role, data|
|
|
184
|
+
if data[:contrast]
|
|
185
|
+
line = format(
|
|
186
|
+
"%-6s %-8s contrast %.2f",
|
|
187
|
+
role,
|
|
188
|
+
data[:hex],
|
|
189
|
+
data[:contrast],
|
|
190
|
+
)
|
|
191
|
+
line += " #{data[:status]}" if status
|
|
192
|
+
puts line
|
|
193
|
+
else
|
|
194
|
+
puts format(
|
|
195
|
+
"%-6s %-8s contrast unknown%s",
|
|
196
|
+
role,
|
|
197
|
+
data[:hex],
|
|
198
|
+
status ? " #{data[:status]}" : "",
|
|
199
|
+
)
|
|
200
|
+
end
|
|
201
|
+
end
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
def print_report(source:, background:, current: nil, suggestions:)
|
|
205
|
+
puts source
|
|
206
|
+
puts "Output background: #{background}"
|
|
207
|
+
puts
|
|
208
|
+
|
|
209
|
+
if current
|
|
210
|
+
print_roles("Current semantic roles:", current, status: true)
|
|
211
|
+
puts
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
print_roles("Suggested semantic roles:", suggestions)
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
options = {
|
|
218
|
+
yaml: false,
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
OptionParser.new do |parser|
|
|
222
|
+
parser.banner = "Usage: themer THEME|RGB [options]"
|
|
223
|
+
|
|
224
|
+
parser.on("--yaml", "Output role definitions as YAML") do
|
|
225
|
+
options[:yaml] = true
|
|
226
|
+
end
|
|
227
|
+
end.parse!
|
|
228
|
+
|
|
229
|
+
argument = ARGV.shift
|
|
230
|
+
|
|
231
|
+
unless argument
|
|
232
|
+
warn "Usage: themer THEME|RGB [--yaml]"
|
|
233
|
+
exit 1
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
begin
|
|
237
|
+
current = nil
|
|
238
|
+
if hex_color?(argument)
|
|
239
|
+
background = normalize_hex(argument)
|
|
240
|
+
source = "Background: #{background}"
|
|
241
|
+
else
|
|
242
|
+
background = theme_background(argument)
|
|
243
|
+
source = "Theme: #{argument}"
|
|
244
|
+
current = current_roles(argument, background)
|
|
245
|
+
end
|
|
246
|
+
|
|
247
|
+
suggestions =
|
|
248
|
+
ROLE_HUES.to_h do |role, hue|
|
|
249
|
+
hex, ratio = suggested_color(background, hue)
|
|
250
|
+
|
|
251
|
+
[
|
|
252
|
+
role,
|
|
253
|
+
{
|
|
254
|
+
hex: hex,
|
|
255
|
+
contrast: ratio,
|
|
256
|
+
},
|
|
257
|
+
]
|
|
258
|
+
end
|
|
259
|
+
|
|
260
|
+
if options[:yaml]
|
|
261
|
+
print_yaml(suggestions)
|
|
262
|
+
else
|
|
263
|
+
print_report(
|
|
264
|
+
source: source,
|
|
265
|
+
background: background,
|
|
266
|
+
current: current,
|
|
267
|
+
suggestions: suggestions,
|
|
268
|
+
)
|
|
269
|
+
end
|
|
270
|
+
rescue ArgumentError => e
|
|
271
|
+
warn e.message
|
|
272
|
+
exit 1
|
|
273
|
+
end
|
data/lib/fatty/ansi/renderer.rb
CHANGED
|
@@ -13,7 +13,13 @@ module Fatty
|
|
|
13
13
|
spec = palette&.[](role.to_sym)
|
|
14
14
|
return text.to_s unless spec
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
text.to_s.split(/(\n)/).map do |part|
|
|
17
|
+
if part == "\n"
|
|
18
|
+
part
|
|
19
|
+
else
|
|
20
|
+
"#{sgr_for_spec(spec)}#{part}#{reset}"
|
|
21
|
+
end
|
|
22
|
+
end.join
|
|
17
23
|
end
|
|
18
24
|
|
|
19
25
|
def render_line(row:, col:, width:, text:, role:, palette:)
|
|
@@ -154,13 +160,17 @@ module Fatty
|
|
|
154
160
|
fg = rgb_for_style_color(style.fg, fallback: fallback_spec[:fg_rgb])
|
|
155
161
|
bg = rgb_for_style_color(style.bg, fallback: fallback_spec[:bg_rgb])
|
|
156
162
|
|
|
157
|
-
|
|
158
|
-
codes << "1" if style.bold
|
|
159
|
-
codes << "3" if style.italic
|
|
160
|
-
codes << "4" if style.underline
|
|
161
|
-
codes << "9" if style.strike
|
|
163
|
+
attrs = Array(fallback_spec[:attrs]).map(&:to_sym)
|
|
162
164
|
|
|
163
|
-
|
|
165
|
+
codes = []
|
|
166
|
+
codes << "1" if attrs.include?(:bold) || style.bold
|
|
167
|
+
codes << "2" if attrs.include?(:dim)
|
|
168
|
+
codes << "3" if attrs.include?(:italic) || style.italic
|
|
169
|
+
codes << "4" if attrs.include?(:underline) || style.underline
|
|
170
|
+
codes << "9" if attrs.include?(:strike) || style.strike
|
|
171
|
+
|
|
172
|
+
reverse = attrs.include?(:reverse) || style.reverse
|
|
173
|
+
if reverse
|
|
164
174
|
if fg && bg
|
|
165
175
|
fg, bg = bg, fg
|
|
166
176
|
else
|
data/lib/fatty/api/output.rb
CHANGED
|
@@ -4,19 +4,21 @@ module Fatty
|
|
|
4
4
|
module OutputApi
|
|
5
5
|
def append(text, follow: true, role: nil)
|
|
6
6
|
payload = {
|
|
7
|
-
text:
|
|
7
|
+
text: text.to_s,
|
|
8
8
|
follow: follow,
|
|
9
9
|
}
|
|
10
|
+
payload[:role] = role if role
|
|
10
11
|
queue(Command.session(output_id, :append, **payload))
|
|
11
12
|
nil
|
|
12
13
|
end
|
|
13
14
|
|
|
14
15
|
def append_now(text, follow: true, mode: nil, role: nil)
|
|
15
16
|
payload = {
|
|
16
|
-
text:
|
|
17
|
+
text: text.to_s,
|
|
17
18
|
follow: follow,
|
|
18
19
|
}
|
|
19
20
|
payload[:mode] = mode if mode
|
|
21
|
+
payload[:role] = role if role
|
|
20
22
|
|
|
21
23
|
terminal.apply_command(Command.session(output_id, :append, **payload))
|
|
22
24
|
terminal.render_frame
|
|
@@ -37,19 +39,6 @@ module Fatty
|
|
|
37
39
|
|
|
38
40
|
private
|
|
39
41
|
|
|
40
|
-
def output_text(text, role:)
|
|
41
|
-
text = text.to_s
|
|
42
|
-
if role
|
|
43
|
-
Fatty::Ansi::Renderer.new.style(
|
|
44
|
-
text,
|
|
45
|
-
role: role,
|
|
46
|
-
palette: markdown_palette,
|
|
47
|
-
)
|
|
48
|
-
else
|
|
49
|
-
text
|
|
50
|
-
end
|
|
51
|
-
end
|
|
52
|
-
|
|
53
42
|
def markdown_palette
|
|
54
43
|
terminal.renderer.palette if terminal.respond_to?(:renderer) && terminal.renderer
|
|
55
44
|
end
|
data/lib/fatty/api.rb
CHANGED
|
@@ -25,20 +25,16 @@ region:
|
|
|
25
25
|
bg: "#c98a4a"
|
|
26
26
|
|
|
27
27
|
good:
|
|
28
|
-
fg: "#
|
|
29
|
-
bg: "#24160f"
|
|
28
|
+
fg: "#22a037"
|
|
30
29
|
|
|
31
30
|
info:
|
|
32
|
-
fg: "#
|
|
33
|
-
bg: "#24160f"
|
|
31
|
+
fg: "#468fd8"
|
|
34
32
|
|
|
35
33
|
warn:
|
|
36
|
-
fg: "#
|
|
37
|
-
bg: "#d8a657"
|
|
34
|
+
fg: "#a88724"
|
|
38
35
|
|
|
39
36
|
error:
|
|
40
|
-
fg: "#
|
|
41
|
-
bg: "#9d3f35"
|
|
37
|
+
fg: "#de6363"
|
|
42
38
|
|
|
43
39
|
pager_status:
|
|
44
40
|
fg: "#24160f"
|
|
@@ -25,20 +25,16 @@ region:
|
|
|
25
25
|
bg: "#1e66f5"
|
|
26
26
|
|
|
27
27
|
good:
|
|
28
|
-
fg: "#
|
|
29
|
-
bg: "#eff1f5"
|
|
28
|
+
fg: "#197628"
|
|
30
29
|
|
|
31
30
|
info:
|
|
32
|
-
fg: "#
|
|
33
|
-
bg: "#eff1f5"
|
|
31
|
+
fg: "#2569ad"
|
|
34
32
|
|
|
35
33
|
warn:
|
|
36
|
-
fg: "#
|
|
37
|
-
bg: "#df8e1d"
|
|
34
|
+
fg: "#7a621a"
|
|
38
35
|
|
|
39
36
|
error:
|
|
40
|
-
fg: "#
|
|
41
|
-
bg: "#d20f39"
|
|
37
|
+
fg: "#c22929"
|
|
42
38
|
|
|
43
39
|
pager_status:
|
|
44
40
|
fg: "#eff1f5"
|
|
@@ -25,20 +25,16 @@ region:
|
|
|
25
25
|
bg: "#89b4fa"
|
|
26
26
|
|
|
27
27
|
good:
|
|
28
|
-
fg: "#
|
|
29
|
-
bg: "#1e1e2e"
|
|
28
|
+
fg: "#23a438"
|
|
30
29
|
|
|
31
30
|
info:
|
|
32
|
-
fg: "#
|
|
33
|
-
bg: "#1e1e2e"
|
|
31
|
+
fg: "#4e94da"
|
|
34
32
|
|
|
35
33
|
warn:
|
|
36
|
-
fg: "#
|
|
37
|
-
bg: "#f9e2af"
|
|
34
|
+
fg: "#ad8b25"
|
|
38
35
|
|
|
39
36
|
error:
|
|
40
|
-
fg: "#
|
|
41
|
-
bg: "#f38ba8"
|
|
37
|
+
fg: "#e06c6c"
|
|
42
38
|
|
|
43
39
|
pager_status:
|
|
44
40
|
fg: "#1e1e2e"
|
|
@@ -25,20 +25,16 @@ region:
|
|
|
25
25
|
bg: "#00d7ff"
|
|
26
26
|
|
|
27
27
|
good:
|
|
28
|
-
fg: "#
|
|
29
|
-
bg: "#000000"
|
|
28
|
+
fg: "#1f9333"
|
|
30
29
|
|
|
31
30
|
info:
|
|
32
|
-
fg: "#
|
|
33
|
-
bg: "#000000"
|
|
31
|
+
fg: "#2d80d2"
|
|
34
32
|
|
|
35
33
|
warn:
|
|
36
|
-
fg: "#
|
|
37
|
-
bg: "#ffff00"
|
|
34
|
+
fg: "#977a20"
|
|
38
35
|
|
|
39
36
|
error:
|
|
40
|
-
fg: "#
|
|
41
|
-
bg: "#ff005f"
|
|
37
|
+
fg: "#d94a4a"
|
|
42
38
|
|
|
43
39
|
pager_status:
|
|
44
40
|
fg: "#000000"
|