rufio 0.9.0 → 0.10.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d38a3f174b672b93170b943705a2273d9d059fe25c30617654e510679e54d6b8
4
- data.tar.gz: df79412f9a76d3043b11de5d3a01c57d62cd88cd3074cf2ce9fb1cab638810b7
3
+ metadata.gz: 9201391f4316c4c09afabccefe7d81bb919acb11fd895981f87ebb5ad4592858
4
+ data.tar.gz: 0e801a038eb4c50fc170a6ce0838903cf8905b4edeb5dacbbcfaf2c04ceaf7be
5
5
  SHA512:
6
- metadata.gz: b4385e2844d0c5c806facec4ac6e0c7841a9a9a332ef476b66af04812ced251f20b3904c95d94fcfb47da59f43f43138bde36d03bbf15a60784e3b1001062547
7
- data.tar.gz: e1005adf29e7eaaadb2d7d01a742a74b43c2eb1415de10af521944c9d52bc663da9b1e39bd6611f12f88af85734e5345fefa2bc0d9637379ab6ef772b9852bc2
6
+ metadata.gz: 9b7ab89aeed58a0af7f9d3fe617a7e71c13a9ea13f934a97ee6c607de6b30314b7ad6a769bf52d7adb617aa8be8a12f87dc674ee08d0da348c9617a24aab1521
7
+ data.tar.gz: 702f4a988028b4dd69f2a4610ab8393c5bd65d7eaabdaa8a6cd4432917d71a91f96179f2ba226d6a6e4a64e0bdcbed1076db6f0740296fe144fb2298332a8f86
data/CHANGELOG.md CHANGED
@@ -7,6 +7,34 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.10.0] - 2025-01-XX
11
+
12
+ ### 🎨 Enhanced - Bookmark UI Overhaul
13
+ - **Floating input dialogs**: All bookmark operations now use modern floating window interface
14
+ - **Add Bookmark dialog**: Blue-bordered floating input with automatic whitespace trimming
15
+ - **List Bookmark dialog**: Interactive selection with direct navigation support
16
+ - **Remove Bookmark dialog**: Two-stage confirmation with color-coded warnings
17
+ - **Improved input handling**: Better cursor positioning, no border overlap, proper padding
18
+
19
+ ### Added
20
+ - **DialogRenderer#show_input_dialog**: Unified floating input interface with ESC support
21
+ - **Color-coded feedback dialogs**: 🔵 Blue (info), 🔴 Red (warning/error), 🟡 Yellow (confirm), 🟢 Green (success)
22
+ - **Automatic input trimming**: Leading/trailing spaces removed from bookmark names
23
+ - **Path truncation**: Long paths display with `~` for home directory
24
+
25
+ ### Fixed
26
+ - **Input field positioning**: Text no longer overlaps with dialog borders
27
+ - **Bookmark list navigation**: Users can now navigate to bookmarks from list view
28
+ - **Dialog layout**: Proper spacing between all dialog elements
29
+
30
+ ### Technical Details
31
+ - New input dialog system with multi-byte character support
32
+ - Enhanced BookmarkManager with private helper methods for dialogs
33
+ - Improved cursor positioning calculations
34
+ - **Detailed changelog**: [CHANGELOG_v0.10.0.md](./CHANGELOG_v0.10.0.md)
35
+
36
+ ## [0.9.0] - 2025-01-XX
37
+
10
38
  ### Added
11
39
  - **Escape key support for file/directory creation**: Press `Esc` to cancel file (`a`) or directory (`A`) creation prompts and return to the main view
12
40
  - **Interactive input improvements**: Backspace support and better character handling for Japanese input
@@ -0,0 +1,145 @@
1
+ # Changelog v0.10.0 - Bookmark UI Enhancement
2
+
3
+ ## [0.10.0] - 2025-01-XX
4
+
5
+ ### 🎨 Enhanced - Bookmark UI Overhaul
6
+
7
+ Complete redesign of bookmark operations with modern floating window dialogs for improved user experience and consistency.
8
+
9
+ ### Added
10
+
11
+ #### Floating Input Dialog System
12
+ - **New `DialogRenderer#show_input_dialog` method**: Unified floating window input interface
13
+ - Centered floating dialog with customizable colors
14
+ - Real-time character input with visual feedback
15
+ - Multi-byte character support (Japanese, Chinese, etc.)
16
+ - Automatic input trimming (leading/trailing spaces)
17
+ - ESC key support for cancellation
18
+ - Input width validation to prevent overflow
19
+
20
+ #### Enhanced Bookmark Operations
21
+
22
+ **Add Bookmark (`b` → `[A]`)**
23
+ - Floating input dialog with blue border
24
+ - Clear prompt: "Enter bookmark name:"
25
+ - Input indicator: `> ` for better visibility
26
+ - Automatic whitespace trimming
27
+ - Success/error feedback with colored dialogs
28
+ - Green border for success
29
+ - Red border for errors
30
+
31
+ **List Bookmarks (`b` → `[L]`)**
32
+ - Interactive selection from floating dialog
33
+ - Blue-bordered bookmark list
34
+ - Path truncation with `~` for home directory
35
+ - 1-9 number key selection
36
+ - Direct navigation to selected bookmark
37
+ - ESC key to cancel
38
+
39
+ **Remove Bookmark (`b` → `[R]`)**
40
+ - Two-stage confirmation process for safety
41
+ - Red-bordered selection dialog (warning color)
42
+ - Yellow-bordered confirmation dialog (caution color)
43
+ - Displays bookmark name in confirmation
44
+ - Success/error feedback dialogs
45
+ - ESC key support at all stages
46
+
47
+ ### Changed
48
+
49
+ #### UI/UX Improvements
50
+ - **Consistent floating window interface** across all bookmark operations
51
+ - **Color-coded dialogs** for different operation types:
52
+ - 🔵 Blue: Information and input (Add, List)
53
+ - 🔴 Red: Warning and removal (Remove selection)
54
+ - 🟡 Yellow: Confirmation (Remove confirmation)
55
+ - 🟢 Green: Success messages
56
+ - 🔴 Red: Error messages
57
+
58
+ #### Input Handling
59
+ - **Improved cursor positioning** in input dialogs
60
+ - Proper padding from dialog borders
61
+ - Correct vertical alignment accounting for title and separators
62
+ - **Better input field layout**
63
+ - Input line positioned with `> ` prompt indicator
64
+ - Adequate spacing between prompt and input area
65
+ - No text overlapping with dialog borders
66
+
67
+ ### Fixed
68
+
69
+ - **Input field positioning**: Text no longer overlaps with dialog borders
70
+ - Fixed `input_y` calculation: `y + 4` → `y + 6`
71
+ - Fixed `input_x` calculation: `x + 2` → `x + 4`
72
+ - Fixed `max_input_width`: `dialog_width - 4` → `dialog_width - 8`
73
+ - **Bookmark list navigation**: Users can now navigate to bookmarks from the list view
74
+ - **Input trimming**: Leading and trailing spaces automatically removed from bookmark names
75
+ - **Dialog height**: Adjusted to prevent input line from touching bottom border
76
+
77
+ ### Technical Details
78
+
79
+ #### New Components
80
+ ```ruby
81
+ # DialogRenderer enhancements
82
+ - show_input_dialog(title, prompt, options)
83
+ - read_input_in_dialog(x, y, width, height, input_x, input_y, options)
84
+
85
+ # BookmarkManager enhancements
86
+ - show_result_dialog(title, message, type)
87
+ - show_remove_confirmation(bookmark_name)
88
+ ```
89
+
90
+ #### Dialog Layout Improvements
91
+ ```
92
+ Old layout (7 lines):
93
+ ┌─────────────────────┐
94
+ │ Add Bookmark │
95
+ ├─────────────────────┤
96
+ │ Enter bookmark name:│ ← overlapped with border
97
+ └─────────────────────┘
98
+
99
+ New layout (8 lines):
100
+ ┌─────────────────────┐
101
+ │ Add Bookmark │
102
+ ├─────────────────────┤
103
+ │ │
104
+ │ Enter bookmark name:│
105
+ │ │
106
+ │ > │ ← proper spacing
107
+ │ │
108
+ └─────────────────────┘
109
+ ```
110
+
111
+ #### Code Quality
112
+ - Removed unused variable warnings
113
+ - Consistent error handling across all bookmark operations
114
+ - Proper screen refresh after dialog operations
115
+ - All tests passing (261 runs, 1141 assertions, 0 failures)
116
+
117
+ ### Migration Notes
118
+
119
+ **User-facing changes:**
120
+ - All bookmark operations now use floating dialogs
121
+ - No more bottom-of-screen input prompts
122
+ - Improved visual feedback for all operations
123
+ - More intuitive navigation and selection
124
+
125
+ **Developer notes:**
126
+ - `BookmarkManager` methods now return different types:
127
+ - `add_interactive`: Still returns `Boolean`
128
+ - `list_interactive`: Now returns `Hash` (selected bookmark) or `nil`
129
+ - `remove_interactive`: Still returns `Boolean`
130
+ - `KeybindHandler` updated to handle new return types
131
+ - Dialog renderer supports input fields via `show_input_dialog`
132
+
133
+ ### Dependencies
134
+
135
+ No new dependencies added. All changes use existing gems:
136
+ - `io-console` for character input
137
+ - Existing `dialog_renderer` infrastructure
138
+
139
+ ---
140
+
141
+ **Full Diff Stats:**
142
+ - Modified: `lib/rufio/dialog_renderer.rb`
143
+ - Modified: `lib/rufio/bookmark_manager.rb`
144
+ - Modified: `lib/rufio/keybind_handler.rb`
145
+ - Tests: All passing ✅
@@ -68,15 +68,25 @@ module Rufio
68
68
  # @param path [String] Path to bookmark
69
69
  # @return [Boolean] Success status
70
70
  def add_interactive(path)
71
- print ConfigLoader.message('bookmark.input_name') || 'Enter bookmark name: '
72
- name = STDIN.gets.chomp
73
- return false if name.empty?
71
+ return false unless @dialog_renderer
74
72
 
73
+ # Show floating input dialog
74
+ title = 'Add Bookmark'
75
+ prompt = 'Enter bookmark name:'
76
+ name = @dialog_renderer.show_input_dialog(title, prompt, {
77
+ border_color: "\e[34m", # Blue
78
+ title_color: "\e[1;34m", # Bold blue
79
+ content_color: "\e[37m" # White
80
+ })
81
+
82
+ return false if name.nil? || name.empty?
83
+
84
+ # Add bookmark (name is already trimmed in show_input_dialog)
75
85
  if @bookmark.add(path, name)
76
- puts "\n#{ConfigLoader.message('bookmark.added') || 'Bookmark added'}: #{name}"
86
+ show_result_dialog('Bookmark Added', "Added: #{name}", :success)
77
87
  true
78
88
  else
79
- puts "\n#{ConfigLoader.message('bookmark.add_failed') || 'Failed to add bookmark'}"
89
+ show_result_dialog('Add Failed', 'Failed to add bookmark', :error)
80
90
  false
81
91
  end
82
92
  end
@@ -87,50 +97,132 @@ module Rufio
87
97
  bookmarks = @bookmark.list
88
98
 
89
99
  if bookmarks.empty?
90
- puts "\n#{ConfigLoader.message('bookmark.no_bookmarks') || 'No bookmarks found'}"
100
+ show_result_dialog('No Bookmarks', 'No bookmarks found', :error)
91
101
  return false
92
102
  end
93
103
 
94
- puts "\nBookmarks:"
104
+ return false unless @dialog_renderer
105
+
106
+ # Build content lines for bookmark selection
107
+ content_lines = ['', 'Select bookmark to remove:', '']
95
108
  bookmarks.each_with_index do |bookmark, index|
96
- puts " #{index + 1}. #{bookmark[:name]} (#{bookmark[:path]})"
109
+ # Truncate path if too long
110
+ display_path = bookmark[:path]
111
+ if display_path.start_with?(Dir.home)
112
+ display_path = display_path.sub(Dir.home, '~')
113
+ end
114
+ if display_path.length > 35
115
+ display_path = "...#{display_path[-32..]}"
116
+ end
117
+ content_lines << " #{index + 1}. #{bookmark[:name]}"
118
+ content_lines << " #{display_path}"
97
119
  end
120
+ content_lines << ''
121
+ content_lines << 'Press 1-9 to select, ESC to cancel'
122
+
123
+ title = 'Remove Bookmark'
124
+ width = 60
125
+ height = [content_lines.length + 4, 20].min
126
+ x, y = @dialog_renderer.calculate_center(width, height)
98
127
 
99
- print ConfigLoader.message('bookmark.input_number') || 'Enter number to remove: '
100
- input = STDIN.gets.chomp
101
- number = input.to_i
128
+ @dialog_renderer.draw_floating_window(x, y, width, height, title, content_lines, {
129
+ border_color: "\e[31m", # Red (warning)
130
+ title_color: "\e[1;31m", # Bold red
131
+ content_color: "\e[37m" # White
132
+ })
102
133
 
103
- if number > 0 && number <= bookmarks.length
104
- bookmark_to_remove = bookmarks[number - 1]
134
+ # Wait for selection
135
+ selected_number = nil
136
+ loop do
137
+ input = STDIN.getch.downcase
138
+
139
+ if input >= '1' && input <= '9'
140
+ number = input.to_i
141
+ if number > 0 && number <= bookmarks.length
142
+ selected_number = number
143
+ break
144
+ end
145
+ elsif input == "\e" # ESC
146
+ @dialog_renderer.clear_area(x, y, width, height)
147
+ return false
148
+ end
149
+ end
150
+
151
+ @dialog_renderer.clear_area(x, y, width, height)
152
+
153
+ # Confirm deletion
154
+ bookmark_to_remove = bookmarks[selected_number - 1]
155
+ if show_remove_confirmation(bookmark_to_remove[:name])
105
156
  if @bookmark.remove(bookmark_to_remove[:name])
106
- puts "\n#{ConfigLoader.message('bookmark.removed') || 'Bookmark removed'}: #{bookmark_to_remove[:name]}"
157
+ show_result_dialog('Bookmark Removed', "Removed: #{bookmark_to_remove[:name]}", :success)
107
158
  true
108
159
  else
109
- puts "\n#{ConfigLoader.message('bookmark.remove_failed') || 'Failed to remove bookmark'}"
160
+ show_result_dialog('Remove Failed', 'Failed to remove bookmark', :error)
110
161
  false
111
162
  end
112
163
  else
113
- puts "\n#{ConfigLoader.message('bookmark.invalid_number') || 'Invalid number'}"
114
164
  false
115
165
  end
116
166
  end
117
167
 
118
168
  # List all bookmarks interactively
119
- # @return [Boolean] Success status
169
+ # @return [Hash, nil] Selected bookmark path or nil
120
170
  def list_interactive
121
171
  bookmarks = @bookmark.list
122
172
 
123
173
  if bookmarks.empty?
124
- puts "\n#{ConfigLoader.message('bookmark.no_bookmarks') || 'No bookmarks found'}"
125
- return false
174
+ show_result_dialog('No Bookmarks', 'No bookmarks found', :error)
175
+ return nil
126
176
  end
127
177
 
128
- puts "\nBookmarks:"
178
+ return nil unless @dialog_renderer
179
+
180
+ # Build content lines
181
+ content_lines = ['', 'Select a bookmark:','']
129
182
  bookmarks.each_with_index do |bookmark, index|
130
- puts " #{index + 1}. #{bookmark[:name]} (#{bookmark[:path]})"
183
+ # Truncate path if too long
184
+ display_path = bookmark[:path]
185
+ if display_path.start_with?(Dir.home)
186
+ display_path = display_path.sub(Dir.home, '~')
187
+ end
188
+ if display_path.length > 35
189
+ display_path = "...#{display_path[-32..]}"
190
+ end
191
+ content_lines << " #{index + 1}. #{bookmark[:name]}"
192
+ content_lines << " #{display_path}"
193
+ end
194
+ content_lines << ''
195
+ content_lines << 'Press 1-9 to select, ESC to cancel'
196
+
197
+ title = 'Bookmarks'
198
+ width = 60
199
+ height = [content_lines.length + 4, 20].min
200
+ x, y = @dialog_renderer.calculate_center(width, height)
201
+
202
+ @dialog_renderer.draw_floating_window(x, y, width, height, title, content_lines, {
203
+ border_color: "\e[34m", # Blue
204
+ title_color: "\e[1;34m", # Bold blue
205
+ content_color: "\e[37m" # White
206
+ })
207
+
208
+ # Wait for selection
209
+ selected_bookmark = nil
210
+ loop do
211
+ input = STDIN.getch.downcase
212
+
213
+ if input >= '1' && input <= '9'
214
+ number = input.to_i
215
+ if number > 0 && number <= bookmarks.length
216
+ selected_bookmark = bookmarks[number - 1]
217
+ break
218
+ end
219
+ elsif input == "\e" # ESC
220
+ break
221
+ end
131
222
  end
132
223
 
133
- true
224
+ @dialog_renderer.clear_area(x, y, width, height)
225
+ selected_bookmark
134
226
  end
135
227
 
136
228
  # Get bookmark by number
@@ -169,5 +261,89 @@ module Rufio
169
261
  def remove(name)
170
262
  @bookmark.remove(name)
171
263
  end
264
+
265
+ private
266
+
267
+ # Show result dialog with success or error styling
268
+ # @param title [String] Dialog title
269
+ # @param message [String] Result message
270
+ # @param type [Symbol] :success or :error
271
+ def show_result_dialog(title, message, type)
272
+ return unless @dialog_renderer
273
+
274
+ # Set colors based on result type
275
+ if type == :success
276
+ border_color = "\e[32m" # Green
277
+ title_color = "\e[1;32m" # Bold green
278
+ else
279
+ border_color = "\e[31m" # Red
280
+ title_color = "\e[1;31m" # Bold red
281
+ end
282
+
283
+ content_lines = [
284
+ '',
285
+ message,
286
+ '',
287
+ 'Press any key to continue...'
288
+ ]
289
+
290
+ width = 50
291
+ height = 6
292
+ x, y = @dialog_renderer.calculate_center(width, height)
293
+
294
+ @dialog_renderer.draw_floating_window(x, y, width, height, title, content_lines, {
295
+ border_color: border_color,
296
+ title_color: title_color,
297
+ content_color: "\e[37m"
298
+ })
299
+
300
+ STDIN.getch
301
+ @dialog_renderer.clear_area(x, y, width, height)
302
+ end
303
+
304
+ # Show confirmation dialog for bookmark removal
305
+ # @param bookmark_name [String] Name of bookmark to remove
306
+ # @return [Boolean] true if confirmed, false if cancelled
307
+ def show_remove_confirmation(bookmark_name)
308
+ return false unless @dialog_renderer
309
+
310
+ content_lines = [
311
+ '',
312
+ "Remove bookmark '#{bookmark_name}'?",
313
+ '',
314
+ ' [Y]es - Remove',
315
+ ' [N]o - Cancel',
316
+ ''
317
+ ]
318
+
319
+ title = 'Confirm Remove'
320
+ width = 50
321
+ height = content_lines.length + 4
322
+ x, y = @dialog_renderer.calculate_center(width, height)
323
+
324
+ @dialog_renderer.draw_floating_window(x, y, width, height, title, content_lines, {
325
+ border_color: "\e[33m", # Yellow (warning)
326
+ title_color: "\e[1;33m", # Bold yellow
327
+ content_color: "\e[37m" # White
328
+ })
329
+
330
+ # Wait for confirmation
331
+ confirmed = false
332
+ loop do
333
+ input = STDIN.getch.downcase
334
+
335
+ case input
336
+ when 'y'
337
+ confirmed = true
338
+ break
339
+ when 'n', "\e" # n or ESC
340
+ confirmed = false
341
+ break
342
+ end
343
+ end
344
+
345
+ @dialog_renderer.clear_area(x, y, width, height)
346
+ confirmed
347
+ end
172
348
  end
173
349
  end
@@ -123,5 +123,111 @@ module Rufio
123
123
 
124
124
  [width, height]
125
125
  end
126
+
127
+ # Show a floating input dialog and get user input
128
+ # @param title [String] Dialog title
129
+ # @param prompt [String] Prompt message
130
+ # @param options [Hash] Customization options
131
+ # @option options [String] :border_color Border color ANSI code
132
+ # @option options [String] :title_color Title color ANSI code
133
+ # @option options [String] :content_color Content color ANSI code
134
+ # @option options [Integer] :width Dialog width (default: 50)
135
+ # @return [String, nil] User input (nil if cancelled)
136
+ def show_input_dialog(title, prompt, options = {})
137
+ require 'io/console'
138
+
139
+ width = options[:width] || 50
140
+ height = 8 # title + separator + prompt + input line + blank + ESC message + borders
141
+
142
+ x, y = calculate_center(width, height)
143
+
144
+ content_lines = [
145
+ '',
146
+ prompt,
147
+ '',
148
+ '> ', # Input line with prompt indicator
149
+ '',
150
+ '',
151
+ 'Press ESC to cancel'
152
+ ]
153
+
154
+ # Draw initial dialog
155
+ draw_floating_window(x, y, width, height, title, content_lines, options)
156
+
157
+ # Position cursor at input line
158
+ # y + 1 (top border) + 1 (title) + 1 (separator) + 1 (blank) + 1 (prompt) + 1 (blank) + 1 (input line) = y + 6
159
+ input_y = y + 6
160
+ input_x = x + 4 # Inside border with prompt '> ' (border 1 + space 1 + '> ' 2)
161
+ print "\e[#{input_y};#{input_x}H"
162
+ STDOUT.flush
163
+
164
+ # Read input with escape support
165
+ input = read_input_in_dialog(x, y, width, height, input_x, input_y, options)
166
+
167
+ # Clear dialog
168
+ clear_area(x, y, width, height)
169
+
170
+ input
171
+ end
172
+
173
+ private
174
+
175
+ # ASCII character range constants
176
+ ASCII_PRINTABLE_START = 32
177
+ ASCII_PRINTABLE_END = 127
178
+ MULTIBYTE_THRESHOLD = 1
179
+
180
+ # Read user input within a dialog
181
+ # @param dialog_x [Integer] Dialog X position
182
+ # @param dialog_y [Integer] Dialog Y position
183
+ # @param dialog_width [Integer] Dialog width
184
+ # @param dialog_height [Integer] Dialog height
185
+ # @param input_x [Integer] Input field X position
186
+ # @param input_y [Integer] Input field Y position
187
+ # @param options [Hash] Display options
188
+ # @return [String, nil] User input (nil if cancelled)
189
+ def read_input_in_dialog(dialog_x, dialog_y, dialog_width, dialog_height, input_x, input_y, options)
190
+ content_color = options[:content_color] || "\e[37m"
191
+ reset_color = "\e[0m"
192
+
193
+ input_chars = []
194
+ max_input_width = dialog_width - 8 # Leave space for borders and padding (border 2 + padding 4 + border 2)
195
+
196
+ loop do
197
+ char = STDIN.getch
198
+
199
+ case char
200
+ when "\e" # Escape - cancel
201
+ return nil
202
+ when "\r", "\n" # Enter - submit
203
+ return input_chars.join.strip
204
+ when "\u007F", "\b" # Backspace/Delete
205
+ unless input_chars.empty?
206
+ input_chars.pop
207
+ # Redraw input line - clear the entire input area
208
+ print "\e[#{input_y};#{input_x}H"
209
+ print "#{content_color}#{' ' * max_input_width}#{reset_color}"
210
+ print "\e[#{input_y};#{input_x}H"
211
+ print "#{content_color}#{input_chars.join}#{reset_color}"
212
+ STDOUT.flush
213
+ end
214
+ when "\u0003" # Ctrl+C
215
+ raise Interrupt
216
+ else
217
+ # Accept printable characters
218
+ if (char.ord >= ASCII_PRINTABLE_START && char.ord < ASCII_PRINTABLE_END) ||
219
+ char.bytesize > MULTIBYTE_THRESHOLD # Multibyte characters (Japanese, etc.)
220
+ current_width = TextUtils.display_width(input_chars.join)
221
+ char_width = TextUtils.display_width(char)
222
+
223
+ if current_width + char_width <= max_input_width
224
+ input_chars << char
225
+ print "#{content_color}#{char}#{reset_color}"
226
+ STDOUT.flush
227
+ end
228
+ end
229
+ end
230
+ end
231
+ end
126
232
  end
127
233
  end
@@ -698,15 +698,24 @@ module Rufio
698
698
  case result[:action]
699
699
  when :add
700
700
  success = @bookmark_manager.add_interactive(result[:path])
701
- wait_for_keypress
701
+ @terminal_ui&.refresh_display
702
702
  success
703
703
  when :list
704
- @bookmark_manager.list_interactive
705
- wait_for_keypress
706
- true
704
+ selected_bookmark = @bookmark_manager.list_interactive
705
+ @terminal_ui&.refresh_display
706
+ if selected_bookmark
707
+ # Navigate to selected bookmark
708
+ if @bookmark_manager.path_exists?(selected_bookmark)
709
+ navigate_to_directory(selected_bookmark[:path])
710
+ else
711
+ show_error_and_wait('bookmark.path_not_exist', selected_bookmark[:path])
712
+ end
713
+ else
714
+ false
715
+ end
707
716
  when :remove
708
717
  @bookmark_manager.remove_interactive
709
- wait_for_keypress
718
+ @terminal_ui&.refresh_display
710
719
  true
711
720
  when :navigate
712
721
  goto_bookmark(result[:number])
data/lib/rufio/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Rufio
4
- VERSION = '0.9.0'
4
+ VERSION = '0.10.0'
5
5
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rufio
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.0
4
+ version: 0.10.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - masisz
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2025-12-20 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: io-console
@@ -117,6 +117,7 @@ extensions: []
117
117
  extra_rdoc_files: []
118
118
  files:
119
119
  - CHANGELOG.md
120
+ - CHANGELOG_v0.10.0.md
120
121
  - CHANGELOG_v0.4.0.md
121
122
  - CHANGELOG_v0.5.0.md
122
123
  - CHANGELOG_v0.6.0.md
@@ -183,7 +184,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
183
184
  - !ruby/object:Gem::Version
184
185
  version: '0'
185
186
  requirements: []
186
- rubygems_version: 3.6.6
187
+ rubygems_version: 4.0.2
187
188
  specification_version: 4
188
189
  summary: Ruby file manager
189
190
  test_files: []