Class: Rufio::BookmarkController

Inherits:
Object
  • Object
show all
Defined in:
lib/rufio/bookmark_controller.rb

Overview

ブックマーク・zoxide・スクリプトパス専用コントローラKeybindHandler からブックマーク系・zoxide・スクリプトパス系メソッドを分離し、単一責任原則に準拠

Instance Method Summary collapse

Constructor Details

#initialize(directory_listing, bookmark_manager, dialog_renderer, nav_controller, script_path_manager, notification_manager, zoxide_integration) ⇒ BookmarkController

Returns a new instance of BookmarkController.



7
8
9
10
11
12
13
14
15
16
17
18
# File 'lib/rufio/bookmark_controller.rb', line 7

def initialize(directory_listing, bookmark_manager, dialog_renderer, nav_controller,
               script_path_manager, notification_manager, zoxide_integration)
  @directory_listing = directory_listing
  @bookmark_manager = bookmark_manager
  @dialog_renderer = dialog_renderer
  @nav_controller = nav_controller
  @script_path_manager = script_path_manager
  @notification_manager = notification_manager
  @zoxide_integration = zoxide_integration
  @terminal_ui = nil
  @last_bookmark_idx = nil
end

Instance Method Details

#add_bookmarkObject

ブックマーク操作



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/rufio/bookmark_controller.rb', line 32

def add_bookmark
  current_path = @directory_listing&.current_path || Dir.pwd

  bookmarks = @bookmark_manager.list
  existing = bookmarks.find { |b| b[:path] == current_path }

  if existing
    content_lines = [
      '',
      'This directory is already bookmarked',
      "Name: #{existing[:name]}",
      '',
      'Press any key to continue...'
    ]

    title = 'Bookmark Exists'
    width = 50
    height = content_lines.length + 4

    show_overlay_dialog(title, content_lines, {
      width: width,
      height: height,
      border_color: "\e[33m",
      title_color: "\e[1;33m",
      content_color: "\e[37m"
    })

    return false
  end

  dir_name = File.basename(current_path)

  title = "Add Bookmark: #{dir_name}"
  prompt = "Enter bookmark name:"
  bookmark_name = @dialog_renderer.show_input_dialog(title, prompt, {
    border_color: "\e[32m",
    title_color: "\e[1;32m",
    content_color: "\e[37m"
  })

  return false if bookmark_name.nil? || bookmark_name.empty?

  result = @bookmark_manager.add(current_path, bookmark_name)

  @terminal_ui&.refresh_display
  result
end

#add_to_script_pathsObject

スクリプトパス管理



233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
# File 'lib/rufio/bookmark_controller.rb', line 233

def add_to_script_paths
  current_path = @directory_listing&.current_path || Dir.pwd

  @script_path_manager ||= ScriptPathManager.new(Config::SCRIPT_PATHS_YML)

  if @script_path_manager.paths.include?(current_path)
    show_notification('Already in paths', current_path, :info)
  elsif @script_path_manager.add_path(current_path)
    show_notification('Added to scripts', current_path, :success)
  else
    show_notification('Failed to add', current_path, :error)
  end

  @terminal_ui&.refresh_display
  true
end

#confirm_delete_script_path(path) ⇒ Object



331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
# File 'lib/rufio/bookmark_controller.rb', line 331

def confirm_delete_script_path(path)
  content_lines = [
    '',
    'Delete this script path?',
    '',
    truncate_path(path, 40),
    '',
    '[y] Yes | [n] No'
  ]

  title = 'Confirm Delete'
  width = 50
  height = content_lines.length + 4

  key = show_overlay_dialog(title, content_lines, {
    width: width,
    height: height,
    border_color: "\e[31m",
    title_color: "\e[1;31m",
    content_color: "\e[37m"
  })

  key.downcase == 'y'
end

#goto_bookmark(number) ⇒ Object



128
129
130
131
132
133
134
135
136
137
# File 'lib/rufio/bookmark_controller.rb', line 128

def goto_bookmark(number)
  bookmark = @bookmark_manager.find_by_number(number)

  return false unless bookmark
  return false unless @bookmark_manager.path_exists?(bookmark)

  # Tab循環位置を更新(数字キー後の Tab が次の番号から続くように)
  @last_bookmark_idx = number - 1
  navigate_to_directory(bookmark[:path])
end

#goto_bookmark_by_path(path) ⇒ Object

パスを指定してブックマーク移動(テスト用)



140
141
142
# File 'lib/rufio/bookmark_controller.rb', line 140

def goto_bookmark_by_path(path)
  navigate_to_directory(path)
end

#goto_next_bookmarkInteger?

次のブックマークに移動(Tabキー)現在のディレクトリがブックマーク内なら current_path を基準に次へ、そうでない場合は @last_bookmark_idx から継続(ブックマーク外に出ても循環が止まらない)存在しないパスのブックマークはスキップする

Returns:

  • (Integer, nil)

    新しいブックマークインデックス、またはnil



156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
# File 'lib/rufio/bookmark_controller.rb', line 156

def goto_next_bookmark
  bookmarks = @bookmark_manager.list
  return nil unless bookmarks&.any?

  current_path = @directory_listing.current_path
  current_position = bookmarks.find_index { |bm| bm[:path] == current_path }
  start_idx = if current_position
    (current_position + 1) % bookmarks.length
  elsif @last_bookmark_idx
    (@last_bookmark_idx + 1) % bookmarks.length
  else
    0
  end

  bookmarks.length.times do |i|
    idx = (start_idx + i) % bookmarks.length
    next unless Dir.exist?(bookmarks[idx][:path])

    @last_bookmark_idx = idx
    navigate_to_directory(bookmarks[idx][:path])
    return @last_bookmark_idx
  end
  nil
end

#goto_prev_bookmarkInteger?

前のブックマークに移動(Shift+Tabキー)存在しないパスのブックマークはスキップする

Returns:

  • (Integer, nil)

    新しいブックマークインデックス、またはnil



184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
# File 'lib/rufio/bookmark_controller.rb', line 184

def goto_prev_bookmark
  bookmarks = @bookmark_manager.list
  return nil unless bookmarks&.any?

  current_path = @directory_listing.current_path
  current_position = bookmarks.find_index { |bm| bm[:path] == current_path }
  start_idx = if current_position
    (current_position - 1 + bookmarks.length) % bookmarks.length
  elsif @last_bookmark_idx
    (@last_bookmark_idx - 1 + bookmarks.length) % bookmarks.length
  else
    bookmarks.length - 1
  end

  bookmarks.length.times do |i|
    idx = (start_idx - i + bookmarks.length) % bookmarks.length
    next unless Dir.exist?(bookmarks[idx][:path])

    @last_bookmark_idx = idx
    navigate_to_directory(bookmarks[idx][:path])
    return @last_bookmark_idx
  end
  nil
end

#goto_start_directoryObject



144
145
146
147
148
149
# File 'lib/rufio/bookmark_controller.rb', line 144

def goto_start_directory
  start_dir = @directory_listing&.start_directory
  return false unless start_dir

  navigate_to_directory(start_dir)
end

ナビゲーション(委譲)



360
361
362
363
364
365
366
367
368
369
370
371
# File 'lib/rufio/bookmark_controller.rb', line 360

def navigate_to_directory(path)
  return false unless @directory_listing

  result = @directory_listing.navigate_to_path(path)
  if result
    @nav_controller.select_index(0)
    @nav_controller.clear_filter_mode
    true
  else
    false
  end
end

#set_directory_listing(directory_listing) ⇒ Object



24
25
26
# File 'lib/rufio/bookmark_controller.rb', line 24

def set_directory_listing(directory_listing)
  @directory_listing = directory_listing
end

#set_terminal_ui(terminal_ui) ⇒ Object



20
21
22
# File 'lib/rufio/bookmark_controller.rb', line 20

def set_terminal_ui(terminal_ui)
  @terminal_ui = terminal_ui
end

#show_bookmark_menuObject



80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# File 'lib/rufio/bookmark_controller.rb', line 80

def show_bookmark_menu
  current_path = @directory_listing&.current_path || Dir.pwd

  menu_items = [
    '1. Add current dir to bookmarks',
    '2. Add to script paths',
    '3. Manage script paths',
    '4. View bookmarks'
  ]

  content_lines = [''] + menu_items + ['', '[1-4] Select | [Esc] Cancel']

  title = 'Bookmark Menu'
  width = 45
  height = content_lines.length + 4

  key = show_overlay_dialog(title, content_lines, {
    width: width,
    height: height,
    border_color: "\e[36m",
    title_color: "\e[1;36m",
    content_color: "\e[37m"
  })

  case key
  when '1'
    add_bookmark
  when '2'
    add_to_script_paths
  when '3'
    show_script_paths_manager
  when '4'
    selected_bookmark = @bookmark_manager.list_interactive
    @terminal_ui&.refresh_display
    if selected_bookmark
      if @bookmark_manager.path_exists?(selected_bookmark)
        navigate_to_directory(selected_bookmark[:path])
      else
        show_error_and_wait('bookmark.path_not_exist', selected_bookmark[:path])
      end
    end
  else
    @terminal_ui&.refresh_display
  end

  true
end

#show_script_paths_managerObject



250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
# File 'lib/rufio/bookmark_controller.rb', line 250

def show_script_paths_manager
  unless @script_path_manager
    show_notification('No script paths configured', '', :info)
    @terminal_ui&.refresh_display
    return false
  end

  paths = @script_path_manager.paths
  if paths.empty?
    show_notification('No script paths', 'Press B > 2 to add', :info)
    @terminal_ui&.refresh_display
    return false
  end

  selected_index = 0
  screen = @terminal_ui&.screen
  renderer = @terminal_ui&.renderer

  loop do
    menu_items = paths.each_with_index.map do |path, i|
      prefix = i == selected_index ? '> ' : '  '
      "#{prefix}#{i + 1}. #{truncate_path(path, 35)}"
    end

    content_lines = [''] + menu_items + ['', '[j/k] Move | [d] Delete | [Enter] Jump | [Esc] Back']

    title = 'Script Paths'
    width = 50
    height = content_lines.length + 4

    if screen && renderer
      screen.enable_overlay
      x, y = @dialog_renderer.calculate_center(width, height)
      @dialog_renderer.draw_floating_window_to_overlay(screen, x, y, width, height, title, content_lines, {
        border_color: "\e[35m",
        title_color: "\e[1;35m",
        content_color: "\e[37m"
      })
      renderer.render(screen)

      key = STDIN.getch
      screen.disable_overlay
      renderer.render(screen)
    else
      x, y = @dialog_renderer.calculate_center(width, height)
      @dialog_renderer.draw_floating_window(x, y, width, height, title, content_lines, {
        border_color: "\e[35m",
        title_color: "\e[1;35m",
        content_color: "\e[37m"
      })

      key = STDIN.getch
      @dialog_renderer.clear_area(x, y, width, height)
    end

    case key
    when 'j'
      selected_index = [selected_index + 1, paths.length - 1].min
    when 'k'
      selected_index = [selected_index - 1, 0].max
    when 'd'
      path_to_delete = paths[selected_index]
      if confirm_delete_script_path(path_to_delete)
        @script_path_manager.remove_path(path_to_delete)
        paths = @script_path_manager.paths
        selected_index = [selected_index, paths.length - 1].min
        break if paths.empty?
      end
    when "\r", "\n"
      path = paths[selected_index]
      navigate_to_directory(path) if Dir.exist?(path)
      break
    when "\e"
      break
    end
  end

  @terminal_ui&.refresh_display
  true
end

#show_zoxide_menuObject

zoxide 連携



213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
# File 'lib/rufio/bookmark_controller.rb', line 213

def show_zoxide_menu
  selected_path = @zoxide_integration.show_menu

  if selected_path && Dir.exist?(selected_path)
    if navigate_to_directory(selected_path)
      @zoxide_integration.add_to_history(selected_path)
      true
    else
      false
    end
  else
    @terminal_ui&.refresh_display
    false
  end
end