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
|
@@ -4,85 +4,99 @@ require "tmpdir"
|
|
|
4
4
|
|
|
5
5
|
module Fatty
|
|
6
6
|
class KeyTestSession < Session
|
|
7
|
-
|
|
7
|
+
attr_reader :output_session
|
|
8
8
|
|
|
9
|
-
def initialize(
|
|
10
|
-
super(
|
|
11
|
-
@
|
|
9
|
+
def initialize(output_dir: Dir.tmpdir)
|
|
10
|
+
super(id: :keytest, keymap: nil)
|
|
11
|
+
@output_session = OutputSession.new
|
|
12
|
+
@path = nil
|
|
13
|
+
@suggestions = []
|
|
12
14
|
end
|
|
13
15
|
|
|
16
|
+
#########################################################################################
|
|
17
|
+
# Session Protocol
|
|
18
|
+
#########################################################################################
|
|
19
|
+
|
|
14
20
|
def init(terminal:)
|
|
15
|
-
super
|
|
21
|
+
commands = super
|
|
16
22
|
@suggestions = []
|
|
17
|
-
@owner ||= terminal.focused_session
|
|
18
|
-
show_quit_status
|
|
19
|
-
force_scrolling_output!
|
|
20
|
-
append <<~TEXT
|
|
21
|
-
Key test mode
|
|
22
23
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
24
|
+
commands.concat(output_session.init(terminal: terminal))
|
|
25
|
+
commands << Command.terminal(:register_session, session: output_session)
|
|
26
|
+
commands << Command.session(output_session.id, :resize)
|
|
27
|
+
commands << Command.session(output_session.id, :set_mode, mode: :scrolling)
|
|
28
|
+
commands << Command.session(output_session.id, :begin_command)
|
|
29
|
+
commands << Command.session(
|
|
30
|
+
output_session.id,
|
|
31
|
+
:append,
|
|
32
|
+
text: <<~TEXT,
|
|
33
|
+
Key test mode
|
|
34
|
+
|
|
35
|
+
Press keys to inspect Fatty's decoding and binding resolution.
|
|
36
|
+
Press q, ESC, or C-g to leave key test mode.
|
|
37
|
+
|
|
38
|
+
TEXT
|
|
39
|
+
follow: true,
|
|
40
|
+
)
|
|
41
|
+
commands << show_quit_status_command
|
|
42
|
+
commands
|
|
28
43
|
end
|
|
29
44
|
|
|
30
|
-
def
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
45
|
+
def update(command)
|
|
46
|
+
log_update(command)
|
|
47
|
+
commands =
|
|
48
|
+
case command.action
|
|
49
|
+
when :key
|
|
50
|
+
ev = command.payload.fetch(:event)
|
|
51
|
+
if quit_key?(ev)
|
|
52
|
+
write_suggestions_commands + [
|
|
53
|
+
Command.session(output_session.id, :append, text: "Leaving key test mode.\n\n", follow: true),
|
|
54
|
+
Command.session(:status, :clear),
|
|
55
|
+
Command.terminal(:pop_modal),
|
|
56
|
+
Command.session(
|
|
57
|
+
:status,
|
|
58
|
+
:show,
|
|
59
|
+
text: "KeyTest suggestions written to #{@path}",
|
|
60
|
+
role: :good,
|
|
61
|
+
),
|
|
62
|
+
]
|
|
63
|
+
else
|
|
64
|
+
snippet = ev.suggested_snippet(terminal_name)
|
|
65
|
+
@suggestions << snippet unless snippet.empty?
|
|
66
|
+
text = [
|
|
67
|
+
ev.report,
|
|
68
|
+
"\nSuggested keybindings:\n",
|
|
69
|
+
snippet,
|
|
70
|
+
"\n",
|
|
71
|
+
].join
|
|
72
|
+
[
|
|
73
|
+
Command.session(
|
|
74
|
+
output_session.id,
|
|
75
|
+
:append,
|
|
76
|
+
text: text,
|
|
77
|
+
follow: true,
|
|
78
|
+
mode: :scrolling),
|
|
79
|
+
show_quit_status_command,
|
|
80
|
+
]
|
|
81
|
+
end
|
|
82
|
+
else
|
|
83
|
+
[]
|
|
84
|
+
end
|
|
85
|
+
Array(commands)
|
|
43
86
|
end
|
|
44
87
|
|
|
45
|
-
def view
|
|
46
|
-
|
|
47
|
-
# pane; this modal only captures keys and appends diagnostic text.
|
|
48
|
-
nil
|
|
88
|
+
def view
|
|
89
|
+
output_session.view
|
|
49
90
|
end
|
|
50
91
|
|
|
51
92
|
def close
|
|
52
|
-
|
|
53
|
-
restore_owner_pager!
|
|
54
|
-
terminal.clear_status if terminal.respond_to?(:clear_status)
|
|
93
|
+
output_session.close
|
|
55
94
|
nil
|
|
56
95
|
end
|
|
57
96
|
|
|
58
97
|
private
|
|
59
98
|
|
|
60
|
-
|
|
61
|
-
return unless @owner&.respond_to?(:append_output)
|
|
62
|
-
|
|
63
|
-
force_scrolling_output!
|
|
64
|
-
|
|
65
|
-
before = @owner.output.lines.length
|
|
66
|
-
@owner.append_output(text.to_s, follow: false)
|
|
67
|
-
|
|
68
|
-
height = @owner.viewport.height.to_i
|
|
69
|
-
added = @owner.output.lines.length - before
|
|
70
|
-
|
|
71
|
-
if added >= height
|
|
72
|
-
@owner.viewport.top = before
|
|
73
|
-
@owner.viewport.clamp!(@owner.output.lines)
|
|
74
|
-
else
|
|
75
|
-
@owner.viewport.page_bottom(@owner.output.lines)
|
|
76
|
-
end
|
|
77
|
-
|
|
78
|
-
terminal.renderer.reset_frame_cache if terminal.respond_to?(:renderer)
|
|
79
|
-
end
|
|
80
|
-
|
|
81
|
-
def force_scrolling_output!
|
|
82
|
-
if @owner&.respond_to?(:pager)
|
|
83
|
-
@owner.pager.paging_to_scrolling
|
|
84
|
-
end
|
|
85
|
-
end
|
|
99
|
+
# simplecov:disable
|
|
86
100
|
|
|
87
101
|
def quit_key?(ev)
|
|
88
102
|
ev.key == :q ||
|
|
@@ -101,26 +115,38 @@ module Fatty
|
|
|
101
115
|
env && env[:terminal] || ENV.fetch("TERM", "unknown")
|
|
102
116
|
end
|
|
103
117
|
|
|
104
|
-
def
|
|
105
|
-
|
|
118
|
+
def show_quit_status_command
|
|
119
|
+
Command.session(
|
|
120
|
+
:status,
|
|
121
|
+
:show,
|
|
122
|
+
text: "KeyTest — press q, ESC, or C-g to quit (terminal: #{terminal_name})",
|
|
123
|
+
role: :warn,
|
|
124
|
+
)
|
|
106
125
|
end
|
|
107
126
|
|
|
108
|
-
def
|
|
127
|
+
def write_suggestions_commands
|
|
109
128
|
suggestions = @suggestions.uniq
|
|
110
|
-
return if suggestions.empty?
|
|
111
|
-
|
|
112
|
-
path = File.join(
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
129
|
+
return [] if suggestions.empty?
|
|
130
|
+
|
|
131
|
+
@path = File.join(
|
|
132
|
+
Dir.tmpdir,
|
|
133
|
+
"fatty-keytest-#{Time.now.strftime('%Y%m%d-%H%M%S')}.yml",
|
|
134
|
+
)
|
|
135
|
+
File.write(@path, suggestion_file_text(suggestions))
|
|
136
|
+
[
|
|
137
|
+
Command.session(
|
|
138
|
+
output_session.id,
|
|
139
|
+
:append,
|
|
140
|
+
text: <<~TEXT,
|
|
141
|
+
=======================================================
|
|
142
|
+
KeyTest suggestions written to:
|
|
143
|
+
#{@path}
|
|
144
|
+
|
|
145
|
+
TEXT
|
|
146
|
+
follow: true,
|
|
147
|
+
mode: :scrolling,
|
|
148
|
+
),
|
|
149
|
+
]
|
|
124
150
|
end
|
|
125
151
|
|
|
126
152
|
def suggestion_file_text(suggestions)
|
|
@@ -195,7 +221,7 @@ module Fatty
|
|
|
195
221
|
|
|
196
222
|
Mouse events may also be bound in keybindings.yml, for example:
|
|
197
223
|
|
|
198
|
-
-
|
|
224
|
+
- button: <BUTTONNAME>
|
|
199
225
|
context: paging
|
|
200
226
|
action: page_up
|
|
201
227
|
|
|
@@ -226,11 +252,5 @@ module Fatty
|
|
|
226
252
|
out << "\n"
|
|
227
253
|
out
|
|
228
254
|
end
|
|
229
|
-
|
|
230
|
-
def restore_owner_pager!
|
|
231
|
-
if @owner&.respond_to?(:pager)
|
|
232
|
-
@owner.pager.quit_paging
|
|
233
|
-
end
|
|
234
|
-
end
|
|
235
255
|
end
|
|
236
256
|
end
|
|
@@ -5,6 +5,10 @@ module Fatty
|
|
|
5
5
|
attr_reader :win
|
|
6
6
|
private attr_writer :win
|
|
7
7
|
|
|
8
|
+
#########################################################################################
|
|
9
|
+
# Session Protocol
|
|
10
|
+
#########################################################################################
|
|
11
|
+
|
|
8
12
|
def close
|
|
9
13
|
Fatty.debug("#{self.class}#close: object_id=#{object_id}", tag: :session)
|
|
10
14
|
old_win = win
|
|
@@ -18,6 +22,10 @@ module Fatty
|
|
|
18
22
|
[]
|
|
19
23
|
end
|
|
20
24
|
|
|
25
|
+
private
|
|
26
|
+
|
|
27
|
+
# simplecov:disable
|
|
28
|
+
|
|
21
29
|
def rebuild_windows!
|
|
22
30
|
old_win = win
|
|
23
31
|
self.win = nil
|
|
@@ -27,7 +35,8 @@ module Fatty
|
|
|
27
35
|
rows = ::Curses.lines
|
|
28
36
|
width, height = geometry(cols: cols, rows: rows)
|
|
29
37
|
x = (cols - width) / 2
|
|
30
|
-
|
|
38
|
+
input_row = renderer.screen.input_rect.row
|
|
39
|
+
y = [input_row - height - 1, 0].max
|
|
31
40
|
self.win = ::Curses::Window.new(height, width, y, x)
|
|
32
41
|
nil
|
|
33
42
|
end
|
|
@@ -57,5 +66,33 @@ module Fatty
|
|
|
57
66
|
def clamp_height(height, max_height:, min_height:)
|
|
58
67
|
height.clamp(min_height, max_height)
|
|
59
68
|
end
|
|
69
|
+
|
|
70
|
+
def safely_close_window(win)
|
|
71
|
+
return unless win
|
|
72
|
+
|
|
73
|
+
begin
|
|
74
|
+
win.erase
|
|
75
|
+
rescue RuntimeError => e
|
|
76
|
+
raise unless closed_window_error?(e)
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
begin
|
|
80
|
+
win.noutrefresh if win.respond_to?(:noutrefresh)
|
|
81
|
+
rescue RuntimeError => e
|
|
82
|
+
raise unless closed_window_error?(e)
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
begin
|
|
86
|
+
win.close
|
|
87
|
+
rescue RuntimeError => e
|
|
88
|
+
raise unless closed_window_error?(e)
|
|
89
|
+
end
|
|
90
|
+
nil
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def closed_window_error?(error)
|
|
94
|
+
message = error.message
|
|
95
|
+
message.include?("closed window") || message.include?("already closed window")
|
|
96
|
+
end
|
|
60
97
|
end
|
|
61
98
|
end
|