rufio 0.82.1 → 0.83.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 +18 -0
- data/docs/architecture_concurrency_ja_v0.82.1.md +169 -0
- data/lib/rufio/terminal_ui.rb +126 -10
- data/lib/rufio/ui_renderer.rb +1 -1
- data/lib/rufio/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: b75328867a09d6dfa3b4c759e242d239ab8d087540a43af19471473cc0515c4c
|
|
4
|
+
data.tar.gz: 798358451d71a8b74ee70ce2d362b2f24fb887e6de9b574f700c0f25a449e389
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 8072bc03c642bbc3043caca4cfa4899c72b6622ab7a74517ef7964010a9257e938005191de9a8e8aaed444749108ef1ef983b6b4dc8483aa8b4d2a6a8cb075a6
|
|
7
|
+
data.tar.gz: d6fb6e10e070e94120518d5a883bd241b46a957e7938b375b09e7dc3e28e73e9652aabe7b6a191e2575872764919581ac6d4b163d48fbb2d5dcd50e7740e2e2f
|
data/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,24 @@ All notable changes to rufio will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [0.83.0] - 2026-03-14
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- **Mouse input support**: Enabled SGR extended mouse reporting (`\e[?1003h\e[?1006h`) with click and scroll handling
|
|
12
|
+
- **Left click (file list)**: Move cursor to the clicked row
|
|
13
|
+
- **Left double-click (file list)**: Re-click within 0.5s opens the file (equivalent to Enter)
|
|
14
|
+
- **Left click (right panel)**: Toggle preview focus on/off
|
|
15
|
+
- **Wheel scroll (file list)**: Scroll up/down (equivalent to j/k)
|
|
16
|
+
- **Wheel scroll (preview focused)**: Scroll the preview panel
|
|
17
|
+
- Mouse reporting is disabled on exit via `cleanup_terminal` (`\e[?1003l\e[?1006l`)
|
|
18
|
+
- **Architecture documentation**: Added `docs/architecture_concurrency_ja_v0.82.1.md`
|
|
19
|
+
- Documents rufio's concurrency model (single-threaded UI + worker threads + child processes)
|
|
20
|
+
- Documents memory model characteristics (screen buffer, preview cache, job history)
|
|
21
|
+
|
|
22
|
+
### Changed
|
|
23
|
+
- **`read_next_input_byte` helper**: Extracted common ESC sequence reading logic to reduce duplication
|
|
24
|
+
- **`UIRenderer#left_panel_ratio` exposed**: Added `attr_reader` for use in mouse click panel detection
|
|
25
|
+
|
|
8
26
|
## [0.82.1] - 2026-03-07
|
|
9
27
|
|
|
10
28
|
### Fixed
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
# rufio 並行実行アーキテクチャ
|
|
2
|
+
|
|
3
|
+
## 結論(Single Thread / Thread / Process / Event Loop)
|
|
4
|
+
|
|
5
|
+
rufio は **単一のメインプロセス**で動作し、UIは **シングルスレッドのイベントループ**で駆動されます。
|
|
6
|
+
ただし、実行中に以下を併用します。
|
|
7
|
+
|
|
8
|
+
- `Thread`: バックグラウンド実行、非同期スキャン、非同期ハイライト、Windows入力補助
|
|
9
|
+
- `Process`(子プロセス): `Open3` / `IO.popen` / `system` による外部コマンド実行
|
|
10
|
+
|
|
11
|
+
つまり実態は、**「シングルスレッドUI + 補助スレッド + 外部プロセス」構成**です。
|
|
12
|
+
|
|
13
|
+
## 1. 起動とプロセス境界
|
|
14
|
+
|
|
15
|
+
- エントリポイントは [`bin/rufio`](../bin/rufio)
|
|
16
|
+
- 本体は [`Rufio::Application`](../lib/rufio/application.rb) が初期化し、[`TerminalUI#main_loop`](../lib/rufio/terminal_ui.rb) に入る
|
|
17
|
+
- アプリ自身は `fork`/常駐ワーカープロセスを持たない(コード上 `fork` 使用なし)
|
|
18
|
+
|
|
19
|
+
### 子プロセスを作る経路
|
|
20
|
+
|
|
21
|
+
- `Open3.capture3` / `Open3.popen3`
|
|
22
|
+
- [`lib/rufio/background_command_executor.rb`](../lib/rufio/background_command_executor.rb)
|
|
23
|
+
- [`lib/rufio/command_mode.rb`](../lib/rufio/command_mode.rb)
|
|
24
|
+
- [`lib/rufio/script_runner.rb`](../lib/rufio/script_runner.rb)
|
|
25
|
+
- [`lib/rufio/script_executor.rb`](../lib/rufio/script_executor.rb)
|
|
26
|
+
- `IO.popen`(`bat` 実行)
|
|
27
|
+
- [`lib/rufio/syntax_highlighter.rb`](../lib/rufio/syntax_highlighter.rb)
|
|
28
|
+
- `system`(`tput`, `which` 等)
|
|
29
|
+
- [`lib/rufio/terminal_ui.rb`](../lib/rufio/terminal_ui.rb)
|
|
30
|
+
- [`lib/rufio/syntax_highlighter.rb`](../lib/rufio/syntax_highlighter.rb)
|
|
31
|
+
|
|
32
|
+
## 2. Event Loop(UIの中心)
|
|
33
|
+
|
|
34
|
+
メインループは [`TerminalUI#main_loop`](../lib/rufio/terminal_ui.rb) で実装されています。
|
|
35
|
+
|
|
36
|
+
- ループ周期の基準: 約30FPS(`min_sleep_interval = 0.0333`)
|
|
37
|
+
- フェーズ: `UPDATE -> DRAW -> RENDER -> SLEEP`
|
|
38
|
+
- 入力: ノンブロッキング
|
|
39
|
+
- Unix: `IO.select(..., timeout=0)` + `STDIN.read_nonblock`
|
|
40
|
+
- Windows: 補助入力スレッド + `Queue` 受信
|
|
41
|
+
- 定期監視
|
|
42
|
+
- バックグラウンドコマンド完了チェック(約0.1秒周期)
|
|
43
|
+
- 通知ランプ期限チェック
|
|
44
|
+
- 非同期ハイライト完了フラグチェック
|
|
45
|
+
|
|
46
|
+
ポイントは「**UIスレッドはブロックしない**」ことで、重い処理は別スレッド/別プロセスへ逃がしています。
|
|
47
|
+
|
|
48
|
+
## 3. Thread モデル
|
|
49
|
+
|
|
50
|
+
### 3.1 常時/都度の補助スレッド
|
|
51
|
+
|
|
52
|
+
- バックグラウンドコマンド
|
|
53
|
+
- [`BackgroundCommandExecutor`](../lib/rufio/background_command_executor.rb)
|
|
54
|
+
- `Thread.new` で1ジョブ実行(同時1本に制限)
|
|
55
|
+
- スクリプトジョブ
|
|
56
|
+
- [`ScriptRunner`](../lib/rufio/script_runner.rb)
|
|
57
|
+
- [`CommandMode`](../lib/rufio/command_mode.rb)
|
|
58
|
+
- ジョブごとに `Thread.new` で実行
|
|
59
|
+
- 非同期ディレクトリスキャン
|
|
60
|
+
- [`NativeScannerRubyCore`](../lib/rufio/native_scanner.rb)
|
|
61
|
+
- スキャンごとに1スレッド
|
|
62
|
+
- 並列スキャン
|
|
63
|
+
- [`ParallelScanner`](../lib/rufio/parallel_scanner.rb)
|
|
64
|
+
- `Queue` + ワーカースレッドプール(既定4)
|
|
65
|
+
- 非同期シンタックスハイライト
|
|
66
|
+
- [`SyntaxHighlighter#highlight_async`](../lib/rufio/syntax_highlighter.rb)
|
|
67
|
+
- `Thread` + `Mutex` + pendingガード
|
|
68
|
+
- Windows入力補助
|
|
69
|
+
- [`TerminalUI#setup_terminal`](../lib/rufio/terminal_ui.rb)
|
|
70
|
+
- `STDIN.read(1)` を読む専用スレッド
|
|
71
|
+
|
|
72
|
+
### 3.2 スレッド安全性の扱い
|
|
73
|
+
|
|
74
|
+
- `Mutex` で共有状態を保護(例: `NativeScannerRubyCore`, `SyntaxHighlighter`)
|
|
75
|
+
- `Queue` で producer/consumer 連携(`ParallelScanner`, Windows入力)
|
|
76
|
+
- UI反映はメインループでポーリング/フラグ監視し、描画系の責務を集中
|
|
77
|
+
|
|
78
|
+
## 4. Process モデル
|
|
79
|
+
|
|
80
|
+
外部コマンド実行は Ruby プロセス内で直接処理せず、子プロセスに委譲しています。
|
|
81
|
+
|
|
82
|
+
- シェルコマンド・スクリプト・rake は `Open3` 経由で実行
|
|
83
|
+
- タイムアウト付き実行では `Process.kill("TERM"/"KILL")` を使用
|
|
84
|
+
- [`ScriptExecutor`](../lib/rufio/script_executor.rb)
|
|
85
|
+
- ハイライトは `bat` 子プロセスから出力取得
|
|
86
|
+
|
|
87
|
+
このため、重い外部処理があっても UI スレッド停止を避けやすい構造です。
|
|
88
|
+
|
|
89
|
+
## 5. Single Thread か?への回答
|
|
90
|
+
|
|
91
|
+
質問に対しては次の回答が正確です。
|
|
92
|
+
|
|
93
|
+
- UI制御: **シングルスレッド(イベントループ)**
|
|
94
|
+
- 並行処理: **マルチスレッドを使用**
|
|
95
|
+
- 実処理実行: **外部子プロセスを多用**
|
|
96
|
+
- アーキテクチャ全体: **単一メインプロセス + イベントループ + ワーカースレッド + 子プロセス**
|
|
97
|
+
|
|
98
|
+
## 6. 補足(運用上の含意)
|
|
99
|
+
|
|
100
|
+
- RubyスレッドはI/O待ちや外部プロセス待ちの分離には有効
|
|
101
|
+
- CPUバウンド処理をRubyスレッドで増やしても、処理系制約(GVL)で伸びにくい可能性がある
|
|
102
|
+
- 現状設計は「UI応答性優先」「外部コマンド委譲型」のTUIとして合理的
|
|
103
|
+
|
|
104
|
+
## 7. メモリモデル
|
|
105
|
+
|
|
106
|
+
rufio のメモリは、概ね次の4種類で構成されます。
|
|
107
|
+
|
|
108
|
+
- 固定サイズの描画バッファ(画面サイズ依存)
|
|
109
|
+
- ディレクトリ/プレビューなどの作業データ(操作対象依存)
|
|
110
|
+
- キャッシュ/履歴(セッション経過で増える可能性あり)
|
|
111
|
+
- 外部プロセス実行時の一時データ(子プロセス出力依存)
|
|
112
|
+
|
|
113
|
+
### 7.1 オブジェクトの寿命
|
|
114
|
+
|
|
115
|
+
- プロセス寿命で生存(起動時作成)
|
|
116
|
+
- `TerminalUI`, `UIRenderer`, `KeybindHandler`, `JobManager` など
|
|
117
|
+
- 画面更新ごとに再生成される一時データ
|
|
118
|
+
- 行描画文字列、差分描画バッファ
|
|
119
|
+
- ジョブ/コマンド実行中のみ生存
|
|
120
|
+
- ワーカースレッド、`Open3` の入出力文字列、スキャナーインスタンス
|
|
121
|
+
|
|
122
|
+
### 7.2 固定上限に近い領域
|
|
123
|
+
|
|
124
|
+
- ダブルバッファ
|
|
125
|
+
- [`Screen`](../lib/rufio/screen.rb): `@cells`(`height x width`)
|
|
126
|
+
- [`Renderer`](../lib/rufio/renderer.rb): `@front`(`height` 行ぶんの表示文字列)
|
|
127
|
+
- これらは基本的に「端末サイズに比例」し、無制限には伸びない
|
|
128
|
+
|
|
129
|
+
### 7.3 変動するが上限管理される領域
|
|
130
|
+
|
|
131
|
+
- 通知
|
|
132
|
+
- [`NotificationManager`](../lib/rufio/notification_manager.rb) は最大3件
|
|
133
|
+
- コマンド履歴(メモリ内)
|
|
134
|
+
- [`CommandHistory`](../lib/rufio/command_history.rb) は `max_size`(既定1000)
|
|
135
|
+
- ディレクトリエントリ
|
|
136
|
+
- [`DirectoryListing`](../lib/rufio/directory_listing.rb) は `refresh` ごとに `@entries` を再構築
|
|
137
|
+
|
|
138
|
+
### 7.4 増加しやすい領域(要注意)
|
|
139
|
+
|
|
140
|
+
- プレビューキャッシュ
|
|
141
|
+
- [`UIRenderer`](../lib/rufio/ui_renderer.rb) の `@preview_cache` は閲覧ファイルパス単位で蓄積
|
|
142
|
+
- `wrapped` / `highlighted_wrapped` も幅ごとに追加される
|
|
143
|
+
- `clear_preview_cache` は実装されているが、通常フローからは呼ばれていない
|
|
144
|
+
- ジョブ一覧
|
|
145
|
+
- [`JobManager`](../lib/rufio/job_manager.rb) の `@jobs` は追加され続ける
|
|
146
|
+
- `clear_completed` はあるが、通常キー操作には接続されていない
|
|
147
|
+
- ジョブログ
|
|
148
|
+
- [`TaskStatus`](../lib/rufio/task_status.rb) の `@logs` は配列で蓄積(上限なし)
|
|
149
|
+
- 標準出力/標準エラーが大きいジョブはメモリ圧迫要因になる
|
|
150
|
+
- ログファイル(ディスク)
|
|
151
|
+
- [`CommandLogger`](../lib/rufio/command_logger.rb) はログファイルを増やし続ける
|
|
152
|
+
- `cleanup_old_logs` は実装済みだが、通常フローで自動実行はされない
|
|
153
|
+
|
|
154
|
+
### 7.5 外部プロセス実行時のメモリ特性
|
|
155
|
+
|
|
156
|
+
- `Open3.capture3` は stdout/stderr を文字列として一括保持するため、
|
|
157
|
+
出力が大きいほど Ruby ヒープ使用量が一時的に増える
|
|
158
|
+
- ただし実処理は子プロセス側で実行されるため、計算本体のメモリは原則として別プロセスに分離される
|
|
159
|
+
|
|
160
|
+
### 7.6 Ruby/C 境界(Zig スキャナー)
|
|
161
|
+
|
|
162
|
+
- Zig経路では [`NativeScannerZigCore`](../lib/rufio/native_scanner_zig.rb) がハンドルを保持し、
|
|
163
|
+
`close` で `core_async_destroy` を呼んで明示解放する
|
|
164
|
+
- `scan` 呼び出し側は `ensure` で `close` しており、通常経路でハンドルリークしにくい設計
|
|
165
|
+
|
|
166
|
+
### 7.7 まとめ
|
|
167
|
+
|
|
168
|
+
メモリモデルとしては、**描画バッファは安定**している一方で、**プレビューキャッシュ・ジョブ履歴・ジョブログ**は
|
|
169
|
+
セッションが長くなるほど増えうる構造です。長時間運用時のメモリ安定性は、この3点の上限管理の有無に最も左右されます。
|
data/lib/rufio/terminal_ui.rb
CHANGED
|
@@ -185,6 +185,10 @@ module Rufio
|
|
|
185
185
|
STDIN.raw!
|
|
186
186
|
end
|
|
187
187
|
|
|
188
|
+
# SGR拡張マウスレポートを有効化(ボタン + ホイール + 任意位置クリック)
|
|
189
|
+
print "\e[?1003h\e[?1006h"
|
|
190
|
+
STDOUT.flush
|
|
191
|
+
|
|
188
192
|
# Windows: IO.select + read_nonblockはコンソールハンドルのESCキーを
|
|
189
193
|
# 検出できない場合がある。バックグラウンドスレッドでSTDINを読み取り
|
|
190
194
|
# Queueに格納することで信頼性のある入力検出を実現する。
|
|
@@ -231,6 +235,15 @@ module Rufio
|
|
|
231
235
|
end
|
|
232
236
|
end
|
|
233
237
|
|
|
238
|
+
# エスケープシーケンスの後続バイトを読み取る(Windows/Unix共通ヘルパー)
|
|
239
|
+
def read_next_input_byte
|
|
240
|
+
if @windows_input_queue
|
|
241
|
+
windows_read_next_byte
|
|
242
|
+
else
|
|
243
|
+
STDIN.read_nonblock(1) rescue nil
|
|
244
|
+
end
|
|
245
|
+
end
|
|
246
|
+
|
|
234
247
|
def cleanup_terminal
|
|
235
248
|
# rawモードを解除
|
|
236
249
|
if STDIN.tty?
|
|
@@ -244,6 +257,10 @@ module Rufio
|
|
|
244
257
|
@windows_input_queue = nil
|
|
245
258
|
end
|
|
246
259
|
|
|
260
|
+
# マウスレポートを無効化
|
|
261
|
+
print "\e[?1003l\e[?1006l"
|
|
262
|
+
STDOUT.flush
|
|
263
|
+
|
|
247
264
|
system('tput rmcup') # normal screen
|
|
248
265
|
system('tput cnorm') # cursor normal
|
|
249
266
|
puts ConfigLoader.message('app.terminated')
|
|
@@ -461,17 +478,27 @@ module Rufio
|
|
|
461
478
|
|
|
462
479
|
# 特殊キーの処理(エスケープシーケンス)(コマンドモード外のみ)
|
|
463
480
|
if input == "\e"
|
|
464
|
-
next_char =
|
|
465
|
-
windows_read_next_byte
|
|
466
|
-
else
|
|
467
|
-
STDIN.read_nonblock(1) rescue nil
|
|
468
|
-
end
|
|
481
|
+
next_char = read_next_input_byte
|
|
469
482
|
if next_char == '['
|
|
470
|
-
#
|
|
471
|
-
third_char =
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
483
|
+
# CSIシーケンス(矢印キー・マウスなど)
|
|
484
|
+
third_char = read_next_input_byte
|
|
485
|
+
if third_char == '<'
|
|
486
|
+
# SGR拡張マウスイベント: \e[<Btn;Col;RowM/m
|
|
487
|
+
mouse_seq = +""
|
|
488
|
+
loop do
|
|
489
|
+
ch = read_next_input_byte
|
|
490
|
+
break if ch.nil?
|
|
491
|
+
mouse_seq << ch
|
|
492
|
+
break if ch == 'M' || ch == 'm'
|
|
493
|
+
end
|
|
494
|
+
if (m = mouse_seq.match(/\A(\d+);(\d+);(\d+)([Mm])\z/))
|
|
495
|
+
btn = m[1].to_i
|
|
496
|
+
col = m[2].to_i
|
|
497
|
+
row = m[3].to_i
|
|
498
|
+
press = m[4] == 'M'
|
|
499
|
+
handle_mouse_event(btn, col, row, press)
|
|
500
|
+
end
|
|
501
|
+
return true
|
|
475
502
|
end
|
|
476
503
|
input = case third_char
|
|
477
504
|
when 'A' then 'k' # Up arrow
|
|
@@ -558,6 +585,95 @@ module Rufio
|
|
|
558
585
|
end
|
|
559
586
|
end
|
|
560
587
|
|
|
588
|
+
# ============================
|
|
589
|
+
# マウスイベント処理
|
|
590
|
+
# ============================
|
|
591
|
+
|
|
592
|
+
# SGRマウスイベントを処理する
|
|
593
|
+
# @param btn [Integer] SGRボタン番号(0=左, 1=中, 2=右, 64=ホイールアップ, 65=ホイールダウン)
|
|
594
|
+
# @param col [Integer] クリック列(1-indexed)
|
|
595
|
+
# @param row [Integer] クリック行(1-indexed)
|
|
596
|
+
# @param press [Boolean] true=押下, false=解放
|
|
597
|
+
def handle_mouse_event(btn, col, row, press)
|
|
598
|
+
case btn
|
|
599
|
+
when 0 # 左クリック(押下のみ処理)
|
|
600
|
+
handle_mouse_left_click(col, row) if press
|
|
601
|
+
when 64 # ホイールアップ
|
|
602
|
+
handle_mouse_scroll(:up, col, row)
|
|
603
|
+
when 65 # ホイールダウン
|
|
604
|
+
handle_mouse_scroll(:down, col, row)
|
|
605
|
+
end
|
|
606
|
+
end
|
|
607
|
+
|
|
608
|
+
# マウス左クリックを処理する
|
|
609
|
+
def handle_mouse_left_click(col, row)
|
|
610
|
+
left_width = left_panel_col_width
|
|
611
|
+
|
|
612
|
+
if col <= left_width
|
|
613
|
+
# 左パネル(ファイルリスト)クリック
|
|
614
|
+
handle_mouse_file_click(row)
|
|
615
|
+
else
|
|
616
|
+
# 右パネル(プレビュー)クリック — プレビューフォーカスを切り替え
|
|
617
|
+
if @keybind_handler.preview_focused?
|
|
618
|
+
@keybind_handler.unfocus_preview_pane
|
|
619
|
+
else
|
|
620
|
+
@keybind_handler.focus_preview_pane
|
|
621
|
+
end
|
|
622
|
+
end
|
|
623
|
+
end
|
|
624
|
+
|
|
625
|
+
# ファイルリストのクリック行からエントリを選択する(ダブルクリック対応)
|
|
626
|
+
def handle_mouse_file_click(row)
|
|
627
|
+
# コンテンツ行はターミナル行2〜(screen_height-1)
|
|
628
|
+
content_height = @screen_height - 2
|
|
629
|
+
return unless row >= 2 && row <= @screen_height - 1
|
|
630
|
+
|
|
631
|
+
current_idx = @keybind_handler.current_index
|
|
632
|
+
start_index = [current_idx - content_height / 2, 0].max
|
|
633
|
+
target_index = start_index + (row - 2)
|
|
634
|
+
|
|
635
|
+
entries = @keybind_handler.send(:get_active_entries)
|
|
636
|
+
return unless target_index >= 0 && target_index < entries.length
|
|
637
|
+
|
|
638
|
+
now = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
639
|
+
if @last_mouse_click_index == target_index &&
|
|
640
|
+
@last_mouse_click_time && (now - @last_mouse_click_time) < 0.5
|
|
641
|
+
# ダブルクリック: Enterキーと同等の動作
|
|
642
|
+
@keybind_handler.handle_key("\r")
|
|
643
|
+
@last_mouse_click_index = nil
|
|
644
|
+
@last_mouse_click_time = nil
|
|
645
|
+
else
|
|
646
|
+
# シングルクリック: カーソル移動
|
|
647
|
+
@keybind_handler.select_index(target_index)
|
|
648
|
+
@last_mouse_click_index = target_index
|
|
649
|
+
@last_mouse_click_time = now
|
|
650
|
+
end
|
|
651
|
+
end
|
|
652
|
+
|
|
653
|
+
# マウスホイールスクロールを処理する
|
|
654
|
+
def handle_mouse_scroll(direction, col, _row)
|
|
655
|
+
left_width = left_panel_col_width
|
|
656
|
+
|
|
657
|
+
if col > left_width && @keybind_handler.preview_focused?
|
|
658
|
+
# プレビューペインのスクロール
|
|
659
|
+
case direction
|
|
660
|
+
when :up then @keybind_handler.scroll_preview_up
|
|
661
|
+
when :down then @keybind_handler.scroll_preview_down
|
|
662
|
+
end
|
|
663
|
+
else
|
|
664
|
+
# ファイルリストのスクロール
|
|
665
|
+
case direction
|
|
666
|
+
when :up then @keybind_handler.handle_key('k')
|
|
667
|
+
when :down then @keybind_handler.handle_key('j')
|
|
668
|
+
end
|
|
669
|
+
end
|
|
670
|
+
end
|
|
671
|
+
|
|
672
|
+
# 左パネルの列幅(1-indexed境界)を返す
|
|
673
|
+
def left_panel_col_width
|
|
674
|
+
(@screen_width * @ui_renderer.left_panel_ratio).to_i
|
|
675
|
+
end
|
|
676
|
+
|
|
561
677
|
# モード変更を適用
|
|
562
678
|
def apply_mode_change(mode)
|
|
563
679
|
case mode
|
data/lib/rufio/ui_renderer.rb
CHANGED
|
@@ -25,7 +25,7 @@ module Rufio
|
|
|
25
25
|
attr_accessor :keybind_handler, :directory_listing, :file_preview
|
|
26
26
|
attr_accessor :background_executor, :test_mode
|
|
27
27
|
attr_accessor :completion_lamp_message, :completion_lamp_time
|
|
28
|
-
attr_reader :tab_mode_manager, :highlight_updated
|
|
28
|
+
attr_reader :tab_mode_manager, :highlight_updated, :left_panel_ratio
|
|
29
29
|
|
|
30
30
|
def preview_enabled?
|
|
31
31
|
@preview_enabled
|
data/lib/rufio/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rufio
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.83.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- masisz
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-03-
|
|
11
|
+
date: 2026-03-14 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: io-console
|
|
@@ -139,6 +139,7 @@ files:
|
|
|
139
139
|
- docs/CHANGELOG_v0.8.0.md
|
|
140
140
|
- docs/CHANGELOG_v0.80.0.md
|
|
141
141
|
- docs/CHANGELOG_v0.9.0.md
|
|
142
|
+
- docs/architecture_concurrency_ja_v0.82.1.md
|
|
142
143
|
- examples/bookmarks.yml
|
|
143
144
|
- examples/config.rb
|
|
144
145
|
- examples/script_paths.yml
|