fatty 0.99.0 → 0.99.3
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.org +11 -29
- data/README.md +2207 -18
- data/README.org +2066 -104
- data/exe/fatty +236 -93
- data/help/help.md +233 -0
- data/lib/fatty/action.rb +3 -7
- data/lib/fatty/actionable.rb +2 -0
- data/lib/fatty/alert.rb +65 -39
- data/lib/fatty/ansi/renderer.rb +26 -6
- data/lib/fatty/ansi.rb +1 -0
- data/lib/fatty/api/alert.rb +15 -0
- data/lib/fatty/api/choose.rb +145 -0
- data/lib/fatty/api/environment.rb +12 -0
- data/lib/fatty/api/keytest.rb +11 -0
- data/lib/fatty/api/menu.rb +104 -0
- data/lib/fatty/api/output.rb +55 -0
- data/lib/fatty/api/progress.rb +24 -0
- data/lib/fatty/api/prompt.rb +77 -0
- data/lib/fatty/api/status.rb +55 -0
- data/lib/fatty/api.rb +38 -0
- data/lib/fatty/callback_environment.rb +74 -0
- data/lib/fatty/colors/color.rb +366 -232
- data/lib/fatty/colors/pairs.rb +2 -0
- data/lib/fatty/command.rb +78 -0
- data/lib/fatty/config.rb +227 -39
- data/lib/fatty/config_files/config.yml +4 -12
- data/lib/fatty/config_files/keydefs.yml +13 -23
- data/lib/fatty/config_files/themes/capuchin_monk.yml +140 -0
- data/lib/fatty/config_files/themes/catppuccin_latte.yml +140 -0
- data/lib/fatty/config_files/themes/catppuccin_mocha.yml +140 -0
- data/lib/fatty/config_files/themes/cyberpunk.yml +141 -0
- data/lib/fatty/config_files/themes/dracula.yml +140 -0
- data/lib/fatty/config_files/themes/everforest_dark.yml +140 -0
- data/lib/fatty/config_files/themes/gruvbox_dark.yml +140 -0
- data/lib/fatty/config_files/themes/gruvbox_light.yml +140 -0
- data/lib/fatty/config_files/themes/mono.yml +119 -47
- data/lib/fatty/config_files/themes/monokai.yml +140 -0
- data/lib/fatty/config_files/themes/nordic.yml +1 -0
- data/lib/fatty/config_files/themes/onedark.yml +140 -0
- data/lib/fatty/config_files/themes/solarized_dark.yml +1 -0
- data/lib/fatty/config_files/themes/solarized_light.yml +140 -0
- data/lib/fatty/config_files/themes/terminal.yml +67 -0
- data/lib/fatty/config_files/themes/tokyo_night.yml +140 -0
- data/lib/fatty/config_files/themes/wordperfect.yml +80 -9
- data/lib/fatty/core_ext/hash.rb +19 -0
- data/lib/fatty/core_ext/string.rb +19 -12
- data/lib/fatty/core_ext.rb +1 -0
- data/lib/fatty/curses/context.rb +86 -84
- data/lib/fatty/curses/event_source.rb +128 -40
- data/lib/fatty/curses/key_decoder.rb +77 -11
- data/lib/fatty/env.rb +21 -20
- data/lib/fatty/help.rb +1 -29
- data/lib/fatty/history/entry.rb +2 -0
- data/lib/fatty/history.rb +17 -14
- data/lib/fatty/input_buffer.rb +71 -47
- data/lib/fatty/input_field.rb +216 -149
- data/lib/fatty/key_event.rb +67 -66
- data/lib/fatty/key_map.rb +54 -16
- data/lib/fatty/keymaps/emacs.rb +40 -6
- data/lib/fatty/log_formats/json.rb +2 -0
- data/lib/fatty/log_formats/text.rb +2 -0
- data/lib/fatty/logger.rb +7 -2
- data/lib/fatty/markdown/ansi_renderer.rb +75 -6
- data/lib/fatty/markdown/render.rb +2 -3
- data/lib/fatty/mouse_event.rb +142 -2
- data/lib/fatty/output_buffer.rb +2 -0
- data/lib/fatty/pager.rb +158 -47
- data/lib/fatty/progress.rb +417 -0
- data/lib/fatty/renderer/curses.rb +340 -184
- data/lib/fatty/renderer/truecolor.rb +266 -163
- data/lib/fatty/renderer.rb +115 -97
- data/lib/fatty/screen.rb +2 -0
- data/lib/fatty/session/alert_session.rb +39 -21
- data/lib/fatty/session/isearch_session.rb +92 -38
- data/lib/fatty/session/keytest_session.rb +105 -85
- data/lib/fatty/session/modal_session.rb +38 -1
- data/lib/fatty/session/output_session.rb +472 -21
- data/lib/fatty/session/popup_session.rb +251 -134
- data/lib/fatty/session/prompt_session.rb +68 -26
- data/lib/fatty/session/search_session.rb +79 -31
- data/lib/fatty/session/shell_session.rb +383 -368
- data/lib/fatty/session/status_session.rb +167 -0
- data/lib/fatty/session.rb +95 -95
- data/lib/fatty/terminal/popup_owner.rb +14 -11
- data/lib/fatty/terminal.rb +515 -813
- data/lib/fatty/themes/loader.rb +4 -2
- data/lib/fatty/themes/manager.rb +4 -0
- data/lib/fatty/themes/registry.rb +2 -0
- data/lib/fatty/themes/resolver.rb +175 -162
- data/lib/fatty/version.rb +1 -1
- data/lib/fatty/viewport.rb +8 -1
- data/lib/fatty.rb +35 -7
- metadata +42 -40
- data/.envrc +0 -2
- data/.simplecov +0 -23
- data/.yardopts +0 -4
- data/CHANGELOG.md +0 -34
- data/Rakefile +0 -15
- data/TODO.org +0 -163
- data/examples/markdown/native-markdown.md +0 -370
- data/examples/markdown/ox-gfm-markdown.md +0 -373
- data/examples/markdown/ox-gfm-markdown.org +0 -376
- data/fatty.gemspec +0 -42
- data/lib/fatty/accept_env.rb +0 -32
- data/lib/fatty/config_files/help.md +0 -120
- data/lib/fatty/config_files/help.org +0 -124
- data/lib/fatty/config_files/themes/wordperfect_light.yml +0 -77
- data/lib/fatty/menu_env.rb +0 -22
- data/lib/fatty/session/input_session.rb +0 -99
- data/lib/fatty/sessions.rb +0 -14
- data/lib/fatty/terminal/progress.rb +0 -374
- data/lib/fatty/view/alert_view.rb +0 -14
- data/lib/fatty/view/cursor_view.rb +0 -18
- data/lib/fatty/view/input_view.rb +0 -9
- data/lib/fatty/view/output_view.rb +0 -9
- data/lib/fatty/view/status_view.rb +0 -14
- data/lib/fatty/view.rb +0 -33
- data/lib/fatty/views.rb +0 -9
- data/sig/fatty.rbs +0 -4
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# lib/fatty/api/prompt.rb
|
|
2
|
+
|
|
3
|
+
module Fatty
|
|
4
|
+
module MenuApi
|
|
5
|
+
def menu(prompt, choices:, initial_choice_idx: 0, cancel_value: nil)
|
|
6
|
+
items = normalize_menu_choices(choices)
|
|
7
|
+
raise ArgumentError, "choices must not be empty" if items.empty?
|
|
8
|
+
|
|
9
|
+
labels = items.keys
|
|
10
|
+
popup = Fatty::PopUpSession.new(
|
|
11
|
+
source: labels,
|
|
12
|
+
kind: :terminal_menu,
|
|
13
|
+
title: "Menu",
|
|
14
|
+
message: prompt,
|
|
15
|
+
prompt: "Narrow: ",
|
|
16
|
+
current: :top,
|
|
17
|
+
validate_unique_labels: true,
|
|
18
|
+
history: terminal.history,
|
|
19
|
+
history_kind: :popup_filter,
|
|
20
|
+
history_ctx: { kind: :popup_filter, popup: :menu, prompt: prompt.to_s },
|
|
21
|
+
)
|
|
22
|
+
popup.instance_variable_set(
|
|
23
|
+
:@current,
|
|
24
|
+
initial_choice_idx.to_i.clamp(0, labels.length - 1),
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
done = false
|
|
28
|
+
result = nil
|
|
29
|
+
acc_proc = ->(payload) do
|
|
30
|
+
label = payload[:item]
|
|
31
|
+
action = items[label]
|
|
32
|
+
|
|
33
|
+
result =
|
|
34
|
+
if action
|
|
35
|
+
call_menu_action(action, label: label)
|
|
36
|
+
else
|
|
37
|
+
cancel_value
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
done = true
|
|
41
|
+
end
|
|
42
|
+
cancel_proc = -> do
|
|
43
|
+
result = cancel_value
|
|
44
|
+
done = true
|
|
45
|
+
end
|
|
46
|
+
owner = Fatty::Terminal::PopupOwner.new(
|
|
47
|
+
on_result: acc_proc,
|
|
48
|
+
on_cancel: cancel_proc,
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
begin
|
|
52
|
+
terminal.apply_command(
|
|
53
|
+
Command.terminal(:push_modal, session: popup, owner: owner),
|
|
54
|
+
)
|
|
55
|
+
terminal.render_frame
|
|
56
|
+
|
|
57
|
+
while !done && terminal.running?
|
|
58
|
+
dirty = false
|
|
59
|
+
command = terminal.event_source.next_event
|
|
60
|
+
if command
|
|
61
|
+
terminal.apply_command(command)
|
|
62
|
+
dirty = true
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
begin
|
|
66
|
+
dirty ||= !!terminal.tick_active_session
|
|
67
|
+
rescue StandardError => e
|
|
68
|
+
Fatty.error(
|
|
69
|
+
"MenuApi#menu tick failed: #{e.class}: #{e.message}",
|
|
70
|
+
tag: :terminal,
|
|
71
|
+
)
|
|
72
|
+
dirty = true
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
terminal.render_frame if dirty
|
|
76
|
+
end
|
|
77
|
+
ensure
|
|
78
|
+
terminal.render_frame
|
|
79
|
+
end
|
|
80
|
+
result
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
private
|
|
84
|
+
|
|
85
|
+
# simplecov:disable
|
|
86
|
+
|
|
87
|
+
def normalize_menu_choices(choices)
|
|
88
|
+
unless choices.is_a?(Hash)
|
|
89
|
+
raise ArgumentError, "menu choices must be a Hash of label => callable"
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
choices.each_with_object({}) do |(label, action), normalized|
|
|
93
|
+
unless action.respond_to?(:call)
|
|
94
|
+
raise ArgumentError, "menu choice #{label.inspect} is not callable"
|
|
95
|
+
end
|
|
96
|
+
normalized[label.to_s] = action
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def call_menu_action(action, label:)
|
|
101
|
+
action.call(self, label)
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
end
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Fatty
|
|
4
|
+
module OutputApi
|
|
5
|
+
def append(text, follow: true)
|
|
6
|
+
queue(Command.session(output_id, :append, text: text.to_s, follow: follow))
|
|
7
|
+
nil
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def append_now(text, follow: true, mode: nil)
|
|
11
|
+
payload = { text: text.to_s, follow: follow }
|
|
12
|
+
payload[:mode] = mode if mode
|
|
13
|
+
|
|
14
|
+
terminal.apply_command(Command.session(output_id, :append, **payload))
|
|
15
|
+
terminal.render_frame
|
|
16
|
+
|
|
17
|
+
nil
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def markdown(text)
|
|
21
|
+
md = Fatty::Markdown.render(
|
|
22
|
+
text,
|
|
23
|
+
palette: markdown_palette,
|
|
24
|
+
theme: markdown_theme,
|
|
25
|
+
truecolor: markdown_truecolor?,
|
|
26
|
+
)
|
|
27
|
+
append(md)
|
|
28
|
+
nil
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
private
|
|
32
|
+
|
|
33
|
+
def markdown_palette
|
|
34
|
+
terminal.renderer.palette if terminal.respond_to?(:renderer) && terminal.renderer
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def markdown_theme
|
|
38
|
+
Fatty::Themes::Manager.fetch(Fatty::Themes::Manager.current)
|
|
39
|
+
rescue StandardError
|
|
40
|
+
nil
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def markdown_truecolor?
|
|
44
|
+
if terminal.respond_to?(:ctx) && terminal.ctx.respond_to?(:truecolor_enabled?)
|
|
45
|
+
terminal.ctx.truecolor_enabled?
|
|
46
|
+
elsif terminal.respond_to?(:renderer) &&
|
|
47
|
+
terminal.renderer.respond_to?(:context) &&
|
|
48
|
+
terminal.renderer.context.respond_to?(:truecolor)
|
|
49
|
+
terminal.renderer.context.truecolor
|
|
50
|
+
else
|
|
51
|
+
false
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Fatty
|
|
4
|
+
module ProgressApi
|
|
5
|
+
# Create a transient status-line progress indicator.
|
|
6
|
+
# For style :spinner, total may be omitted for indeterminate progress.
|
|
7
|
+
def add_progress(
|
|
8
|
+
label: Progress::DEFAULT_LABEL,
|
|
9
|
+
total: nil,
|
|
10
|
+
style: Progress::DEFAULT_STYLE,
|
|
11
|
+
role: Progress::DEFAULT_ROLE,
|
|
12
|
+
width: Progress::DEFAULT_WIDTH
|
|
13
|
+
)
|
|
14
|
+
@progress = Progress.new(
|
|
15
|
+
terminal: terminal,
|
|
16
|
+
label: label,
|
|
17
|
+
total: total,
|
|
18
|
+
style: style,
|
|
19
|
+
role: role,
|
|
20
|
+
width: width,
|
|
21
|
+
)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# lib/fatty/api/prompt.rb
|
|
2
|
+
|
|
3
|
+
module Fatty
|
|
4
|
+
module PromptApi
|
|
5
|
+
# Create a popup to ask the user to enter an arbitrary string. These
|
|
6
|
+
# prompts will keep their own history based on the history_key, or if not
|
|
7
|
+
# history_key is given, the prompt text. If save_history is set to false, no
|
|
8
|
+
# history will be recorded, which can suppress writing sensitive values
|
|
9
|
+
# such as passwords to the history file.
|
|
10
|
+
def prompt(prompt, initial: "", cancel_value: nil, history_key: nil, save_history: true)
|
|
11
|
+
history_ctx = lambda do
|
|
12
|
+
base =
|
|
13
|
+
if @history_ctx.respond_to?(:call)
|
|
14
|
+
@history_ctx.call
|
|
15
|
+
elsif @history_ctx.is_a?(Hash)
|
|
16
|
+
@history_ctx
|
|
17
|
+
else
|
|
18
|
+
{}
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
base.merge(prompt: (history_key || prompt).to_s)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
popup = Fatty::PromptSession.new(
|
|
25
|
+
title: "Prompt",
|
|
26
|
+
message: prompt,
|
|
27
|
+
prompt: "> ",
|
|
28
|
+
initial: initial,
|
|
29
|
+
kind: :terminal_prompt,
|
|
30
|
+
save_history: save_history,
|
|
31
|
+
history_ctx: history_ctx,
|
|
32
|
+
)
|
|
33
|
+
done = false
|
|
34
|
+
result = nil
|
|
35
|
+
|
|
36
|
+
acc_proc = ->(payload) do
|
|
37
|
+
result = payload[:text]
|
|
38
|
+
done = true
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
cancel_proc = -> do
|
|
42
|
+
result = cancel_value
|
|
43
|
+
done = true
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
owner = Terminal::PopupOwner.new(on_result: acc_proc, on_cancel: cancel_proc)
|
|
47
|
+
|
|
48
|
+
begin
|
|
49
|
+
terminal.apply_command(
|
|
50
|
+
Fatty::Command.terminal(:push_modal, session: popup, owner: owner)
|
|
51
|
+
)
|
|
52
|
+
terminal.render_frame
|
|
53
|
+
|
|
54
|
+
while !done && terminal.running?
|
|
55
|
+
dirty = false
|
|
56
|
+
command = terminal.event_source.next_event
|
|
57
|
+
|
|
58
|
+
if command
|
|
59
|
+
terminal.apply_command(command)
|
|
60
|
+
dirty = true
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
begin
|
|
64
|
+
dirty ||= !!terminal.tick_active_session
|
|
65
|
+
rescue StandardError => e
|
|
66
|
+
Fatty.error("PromptApi#prompt tick failed: #{e.class}: #{e.message}", tag: :terminal)
|
|
67
|
+
dirty = true
|
|
68
|
+
end
|
|
69
|
+
terminal.render_frame if dirty
|
|
70
|
+
end
|
|
71
|
+
ensure
|
|
72
|
+
terminal.render_frame
|
|
73
|
+
end
|
|
74
|
+
result
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Fatty
|
|
4
|
+
###########################################################################################
|
|
5
|
+
# Public API convenience methods for use by the library user
|
|
6
|
+
###########################################################################################
|
|
7
|
+
module StatusApi
|
|
8
|
+
# Display text in the status area with the given "role", which determines
|
|
9
|
+
# the coloring of the displayed text via themeing.
|
|
10
|
+
def status(text, role: :info, replace: false, render: true)
|
|
11
|
+
terminal.apply_command(
|
|
12
|
+
Command.session(
|
|
13
|
+
:status,
|
|
14
|
+
:show,
|
|
15
|
+
text: text,
|
|
16
|
+
role: role,
|
|
17
|
+
append: !replace,
|
|
18
|
+
)
|
|
19
|
+
)
|
|
20
|
+
terminal.without_cursor_restore do
|
|
21
|
+
terminal.render_frame
|
|
22
|
+
end if render
|
|
23
|
+
nil
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# Display a message to the user in the status line, colored according to
|
|
27
|
+
# the Config for "good," i.e., success.
|
|
28
|
+
def good(text, replace: false, render: true)
|
|
29
|
+
status(text, role: :good, replace:, render:)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Display a message to the user in the status line, colored according to
|
|
33
|
+
# the Config for "info".
|
|
34
|
+
def info(text, replace: false, render: true)
|
|
35
|
+
status(text, role: :info, replace:, render:)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# Display a message to the user in the status line, colored according to
|
|
39
|
+
# the Config for "warn," i.e., short of an error but not complete
|
|
40
|
+
# success either.
|
|
41
|
+
def warn(text, replace: false, render: true)
|
|
42
|
+
status(text, role: :warn, replace:, render:)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Display a message to the user in the status line, colored according to
|
|
46
|
+
# the Config for "oops," i.e., a soft failure.
|
|
47
|
+
def error(text, replace: false, render: true)
|
|
48
|
+
status(text, role: :error, replace:, render:)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def oops(text, replace: false, render: true)
|
|
52
|
+
status(text, role: :error, replace:, render:)
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
data/lib/fatty/api.rb
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
module Fatty
|
|
2
|
+
module ChooseApi
|
|
3
|
+
# simplecov:disable
|
|
4
|
+
|
|
5
|
+
private
|
|
6
|
+
|
|
7
|
+
def normalize_choices(choices)
|
|
8
|
+
case choices
|
|
9
|
+
when Hash
|
|
10
|
+
choices.map do |label, value|
|
|
11
|
+
[label.to_s, value]
|
|
12
|
+
end
|
|
13
|
+
when Array
|
|
14
|
+
choices.map do |choice|
|
|
15
|
+
unless choice.is_a?(String)
|
|
16
|
+
raise ArgumentError, "choices array must contain strings"
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
[choice, choice]
|
|
20
|
+
end
|
|
21
|
+
else
|
|
22
|
+
raise ArgumentError, "choices must be an Array of strings or a Hash"
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# simplecov:enable
|
|
29
|
+
|
|
30
|
+
require_relative './api/output.rb'
|
|
31
|
+
require_relative './api/status.rb'
|
|
32
|
+
require_relative './api/alert.rb'
|
|
33
|
+
require_relative './api/choose.rb'
|
|
34
|
+
require_relative './api/prompt.rb'
|
|
35
|
+
require_relative './api/progress.rb'
|
|
36
|
+
require_relative './api/menu.rb'
|
|
37
|
+
require_relative './api/keytest.rb'
|
|
38
|
+
require_relative './api/environment.rb'
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
#
|
|
3
|
+
# This class provides a wrapper around components that can be handed off to
|
|
4
|
+
# Terminal's on_accept method (or other callbacks) for access to Fatty's
|
|
5
|
+
# facilities. The on_accept proc will receive two parameters: (1) the edited
|
|
6
|
+
# line and (2) an instance of this class called `env` from which the user can
|
|
7
|
+
# access certain facilities that Fatty provides.
|
|
8
|
+
#
|
|
9
|
+
# For example, by using env.append("some text"), the given text will be
|
|
10
|
+
# displayed in the output pane with scrolling, search, etc. A related method,
|
|
11
|
+
# `env.markdown(<markdown_text>)` will render the given text as markdown and
|
|
12
|
+
# then append it to the output pane.
|
|
13
|
+
#
|
|
14
|
+
# Using env.status will display text in the status area. Likewise with
|
|
15
|
+
# env.alert for the alert panel.
|
|
16
|
+
#
|
|
17
|
+
# You can add a Progress object to the status_area with env.add_progress and
|
|
18
|
+
# update it with `env.progress.update`.
|
|
19
|
+
module Fatty
|
|
20
|
+
class CallbackEnvironment
|
|
21
|
+
INTERRUPT_POLL_INTERVAL = 1.0
|
|
22
|
+
|
|
23
|
+
include OutputApi
|
|
24
|
+
include MenuApi
|
|
25
|
+
include ProgressApi
|
|
26
|
+
include ChooseApi
|
|
27
|
+
include PromptApi
|
|
28
|
+
include StatusApi
|
|
29
|
+
include AlertApi
|
|
30
|
+
include KeytestApi
|
|
31
|
+
include EnvironmentApi
|
|
32
|
+
|
|
33
|
+
attr_reader :label, :payload, :commands, :terminal, :progress
|
|
34
|
+
|
|
35
|
+
def initialize(terminal:, output_id:, label: nil)
|
|
36
|
+
@terminal = terminal
|
|
37
|
+
@output_id = output_id
|
|
38
|
+
@label = label
|
|
39
|
+
@commands = []
|
|
40
|
+
@last_interrupt_check_at = nil
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def queue(command)
|
|
44
|
+
@commands << command
|
|
45
|
+
command
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def check_interrupt!
|
|
49
|
+
now = monotonic_time
|
|
50
|
+
|
|
51
|
+
if interrupt_check_due?(now)
|
|
52
|
+
@last_interrupt_check_at = now
|
|
53
|
+
raise Fatty::Interrupt if terminal.interrupt_pending?
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
nil
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
private
|
|
60
|
+
|
|
61
|
+
def interrupt_check_due?(now)
|
|
62
|
+
@last_interrupt_check_at.nil? ||
|
|
63
|
+
now - @last_interrupt_check_at >= INTERRUPT_POLL_INTERVAL
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def monotonic_time
|
|
67
|
+
Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# simplecov:disable
|
|
71
|
+
|
|
72
|
+
attr_reader :output_id
|
|
73
|
+
end
|
|
74
|
+
end
|