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.
Files changed (120) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.org +11 -29
  3. data/README.md +2207 -18
  4. data/README.org +2066 -104
  5. data/exe/fatty +236 -93
  6. data/help/help.md +233 -0
  7. data/lib/fatty/action.rb +3 -7
  8. data/lib/fatty/actionable.rb +2 -0
  9. data/lib/fatty/alert.rb +65 -39
  10. data/lib/fatty/ansi/renderer.rb +26 -6
  11. data/lib/fatty/ansi.rb +1 -0
  12. data/lib/fatty/api/alert.rb +15 -0
  13. data/lib/fatty/api/choose.rb +145 -0
  14. data/lib/fatty/api/environment.rb +12 -0
  15. data/lib/fatty/api/keytest.rb +11 -0
  16. data/lib/fatty/api/menu.rb +104 -0
  17. data/lib/fatty/api/output.rb +55 -0
  18. data/lib/fatty/api/progress.rb +24 -0
  19. data/lib/fatty/api/prompt.rb +77 -0
  20. data/lib/fatty/api/status.rb +55 -0
  21. data/lib/fatty/api.rb +38 -0
  22. data/lib/fatty/callback_environment.rb +74 -0
  23. data/lib/fatty/colors/color.rb +366 -232
  24. data/lib/fatty/colors/pairs.rb +2 -0
  25. data/lib/fatty/command.rb +78 -0
  26. data/lib/fatty/config.rb +227 -39
  27. data/lib/fatty/config_files/config.yml +4 -12
  28. data/lib/fatty/config_files/keydefs.yml +13 -23
  29. data/lib/fatty/config_files/themes/capuchin_monk.yml +140 -0
  30. data/lib/fatty/config_files/themes/catppuccin_latte.yml +140 -0
  31. data/lib/fatty/config_files/themes/catppuccin_mocha.yml +140 -0
  32. data/lib/fatty/config_files/themes/cyberpunk.yml +141 -0
  33. data/lib/fatty/config_files/themes/dracula.yml +140 -0
  34. data/lib/fatty/config_files/themes/everforest_dark.yml +140 -0
  35. data/lib/fatty/config_files/themes/gruvbox_dark.yml +140 -0
  36. data/lib/fatty/config_files/themes/gruvbox_light.yml +140 -0
  37. data/lib/fatty/config_files/themes/mono.yml +119 -47
  38. data/lib/fatty/config_files/themes/monokai.yml +140 -0
  39. data/lib/fatty/config_files/themes/nordic.yml +1 -0
  40. data/lib/fatty/config_files/themes/onedark.yml +140 -0
  41. data/lib/fatty/config_files/themes/solarized_dark.yml +1 -0
  42. data/lib/fatty/config_files/themes/solarized_light.yml +140 -0
  43. data/lib/fatty/config_files/themes/terminal.yml +67 -0
  44. data/lib/fatty/config_files/themes/tokyo_night.yml +140 -0
  45. data/lib/fatty/config_files/themes/wordperfect.yml +80 -9
  46. data/lib/fatty/core_ext/hash.rb +19 -0
  47. data/lib/fatty/core_ext/string.rb +19 -12
  48. data/lib/fatty/core_ext.rb +1 -0
  49. data/lib/fatty/curses/context.rb +86 -84
  50. data/lib/fatty/curses/event_source.rb +128 -40
  51. data/lib/fatty/curses/key_decoder.rb +77 -11
  52. data/lib/fatty/env.rb +21 -20
  53. data/lib/fatty/help.rb +1 -29
  54. data/lib/fatty/history/entry.rb +2 -0
  55. data/lib/fatty/history.rb +17 -14
  56. data/lib/fatty/input_buffer.rb +71 -47
  57. data/lib/fatty/input_field.rb +216 -149
  58. data/lib/fatty/key_event.rb +67 -66
  59. data/lib/fatty/key_map.rb +54 -16
  60. data/lib/fatty/keymaps/emacs.rb +40 -6
  61. data/lib/fatty/log_formats/json.rb +2 -0
  62. data/lib/fatty/log_formats/text.rb +2 -0
  63. data/lib/fatty/logger.rb +7 -2
  64. data/lib/fatty/markdown/ansi_renderer.rb +75 -6
  65. data/lib/fatty/markdown/render.rb +2 -3
  66. data/lib/fatty/mouse_event.rb +142 -2
  67. data/lib/fatty/output_buffer.rb +2 -0
  68. data/lib/fatty/pager.rb +158 -47
  69. data/lib/fatty/progress.rb +417 -0
  70. data/lib/fatty/renderer/curses.rb +340 -184
  71. data/lib/fatty/renderer/truecolor.rb +266 -163
  72. data/lib/fatty/renderer.rb +115 -97
  73. data/lib/fatty/screen.rb +2 -0
  74. data/lib/fatty/session/alert_session.rb +39 -21
  75. data/lib/fatty/session/isearch_session.rb +92 -38
  76. data/lib/fatty/session/keytest_session.rb +105 -85
  77. data/lib/fatty/session/modal_session.rb +38 -1
  78. data/lib/fatty/session/output_session.rb +472 -21
  79. data/lib/fatty/session/popup_session.rb +251 -134
  80. data/lib/fatty/session/prompt_session.rb +68 -26
  81. data/lib/fatty/session/search_session.rb +79 -31
  82. data/lib/fatty/session/shell_session.rb +383 -368
  83. data/lib/fatty/session/status_session.rb +167 -0
  84. data/lib/fatty/session.rb +95 -95
  85. data/lib/fatty/terminal/popup_owner.rb +14 -11
  86. data/lib/fatty/terminal.rb +515 -813
  87. data/lib/fatty/themes/loader.rb +4 -2
  88. data/lib/fatty/themes/manager.rb +4 -0
  89. data/lib/fatty/themes/registry.rb +2 -0
  90. data/lib/fatty/themes/resolver.rb +175 -162
  91. data/lib/fatty/version.rb +1 -1
  92. data/lib/fatty/viewport.rb +8 -1
  93. data/lib/fatty.rb +35 -7
  94. metadata +42 -40
  95. data/.envrc +0 -2
  96. data/.simplecov +0 -23
  97. data/.yardopts +0 -4
  98. data/CHANGELOG.md +0 -34
  99. data/Rakefile +0 -15
  100. data/TODO.org +0 -163
  101. data/examples/markdown/native-markdown.md +0 -370
  102. data/examples/markdown/ox-gfm-markdown.md +0 -373
  103. data/examples/markdown/ox-gfm-markdown.org +0 -376
  104. data/fatty.gemspec +0 -42
  105. data/lib/fatty/accept_env.rb +0 -32
  106. data/lib/fatty/config_files/help.md +0 -120
  107. data/lib/fatty/config_files/help.org +0 -124
  108. data/lib/fatty/config_files/themes/wordperfect_light.yml +0 -77
  109. data/lib/fatty/menu_env.rb +0 -22
  110. data/lib/fatty/session/input_session.rb +0 -99
  111. data/lib/fatty/sessions.rb +0 -14
  112. data/lib/fatty/terminal/progress.rb +0 -374
  113. data/lib/fatty/view/alert_view.rb +0 -14
  114. data/lib/fatty/view/cursor_view.rb +0 -18
  115. data/lib/fatty/view/input_view.rb +0 -9
  116. data/lib/fatty/view/output_view.rb +0 -9
  117. data/lib/fatty/view/status_view.rb +0 -14
  118. data/lib/fatty/view.rb +0 -33
  119. data/lib/fatty/views.rb +0 -9
  120. data/sig/fatty.rbs +0 -4
@@ -5,7 +5,7 @@ require "yaml"
5
5
  module Fatty
6
6
  module Themes
7
7
  module Loader
8
- RESERVED_KEYS = %i[name inherit markdown].freeze
8
+ RESERVED_KEYS = %i[name inherit markdown markdown_code_theme].freeze
9
9
 
10
10
  ROLE_ALIASES = {
11
11
  status_good: :good,
@@ -19,6 +19,7 @@ module Fatty
19
19
  }.freeze
20
20
 
21
21
  def self.load_dir(path, registry:)
22
+ Fatty.info("Loading theme directory #{path}", tag: :theme)
22
23
  Dir.glob(File.join(path.to_s, "*.{yml,yaml}")).sort.each do |file|
23
24
  load_file(file, registry: registry)
24
25
  end
@@ -26,6 +27,7 @@ module Fatty
26
27
  end
27
28
 
28
29
  def self.load_file(path, registry:)
30
+ Fatty.info("Loading theme #{path}", tag: :theme)
29
31
  data = YAML.safe_load_file(
30
32
  path,
31
33
  permitted_classes: [Symbol],
@@ -55,9 +57,9 @@ module Fatty
55
57
  out = {
56
58
  name: normalize_optional_symbol(data[:name]),
57
59
  inherit: normalize_optional_symbol(data[:inherit]),
60
+ markdown_code_theme: normalize_optional_symbol(data[:markdown_code_theme]),
58
61
  roles: {},
59
62
  }
60
-
61
63
  data.each do |key, value|
62
64
  k = key.to_sym
63
65
  next if RESERVED_KEYS.include?(k)
@@ -10,6 +10,7 @@ module Fatty
10
10
  begin
11
11
  reg = Registry.new
12
12
  Loader.load_dir(Fatty::Config.user_themes_dir, registry: reg)
13
+ Loader.load_dir(Fatty::Config.app_themes_dir, registry: reg) if Fatty::Config.app_themes_dir
13
14
  reg
14
15
  end
15
16
  end
@@ -17,6 +18,7 @@ module Fatty
17
18
  def self.load!
18
19
  registry.clear
19
20
  Loader.load_dir(Fatty::Config.user_themes_dir, registry: registry)
21
+ Loader.load_dir(Fatty::Config.app_themes_dir, registry: registry) if Fatty::Config.app_themes_dir
20
22
  registry
21
23
  end
22
24
 
@@ -38,6 +40,8 @@ module Fatty
38
40
  end
39
41
 
40
42
  def self.set(theme)
43
+ return current unless theme
44
+
41
45
  t = theme.to_sym
42
46
  if theme_names.include?(t)
43
47
  @current = t
@@ -44,6 +44,8 @@ module Fatty
44
44
 
45
45
  private
46
46
 
47
+ # simplecov:disable
48
+
47
49
  def normalize_name(name)
48
50
  return if name.nil?
49
51
 
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ using Fatty::CoreExt::Hash
4
+
3
5
  module Fatty
4
6
  module Themes
5
7
  class ResolveError < StandardError; end
@@ -32,193 +34,204 @@ module Fatty
32
34
  # directly on the theme_spec.
33
35
  # module Resolver
34
36
  module Resolver
35
- DEFAULT_ROLE_SPECS = {
36
- region: { attrs: [:reverse] },
37
- cursor: { attrs: [:reverse] },
38
- input_suggestion: { attrs: [:dim] },
39
- pager_status: { attrs: [:reverse] },
40
- search_input: { attrs: [:reverse] },
41
- match_current: { attrs: [:reverse] },
42
- match_other: { attrs: [:underline] },
43
- popup_counts: { attrs: [:bold] },
44
- alert: { attrs: [:bold] },
45
- markdown_table_cell: {},
46
- markdown_underline: { attrs: [:underline] },
47
- markdown_hrule: { attrs: [:dim] },
48
- }.freeze
49
-
50
- ROLE_PARENTS = {
51
- input: :output,
52
- input_suggestion: :input,
53
-
54
- region: :output,
55
- cursor: :input,
56
-
57
- popup: :output,
58
- popup_frame: :popup,
59
- popup_input: :input,
60
- popup_selection: :region,
61
- popup_counts: :popup,
62
-
63
- search_input: :popup,
64
-
65
- match_current: :region,
66
- match_other: :region,
67
-
68
- status: :output,
69
- alert: :output,
70
- info: :output,
71
- good: :info,
72
- warn: :info,
73
- error: :warn,
74
-
75
- pager_status: :status,
76
-
77
- markdown_h1: :output,
78
- markdown_h2: :markdown_h1,
79
- markdown_h3: :markdown_h2,
80
-
81
- markdown_code: :output,
82
- markdown_code_gutter: :markdown_code,
83
-
84
- markdown_strong: :output,
85
- markdown_emphasis: :output,
86
-
87
- markdown_link: :output,
88
- markdown_url: :markdown_link,
89
-
90
- markdown_quote_gutter: :output,
91
- markdown_highlight: :output,
92
- markdown_table_header: :markdown_strong,
93
- markdown_table_cell: :output,
94
- markdown_underline: :output,
95
- markdown_hrule: :output,
96
- }.freeze
97
-
98
- def self.empty_theme
99
- {
100
- name: nil,
101
- inherit: nil,
102
- roles: {},
103
- source: nil,
104
- }
105
- end
37
+ class << self
38
+ DEFAULT_ROLE_SPECS = {
39
+ region: { attrs: [:reverse] },
40
+ cursor: { attrs: [:reverse] },
41
+ input_suggestion: { attrs: [:dim] },
42
+ pager_status: { attrs: [:reverse] },
43
+ search_input: { attrs: [:reverse] },
44
+ match_current: { attrs: [:reverse] },
45
+ match_other: { attrs: [:underline] },
46
+ popup_counts: { attrs: [:bold] },
47
+ alert: { attrs: [:bold] },
48
+ markdown_table_cell: {},
49
+ markdown_underline: { attrs: [:underline] },
50
+ markdown_hrule: { attrs: [:dim] },
51
+ line_number: { attrs: [:dim] },
52
+ }.freeze
53
+
54
+ ROLE_PARENTS = {
55
+ input: :output,
56
+ input_suggestion: :input,
57
+
58
+ region: :output,
59
+ cursor: :input,
60
+
61
+ popup: :output,
62
+ popup_frame: :popup,
63
+ popup_input: :input,
64
+ popup_selection: :region,
65
+ popup_counts: :popup,
66
+
67
+ search_input: :popup,
68
+
69
+ match_current: :region,
70
+ match_other: :region,
71
+
72
+ status: :output,
73
+ alert: :output,
74
+ info: :output,
75
+ good: :info,
76
+ warn: :info,
77
+ error: :warn,
78
+
79
+ pager_status: :status,
80
+ line_number: :output,
81
+
82
+ markdown_h1: :output,
83
+ markdown_h2: :markdown_h1,
84
+ markdown_h3: :markdown_h2,
85
+
86
+ markdown_code: :output,
87
+ markdown_code_block: :markdown_code,
88
+ markdown_code_gutter: :markdown_code_block,
89
+
90
+ markdown_strong: :output,
91
+ markdown_emphasis: :output,
92
+
93
+ markdown_link: :output,
94
+ markdown_url: :markdown_link,
95
+
96
+ markdown_quote_gutter: :output,
97
+ markdown_highlight: :output,
98
+ markdown_table_header: :markdown_strong,
99
+ markdown_table_cell: :output,
100
+ markdown_underline: :output,
101
+ markdown_hrule: :output,
102
+ }.freeze
103
+
104
+ def resolve(registry, name)
105
+ raw = merge_theme_chain(registry, name.to_sym, stack: [])
106
+ raw[:roles] = resolve_role_inheritance(raw[:roles])
107
+ raw[:roles] = add_composite_roles(raw[:roles])
108
+ raw[:name] = name.to_sym
109
+ raw
110
+ end
106
111
 
107
- def self.resolve(registry, name)
108
- raw = merge_theme_chain(registry, name.to_sym, stack: [])
109
- raw[:roles] = resolve_role_inheritance(raw[:roles])
110
- raw[:roles] = add_composite_roles(raw[:roles])
111
- raw[:name] = name.to_sym
112
- raw
113
- end
112
+ private
114
113
 
115
- def self.merge_theme_chain(registry, name, stack:)
116
- defn = registry.fetch(name)
117
- raise MissingThemeError, "Theme not found: #{name}" unless defn
114
+ # simplecov:disable
118
115
 
119
- if stack.include?(name)
120
- cycle = (stack + [name]).join(" -> ")
121
- raise InheritanceCycleError, "Theme inheritance cycle: #{cycle}"
116
+ def empty_theme
117
+ {
118
+ name: nil,
119
+ inherit: nil,
120
+ roles: {},
121
+ source: nil,
122
+ }
122
123
  end
123
124
 
124
- parent =
125
- if defn[:inherit]
126
- merge_theme_chain(registry, defn[:inherit], stack: stack + [name])
127
- else
128
- empty_theme
129
- end
125
+ def merge_theme_chain(registry, name, stack:)
126
+ defn = registry.fetch(name)
127
+ raise MissingThemeError, "Theme not found: #{name}" unless defn
130
128
 
131
- merged = deep_merge(parent, defn)
132
- merged[:name] = name
133
- merged[:inherit] = defn[:inherit]
134
- merged[:source] = defn[:source]
135
- merged
136
- end
129
+ if stack.include?(name)
130
+ cycle = (stack + [name]).join(" -> ")
131
+ raise InheritanceCycleError, "Theme inheritance cycle: #{cycle}"
132
+ end
137
133
 
138
- def self.resolve_role_inheritance(roles)
139
- resolved = {}
140
- names = (
141
- ROLE_PARENTS.keys +
142
- ROLE_PARENTS.values +
143
- DEFAULT_ROLE_SPECS.keys +
144
- roles.keys
145
- ).compact.uniq
146
-
147
- names.each do |name|
148
- resolve_role(name, roles, resolved, stack: [])
134
+ parent =
135
+ if defn[:inherit]
136
+ merge_theme_chain(registry, defn[:inherit], stack: stack + [name])
137
+ else
138
+ empty_theme
139
+ end
140
+
141
+ merged = merge_theme(parent, defn)
142
+ merged[:name] = name
143
+ merged[:inherit] = defn[:inherit]
144
+ merged[:source] = defn[:source]
145
+ merged
149
146
  end
150
147
 
151
- resolved
152
- end
153
-
154
- def self.resolve_role(name, roles, resolved, stack:)
155
- return resolved[name] if resolved.key?(name)
148
+ def resolve_role_inheritance(roles)
149
+ resolved = {}
150
+ names = (
151
+ ROLE_PARENTS.keys +
152
+ ROLE_PARENTS.values +
153
+ DEFAULT_ROLE_SPECS.keys +
154
+ roles.keys
155
+ ).compact.uniq
156
+
157
+ names.each do |name|
158
+ resolve_role(name, roles, resolved, stack: [])
159
+ end
156
160
 
157
- if stack.include?(name)
158
- raise InheritanceCycleError, "Role inheritance cycle: #{(stack + [name]).join(' -> ')}"
161
+ resolved
159
162
  end
160
163
 
161
- spec = roles[name] || DEFAULT_ROLE_SPECS.fetch(name, {})
162
- parent_name =
163
- if spec.key?(:inherit)
164
- spec[:inherit]&.to_sym
165
- else
166
- ROLE_PARENTS[name]
167
- end
164
+ def resolve_role(name, roles, resolved, stack:)
165
+ return resolved[name] if resolved.key?(name)
168
166
 
169
- parent_spec =
170
- if parent_name
171
- resolve_role(parent_name, roles, resolved, stack: stack + [name])
172
- else
173
- {}
167
+ if stack.include?(name)
168
+ raise InheritanceCycleError, "Role inheritance cycle: #{(stack + [name]).join(' -> ')}"
174
169
  end
175
170
 
176
- resolved[name] = deep_merge_hash(parent_spec, spec.reject { |k, _| k == :inherit })
177
- end
178
-
179
- def self.deep_merge(parent, child)
180
- out = parent.dup
171
+ spec = roles[name] || DEFAULT_ROLE_SPECS.fetch(name, {})
172
+ parent_name =
173
+ if spec.key?(:inherit)
174
+ spec[:inherit]&.to_sym
175
+ else
176
+ ROLE_PARENTS[name]
177
+ end
178
+
179
+ parent_spec =
180
+ if parent_name
181
+ resolve_role(parent_name, roles, resolved, stack: stack + [name])
182
+ else
183
+ {}
184
+ end
185
+
186
+ resolved[name] = parent_spec.deep_merge(spec).reject { |k, _| k == :inherit }
187
+ end
181
188
 
182
- out[:roles] = deep_merge_hash(parent[:roles] || {}, child[:roles] || {})
189
+ def merge_theme(parent, child)
190
+ out = parent.dup
191
+ out[:roles] = (parent[:roles] || {}).deep_merge(child[:roles] || {})
192
+ child.each do |key, value|
193
+ next if key == :roles
183
194
 
184
- child.each do |key, value|
185
- next if key == :roles
195
+ out[key] = value
196
+ end
197
+ out
198
+ end
186
199
 
187
- out[key] = value
200
+ def deep_merge_hash(parent, child)
201
+ parent.merge(child) do |_key, old_value, new_value|
202
+ if old_value.is_a?(Hash) && new_value.is_a?(Hash)
203
+ deep_merge_hash(old_value, new_value)
204
+ else
205
+ new_value
206
+ end
207
+ end
188
208
  end
189
209
 
190
- out
191
- end
210
+ def add_composite_roles(roles)
211
+ roles = roles.dup
192
212
 
193
- def self.deep_merge_hash(parent, child)
194
- parent.merge(child) do |_key, old_value, new_value|
195
- if old_value.is_a?(Hash) && new_value.is_a?(Hash)
196
- deep_merge_hash(old_value, new_value)
197
- else
198
- new_value
199
- end
213
+ roles[:alert_info] = composite_role(roles[:alert] || {}, roles[:info] || {})
214
+ roles[:alert_good] = composite_role(roles[:alert] || {}, roles[:good] || {})
215
+ roles[:alert_warn] = composite_role(roles[:alert] || {}, roles[:warn] || {})
216
+ roles[:alert_error] = composite_role(roles[:alert] || {}, roles[:error] || {})
217
+ roles
200
218
  end
201
- end
202
219
 
203
- def self.add_composite_roles(roles)
204
- roles = roles.dup
220
+ def composite_role(base, accent)
221
+ {
222
+ fg: accent[:fg] || accent["fg"] || base[:fg] || base["fg"],
223
+ bg: accent[:bg] || accent["bg"] || base[:bg] || base["bg"],
224
+ attrs: combine_attrs(base, accent),
225
+ }.compact
226
+ end
205
227
 
206
- roles[:alert_info] = composite_role(roles[:alert] || {}, roles[:info] || {})
207
- roles[:alert_good] = composite_role(roles[:alert] || {}, roles[:good] || {})
208
- roles[:alert_warn] = composite_role(roles[:alert] || {}, roles[:warn] || {})
209
- roles[:alert_error] = composite_role(roles[:alert] || {}, roles[:error] || {})
210
- roles
211
- end
212
- private_class_method :add_composite_roles
213
-
214
- def self.composite_role(base, accent)
215
- {
216
- fg: accent[:fg] || accent["fg"] || base[:fg] || base["fg"],
217
- bg: base[:bg] || base["bg"] || accent[:bg] || accent["bg"],
218
- attrs: accent[:attrs] || accent["attrs"] || base[:attrs] || base["attrs"],
219
- }.compact
228
+ def combine_attrs(base, accent)
229
+ (
230
+ Array(base[:attrs] || base["attrs"]) +
231
+ Array(accent[:attrs] || accent["attrs"])
232
+ ).uniq
233
+ end
220
234
  end
221
- private_class_method :composite_role
222
235
  end
223
236
  end
224
237
  end
data/lib/fatty/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Fatty
4
- VERSION = "0.99.0"
4
+ VERSION = "0.99.3"
5
5
  end
@@ -5,11 +5,18 @@ module Fatty
5
5
  attr_accessor :top
6
6
  attr_accessor :height
7
7
 
8
- def initialize(top: 0, height:)
8
+ def initialize(top: 0, height: 10)
9
9
  @top = top
10
10
  @height = height
11
11
  end
12
12
 
13
+ def state
14
+ [
15
+ top,
16
+ height,
17
+ ]
18
+ end
19
+
13
20
  def adjust_for_trim(n)
14
21
  @top = [@top - n, 0].max
15
22
  end
data/lib/fatty.rb CHANGED
@@ -14,7 +14,33 @@ require 'debug'
14
14
  # Gem Overview (extracted from README.org by gem_docs)
15
15
  #
16
16
  # * Introduction
17
+ # ~Fatty~ aims to provide a full-featured command-line environment that provides:
17
18
  #
19
+ # 1. an editing command-line input,
20
+ # 2. a history facility,
21
+ # 3. command completion,
22
+ # 4. completion of partially-typed file path names,
23
+ # 5. output into a paging environment,
24
+ # 6. searching within the paged output,
25
+ # 7. issuing messages to a "status" area separate from the output pane,
26
+ # 8. binding keys to pre-defined actions,
27
+ # 9. defining unrecognized key-codes as named keys,
28
+ # 10. color themes that can be selected in real time,
29
+ # 11. a way to define new themes,
30
+ # 12. processes completed command-lines with a callback procedure of your
31
+ # choosing,
32
+ # 13. several user-interface widgets such a selection popups, prompt for input, etc.,
33
+ # 14. a set of progress indicators you can use to display to the end user,
34
+ # 15. a way to render markdown to the output pane,
35
+ #
36
+ # In other words, fatty allows you to write a terminal-based REPL of your choosing but takes
37
+ # care of all the difficult parts.
38
+ #
39
+ # ~Fatty~ is written entirely in Ruby and was born from my frustrations at the
40
+ # limitations of libraries like ~readline~ and ~reline~. It relies on ~curses~
41
+ # and ~truecolor~ for low-level rendering and is surprisingly snappy.
42
+ #
43
+ # ~Fatty~ is /not/ a terminal emulator but runs on top of one.
18
44
  module Fatty
19
45
  require_relative "fatty/version"
20
46
  require_relative "fatty/core_ext"
@@ -22,10 +48,9 @@ module Fatty
22
48
  require_relative "fatty/config"
23
49
  require_relative "fatty/logger"
24
50
  require_relative "fatty/counter"
25
- require_relative "fatty/action_environment"
26
- require_relative "fatty/accept_env"
27
51
  require_relative "fatty/action"
28
52
  require_relative "fatty/actionable"
53
+ require_relative "fatty/command"
29
54
  require_relative "fatty/history"
30
55
  require_relative "fatty/search"
31
56
  require_relative "fatty/input_buffer"
@@ -36,20 +61,23 @@ module Fatty
36
61
  require_relative "fatty/key_event"
37
62
  require_relative "fatty/mouse_event"
38
63
  require_relative "fatty/key_map"
39
- require_relative "fatty/themes"
40
- require_relative "fatty/ansi"
41
64
  require_relative "fatty/colors"
65
+ require_relative "fatty/ansi"
42
66
  require_relative "fatty/curses"
43
67
  require_relative "fatty/renderer"
68
+ require_relative "fatty/themes"
44
69
  require_relative "fatty/prompt"
45
- require_relative "fatty/menu_env"
70
+ require_relative "fatty/progress"
46
71
  require_relative "fatty/screen"
47
72
  require_relative "fatty/viewport"
48
- require_relative "fatty/views"
49
- require_relative "fatty/sessions"
73
+ require_relative "fatty/session"
74
+ require_relative "fatty/api"
50
75
  require_relative "fatty/terminal"
51
76
  require_relative "fatty/markdown"
52
77
  require_relative "fatty/help"
78
+ require_relative "fatty/action_environment"
79
+ require_relative "fatty/callback_environment"
53
80
 
54
81
  class Error < StandardError; end
82
+ class Interrupt < StandardError; end
55
83
  end