rufio 1.1.0 → 1.3.0
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.md +34 -0
- data/README.md +74 -3
- data/README_ja.md +71 -2
- data/Rakefile +14 -1
- data/bin/rufio +31 -2
- data/docs/fast_zip_design_ja.md +167 -0
- data/info/help.md +2 -0
- data/info/keybindings.md +3 -1
- data/info/welcome.md +1 -1
- data/lib/rufio/application.rb +12 -1
- data/lib/rufio/archive_controller.rb +211 -0
- data/lib/rufio/background_command_executor.rb +9 -0
- data/lib/rufio/background_status.rb +49 -0
- data/lib/rufio/bookmark_controller.rb +38 -121
- data/lib/rufio/bookmark_manager.rb +77 -331
- data/lib/rufio/command_completion.rb +6 -1
- data/lib/rufio/command_history.rb +5 -2
- data/lib/rufio/command_mode.rb +40 -134
- data/lib/rufio/command_mode_ui.rb +4 -42
- data/lib/rufio/config.rb +88 -136
- data/lib/rufio/config_loader.rb +3 -11
- data/lib/rufio/dialog_renderer.rb +64 -152
- data/lib/rufio/dialog_support.rb +69 -0
- data/lib/rufio/document_text_extractor.rb +167 -0
- data/lib/rufio/file_operation_controller.rb +49 -222
- data/lib/rufio/file_preview.rb +46 -2
- data/lib/rufio/global_search.rb +121 -9
- data/lib/rufio/help_menu.rb +8 -2
- data/lib/rufio/interpreter_resolver.rb +6 -11
- data/lib/rufio/job_manager.rb +2 -5
- data/lib/rufio/key_input.rb +77 -0
- data/lib/rufio/keybind_handler.rb +81 -115
- data/lib/rufio/local_script_scanner.rb +6 -18
- data/lib/rufio/native/aarch64-linux-gnu/librufio_zig.so +0 -0
- data/lib/rufio/native/aarch64-linux-musl/librufio_zig.so +0 -0
- data/lib/rufio/native/aarch64-macos/librufio_zig.dylib +0 -0
- data/lib/rufio/native/aarch64-windows/rufio_zig.dll +0 -0
- data/lib/rufio/native/x86_64-linux-gnu/librufio_zig.so +0 -0
- data/lib/rufio/native/x86_64-linux-musl/librufio_zig.so +0 -0
- data/lib/rufio/native/x86_64-macos/librufio_zig.dylib +0 -0
- data/lib/rufio/native/x86_64-windows/rufio_zig.dll +0 -0
- data/lib/rufio/native_content_search.rb +153 -0
- data/lib/rufio/native_scanner.rb +13 -68
- data/lib/rufio/native_scanner_zig.rb +106 -56
- data/lib/rufio/native_zip.rb +121 -0
- data/lib/rufio/navigation_controller.rb +18 -20
- data/lib/rufio/screen.rb +2 -12
- data/lib/rufio/script_executor.rb +6 -73
- data/lib/rufio/script_file.rb +44 -0
- data/lib/rufio/script_path_manager.rb +9 -43
- data/lib/rufio/script_runner.rb +13 -50
- data/lib/rufio/search_controller.rb +1 -1
- data/lib/rufio/shell_command_completion.rb +1 -5
- data/lib/rufio/shell_init.rb +90 -0
- data/lib/rufio/task_status.rb +5 -1
- data/lib/rufio/terminal_ui.rb +55 -294
- data/lib/rufio/text_utils.rb +26 -3
- data/lib/rufio/ui_renderer.rb +63 -40
- data/lib/rufio/version.rb +1 -1
- data/lib/rufio/zip_archive.rb +314 -0
- data/lib/rufio/zip_extractor.rb +346 -0
- data/lib/rufio/zip_writer.rb +268 -0
- data/lib/rufio/zoxide_integration.rb +5 -43
- data/lib/rufio.rb +5 -0
- data/lib_zig/rufio_native/Makefile +54 -17
- data/lib_zig/rufio_native/bench.sh +36 -0
- data/lib_zig/rufio_native/build.zig +32 -35
- data/lib_zig/rufio_native/src/cli.zig +99 -0
- data/lib_zig/rufio_native/src/main.zig +187 -83
- data/lib_zig/rufio_native/src/os.zig +889 -0
- data/lib_zig/rufio_native/src/search.zig +919 -0
- data/lib_zig/rufio_native/src/search_test.zig +88 -0
- data/lib_zig/rufio_native/src/zip.zig +482 -0
- metadata +125 -3
- data/lib/rufio/native/rufio_zig.bundle +0 -0
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require_relative 'dialog_support'
|
|
4
|
+
require_relative 'text_utils'
|
|
3
5
|
require_relative 'bookmark'
|
|
4
6
|
require_relative 'bookmark_storage'
|
|
5
7
|
require_relative 'config_loader'
|
|
@@ -7,6 +9,8 @@ require_relative 'config_loader'
|
|
|
7
9
|
module Rufio
|
|
8
10
|
# Manages bookmark operations with interactive UI
|
|
9
11
|
class BookmarkManager
|
|
12
|
+
include DialogSupport
|
|
13
|
+
|
|
10
14
|
def initialize(bookmark = nil, dialog_renderer = nil)
|
|
11
15
|
@bookmark = bookmark || create_default_bookmark
|
|
12
16
|
@dialog_renderer = dialog_renderer
|
|
@@ -31,159 +35,29 @@ module Rufio
|
|
|
31
35
|
|
|
32
36
|
public
|
|
33
37
|
|
|
34
|
-
#
|
|
35
|
-
# @
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
'[A]dd current directory to bookmarks',
|
|
44
|
-
'[L]ist bookmarks',
|
|
45
|
-
'[R]ename bookmark',
|
|
46
|
-
'[D]elete bookmark',
|
|
47
|
-
'',
|
|
48
|
-
'Press 1-9 to go to bookmark directly',
|
|
49
|
-
'',
|
|
50
|
-
'Press any other key to cancel'
|
|
51
|
-
]
|
|
52
|
-
|
|
53
|
-
dialog_width = 45
|
|
54
|
-
dialog_height = 4 + content_lines.length
|
|
55
|
-
|
|
56
|
-
result = { action: :cancel }
|
|
57
|
-
show_overlay_dialog(title, content_lines, {
|
|
58
|
-
width: dialog_width,
|
|
59
|
-
height: dialog_height,
|
|
60
|
-
border_color: "\e[34m", # Blue
|
|
61
|
-
title_color: "\e[1;34m", # Bold blue
|
|
62
|
-
content_color: "\e[37m" # White
|
|
63
|
-
}) do
|
|
64
|
-
# Wait for key input
|
|
65
|
-
loop do
|
|
66
|
-
input = STDIN.getch.downcase
|
|
67
|
-
|
|
68
|
-
case input
|
|
69
|
-
when 'a'
|
|
70
|
-
result = { action: :add, path: current_path }
|
|
71
|
-
break
|
|
72
|
-
when 'l'
|
|
73
|
-
result = { action: :list }
|
|
74
|
-
break
|
|
75
|
-
when 'r'
|
|
76
|
-
result = { action: :rename }
|
|
77
|
-
break
|
|
78
|
-
when 'd'
|
|
79
|
-
result = { action: :remove }
|
|
80
|
-
break
|
|
81
|
-
when '1', '2', '3', '4', '5', '6', '7', '8', '9'
|
|
82
|
-
result = { action: :navigate, number: input.to_i }
|
|
83
|
-
break
|
|
84
|
-
else
|
|
85
|
-
# Cancel
|
|
86
|
-
result = { action: :cancel }
|
|
87
|
-
break
|
|
88
|
-
end
|
|
89
|
-
end
|
|
90
|
-
nil
|
|
91
|
-
end
|
|
92
|
-
|
|
93
|
-
result
|
|
94
|
-
end
|
|
95
|
-
|
|
96
|
-
# Add a bookmark interactively
|
|
97
|
-
# @param path [String] Path to bookmark
|
|
98
|
-
# @return [Boolean] Success status
|
|
99
|
-
def add_interactive(path)
|
|
100
|
-
return false unless @dialog_renderer
|
|
101
|
-
|
|
102
|
-
# Show floating input dialog
|
|
103
|
-
title = 'Add Bookmark'
|
|
104
|
-
prompt = 'Enter bookmark name:'
|
|
105
|
-
name = @dialog_renderer.show_input_dialog(title, prompt, {
|
|
106
|
-
border_color: "\e[34m", # Blue
|
|
107
|
-
title_color: "\e[1;34m", # Bold blue
|
|
108
|
-
content_color: "\e[37m" # White
|
|
109
|
-
})
|
|
110
|
-
|
|
111
|
-
return false if name.nil? || name.empty?
|
|
112
|
-
|
|
113
|
-
# Add bookmark (name is already trimmed in show_input_dialog)
|
|
114
|
-
if @bookmark.add(path, name)
|
|
115
|
-
show_result_dialog('Bookmark Added', "Added: #{name}", :success)
|
|
116
|
-
true
|
|
117
|
-
else
|
|
118
|
-
show_result_dialog('Add Failed', 'Failed to add bookmark', :error)
|
|
119
|
-
false
|
|
120
|
-
end
|
|
38
|
+
# List all bookmarks interactively
|
|
39
|
+
# @return [Hash, nil] Selected bookmark path or nil
|
|
40
|
+
def list_interactive
|
|
41
|
+
select_bookmark_from_dialog(
|
|
42
|
+
title: 'Bookmarks',
|
|
43
|
+
header: 'Select a bookmark:',
|
|
44
|
+
border_color: "\e[34m",
|
|
45
|
+
title_color: "\e[1;34m"
|
|
46
|
+
)
|
|
121
47
|
end
|
|
122
48
|
|
|
123
49
|
# Rename a bookmark interactively
|
|
124
50
|
# @return [Boolean] Success status
|
|
125
51
|
def rename_interactive
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
# Build content lines for bookmark selection
|
|
136
|
-
content_lines = ['', 'Select bookmark to rename:', '']
|
|
137
|
-
bookmarks.each_with_index do |bookmark, index|
|
|
138
|
-
# Truncate path if too long
|
|
139
|
-
display_path = bookmark[:path]
|
|
140
|
-
if display_path.start_with?(Dir.home)
|
|
141
|
-
display_path = display_path.sub(Dir.home, '~')
|
|
142
|
-
end
|
|
143
|
-
if display_path.length > 35
|
|
144
|
-
display_path = "...#{display_path[-32..]}"
|
|
145
|
-
end
|
|
146
|
-
content_lines << " #{index + 1}. #{bookmark[:name]}"
|
|
147
|
-
content_lines << " #{display_path}"
|
|
148
|
-
end
|
|
149
|
-
content_lines << ''
|
|
150
|
-
content_lines << 'Press 1-9 to select, ESC to cancel'
|
|
151
|
-
|
|
152
|
-
title = 'Rename Bookmark'
|
|
153
|
-
width = 60
|
|
154
|
-
height = [content_lines.length + 4, 20].min
|
|
155
|
-
|
|
156
|
-
# Wait for selection
|
|
157
|
-
selected_number = nil
|
|
158
|
-
show_overlay_dialog(title, content_lines, {
|
|
159
|
-
width: width,
|
|
160
|
-
height: height,
|
|
161
|
-
border_color: "\e[33m", # Yellow
|
|
162
|
-
title_color: "\e[1;33m", # Bold yellow
|
|
163
|
-
content_color: "\e[37m" # White
|
|
164
|
-
}) do
|
|
165
|
-
loop do
|
|
166
|
-
input = STDIN.getch.downcase
|
|
167
|
-
|
|
168
|
-
if input >= '1' && input <= '9'
|
|
169
|
-
number = input.to_i
|
|
170
|
-
if number > 0 && number <= bookmarks.length
|
|
171
|
-
selected_number = number
|
|
172
|
-
break
|
|
173
|
-
end
|
|
174
|
-
elsif input == "\e" # ESC
|
|
175
|
-
break
|
|
176
|
-
end
|
|
177
|
-
end
|
|
178
|
-
nil
|
|
179
|
-
end
|
|
180
|
-
|
|
181
|
-
return false unless selected_number
|
|
182
|
-
|
|
183
|
-
# Get new name
|
|
184
|
-
bookmark_to_rename = bookmarks[selected_number - 1]
|
|
185
|
-
old_name = bookmark_to_rename[:name]
|
|
186
|
-
|
|
52
|
+
selected = select_bookmark_from_dialog(
|
|
53
|
+
title: 'Rename Bookmark',
|
|
54
|
+
header: 'Select bookmark to rename:',
|
|
55
|
+
border_color: "\e[33m",
|
|
56
|
+
title_color: "\e[1;33m"
|
|
57
|
+
)
|
|
58
|
+
return false unless selected
|
|
59
|
+
|
|
60
|
+
old_name = selected[:name]
|
|
187
61
|
new_name = @dialog_renderer.show_input_dialog("Rename: #{old_name}", "Enter new name:", {
|
|
188
62
|
border_color: "\e[33m", # Yellow
|
|
189
63
|
title_color: "\e[1;33m", # Bold yellow
|
|
@@ -192,140 +66,27 @@ module Rufio
|
|
|
192
66
|
|
|
193
67
|
return false if new_name.nil? || new_name.empty?
|
|
194
68
|
|
|
195
|
-
# Rename bookmark
|
|
196
69
|
@bookmark.rename(old_name, new_name)
|
|
197
70
|
end
|
|
198
71
|
|
|
199
72
|
# Remove a bookmark interactively
|
|
200
73
|
# @return [Boolean] Success status
|
|
201
74
|
def remove_interactive
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
content_lines = ['', 'Select bookmark to delete:', '']
|
|
213
|
-
bookmarks.each_with_index do |bookmark, index|
|
|
214
|
-
# Truncate path if too long
|
|
215
|
-
display_path = bookmark[:path]
|
|
216
|
-
if display_path.start_with?(Dir.home)
|
|
217
|
-
display_path = display_path.sub(Dir.home, '~')
|
|
218
|
-
end
|
|
219
|
-
if display_path.length > 35
|
|
220
|
-
display_path = "...#{display_path[-32..]}"
|
|
221
|
-
end
|
|
222
|
-
content_lines << " #{index + 1}. #{bookmark[:name]}"
|
|
223
|
-
content_lines << " #{display_path}"
|
|
224
|
-
end
|
|
225
|
-
content_lines << ''
|
|
226
|
-
content_lines << 'Press 1-9 to select, ESC to cancel'
|
|
227
|
-
|
|
228
|
-
title = 'Delete Bookmark'
|
|
229
|
-
width = 60
|
|
230
|
-
height = [content_lines.length + 4, 20].min
|
|
231
|
-
|
|
232
|
-
# Wait for selection
|
|
233
|
-
selected_number = nil
|
|
234
|
-
show_overlay_dialog(title, content_lines, {
|
|
235
|
-
width: width,
|
|
236
|
-
height: height,
|
|
237
|
-
border_color: "\e[31m", # Red (warning)
|
|
238
|
-
title_color: "\e[1;31m", # Bold red
|
|
239
|
-
content_color: "\e[37m" # White
|
|
240
|
-
}) do
|
|
241
|
-
loop do
|
|
242
|
-
input = STDIN.getch.downcase
|
|
243
|
-
|
|
244
|
-
if input >= '1' && input <= '9'
|
|
245
|
-
number = input.to_i
|
|
246
|
-
if number > 0 && number <= bookmarks.length
|
|
247
|
-
selected_number = number
|
|
248
|
-
break
|
|
249
|
-
end
|
|
250
|
-
elsif input == "\e" # ESC
|
|
251
|
-
break
|
|
252
|
-
end
|
|
253
|
-
end
|
|
254
|
-
nil
|
|
255
|
-
end
|
|
256
|
-
|
|
257
|
-
return false unless selected_number
|
|
258
|
-
|
|
259
|
-
# Confirm deletion
|
|
260
|
-
bookmark_to_remove = bookmarks[selected_number - 1]
|
|
261
|
-
if show_remove_confirmation(bookmark_to_remove[:name])
|
|
262
|
-
@bookmark.remove(bookmark_to_remove[:name])
|
|
75
|
+
selected = select_bookmark_from_dialog(
|
|
76
|
+
title: 'Delete Bookmark',
|
|
77
|
+
header: 'Select bookmark to delete:',
|
|
78
|
+
border_color: "\e[31m",
|
|
79
|
+
title_color: "\e[1;31m"
|
|
80
|
+
)
|
|
81
|
+
return false unless selected
|
|
82
|
+
|
|
83
|
+
if show_remove_confirmation(selected[:name])
|
|
84
|
+
@bookmark.remove(selected[:name])
|
|
263
85
|
else
|
|
264
86
|
false
|
|
265
87
|
end
|
|
266
88
|
end
|
|
267
89
|
|
|
268
|
-
# List all bookmarks interactively
|
|
269
|
-
# @return [Hash, nil] Selected bookmark path or nil
|
|
270
|
-
def list_interactive
|
|
271
|
-
bookmarks = @bookmark.list
|
|
272
|
-
|
|
273
|
-
if bookmarks.empty?
|
|
274
|
-
show_result_dialog('No Bookmarks', 'No bookmarks found', :error)
|
|
275
|
-
return nil
|
|
276
|
-
end
|
|
277
|
-
|
|
278
|
-
return nil unless @dialog_renderer
|
|
279
|
-
|
|
280
|
-
# Build content lines
|
|
281
|
-
content_lines = ['', 'Select a bookmark:','']
|
|
282
|
-
bookmarks.each_with_index do |bookmark, index|
|
|
283
|
-
# Truncate path if too long
|
|
284
|
-
display_path = bookmark[:path]
|
|
285
|
-
if display_path.start_with?(Dir.home)
|
|
286
|
-
display_path = display_path.sub(Dir.home, '~')
|
|
287
|
-
end
|
|
288
|
-
if display_path.length > 35
|
|
289
|
-
display_path = "...#{display_path[-32..]}"
|
|
290
|
-
end
|
|
291
|
-
content_lines << " #{index + 1}. #{bookmark[:name]}"
|
|
292
|
-
content_lines << " #{display_path}"
|
|
293
|
-
end
|
|
294
|
-
content_lines << ''
|
|
295
|
-
content_lines << 'Press 1-9 to select, ESC to cancel'
|
|
296
|
-
|
|
297
|
-
title = 'Bookmarks'
|
|
298
|
-
width = 60
|
|
299
|
-
height = [content_lines.length + 4, 20].min
|
|
300
|
-
|
|
301
|
-
# Wait for selection
|
|
302
|
-
selected_bookmark = nil
|
|
303
|
-
show_overlay_dialog(title, content_lines, {
|
|
304
|
-
width: width,
|
|
305
|
-
height: height,
|
|
306
|
-
border_color: "\e[34m", # Blue
|
|
307
|
-
title_color: "\e[1;34m", # Bold blue
|
|
308
|
-
content_color: "\e[37m" # White
|
|
309
|
-
}) do
|
|
310
|
-
loop do
|
|
311
|
-
input = STDIN.getch.downcase
|
|
312
|
-
|
|
313
|
-
if input >= '1' && input <= '9'
|
|
314
|
-
number = input.to_i
|
|
315
|
-
if number > 0 && number <= bookmarks.length
|
|
316
|
-
selected_bookmark = bookmarks[number - 1]
|
|
317
|
-
break
|
|
318
|
-
end
|
|
319
|
-
elsif input == "\e" # ESC
|
|
320
|
-
break
|
|
321
|
-
end
|
|
322
|
-
end
|
|
323
|
-
nil
|
|
324
|
-
end
|
|
325
|
-
|
|
326
|
-
selected_bookmark
|
|
327
|
-
end
|
|
328
|
-
|
|
329
90
|
# Get bookmark by number
|
|
330
91
|
# @param number [Integer] Bookmark number (1-9)
|
|
331
92
|
# @return [Hash, nil] Bookmark hash with :path and :name
|
|
@@ -390,46 +151,53 @@ module Rufio
|
|
|
390
151
|
|
|
391
152
|
private
|
|
392
153
|
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
@terminal_ui.renderer
|
|
401
|
-
|
|
402
|
-
if use_overlay
|
|
403
|
-
# オーバーレイを使用
|
|
404
|
-
@terminal_ui.show_overlay_dialog(title, content_lines, options, &block)
|
|
405
|
-
else
|
|
406
|
-
# フォールバック: 従来の方法
|
|
407
|
-
width = options[:width]
|
|
408
|
-
height = options[:height]
|
|
409
|
-
|
|
410
|
-
unless width && height
|
|
411
|
-
width, height = @dialog_renderer.calculate_dimensions(content_lines, {
|
|
412
|
-
title: title,
|
|
413
|
-
min_width: options[:min_width] || 40,
|
|
414
|
-
max_width: options[:max_width] || 80
|
|
415
|
-
})
|
|
416
|
-
end
|
|
154
|
+
def select_bookmark_from_dialog(title:, header:, border_color:, title_color:)
|
|
155
|
+
bookmarks = @bookmark.list
|
|
156
|
+
|
|
157
|
+
if bookmarks.empty?
|
|
158
|
+
show_result_dialog('No Bookmarks', 'No bookmarks found', :error)
|
|
159
|
+
return nil
|
|
160
|
+
end
|
|
417
161
|
|
|
418
|
-
|
|
162
|
+
return nil unless @dialog_renderer
|
|
419
163
|
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
}
|
|
164
|
+
content_lines = ['', header, '']
|
|
165
|
+
bookmarks.each_with_index do |bookmark, index|
|
|
166
|
+
display_path = TextUtils.shorten_path_from_end(bookmark[:path], 35, tilde: true)
|
|
167
|
+
content_lines << " #{index + 1}. #{bookmark[:name]}"
|
|
168
|
+
content_lines << " #{display_path}"
|
|
169
|
+
end
|
|
170
|
+
content_lines << ''
|
|
171
|
+
content_lines << 'Press 1-9 to select, ESC to cancel'
|
|
425
172
|
|
|
426
|
-
|
|
173
|
+
width = 60
|
|
174
|
+
height = [content_lines.length + 4, 20].min
|
|
427
175
|
|
|
428
|
-
|
|
429
|
-
|
|
176
|
+
selected_bookmark = nil
|
|
177
|
+
show_overlay_dialog(title, content_lines, {
|
|
178
|
+
width: width,
|
|
179
|
+
height: height,
|
|
180
|
+
border_color: border_color,
|
|
181
|
+
title_color: title_color,
|
|
182
|
+
content_color: "\e[37m"
|
|
183
|
+
}) do
|
|
184
|
+
loop do
|
|
185
|
+
input = KeyInput.getch.downcase
|
|
430
186
|
|
|
431
|
-
|
|
187
|
+
if input >= '1' && input <= '9'
|
|
188
|
+
number = input.to_i
|
|
189
|
+
if number > 0 && number <= bookmarks.length
|
|
190
|
+
selected_bookmark = bookmarks[number - 1]
|
|
191
|
+
break
|
|
192
|
+
end
|
|
193
|
+
elsif input == "\e"
|
|
194
|
+
break
|
|
195
|
+
end
|
|
196
|
+
end
|
|
197
|
+
nil
|
|
432
198
|
end
|
|
199
|
+
|
|
200
|
+
selected_bookmark
|
|
433
201
|
end
|
|
434
202
|
|
|
435
203
|
# Show result dialog with success or error styling
|
|
@@ -483,35 +251,13 @@ module Rufio
|
|
|
483
251
|
''
|
|
484
252
|
]
|
|
485
253
|
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
# Wait for confirmation
|
|
491
|
-
confirmed = false
|
|
492
|
-
show_overlay_dialog(title, content_lines, {
|
|
493
|
-
width: width,
|
|
494
|
-
height: height,
|
|
254
|
+
confirm_dialog('Confirm Delete', content_lines, {
|
|
255
|
+
width: 50,
|
|
256
|
+
height: content_lines.length + 4,
|
|
495
257
|
border_color: "\e[33m", # Yellow (warning)
|
|
496
258
|
title_color: "\e[1;33m", # Bold yellow
|
|
497
259
|
content_color: "\e[37m" # White
|
|
498
|
-
})
|
|
499
|
-
loop do
|
|
500
|
-
input = STDIN.getch.downcase
|
|
501
|
-
|
|
502
|
-
case input
|
|
503
|
-
when 'y'
|
|
504
|
-
confirmed = true
|
|
505
|
-
break
|
|
506
|
-
when 'n', "\e" # n or ESC
|
|
507
|
-
confirmed = false
|
|
508
|
-
break
|
|
509
|
-
end
|
|
510
|
-
end
|
|
511
|
-
nil
|
|
512
|
-
end
|
|
513
|
-
|
|
514
|
-
confirmed
|
|
260
|
+
})
|
|
515
261
|
end
|
|
516
262
|
end
|
|
517
263
|
end
|
|
@@ -4,9 +4,14 @@ module Rufio
|
|
|
4
4
|
# コマンド補完機能を提供するクラス
|
|
5
5
|
class CommandCompletion
|
|
6
6
|
# 初期化
|
|
7
|
-
# @param history [CommandHistory, nil]
|
|
7
|
+
# @param history [CommandHistory, CommandMode, nil] 履歴、または単独で渡すコマンドモード
|
|
8
8
|
# @param command_mode [CommandMode, nil] コマンドモード(スクリプト補完に使用)
|
|
9
9
|
def initialize(history = nil, command_mode = nil)
|
|
10
|
+
# CommandMode だけを渡す従来の呼び方も受け付ける。
|
|
11
|
+
if history.is_a?(CommandMode) && command_mode.nil?
|
|
12
|
+
command_mode = history
|
|
13
|
+
history = nil
|
|
14
|
+
end
|
|
10
15
|
@command_mode = command_mode || CommandMode.new
|
|
11
16
|
@shell_completion = ShellCommandCompletion.new
|
|
12
17
|
@history = history
|
|
@@ -5,8 +5,6 @@ module Rufio
|
|
|
5
5
|
class CommandHistory
|
|
6
6
|
DEFAULT_MAX_SIZE = 1000
|
|
7
7
|
|
|
8
|
-
attr_reader :size
|
|
9
|
-
|
|
10
8
|
# 初期化
|
|
11
9
|
# @param history_file [String] 履歴ファイルのパス
|
|
12
10
|
# @param max_size [Integer] 履歴の最大保存数
|
|
@@ -37,6 +35,11 @@ module Rufio
|
|
|
37
35
|
reset_position
|
|
38
36
|
end
|
|
39
37
|
|
|
38
|
+
# 呼び出し側の変更が履歴本体や上下移動の位置に影響しないスナップショット。
|
|
39
|
+
def entries
|
|
40
|
+
@history.map(&:dup)
|
|
41
|
+
end
|
|
42
|
+
|
|
40
43
|
# 前のコマンドを取得(上矢印キー相当)
|
|
41
44
|
# @return [String, nil] 前のコマンド、存在しない場合はnil
|
|
42
45
|
def previous
|