rufio 0.20.0 → 0.30.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_v0.21.0.md +175 -0
- data/CHANGELOG_v0.30.0.md +148 -0
- data/README.md +21 -15
- data/README_EN.md +8 -12
- data/info/help.md +111 -0
- data/info/keybindings.md +102 -0
- data/info/welcome.md +40 -0
- data/lib/rufio/application.rb +0 -1
- data/lib/rufio/directory_listing.rb +2 -1
- data/lib/rufio/keybind_handler.rb +415 -40
- data/lib/rufio/selection_manager.rb +10 -1
- data/lib/rufio/terminal_ui.rb +147 -156
- data/lib/rufio/text_utils.rb +49 -0
- data/lib/rufio/version.rb +1 -1
- metadata +6 -2
- data/info/welcome.txt +0 -21
data/lib/rufio/terminal_ui.rb
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require 'io/console'
|
|
4
|
+
require_relative 'text_utils'
|
|
4
5
|
|
|
5
6
|
module Rufio
|
|
6
7
|
class TerminalUI
|
|
7
8
|
# Layout constants
|
|
8
|
-
HEADER_HEIGHT =
|
|
9
|
-
FOOTER_HEIGHT = 1 # Footer
|
|
10
|
-
HEADER_FOOTER_MARGIN =
|
|
9
|
+
HEADER_HEIGHT = 1 # Header占有行数
|
|
10
|
+
FOOTER_HEIGHT = 1 # Footer占有行数(ブックマーク一覧 + ステータス情報)
|
|
11
|
+
HEADER_FOOTER_MARGIN = 3 # Header + Footer分のマージン
|
|
11
12
|
|
|
12
13
|
# Panel layout ratios
|
|
13
14
|
LEFT_PANEL_RATIO = 0.5 # 左パネルの幅比率
|
|
@@ -17,8 +18,6 @@ module Rufio
|
|
|
17
18
|
DEFAULT_SCREEN_WIDTH = 80 # デフォルト画面幅
|
|
18
19
|
DEFAULT_SCREEN_HEIGHT = 24 # デフォルト画面高さ
|
|
19
20
|
HEADER_PADDING = 2 # ヘッダーのパディング
|
|
20
|
-
BASE_INFO_RESERVED_WIDTH = 20 # ベースディレクトリ表示の予約幅
|
|
21
|
-
BASE_INFO_MIN_WIDTH = 10 # ベースディレクトリ表示の最小幅
|
|
22
21
|
FILTER_TEXT_RESERVED = 15 # フィルタテキスト表示の予約幅
|
|
23
22
|
|
|
24
23
|
# File display constants
|
|
@@ -31,7 +30,7 @@ module Rufio
|
|
|
31
30
|
GIGABYTE = MEGABYTE * 1024
|
|
32
31
|
|
|
33
32
|
# Line offsets
|
|
34
|
-
CONTENT_START_LINE =
|
|
33
|
+
CONTENT_START_LINE = 2 # コンテンツ開始行(ヘッダー1行スキップ)
|
|
35
34
|
|
|
36
35
|
def initialize
|
|
37
36
|
console = IO.console
|
|
@@ -116,6 +115,9 @@ module Rufio
|
|
|
116
115
|
end
|
|
117
116
|
|
|
118
117
|
def draw_screen
|
|
118
|
+
# 処理時間測定開始
|
|
119
|
+
start_time = Time.now
|
|
120
|
+
|
|
119
121
|
# move cursor to top of screen (don't clear)
|
|
120
122
|
print "\e[H"
|
|
121
123
|
|
|
@@ -125,9 +127,8 @@ module Rufio
|
|
|
125
127
|
return
|
|
126
128
|
end
|
|
127
129
|
|
|
128
|
-
# header (
|
|
130
|
+
# header (1 line)
|
|
129
131
|
draw_header
|
|
130
|
-
draw_base_directory_info
|
|
131
132
|
|
|
132
133
|
# main content (left: directory list, right: preview)
|
|
133
134
|
entries = get_display_entries
|
|
@@ -144,8 +145,9 @@ module Rufio
|
|
|
144
145
|
draw_directory_list(entries, left_width, content_height)
|
|
145
146
|
draw_file_preview(selected_entry, right_width, content_height, left_width)
|
|
146
147
|
|
|
147
|
-
# footer
|
|
148
|
-
|
|
148
|
+
# footer (統合されたステータス情報を含む)
|
|
149
|
+
render_time = Time.now - start_time
|
|
150
|
+
draw_footer(render_time)
|
|
149
151
|
|
|
150
152
|
# コマンドモードがアクティブな場合はコマンド入力ウィンドウを表示
|
|
151
153
|
if @command_mode_active
|
|
@@ -163,6 +165,11 @@ module Rufio
|
|
|
163
165
|
current_path = @directory_listing.current_path
|
|
164
166
|
header = "📁 rufio - #{current_path}"
|
|
165
167
|
|
|
168
|
+
# Add help mode indicator if in help mode
|
|
169
|
+
if @keybind_handler.help_mode?
|
|
170
|
+
header += " [Help Mode - Press ESC to exit]"
|
|
171
|
+
end
|
|
172
|
+
|
|
166
173
|
# Add filter indicator if in filter mode
|
|
167
174
|
if @keybind_handler.filter_active?
|
|
168
175
|
filter_text = " [Filter: #{@keybind_handler.filter_query}]"
|
|
@@ -171,7 +178,12 @@ module Rufio
|
|
|
171
178
|
|
|
172
179
|
# abbreviate if path is too long
|
|
173
180
|
if header.length > @screen_width - HEADER_PADDING
|
|
174
|
-
if @keybind_handler.
|
|
181
|
+
if @keybind_handler.help_mode?
|
|
182
|
+
# prioritize showing help mode indicator
|
|
183
|
+
help_text = " [Help Mode - Press ESC to exit]"
|
|
184
|
+
base_length = @screen_width - help_text.length - FILTER_TEXT_RESERVED
|
|
185
|
+
header = "📁 rufio - ...#{current_path[-base_length..-1]}#{help_text}"
|
|
186
|
+
elsif @keybind_handler.filter_active?
|
|
175
187
|
# prioritize showing filter when active
|
|
176
188
|
filter_text = " [Filter: #{@keybind_handler.filter_query}]"
|
|
177
189
|
base_length = @screen_width - filter_text.length - FILTER_TEXT_RESERVED
|
|
@@ -184,42 +196,6 @@ module Rufio
|
|
|
184
196
|
puts "\e[7m#{header.ljust(@screen_width)}\e[0m" # reverse display
|
|
185
197
|
end
|
|
186
198
|
|
|
187
|
-
def draw_base_directory_info
|
|
188
|
-
# 強制的に表示 - デバッグ用に安全チェックを緩和
|
|
189
|
-
if @keybind_handler && @keybind_handler.instance_variable_get(:@base_directory)
|
|
190
|
-
base_dir = @keybind_handler.instance_variable_get(:@base_directory)
|
|
191
|
-
selected_count = @keybind_handler.selected_items.length
|
|
192
|
-
base_info = "📋 Base Directory: #{base_dir}"
|
|
193
|
-
|
|
194
|
-
# 選択されたアイテム数を表示
|
|
195
|
-
if selected_count > 0
|
|
196
|
-
base_info += " | Selected: #{selected_count} item(s)"
|
|
197
|
-
end
|
|
198
|
-
else
|
|
199
|
-
# keybind_handlerがない場合、またはbase_directoryが設定されていない場合
|
|
200
|
-
base_info = "📋 Base Directory: #{Dir.pwd}"
|
|
201
|
-
end
|
|
202
|
-
|
|
203
|
-
# 長すぎる場合は省略
|
|
204
|
-
if base_info.length > @screen_width - HEADER_PADDING
|
|
205
|
-
if base_info.include?(" | Selected:")
|
|
206
|
-
selected_part = base_info.split(" | Selected:").last
|
|
207
|
-
available_length = @screen_width - BASE_INFO_RESERVED_WIDTH - " | Selected:#{selected_part}".length
|
|
208
|
-
else
|
|
209
|
-
available_length = @screen_width - BASE_INFO_RESERVED_WIDTH
|
|
210
|
-
end
|
|
211
|
-
|
|
212
|
-
if available_length > BASE_INFO_MIN_WIDTH
|
|
213
|
-
# パスの最後の部分を表示
|
|
214
|
-
dir_part = base_info.split(": ").last.split(" | ").first
|
|
215
|
-
short_base_dir = "...#{dir_part[-available_length..-1]}"
|
|
216
|
-
base_info = base_info.gsub(dir_part, short_base_dir)
|
|
217
|
-
end
|
|
218
|
-
end
|
|
219
|
-
|
|
220
|
-
# 2行目に確実に表示
|
|
221
|
-
print "\e[2;1H\e[44m\e[37m#{base_info.ljust(@screen_width)}\e[0m"
|
|
222
|
-
end
|
|
223
199
|
|
|
224
200
|
|
|
225
201
|
def draw_directory_list(entries, width, height)
|
|
@@ -348,12 +324,19 @@ module Rufio
|
|
|
348
324
|
if selected_entry && i == 0
|
|
349
325
|
# プレビューヘッダー
|
|
350
326
|
header = " #{selected_entry[:name]} "
|
|
327
|
+
# プレビューフォーカス中は表示を追加
|
|
328
|
+
if @keybind_handler&.preview_focused?
|
|
329
|
+
header += "[PREVIEW MODE]"
|
|
330
|
+
end
|
|
351
331
|
content_to_print = header
|
|
352
332
|
elsif selected_entry && selected_entry[:type] == 'file' && i >= 2
|
|
353
333
|
# ファイルプレビュー(折り返し対応)
|
|
354
334
|
preview_content = get_preview_content(selected_entry)
|
|
355
|
-
wrapped_lines = wrap_preview_lines(preview_content, safe_width - 1) # スペース分を除く
|
|
356
|
-
|
|
335
|
+
wrapped_lines = TextUtils.wrap_preview_lines(preview_content, safe_width - 1) # スペース分を除く
|
|
336
|
+
|
|
337
|
+
# スクロールオフセットを適用
|
|
338
|
+
scroll_offset = @keybind_handler&.preview_scroll_offset || 0
|
|
339
|
+
display_line_index = i - 2 + scroll_offset
|
|
357
340
|
|
|
358
341
|
if display_line_index < wrapped_lines.length
|
|
359
342
|
line = wrapped_lines[display_line_index] || ''
|
|
@@ -370,16 +353,16 @@ module Rufio
|
|
|
370
353
|
if safe_width <= 0
|
|
371
354
|
# 表示スペースがない場合は何も出力しない
|
|
372
355
|
next
|
|
373
|
-
elsif display_width(content_to_print) > safe_width
|
|
356
|
+
elsif TextUtils.display_width(content_to_print) > safe_width
|
|
374
357
|
# 表示幅ベースで切り詰める
|
|
375
|
-
content_to_print = truncate_to_width(content_to_print, safe_width)
|
|
358
|
+
content_to_print = TextUtils.truncate_to_width(content_to_print, safe_width)
|
|
376
359
|
end
|
|
377
360
|
|
|
378
361
|
# 出力(パディングなし、はみ出し防止のため)
|
|
379
362
|
print content_to_print
|
|
380
363
|
|
|
381
364
|
# 残りのスペースを埋める(ただし安全な範囲内のみ)
|
|
382
|
-
remaining_space = safe_width - display_width(content_to_print)
|
|
365
|
+
remaining_space = safe_width - TextUtils.display_width(content_to_print)
|
|
383
366
|
print ' ' * remaining_space if remaining_space > 0
|
|
384
367
|
end
|
|
385
368
|
end
|
|
@@ -402,98 +385,6 @@ module Rufio
|
|
|
402
385
|
["(#{ConfigLoader.message('file.preview_error')})"]
|
|
403
386
|
end
|
|
404
387
|
|
|
405
|
-
def wrap_preview_lines(lines, max_width)
|
|
406
|
-
return [] if lines.empty? || max_width <= 0
|
|
407
|
-
|
|
408
|
-
wrapped_lines = []
|
|
409
|
-
|
|
410
|
-
lines.each do |line|
|
|
411
|
-
if display_width(line) <= max_width
|
|
412
|
-
# 短い行はそのまま追加
|
|
413
|
-
wrapped_lines << line
|
|
414
|
-
else
|
|
415
|
-
# 長い行は折り返し
|
|
416
|
-
remaining_line = line
|
|
417
|
-
while display_width(remaining_line) > max_width
|
|
418
|
-
# 単語境界で折り返すことを試みる
|
|
419
|
-
break_point = find_break_point(remaining_line, max_width)
|
|
420
|
-
wrapped_lines << remaining_line[0...break_point]
|
|
421
|
-
remaining_line = remaining_line[break_point..-1]
|
|
422
|
-
end
|
|
423
|
-
# 残りの部分を追加
|
|
424
|
-
wrapped_lines << remaining_line if remaining_line.length > 0
|
|
425
|
-
end
|
|
426
|
-
end
|
|
427
|
-
|
|
428
|
-
wrapped_lines
|
|
429
|
-
end
|
|
430
|
-
|
|
431
|
-
def display_width(string)
|
|
432
|
-
# 文字列の表示幅を計算する
|
|
433
|
-
# 日本語文字(全角)は幅2、ASCII文字(半角)は幅1として計算
|
|
434
|
-
width = 0
|
|
435
|
-
string.each_char do |char|
|
|
436
|
-
# 全角文字の判定
|
|
437
|
-
width += if char.ord > 127 || char.match?(/[あ-んア-ン一-龯]/)
|
|
438
|
-
2
|
|
439
|
-
else
|
|
440
|
-
1
|
|
441
|
-
end
|
|
442
|
-
end
|
|
443
|
-
width
|
|
444
|
-
end
|
|
445
|
-
|
|
446
|
-
def truncate_to_width(string, max_width)
|
|
447
|
-
# 表示幅を指定して文字列を切り詰める
|
|
448
|
-
return string if display_width(string) <= max_width
|
|
449
|
-
|
|
450
|
-
current_width = 0
|
|
451
|
-
result = ''
|
|
452
|
-
|
|
453
|
-
string.each_char do |char|
|
|
454
|
-
char_width = char.ord > 127 || char.match?(/[あ-んア-ン一-龯]/) ? 2 : 1
|
|
455
|
-
|
|
456
|
-
if current_width + char_width > max_width
|
|
457
|
-
# "..."を追加できるかチェック
|
|
458
|
-
result += '...' if max_width >= 3 && current_width <= max_width - 3
|
|
459
|
-
break
|
|
460
|
-
end
|
|
461
|
-
|
|
462
|
-
result += char
|
|
463
|
-
current_width += char_width
|
|
464
|
-
end
|
|
465
|
-
|
|
466
|
-
result
|
|
467
|
-
end
|
|
468
|
-
|
|
469
|
-
def find_break_point(line, max_width)
|
|
470
|
-
# 最大幅以内で適切な折り返し位置を見つける
|
|
471
|
-
return line.length if display_width(line) <= max_width
|
|
472
|
-
|
|
473
|
-
# 文字ごとに幅を計算しながら適切な位置を探す
|
|
474
|
-
current_width = 0
|
|
475
|
-
best_break_point = 0
|
|
476
|
-
space_break_point = nil
|
|
477
|
-
punct_break_point = nil
|
|
478
|
-
|
|
479
|
-
line.each_char.with_index do |char, index|
|
|
480
|
-
char_width = char.ord > 127 || char.match?(/[あ-んア-ン一-龯]/) ? 2 : 1
|
|
481
|
-
|
|
482
|
-
break if current_width + char_width > max_width
|
|
483
|
-
|
|
484
|
-
current_width += char_width
|
|
485
|
-
best_break_point = index + 1
|
|
486
|
-
|
|
487
|
-
# スペースで区切れる位置を記録
|
|
488
|
-
space_break_point = index + 1 if char == ' ' && current_width > max_width * 0.5
|
|
489
|
-
|
|
490
|
-
# 日本語の句読点で区切れる位置を記録
|
|
491
|
-
punct_break_point = index + 1 if char.match?(/[、。,.!?]/) && current_width > max_width * 0.5
|
|
492
|
-
end
|
|
493
|
-
|
|
494
|
-
# 最適な折り返し位置を選択
|
|
495
|
-
space_break_point || punct_break_point || best_break_point
|
|
496
|
-
end
|
|
497
388
|
|
|
498
389
|
def get_display_entries
|
|
499
390
|
if @keybind_handler.filter_active?
|
|
@@ -506,9 +397,9 @@ module Rufio
|
|
|
506
397
|
end
|
|
507
398
|
end
|
|
508
399
|
|
|
509
|
-
def draw_footer
|
|
510
|
-
#
|
|
511
|
-
footer_line = @screen_height - FOOTER_HEIGHT
|
|
400
|
+
def draw_footer(render_time = nil)
|
|
401
|
+
# フッタは最下行に表示
|
|
402
|
+
footer_line = @screen_height - FOOTER_HEIGHT + 1
|
|
512
403
|
print "\e[#{footer_line};1H"
|
|
513
404
|
|
|
514
405
|
if @keybind_handler.filter_active?
|
|
@@ -517,14 +408,50 @@ module Rufio
|
|
|
517
408
|
else
|
|
518
409
|
help_text = "Filtered view active - Space to edit filter, ESC to clear filter"
|
|
519
410
|
end
|
|
411
|
+
# フィルタモードでは通常のフッタを表示
|
|
412
|
+
footer_content = help_text.ljust(@screen_width)[0...@screen_width]
|
|
413
|
+
print "\e[7m#{footer_content}\e[0m"
|
|
520
414
|
else
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
415
|
+
# 通常モードではブックマーク一覧、ステータス情報、?:helpを1行に表示
|
|
416
|
+
require_relative 'bookmark'
|
|
417
|
+
bookmark = Bookmark.new
|
|
418
|
+
bookmarks = bookmark.list
|
|
419
|
+
|
|
420
|
+
# 起動ディレクトリを取得
|
|
421
|
+
start_dir = @directory_listing&.start_directory
|
|
422
|
+
start_dir_name = if start_dir
|
|
423
|
+
File.basename(start_dir)
|
|
424
|
+
else
|
|
425
|
+
"start"
|
|
426
|
+
end
|
|
427
|
+
|
|
428
|
+
# ブックマーク一覧を作成(0.起動dir を先頭に追加)
|
|
429
|
+
bookmark_parts = ["0.#{start_dir_name}"]
|
|
430
|
+
unless bookmarks.empty?
|
|
431
|
+
bookmark_parts.concat(bookmarks.take(9).map.with_index(1) { |bm, idx| "#{idx}.#{bm[:name]}" })
|
|
432
|
+
end
|
|
433
|
+
bookmark_text = bookmark_parts.join(" ")
|
|
524
434
|
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
435
|
+
# ステータス情報を作成
|
|
436
|
+
time_info = render_time ? "#{(render_time * 1000).round(1)}ms" : "-ms"
|
|
437
|
+
|
|
438
|
+
# 右側の情報: 処理時間 | ?:help
|
|
439
|
+
right_info = "#{time_info} | ?:help"
|
|
440
|
+
|
|
441
|
+
# ブックマーク一覧を利用可能な幅に収める
|
|
442
|
+
available_width = @screen_width - right_info.length - 3
|
|
443
|
+
if bookmark_text.length > available_width && available_width > 3
|
|
444
|
+
bookmark_text = bookmark_text[0...available_width - 3] + "..."
|
|
445
|
+
elsif available_width <= 3
|
|
446
|
+
bookmark_text = ""
|
|
447
|
+
end
|
|
448
|
+
|
|
449
|
+
# フッタ全体を構築
|
|
450
|
+
padding = @screen_width - bookmark_text.length - right_info.length
|
|
451
|
+
footer_content = "#{bookmark_text}#{' ' * padding}#{right_info}"
|
|
452
|
+
footer_content = footer_content.ljust(@screen_width)[0...@screen_width]
|
|
453
|
+
print "\e[7m#{footer_content}\e[0m"
|
|
454
|
+
end
|
|
528
455
|
end
|
|
529
456
|
|
|
530
457
|
def handle_input
|
|
@@ -786,11 +713,12 @@ module Rufio
|
|
|
786
713
|
is_project_selected = (bookmark[:name] == selected_name)
|
|
787
714
|
selection_mark = is_project_selected ? "✓ " : " "
|
|
788
715
|
|
|
789
|
-
#
|
|
716
|
+
# ブックマーク名を表示(番号付き)
|
|
717
|
+
number = index + 1 # 1-based index
|
|
790
718
|
name = bookmark[:name]
|
|
791
|
-
max_name_length = width -
|
|
719
|
+
max_name_length = width - 8 # selection_mark(2) + number(1-2) + ". "(2) + padding
|
|
792
720
|
display_name = name.length > max_name_length ? name[0...max_name_length - 3] + '...' : name
|
|
793
|
-
line_content = "#{selection_mark}#{display_name}".ljust(width)
|
|
721
|
+
line_content = "#{selection_mark}#{number}. #{display_name}".ljust(width)
|
|
794
722
|
|
|
795
723
|
if index == current_index
|
|
796
724
|
# カーソル位置は選択色でハイライト
|
|
@@ -994,6 +922,69 @@ module Rufio
|
|
|
994
922
|
draw_screen
|
|
995
923
|
end
|
|
996
924
|
|
|
925
|
+
# ヘルプダイアログを表示
|
|
926
|
+
def show_help_dialog
|
|
927
|
+
content_lines = [
|
|
928
|
+
'',
|
|
929
|
+
"rufio v#{VERSION}",
|
|
930
|
+
'',
|
|
931
|
+
'Key Bindings:',
|
|
932
|
+
'',
|
|
933
|
+
'j/k - Move up/down',
|
|
934
|
+
'h/l - Navigate back/enter',
|
|
935
|
+
'g/G - Go to top/bottom',
|
|
936
|
+
'o - Open file',
|
|
937
|
+
'f - Filter files',
|
|
938
|
+
's - Search with fzf',
|
|
939
|
+
'F - Content search (rga)',
|
|
940
|
+
'a/A - Create file/directory',
|
|
941
|
+
'm/c/x - Move/Copy/Delete',
|
|
942
|
+
'b - Add bookmark',
|
|
943
|
+
'z - Zoxide navigation',
|
|
944
|
+
'0 - Go to start directory',
|
|
945
|
+
'1-9 - Go to bookmark',
|
|
946
|
+
'p - Project mode',
|
|
947
|
+
': - Command mode',
|
|
948
|
+
'q - Quit',
|
|
949
|
+
''
|
|
950
|
+
]
|
|
951
|
+
|
|
952
|
+
# お知らせ情報を追加
|
|
953
|
+
require_relative 'info_notice'
|
|
954
|
+
info_notice = InfoNotice.new
|
|
955
|
+
all_notices = Dir.glob(File.join(info_notice.info_dir, '*.txt'))
|
|
956
|
+
|
|
957
|
+
if !all_notices.empty?
|
|
958
|
+
content_lines << 'Recent Updates:'
|
|
959
|
+
content_lines << ''
|
|
960
|
+
all_notices.take(3).each do |file|
|
|
961
|
+
title = info_notice.extract_title(file)
|
|
962
|
+
content_lines << " • #{title}"
|
|
963
|
+
end
|
|
964
|
+
content_lines << ''
|
|
965
|
+
end
|
|
966
|
+
|
|
967
|
+
content_lines << 'Press any key to continue...'
|
|
968
|
+
|
|
969
|
+
width = 60
|
|
970
|
+
height = [content_lines.length + 4, @screen_height - 4].min
|
|
971
|
+
x, y = @dialog_renderer.calculate_center(width, height)
|
|
972
|
+
|
|
973
|
+
@dialog_renderer.draw_floating_window(x, y, width, height, 'rufio - Help', content_lines, {
|
|
974
|
+
border_color: "\e[36m", # Cyan
|
|
975
|
+
title_color: "\e[1;36m", # Bold cyan
|
|
976
|
+
content_color: "\e[37m" # White
|
|
977
|
+
})
|
|
978
|
+
|
|
979
|
+
require 'io/console'
|
|
980
|
+
IO.console.getch
|
|
981
|
+
@dialog_renderer.clear_area(x, y, width, height)
|
|
982
|
+
|
|
983
|
+
# 画面を再描画
|
|
984
|
+
refresh_display
|
|
985
|
+
draw_screen
|
|
986
|
+
end
|
|
987
|
+
|
|
997
988
|
# プロジェクトモードでコマンドを実行
|
|
998
989
|
def activate_project_command_mode(project_mode, project_command, project_log)
|
|
999
990
|
return unless project_mode.selected_path
|
data/lib/rufio/text_utils.rb
CHANGED
|
@@ -104,5 +104,54 @@ module Rufio
|
|
|
104
104
|
|
|
105
105
|
space_break_point || punct_break_point || best_break_point
|
|
106
106
|
end
|
|
107
|
+
|
|
108
|
+
# Wrap preview lines to fit within max_width
|
|
109
|
+
# @param lines [Array<String>] Lines to wrap
|
|
110
|
+
# @param max_width [Integer] Maximum width for each line
|
|
111
|
+
# @return [Array<String>] Wrapped lines
|
|
112
|
+
def wrap_preview_lines(lines, max_width)
|
|
113
|
+
return lines if max_width <= 0
|
|
114
|
+
|
|
115
|
+
wrapped = []
|
|
116
|
+
lines.each do |line|
|
|
117
|
+
# Remove trailing whitespace
|
|
118
|
+
line = line.rstrip
|
|
119
|
+
|
|
120
|
+
# If line is empty, keep it
|
|
121
|
+
if line.empty?
|
|
122
|
+
wrapped << ''
|
|
123
|
+
next
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
# If line fits within max_width, keep it as is
|
|
127
|
+
if display_width(line) <= max_width
|
|
128
|
+
wrapped << line
|
|
129
|
+
next
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
# Split long lines
|
|
133
|
+
current_line = []
|
|
134
|
+
current_width = 0
|
|
135
|
+
|
|
136
|
+
line.each_char do |char|
|
|
137
|
+
char_width = display_width(char)
|
|
138
|
+
|
|
139
|
+
if current_width + char_width > max_width
|
|
140
|
+
# Start a new line
|
|
141
|
+
wrapped << current_line.join
|
|
142
|
+
current_line = [char]
|
|
143
|
+
current_width = char_width
|
|
144
|
+
else
|
|
145
|
+
current_line << char
|
|
146
|
+
current_width += char_width
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
# Add remaining characters
|
|
151
|
+
wrapped << current_line.join unless current_line.empty?
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
wrapped
|
|
155
|
+
end
|
|
107
156
|
end
|
|
108
157
|
end
|
data/lib/rufio/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rufio
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.30.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- masisz
|
|
@@ -119,6 +119,8 @@ files:
|
|
|
119
119
|
- CHANGELOG.md
|
|
120
120
|
- CHANGELOG_v0.10.0.md
|
|
121
121
|
- CHANGELOG_v0.20.0.md
|
|
122
|
+
- CHANGELOG_v0.21.0.md
|
|
123
|
+
- CHANGELOG_v0.30.0.md
|
|
122
124
|
- CHANGELOG_v0.4.0.md
|
|
123
125
|
- CHANGELOG_v0.5.0.md
|
|
124
126
|
- CHANGELOG_v0.6.0.md
|
|
@@ -132,7 +134,9 @@ files:
|
|
|
132
134
|
- config_example.rb
|
|
133
135
|
- docs/PLUGIN_GUIDE.md
|
|
134
136
|
- docs/plugin_example.rb
|
|
135
|
-
- info/
|
|
137
|
+
- info/help.md
|
|
138
|
+
- info/keybindings.md
|
|
139
|
+
- info/welcome.md
|
|
136
140
|
- lib/rufio.rb
|
|
137
141
|
- lib/rufio/application.rb
|
|
138
142
|
- lib/rufio/bookmark.rb
|
data/info/welcome.txt
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
# Welcome to rufio!
|
|
2
|
-
|
|
3
|
-
Thank you for using rufio - a terminal-based file manager.
|
|
4
|
-
|
|
5
|
-
Key Features:
|
|
6
|
-
- Vim-like keybindings (j/k/h/l for navigation)
|
|
7
|
-
- Real-time filtering (f key)
|
|
8
|
-
- Advanced search with fzf and rga
|
|
9
|
-
- Bookmark support (b key)
|
|
10
|
-
- Plugin system for extensibility
|
|
11
|
-
|
|
12
|
-
Quick Start:
|
|
13
|
-
j/k - Move up/down
|
|
14
|
-
h/l - Parent dir / Enter dir
|
|
15
|
-
f - Filter files
|
|
16
|
-
b - Bookmarks
|
|
17
|
-
: - Command mode
|
|
18
|
-
q - Quit
|
|
19
|
-
|
|
20
|
-
For more information, visit:
|
|
21
|
-
https://github.com/masisz/rufio
|