rufio 0.91.0 → 1.0.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 +12 -0
- data/lib/rufio/keybind_handler.rb +0 -1
- data/lib/rufio/script_executor.rb +9 -4
- data/lib/rufio/terminal_ui.rb +118 -38
- data/lib/rufio/ui_renderer.rb +32 -3
- data/lib/rufio/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 78138156eb9ae86f5a57696e3b0170417da3c7b2c8a2d0dba4af3460efe69ddd
|
|
4
|
+
data.tar.gz: b8c184800c8e26955663e0404654e50973407441ac61658511b15fc2bbf6c96f
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 572569248e94a4456f20bcbf7a8235b26bbae55aadc24c911ae528ebcb23b08f2cd0ec1cb9f97c6781308b6856e676b4983e42728bd21ae4a21e0820b0eb0e28
|
|
7
|
+
data.tar.gz: 65d4deb78ca48dc9e892b63e42bd98827a50d1b0168f7df198957c476696d67999268f4e2021bbc4beb6edad5be96e8acbac6a087bfe5855e25ac63bb23be102
|
data/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,18 @@ 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
|
+
## [1.0.0] - 2026-04-28
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- **Job mode: View log with Space key**: Press Space on a selected job to display its full execution log. Footer switches to `[ESC] Close Log` while in log view; press ESC to return to the job list
|
|
12
|
+
- **Job mode: Disable Tab key**: Tab (bookmark cycling) is now suppressed in job mode to prevent accidental navigation. Removed `[Tab] Switch Mode` from the job mode footer
|
|
13
|
+
|
|
14
|
+
### Fixed
|
|
15
|
+
- **Windows: ESC key not working**: `STDIN.raw` + `getbyte` silently drops the ESC byte (0x1B) under Windows ConPTY. The blocking input thread now uses `getch` instead, pushing each received byte onto the queue
|
|
16
|
+
- **Windows: Preview flickering**: Redundant `print "\e[2J\e[H"` calls before `renderer.clear` caused the screen to blank momentarily on every redraw. Removed the duplicate clears in `refresh_display`, `set_job_mode`, and `exit_job_mode`. Also unified the async highlight-updated flag into `UIRenderer` (it was maintained separately in both `TerminalUI` and `UIRenderer`, causing missed redraws)
|
|
17
|
+
- **Windows: Cursor visible as blinking vertical bar in bottom-right corner**: `tput civis` is a no-op on Windows, leaving the cursor visible. Replaced `tput civis/cnorm/smcup/rmcup` with ANSI sequences `\e[?25l`/`\e[?25h`/`\e[?1049h`/`\e[?1049l` which work on Windows Terminal. Cursor is shown only during command mode input and hidden otherwise
|
|
18
|
+
- **Windows: `bundle install` fails with "cannot load git ls-files"**: `rufio.gemspec` now falls back to `Dir.glob` when `git` is not on PATH
|
|
19
|
+
|
|
8
20
|
## [0.91.0] - 2026-04-12
|
|
9
21
|
|
|
10
22
|
### Changed
|
|
@@ -118,7 +118,8 @@ module Rufio
|
|
|
118
118
|
|
|
119
119
|
begin
|
|
120
120
|
Timeout.timeout(timeout_sec) do
|
|
121
|
-
|
|
121
|
+
args = env.empty? ? [*command] : [env, *command]
|
|
122
|
+
stdin, stdout_io, stderr_io, wait_thread = Open3.popen3(*args, **options)
|
|
122
123
|
pid = wait_thread.pid
|
|
123
124
|
stdin.close
|
|
124
125
|
stdout = stdout_io.read
|
|
@@ -162,7 +163,9 @@ module Rufio
|
|
|
162
163
|
|
|
163
164
|
# タイムアウトなしで実行
|
|
164
165
|
def execute_without_timeout(command, env, options)
|
|
165
|
-
|
|
166
|
+
# 空の env ハッシュを渡すと Windows で SystemRoot 等が引き継がれないため省略する
|
|
167
|
+
args = env.empty? ? [*command] : [env, *command]
|
|
168
|
+
stdout, stderr, status = Open3.capture3(*args, **options)
|
|
166
169
|
|
|
167
170
|
{
|
|
168
171
|
success: status.success?,
|
|
@@ -183,7 +186,8 @@ module Rufio
|
|
|
183
186
|
|
|
184
187
|
begin
|
|
185
188
|
Timeout.timeout(timeout_sec) do
|
|
186
|
-
|
|
189
|
+
args = env.empty? ? [shell_command] : [env, shell_command]
|
|
190
|
+
stdin, stdout_io, stderr_io, wait_thread = Open3.popen3(*args, **options)
|
|
187
191
|
pid = wait_thread.pid
|
|
188
192
|
stdin.close
|
|
189
193
|
stdout = stdout_io.read
|
|
@@ -226,7 +230,8 @@ module Rufio
|
|
|
226
230
|
|
|
227
231
|
# シェルコマンドをタイムアウトなしで実行
|
|
228
232
|
def execute_shell_without_timeout(shell_command, env, options)
|
|
229
|
-
|
|
233
|
+
args = env.empty? ? [shell_command] : [env, shell_command]
|
|
234
|
+
stdout, stderr, status = Open3.capture3(*args, **options)
|
|
230
235
|
|
|
231
236
|
{
|
|
232
237
|
success: status.success?,
|
data/lib/rufio/terminal_ui.rb
CHANGED
|
@@ -48,6 +48,8 @@ module Rufio
|
|
|
48
48
|
@running = false
|
|
49
49
|
@test_mode = test_mode
|
|
50
50
|
@multibyte_reader = MultibyteInputReader.new(STDIN)
|
|
51
|
+
@input_queue = nil
|
|
52
|
+
@input_thread = nil
|
|
51
53
|
@command_mode_active = false
|
|
52
54
|
@command_input = ""
|
|
53
55
|
@command_mode = CommandMode.new
|
|
@@ -73,8 +75,6 @@ module Rufio
|
|
|
73
75
|
|
|
74
76
|
# シンタックスハイライター(bat が利用可能な場合のみ動作)
|
|
75
77
|
@syntax_highlighter = SyntaxHighlighter.new
|
|
76
|
-
# 非同期ハイライト完了フラグ(Thread → メインループへの通知)
|
|
77
|
-
@highlight_updated = false
|
|
78
78
|
|
|
79
79
|
|
|
80
80
|
# Tab mode manager
|
|
@@ -132,7 +132,6 @@ module Rufio
|
|
|
132
132
|
def refresh_display
|
|
133
133
|
# ウィンドウサイズを更新してから画面をクリアして再描画
|
|
134
134
|
update_screen_size
|
|
135
|
-
print "\e[2J\e[H" # clear screen, cursor to home
|
|
136
135
|
|
|
137
136
|
# プレビューキャッシュをクリア(ディレクトリ変更やリフレッシュ時)
|
|
138
137
|
@preview_cache.clear
|
|
@@ -176,16 +175,34 @@ module Rufio
|
|
|
176
175
|
# ブックマークハイライトが期限切れかどうか
|
|
177
176
|
# @return [Boolean] true=期限切れ or ハイライト中でない, false=ハイライト中
|
|
178
177
|
def setup_terminal
|
|
179
|
-
# terminal setup
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
print "\e[2J\e[H"
|
|
178
|
+
# terminal setup(ANSI エスケープで統一 — tput は Windows で動作しない)
|
|
179
|
+
print "\e[?1049h" # alternate screen buffer
|
|
180
|
+
print "\e[?25l" # cursor invisible
|
|
181
|
+
print "\e[2J\e[H" # clear screen, cursor to home (first time only)
|
|
183
182
|
|
|
184
183
|
# rawモードに設定(ゲームループのノンブロッキング入力用)
|
|
185
184
|
if STDIN.tty?
|
|
186
185
|
STDIN.raw!
|
|
187
186
|
end
|
|
188
187
|
|
|
188
|
+
# Windows: ブロッキング読み取りスレッドを起動。
|
|
189
|
+
# ConPTY パイプでは IO.select のシグナル遅延で ESC を取りこぼすため、
|
|
190
|
+
# 常にブロッキングで読み取りキューに積む。
|
|
191
|
+
# getbyte は raw モード下で ESC (0x1B) を取りこぼす ConPTY バグがあるため
|
|
192
|
+
# getch を使用し、受信した各バイトをキューに積む。
|
|
193
|
+
if windows?
|
|
194
|
+
@input_queue = Queue.new
|
|
195
|
+
@input_thread = Thread.new do
|
|
196
|
+
loop do
|
|
197
|
+
ch = STDIN.getch(min: 1)
|
|
198
|
+
break if ch.nil?
|
|
199
|
+
ch.bytes.each { |b| @input_queue << b }
|
|
200
|
+
end
|
|
201
|
+
rescue
|
|
202
|
+
# スレッド終了
|
|
203
|
+
end
|
|
204
|
+
end
|
|
205
|
+
|
|
189
206
|
# SGR拡張マウスレポートを有効化
|
|
190
207
|
# Unix: \e[?1003h (any-event) + \e[?1006h (SGR座標) → クリック・スクロール・移動
|
|
191
208
|
# Windows: \e[?1003h は Windows Terminal / conhost 非対応。
|
|
@@ -215,29 +232,72 @@ module Rufio
|
|
|
215
232
|
end
|
|
216
233
|
|
|
217
234
|
# エスケープシーケンスの後続バイトを読み取る(矢印キー等の短いシーケンス用)。
|
|
218
|
-
# Windows: IO.select
|
|
235
|
+
# Windows: IO.select を使わずキューから取得(5ms タイムアウト)。
|
|
219
236
|
def read_next_input_byte
|
|
220
237
|
if windows?
|
|
221
|
-
|
|
222
|
-
|
|
238
|
+
b = windows_queue_pop_with_timeout(0.005)
|
|
239
|
+
b.nil? ? nil : b.chr(Encoding::BINARY)
|
|
223
240
|
else
|
|
224
241
|
STDIN.read_nonblock(1) rescue nil
|
|
225
242
|
end
|
|
226
243
|
end
|
|
227
244
|
|
|
228
245
|
# SGRマウスシーケンスの後続バイトを読み取る。
|
|
229
|
-
#
|
|
230
|
-
# Windows Console のイベントキューにバイトが積まれるまで 20ms 待つ。
|
|
246
|
+
# Windows: キューから取得(20ms タイムアウト)。
|
|
231
247
|
def read_next_mouse_byte
|
|
232
248
|
if windows?
|
|
233
|
-
|
|
234
|
-
|
|
249
|
+
b = windows_queue_pop_with_timeout(0.020)
|
|
250
|
+
b.nil? ? nil : b.chr(Encoding::BINARY)
|
|
235
251
|
else
|
|
236
252
|
STDIN.read_nonblock(1) rescue nil
|
|
237
253
|
end
|
|
238
254
|
end
|
|
239
255
|
|
|
256
|
+
# Windows 専用: キューから1文字(マルチバイト対応)を組み立てる。
|
|
257
|
+
# first_byte_int は getbyte が返す Integer。
|
|
258
|
+
def windows_build_char(first_byte_int)
|
|
259
|
+
remaining = case first_byte_int
|
|
260
|
+
when 0x00..0x7F then 0
|
|
261
|
+
when 0xC0..0xDF then 1
|
|
262
|
+
when 0xE0..0xEF then 2
|
|
263
|
+
when 0xF0..0xF7 then 3
|
|
264
|
+
else 0
|
|
265
|
+
end
|
|
266
|
+
if remaining == 0
|
|
267
|
+
first_byte_int.chr(Encoding::UTF_8)
|
|
268
|
+
else
|
|
269
|
+
buf = first_byte_int.chr(Encoding::BINARY)
|
|
270
|
+
remaining.times do
|
|
271
|
+
b = windows_queue_pop_with_timeout(0.005)
|
|
272
|
+
return nil if b.nil?
|
|
273
|
+
buf << b.chr(Encoding::BINARY)
|
|
274
|
+
end
|
|
275
|
+
result = buf.force_encoding(Encoding::UTF_8)
|
|
276
|
+
result.valid_encoding? ? result : nil
|
|
277
|
+
end
|
|
278
|
+
end
|
|
279
|
+
|
|
280
|
+
# Windows 専用: @input_queue からタイムアウト付きで Integer バイトを取り出す。
|
|
281
|
+
def windows_queue_pop_with_timeout(timeout_sec)
|
|
282
|
+
deadline = Time.now + timeout_sec
|
|
283
|
+
loop do
|
|
284
|
+
begin
|
|
285
|
+
return @input_queue.pop(true)
|
|
286
|
+
rescue ThreadError
|
|
287
|
+
return nil if Time.now >= deadline
|
|
288
|
+
sleep 0.001
|
|
289
|
+
end
|
|
290
|
+
end
|
|
291
|
+
end
|
|
292
|
+
|
|
240
293
|
def cleanup_terminal
|
|
294
|
+
# Windows 入力スレッドを停止(raw! 解除前に kill)
|
|
295
|
+
if windows? && @input_thread
|
|
296
|
+
@input_thread.kill rescue nil
|
|
297
|
+
@input_thread.join(0.5) rescue nil
|
|
298
|
+
@input_thread = nil
|
|
299
|
+
end
|
|
300
|
+
|
|
241
301
|
# rawモードを解除
|
|
242
302
|
if STDIN.tty?
|
|
243
303
|
STDIN.cooked!
|
|
@@ -251,8 +311,9 @@ module Rufio
|
|
|
251
311
|
end
|
|
252
312
|
STDOUT.flush
|
|
253
313
|
|
|
254
|
-
|
|
255
|
-
|
|
314
|
+
print "\e[?25h" # cursor visible
|
|
315
|
+
print "\e[?1049l" # restore normal screen buffer
|
|
316
|
+
STDOUT.flush
|
|
256
317
|
puts ConfigLoader.message('app.terminated')
|
|
257
318
|
end
|
|
258
319
|
|
|
@@ -369,9 +430,9 @@ module Rufio
|
|
|
369
430
|
needs_redraw = true
|
|
370
431
|
end
|
|
371
432
|
|
|
372
|
-
#
|
|
373
|
-
if @highlight_updated
|
|
374
|
-
@
|
|
433
|
+
# 非同期シンタックスハイライト完了チェック(UIRenderer側のフラグを参照)
|
|
434
|
+
if @ui_renderer.highlight_updated?
|
|
435
|
+
@ui_renderer.reset_highlight_updated
|
|
375
436
|
needs_redraw = true
|
|
376
437
|
end
|
|
377
438
|
|
|
@@ -432,25 +493,28 @@ module Rufio
|
|
|
432
493
|
private
|
|
433
494
|
|
|
434
495
|
# ノンブロッキング入力処理(ゲームループ用)
|
|
435
|
-
# Windows:
|
|
436
|
-
#
|
|
437
|
-
# 1ms の正のタイムアウトを使う。コンソールハンドルでも ConPTY パイプでも動作する。
|
|
496
|
+
# Windows: ブロッキング入力スレッドのキューからノンブロッキングで取得
|
|
497
|
+
# (IO.select の ConPTY シグナル遅延問題を回避)
|
|
438
498
|
# Unix: IO.select(timeout=0) で入力確認後 read_nonblock
|
|
439
499
|
def handle_input_nonblocking
|
|
440
|
-
# 入力バイトを1つ読み取る
|
|
441
500
|
if windows?
|
|
442
|
-
# Windows:
|
|
443
|
-
|
|
501
|
+
# Windows: ブロッキング入力スレッドが積んだキューから取得
|
|
502
|
+
raw_byte = begin
|
|
503
|
+
@input_queue.pop(true)
|
|
504
|
+
rescue ThreadError
|
|
505
|
+
return false
|
|
506
|
+
end
|
|
507
|
+
input = windows_build_char(raw_byte)
|
|
508
|
+
return false unless input
|
|
444
509
|
else
|
|
445
510
|
# Unix: 0msタイムアウトで即座にチェック(30FPS = 33.33ms/frame)
|
|
446
511
|
return false unless IO.select([STDIN], nil, nil, 0)
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
return false
|
|
512
|
+
begin
|
|
513
|
+
input = @multibyte_reader.read_char
|
|
514
|
+
return false if input.nil?
|
|
515
|
+
rescue Errno::ENOTTY, Errno::ENODEV
|
|
516
|
+
return false
|
|
517
|
+
end
|
|
454
518
|
end
|
|
455
519
|
|
|
456
520
|
# コマンドモードがアクティブな場合は、エスケープシーケンス処理をスキップ
|
|
@@ -492,15 +556,19 @@ module Rufio
|
|
|
492
556
|
when 'C' then 'l' # Right arrow
|
|
493
557
|
when 'D' then 'h' # Left arrow
|
|
494
558
|
when 'Z' then handle_shift_tab; return true # Shift+Tab
|
|
495
|
-
else
|
|
559
|
+
else
|
|
560
|
+
# 未知の CSI シーケンス(\e[27;1u 等): 残りバイトを読み捨てて
|
|
561
|
+
# パイプを汚染しないようにする
|
|
562
|
+
drain_csi_sequence(third_char)
|
|
563
|
+
"\e"
|
|
496
564
|
end
|
|
497
565
|
else
|
|
498
566
|
input = "\e" # ESCキー(そのまま保持)
|
|
499
567
|
end
|
|
500
568
|
end
|
|
501
569
|
|
|
502
|
-
# TabキーはFiles
|
|
503
|
-
if input == "\t" && @tab_mode_manager.current_mode == :files
|
|
570
|
+
# TabキーはFilesモードの時のみブックマーク循環移動(ジョブモード中は無効)
|
|
571
|
+
if input == "\t" && @tab_mode_manager.current_mode == :files && !@in_job_mode
|
|
504
572
|
handle_tab_key
|
|
505
573
|
return true
|
|
506
574
|
end
|
|
@@ -703,6 +771,8 @@ module Rufio
|
|
|
703
771
|
def activate_command_mode
|
|
704
772
|
@command_mode_active = true
|
|
705
773
|
@command_input = ""
|
|
774
|
+
print "\e[?25h" # カーソルを表示(テキスト入力中)
|
|
775
|
+
STDOUT.flush
|
|
706
776
|
# 閲覧中ディレクトリをコマンドモードに通知(ローカルスクリプト・Rakefileの検出用)
|
|
707
777
|
browsing_dir = @directory_listing&.current_path || Dir.pwd
|
|
708
778
|
@command_mode.update_browsing_directory(browsing_dir)
|
|
@@ -712,6 +782,8 @@ module Rufio
|
|
|
712
782
|
def deactivate_command_mode
|
|
713
783
|
@command_mode_active = false
|
|
714
784
|
@command_input = ""
|
|
785
|
+
print "\e[?25l" # カーソルを非表示(通常のファイラー表示に戻る)
|
|
786
|
+
STDOUT.flush
|
|
715
787
|
# オーバーレイをクリア
|
|
716
788
|
@screen&.clear_overlay if @screen&.overlay_enabled?
|
|
717
789
|
end
|
|
@@ -923,8 +995,7 @@ module Rufio
|
|
|
923
995
|
@job_manager = job_manager
|
|
924
996
|
@notification_manager = notification_manager
|
|
925
997
|
@in_job_mode = true
|
|
926
|
-
#
|
|
927
|
-
print "\e[2J\e[H"
|
|
998
|
+
# レンダラーをリセット(print "\e[2J\e[H" は renderer.clear に含まれる)
|
|
928
999
|
@renderer.clear if @renderer
|
|
929
1000
|
# 再描画フラグを立てる
|
|
930
1001
|
@job_mode_needs_redraw = true
|
|
@@ -937,7 +1008,6 @@ module Rufio
|
|
|
937
1008
|
@job_manager = nil
|
|
938
1009
|
# バッファベースの全画面再描画を使用
|
|
939
1010
|
update_screen_size
|
|
940
|
-
print "\e[2J\e[H"
|
|
941
1011
|
if @screen && @renderer
|
|
942
1012
|
@renderer.clear
|
|
943
1013
|
@screen.clear
|
|
@@ -1135,6 +1205,16 @@ module Rufio
|
|
|
1135
1205
|
})
|
|
1136
1206
|
end
|
|
1137
1207
|
|
|
1208
|
+
# 未知の CSI シーケンス(\e[X...)の残りバイトを終端アルファベットまで読み捨てる。
|
|
1209
|
+
# Windows Terminal が \e[27;1u 等を送った場合のパイプ汚染を防ぐ。
|
|
1210
|
+
def drain_csi_sequence(first_char)
|
|
1211
|
+
return if first_char.nil? || first_char =~ /[A-Za-z]/
|
|
1212
|
+
10.times do
|
|
1213
|
+
ch = read_next_input_byte
|
|
1214
|
+
break if ch.nil? || ch =~ /[A-Za-z]/
|
|
1215
|
+
end
|
|
1216
|
+
end
|
|
1217
|
+
|
|
1138
1218
|
end
|
|
1139
1219
|
end
|
|
1140
1220
|
|
data/lib/rufio/ui_renderer.rb
CHANGED
|
@@ -128,7 +128,8 @@ module Rufio
|
|
|
128
128
|
|
|
129
129
|
if in_job_mode
|
|
130
130
|
# ジョブモード: フッタ y=0(上部)、コンテンツ y=1〜h-2、統合行 y=h-1(下部)
|
|
131
|
-
|
|
131
|
+
log_mode = job_mode_instance&.log_mode? || false
|
|
132
|
+
draw_job_footer_to_buffer(screen, 0, job_manager, log_mode: log_mode)
|
|
132
133
|
draw_job_list_to_buffer(screen, content_height, job_manager, job_mode_instance)
|
|
133
134
|
draw_mode_tabs_to_buffer(screen, @screen_height - 1)
|
|
134
135
|
else
|
|
@@ -659,6 +660,12 @@ module Rufio
|
|
|
659
660
|
def draw_job_list_to_buffer(screen, height, job_manager, job_mode_instance)
|
|
660
661
|
return unless job_manager
|
|
661
662
|
|
|
663
|
+
# ログモード中は選択ジョブのログを表示
|
|
664
|
+
if job_mode_instance&.log_mode?
|
|
665
|
+
draw_job_log_to_buffer(screen, height, job_mode_instance.selected_job)
|
|
666
|
+
return
|
|
667
|
+
end
|
|
668
|
+
|
|
662
669
|
jobs = job_manager.jobs
|
|
663
670
|
selected_index = job_mode_instance&.selected_index || 0
|
|
664
671
|
|
|
@@ -674,6 +681,24 @@ module Rufio
|
|
|
674
681
|
end
|
|
675
682
|
end
|
|
676
683
|
|
|
684
|
+
def draw_job_log_to_buffer(screen, height, job)
|
|
685
|
+
unless job
|
|
686
|
+
screen.put_string(0, CONTENT_START_LINE, 'No job selected'.ljust(@screen_width), fg: "\e[90m")
|
|
687
|
+
return
|
|
688
|
+
end
|
|
689
|
+
|
|
690
|
+
log_lines = job.logs || []
|
|
691
|
+
title = "=== Log: #{job.name} ==="
|
|
692
|
+
screen.put_string(0, CONTENT_START_LINE, title.ljust(@screen_width), fg: "\e[1;36m")
|
|
693
|
+
|
|
694
|
+
(0...height - 1).each do |i|
|
|
695
|
+
line_num = i + CONTENT_START_LINE + 1
|
|
696
|
+
line = log_lines[i] || ''
|
|
697
|
+
line = line[0...@screen_width].ljust(@screen_width)
|
|
698
|
+
screen.put_string(0, line_num, line, fg: "\e[37m")
|
|
699
|
+
end
|
|
700
|
+
end
|
|
701
|
+
|
|
677
702
|
def draw_job_line_to_buffer(screen, job, is_selected, y)
|
|
678
703
|
icon = job.status_icon
|
|
679
704
|
name = job.name
|
|
@@ -712,9 +737,13 @@ module Rufio
|
|
|
712
737
|
end
|
|
713
738
|
end
|
|
714
739
|
|
|
715
|
-
def draw_job_footer_to_buffer(screen, y, job_manager)
|
|
740
|
+
def draw_job_footer_to_buffer(screen, y, job_manager, log_mode: false)
|
|
716
741
|
job_count = job_manager&.job_count || 0
|
|
717
|
-
help_text =
|
|
742
|
+
help_text = if log_mode
|
|
743
|
+
"[ESC] Close Log | Jobs: #{job_count}"
|
|
744
|
+
else
|
|
745
|
+
"[Space] View Log | [x] Cancel | Jobs: #{job_count}"
|
|
746
|
+
end
|
|
718
747
|
footer_content = help_text.center(@screen_width)[0...@screen_width]
|
|
719
748
|
|
|
720
749
|
footer_content.each_char.with_index do |char, x|
|
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: 1.0.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-04-
|
|
11
|
+
date: 2026-04-29 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: io-console
|