rufio 0.50.0 → 0.61.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 +52 -0
- data/README.md +180 -594
- data/examples/config.yml +8 -0
- data/lib/rufio/bookmark.rb +6 -30
- data/lib/rufio/bookmark_manager.rb +15 -1
- data/lib/rufio/bookmark_storage.rb +148 -0
- data/lib/rufio/command_completion.rb +20 -5
- data/lib/rufio/command_mode.rb +102 -9
- data/lib/rufio/command_mode_ui.rb +8 -8
- data/lib/rufio/config.rb +54 -54
- data/lib/rufio/config_loader.rb +53 -0
- data/lib/rufio/job_manager.rb +128 -0
- data/lib/rufio/job_mode.rb +146 -0
- data/lib/rufio/keybind_handler.rb +243 -232
- data/lib/rufio/notification_manager.rb +77 -0
- data/lib/rufio/script_config_loader.rb +101 -0
- data/lib/rufio/script_path_manager.rb +386 -0
- data/lib/rufio/script_runner.rb +216 -0
- data/lib/rufio/task_status.rb +118 -0
- data/lib/rufio/terminal_ui.rb +183 -497
- data/lib/rufio/version.rb +1 -1
- data/lib/rufio.rb +9 -4
- data/scripts/test_jobs/build_simulation.sh +29 -0
- data/scripts/test_jobs/deploy_simulation.sh +37 -0
- data/scripts/test_jobs/quick.sh +11 -0
- data/scripts/test_jobs/random_result.sh +23 -0
- data/scripts/test_jobs/slow_fail.sh +10 -0
- data/scripts/test_jobs/slow_success.sh +10 -0
- data/scripts/test_jobs/very_slow.sh +19 -0
- metadata +21 -10
- data/docs/file-preview-optimization-analysis.md +0 -759
- data/docs/file-preview-performance-issue-FIXED.md +0 -547
- data/lib/rufio/project_command.rb +0 -147
- data/lib/rufio/project_log.rb +0 -68
- data/lib/rufio/project_mode.rb +0 -58
data/examples/config.yml
ADDED
data/lib/rufio/bookmark.rb
CHANGED
|
@@ -2,13 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
require 'json'
|
|
4
4
|
require 'fileutils'
|
|
5
|
+
require_relative 'bookmark_storage'
|
|
5
6
|
|
|
6
7
|
module Rufio
|
|
7
8
|
class Bookmark
|
|
8
9
|
MAX_BOOKMARKS = 9
|
|
9
10
|
|
|
10
|
-
def initialize(config_file = nil)
|
|
11
|
+
def initialize(config_file = nil, storage: nil)
|
|
11
12
|
@config_file = config_file || default_config_file
|
|
13
|
+
@storage = storage || JsonBookmarkStorage.new(@config_file)
|
|
12
14
|
@bookmarks = []
|
|
13
15
|
ensure_config_directory
|
|
14
16
|
load
|
|
@@ -70,38 +72,12 @@ module Rufio
|
|
|
70
72
|
end
|
|
71
73
|
|
|
72
74
|
def save
|
|
73
|
-
|
|
74
|
-
File.write(@config_file, JSON.pretty_generate(@bookmarks))
|
|
75
|
-
true
|
|
76
|
-
rescue StandardError => e
|
|
77
|
-
warn "Failed to save bookmarks: #{e.message}"
|
|
78
|
-
false
|
|
79
|
-
end
|
|
75
|
+
@storage.save(@bookmarks)
|
|
80
76
|
end
|
|
81
77
|
|
|
82
78
|
def load
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
begin
|
|
86
|
-
content = File.read(@config_file)
|
|
87
|
-
@bookmarks = JSON.parse(content, symbolize_names: true)
|
|
88
|
-
@bookmarks = [] unless @bookmarks.is_a?(Array)
|
|
89
|
-
|
|
90
|
-
# 無効なブックマークを除去
|
|
91
|
-
@bookmarks = @bookmarks.select do |bookmark|
|
|
92
|
-
bookmark.is_a?(Hash) &&
|
|
93
|
-
bookmark.key?(:path) &&
|
|
94
|
-
bookmark.key?(:name) &&
|
|
95
|
-
bookmark[:path].is_a?(String) &&
|
|
96
|
-
bookmark[:name].is_a?(String)
|
|
97
|
-
end
|
|
98
|
-
|
|
99
|
-
true
|
|
100
|
-
rescue JSON::ParserError, StandardError => e
|
|
101
|
-
warn "Failed to load bookmarks: #{e.message}"
|
|
102
|
-
@bookmarks = []
|
|
103
|
-
true
|
|
104
|
-
end
|
|
79
|
+
@bookmarks = @storage.load
|
|
80
|
+
true
|
|
105
81
|
end
|
|
106
82
|
|
|
107
83
|
private
|
|
@@ -1,16 +1,30 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require_relative 'bookmark'
|
|
4
|
+
require_relative 'bookmark_storage'
|
|
4
5
|
require_relative 'config_loader'
|
|
5
6
|
|
|
6
7
|
module Rufio
|
|
7
8
|
# Manages bookmark operations with interactive UI
|
|
8
9
|
class BookmarkManager
|
|
9
10
|
def initialize(bookmark = nil, dialog_renderer = nil)
|
|
10
|
-
@bookmark = bookmark ||
|
|
11
|
+
@bookmark = bookmark || create_default_bookmark
|
|
11
12
|
@dialog_renderer = dialog_renderer
|
|
12
13
|
end
|
|
13
14
|
|
|
15
|
+
private
|
|
16
|
+
|
|
17
|
+
def create_default_bookmark
|
|
18
|
+
# 必要に応じてJSONからYAMLに移行
|
|
19
|
+
ConfigLoader.migrate_bookmarks_if_needed
|
|
20
|
+
|
|
21
|
+
# YAMLストレージを使用
|
|
22
|
+
storage = ConfigLoader.bookmark_storage
|
|
23
|
+
Bookmark.new(ConfigLoader::YAML_CONFIG_PATH, storage: storage)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
public
|
|
27
|
+
|
|
14
28
|
# Show bookmark menu and handle user selection
|
|
15
29
|
# @param current_path [String] Current directory path
|
|
16
30
|
# @return [Symbol, nil] Action to perform (:navigate, :add, :list, :remove, :cancel)
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'json'
|
|
4
|
+
require 'yaml'
|
|
5
|
+
require 'fileutils'
|
|
6
|
+
|
|
7
|
+
module Rufio
|
|
8
|
+
# ブックマークストレージの基底クラス
|
|
9
|
+
class BookmarkStorage
|
|
10
|
+
def initialize(file_path)
|
|
11
|
+
@file_path = file_path
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def load
|
|
15
|
+
raise NotImplementedError, 'Subclasses must implement #load'
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def save(_bookmarks)
|
|
19
|
+
raise NotImplementedError, 'Subclasses must implement #save'
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
protected
|
|
23
|
+
|
|
24
|
+
def ensure_directory
|
|
25
|
+
dir = File.dirname(@file_path)
|
|
26
|
+
FileUtils.mkdir_p(dir) unless Dir.exist?(dir)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def valid_bookmark?(bookmark)
|
|
30
|
+
bookmark.is_a?(Hash) &&
|
|
31
|
+
bookmark.key?(:path) &&
|
|
32
|
+
bookmark.key?(:name) &&
|
|
33
|
+
bookmark[:path].is_a?(String) &&
|
|
34
|
+
bookmark[:name].is_a?(String)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def filter_valid_bookmarks(bookmarks)
|
|
38
|
+
return [] unless bookmarks.is_a?(Array)
|
|
39
|
+
|
|
40
|
+
bookmarks.select { |b| valid_bookmark?(b) }
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# JSON形式のブックマークストレージ
|
|
45
|
+
class JsonBookmarkStorage < BookmarkStorage
|
|
46
|
+
def load
|
|
47
|
+
return [] unless File.exist?(@file_path)
|
|
48
|
+
|
|
49
|
+
content = File.read(@file_path)
|
|
50
|
+
bookmarks = JSON.parse(content, symbolize_names: true)
|
|
51
|
+
filter_valid_bookmarks(bookmarks)
|
|
52
|
+
rescue JSON::ParserError, StandardError
|
|
53
|
+
[]
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def save(bookmarks)
|
|
57
|
+
ensure_directory
|
|
58
|
+
File.write(@file_path, JSON.pretty_generate(bookmarks))
|
|
59
|
+
true
|
|
60
|
+
rescue StandardError => e
|
|
61
|
+
warn "Failed to save bookmarks to JSON: #{e.message}"
|
|
62
|
+
false
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# YAML形式のブックマークストレージ(config.ymlに統合)
|
|
67
|
+
class YamlBookmarkStorage < BookmarkStorage
|
|
68
|
+
def load
|
|
69
|
+
return [] unless File.exist?(@file_path)
|
|
70
|
+
|
|
71
|
+
content = YAML.safe_load(File.read(@file_path), symbolize_names: true)
|
|
72
|
+
return [] unless content.is_a?(Hash) && content[:bookmarks]
|
|
73
|
+
|
|
74
|
+
filter_valid_bookmarks(content[:bookmarks])
|
|
75
|
+
rescue StandardError
|
|
76
|
+
[]
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def save(bookmarks)
|
|
80
|
+
ensure_directory
|
|
81
|
+
|
|
82
|
+
# 既存の設定を読み込み
|
|
83
|
+
existing_config = if File.exist?(@file_path)
|
|
84
|
+
YAML.safe_load(File.read(@file_path), symbolize_names: true) || {}
|
|
85
|
+
else
|
|
86
|
+
{}
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
# ブックマークを文字列キーのハッシュに変換(YAMLの可読性のため)
|
|
90
|
+
bookmarks_for_yaml = bookmarks.map do |b|
|
|
91
|
+
{ 'path' => b[:path], 'name' => b[:name] }
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
# ブックマークセクションを更新
|
|
95
|
+
existing_config_string_keys = deep_stringify_keys(existing_config)
|
|
96
|
+
existing_config_string_keys['bookmarks'] = bookmarks_for_yaml
|
|
97
|
+
|
|
98
|
+
File.write(@file_path, YAML.dump(existing_config_string_keys))
|
|
99
|
+
true
|
|
100
|
+
rescue StandardError => e
|
|
101
|
+
warn "Failed to save bookmarks to YAML: #{e.message}"
|
|
102
|
+
false
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
private
|
|
106
|
+
|
|
107
|
+
def deep_stringify_keys(hash)
|
|
108
|
+
return hash unless hash.is_a?(Hash)
|
|
109
|
+
|
|
110
|
+
hash.transform_keys(&:to_s).transform_values do |v|
|
|
111
|
+
case v
|
|
112
|
+
when Hash
|
|
113
|
+
deep_stringify_keys(v)
|
|
114
|
+
when Array
|
|
115
|
+
v.map { |item| item.is_a?(Hash) ? deep_stringify_keys(item) : item }
|
|
116
|
+
else
|
|
117
|
+
v
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
# ブックマークのJSON→YAMLマイグレーター
|
|
124
|
+
class BookmarkMigrator
|
|
125
|
+
class << self
|
|
126
|
+
def migrate(json_path, yaml_path)
|
|
127
|
+
return false unless File.exist?(json_path)
|
|
128
|
+
|
|
129
|
+
# JSONからブックマークを読み込み
|
|
130
|
+
json_storage = JsonBookmarkStorage.new(json_path)
|
|
131
|
+
bookmarks = json_storage.load
|
|
132
|
+
|
|
133
|
+
# YAMLに保存
|
|
134
|
+
yaml_storage = YamlBookmarkStorage.new(yaml_path)
|
|
135
|
+
yaml_storage.save(bookmarks)
|
|
136
|
+
|
|
137
|
+
# JSONファイルをバックアップして削除
|
|
138
|
+
backup_path = "#{json_path}.bak"
|
|
139
|
+
FileUtils.mv(json_path, backup_path)
|
|
140
|
+
|
|
141
|
+
true
|
|
142
|
+
rescue StandardError => e
|
|
143
|
+
warn "Failed to migrate bookmarks: #{e.message}"
|
|
144
|
+
false
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
end
|
|
@@ -5,8 +5,9 @@ module Rufio
|
|
|
5
5
|
class CommandCompletion
|
|
6
6
|
# 初期化
|
|
7
7
|
# @param history [CommandHistory, nil] コマンド履歴(オプション)
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
# @param command_mode [CommandMode, nil] コマンドモード(スクリプト補完に使用)
|
|
9
|
+
def initialize(history = nil, command_mode = nil)
|
|
10
|
+
@command_mode = command_mode || CommandMode.new
|
|
10
11
|
@shell_completion = ShellCommandCompletion.new
|
|
11
12
|
@history = history
|
|
12
13
|
end
|
|
@@ -15,9 +16,9 @@ module Rufio
|
|
|
15
16
|
# @param input [String] 入力されたテキスト
|
|
16
17
|
# @return [Array<String>] 補完候補のリスト
|
|
17
18
|
def complete(input)
|
|
18
|
-
#
|
|
19
|
+
# 入力が空の場合は内部コマンドとスクリプトを返す
|
|
19
20
|
if input.nil? || input.strip.empty?
|
|
20
|
-
return @command_mode.available_commands.map(&:to_s)
|
|
21
|
+
return @command_mode.available_commands.map(&:to_s) + script_candidates('')
|
|
21
22
|
end
|
|
22
23
|
|
|
23
24
|
# シェルコマンド補完(!で始まる場合)
|
|
@@ -25,7 +26,12 @@ module Rufio
|
|
|
25
26
|
return complete_shell_command(input.strip)
|
|
26
27
|
end
|
|
27
28
|
|
|
28
|
-
#
|
|
29
|
+
# スクリプト補完(@で始まる場合)
|
|
30
|
+
if input.strip.start_with?('@')
|
|
31
|
+
return @command_mode.complete_script(input.strip)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# 通常のコマンド補完(内部コマンド + スクリプト)
|
|
29
35
|
available_commands = @command_mode.available_commands.map(&:to_s)
|
|
30
36
|
input_lower = input.downcase
|
|
31
37
|
candidates = available_commands.select do |command|
|
|
@@ -61,6 +67,15 @@ module Rufio
|
|
|
61
67
|
|
|
62
68
|
private
|
|
63
69
|
|
|
70
|
+
# スクリプト候補を取得
|
|
71
|
+
# @param prefix [String] 入力中の文字列
|
|
72
|
+
# @return [Array<String>] スクリプト候補(@付き)
|
|
73
|
+
def script_candidates(prefix)
|
|
74
|
+
return [] unless @command_mode&.script_runner
|
|
75
|
+
|
|
76
|
+
@command_mode.complete_script("@#{prefix}")
|
|
77
|
+
end
|
|
78
|
+
|
|
64
79
|
# シェルコマンドの補完
|
|
65
80
|
# @param input [String] ! で始まる入力
|
|
66
81
|
# @return [Array<String>] 補完候補のリスト
|
data/lib/rufio/command_mode.rb
CHANGED
|
@@ -7,19 +7,54 @@ module Rufio
|
|
|
7
7
|
# すべてのコマンドはDslCommandとして扱われる
|
|
8
8
|
class CommandMode
|
|
9
9
|
attr_accessor :background_executor
|
|
10
|
+
attr_reader :script_runner, :script_path_manager
|
|
10
11
|
|
|
11
12
|
def initialize(background_executor = nil)
|
|
12
13
|
@commands = {}
|
|
13
14
|
@background_executor = background_executor
|
|
15
|
+
@script_runner = nil
|
|
16
|
+
@script_path_manager = nil
|
|
17
|
+
@job_manager = nil
|
|
14
18
|
load_builtin_commands
|
|
15
19
|
load_dsl_commands
|
|
16
20
|
end
|
|
17
21
|
|
|
22
|
+
# ScriptRunnerを設定する
|
|
23
|
+
# @param script_paths [Array<String>] スクリプトパス
|
|
24
|
+
# @param job_manager [JobManager] ジョブマネージャー
|
|
25
|
+
def setup_script_runner(script_paths:, job_manager:)
|
|
26
|
+
@job_manager = job_manager
|
|
27
|
+
@script_runner = ScriptRunner.new(
|
|
28
|
+
script_paths: script_paths,
|
|
29
|
+
job_manager: job_manager
|
|
30
|
+
)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# ScriptPathManagerを設定する(設定ファイルベース)
|
|
34
|
+
# @param config_file [String] 設定ファイルのパス
|
|
35
|
+
# @param job_manager [JobManager] ジョブマネージャー
|
|
36
|
+
def setup_script_path_manager(config_file:, job_manager:)
|
|
37
|
+
@job_manager = job_manager
|
|
38
|
+
@script_path_manager = ScriptPathManager.new(config_file)
|
|
39
|
+
# ScriptRunnerも設定(ScriptPathManagerのパスを使用)
|
|
40
|
+
@script_runner = ScriptRunner.new(
|
|
41
|
+
script_paths: @script_path_manager.paths,
|
|
42
|
+
job_manager: job_manager
|
|
43
|
+
)
|
|
44
|
+
end
|
|
45
|
+
|
|
18
46
|
# コマンドを実行する
|
|
19
|
-
|
|
47
|
+
# @param command_string [String] コマンド文字列
|
|
48
|
+
# @param working_dir [String, nil] 作業ディレクトリ(スクリプト実行時に使用)
|
|
49
|
+
def execute(command_string, working_dir: nil)
|
|
20
50
|
# 空のコマンドは無視
|
|
21
51
|
return nil if command_string.nil? || command_string.strip.empty?
|
|
22
52
|
|
|
53
|
+
# スクリプト実行 (@ で始まる場合)
|
|
54
|
+
if command_string.strip.start_with?('@')
|
|
55
|
+
return execute_script(command_string.strip[1..-1], working_dir)
|
|
56
|
+
end
|
|
57
|
+
|
|
23
58
|
# シェルコマンドの実行 (! で始まる場合)
|
|
24
59
|
if command_string.strip.start_with?('!')
|
|
25
60
|
shell_command = command_string.strip[1..-1]
|
|
@@ -27,9 +62,9 @@ module Rufio
|
|
|
27
62
|
# バックグラウンドエグゼキュータが利用可能な場合は非同期実行
|
|
28
63
|
if @background_executor
|
|
29
64
|
if @background_executor.execute_async(shell_command)
|
|
30
|
-
return "🔄
|
|
65
|
+
return "🔄 Running in background: #{shell_command.split.first}"
|
|
31
66
|
else
|
|
32
|
-
return "⚠️
|
|
67
|
+
return "⚠️ Command already running"
|
|
33
68
|
end
|
|
34
69
|
else
|
|
35
70
|
# バックグラウンドエグゼキュータがない場合は同期実行
|
|
@@ -42,12 +77,18 @@ module Rufio
|
|
|
42
77
|
|
|
43
78
|
# 統一されたコマンドストアから検索
|
|
44
79
|
command = @commands[command_name]
|
|
45
|
-
|
|
46
|
-
|
|
80
|
+
if command
|
|
81
|
+
# 内部コマンドを実行
|
|
82
|
+
return execute_unified_command(command_name, command)
|
|
47
83
|
end
|
|
48
84
|
|
|
49
|
-
#
|
|
50
|
-
|
|
85
|
+
# 内部コマンドが見つからない場合、スクリプトパスから検索
|
|
86
|
+
if @script_path_manager || @script_runner
|
|
87
|
+
script_result = try_execute_script_from_paths(command_string.strip, working_dir)
|
|
88
|
+
return script_result if script_result
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
"⚠️ コマンドが見つかりません: #{command_name}"
|
|
51
92
|
end
|
|
52
93
|
|
|
53
94
|
# 利用可能なコマンドのリストを取得
|
|
@@ -87,6 +128,17 @@ module Rufio
|
|
|
87
128
|
end
|
|
88
129
|
end
|
|
89
130
|
|
|
131
|
+
# スクリプト名を補完する
|
|
132
|
+
# @param prefix [String] 入力中の文字列(@を含む)
|
|
133
|
+
# @return [Array<String>] 補完候補(@付き)
|
|
134
|
+
def complete_script(prefix)
|
|
135
|
+
return [] unless @script_runner
|
|
136
|
+
|
|
137
|
+
# @を除去して検索
|
|
138
|
+
search_prefix = prefix.sub(/^@/, '')
|
|
139
|
+
@script_runner.complete(search_prefix).map { |name| "@#{name}" }
|
|
140
|
+
end
|
|
141
|
+
|
|
90
142
|
private
|
|
91
143
|
|
|
92
144
|
# 組み込みコマンドをロードする
|
|
@@ -113,9 +165,9 @@ module Rufio
|
|
|
113
165
|
if @background_executor.execute_ruby_async(command_display_name) do
|
|
114
166
|
ScriptExecutor.execute_command(dsl_cmd)
|
|
115
167
|
end
|
|
116
|
-
return "🔄
|
|
168
|
+
return "🔄 Running in background: #{command_display_name}"
|
|
117
169
|
else
|
|
118
|
-
return "⚠️
|
|
170
|
+
return "⚠️ Command already running"
|
|
119
171
|
end
|
|
120
172
|
end
|
|
121
173
|
|
|
@@ -150,5 +202,46 @@ module Rufio
|
|
|
150
202
|
{ success: false, error: "コマンド実行エラー: #{e.message}" }
|
|
151
203
|
end
|
|
152
204
|
end
|
|
205
|
+
|
|
206
|
+
# スクリプトを実行する(@プレフィックス用)
|
|
207
|
+
# @param script_name [String] スクリプト名
|
|
208
|
+
# @param working_dir [String, nil] 作業ディレクトリ
|
|
209
|
+
# @return [String] 実行結果メッセージ
|
|
210
|
+
def execute_script(script_name, working_dir)
|
|
211
|
+
unless @script_runner
|
|
212
|
+
return "⚠️ スクリプトランナーが設定されていません"
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
working_dir ||= Dir.pwd
|
|
216
|
+
|
|
217
|
+
job = @script_runner.run(script_name, working_dir: working_dir)
|
|
218
|
+
|
|
219
|
+
if job
|
|
220
|
+
"🚀 ジョブを開始: #{script_name}"
|
|
221
|
+
else
|
|
222
|
+
"⚠️ スクリプトが見つかりません: #{script_name}"
|
|
223
|
+
end
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
# スクリプトパスからスクリプトを検索して実行を試みる
|
|
227
|
+
# @param command_name [String] コマンド名
|
|
228
|
+
# @param working_dir [String, nil] 作業ディレクトリ
|
|
229
|
+
# @return [String, nil] 実行結果メッセージ、見つからない場合nil
|
|
230
|
+
def try_execute_script_from_paths(command_name, working_dir)
|
|
231
|
+
return nil unless @script_runner
|
|
232
|
+
|
|
233
|
+
script = @script_runner.find_script(command_name)
|
|
234
|
+
return nil unless script
|
|
235
|
+
|
|
236
|
+
working_dir ||= Dir.pwd
|
|
237
|
+
|
|
238
|
+
job = @script_runner.run(command_name, working_dir: working_dir)
|
|
239
|
+
|
|
240
|
+
if job
|
|
241
|
+
"🚀 ジョブを開始: #{script[:name]}"
|
|
242
|
+
else
|
|
243
|
+
nil
|
|
244
|
+
end
|
|
245
|
+
end
|
|
153
246
|
end
|
|
154
247
|
end
|
|
@@ -47,13 +47,13 @@ module Rufio
|
|
|
47
47
|
# @param suggestions [Array<String>] 補完候補(オプション)
|
|
48
48
|
def show_input_prompt(input, suggestions = [])
|
|
49
49
|
# タイトル
|
|
50
|
-
title = "
|
|
50
|
+
title = "Command Mode"
|
|
51
51
|
|
|
52
|
-
#
|
|
52
|
+
# Build content lines
|
|
53
53
|
content_lines = [""]
|
|
54
|
-
content_lines << "#{input}_" #
|
|
54
|
+
content_lines << "#{input}_" # Show cursor as _
|
|
55
55
|
content_lines << ""
|
|
56
|
-
content_lines << "Tab:
|
|
56
|
+
content_lines << "Tab: Complete | Enter: Execute | ESC: Cancel"
|
|
57
57
|
|
|
58
58
|
# ウィンドウの色設定(青)
|
|
59
59
|
border_color = "\e[34m" # Blue
|
|
@@ -94,7 +94,7 @@ module Rufio
|
|
|
94
94
|
else
|
|
95
95
|
# 文字列形式の結果(従来の動作)
|
|
96
96
|
result_text = result
|
|
97
|
-
is_error = result.include?("⚠️") || result.include?("
|
|
97
|
+
is_error = result.include?("⚠️") || result.include?("Error")
|
|
98
98
|
end
|
|
99
99
|
|
|
100
100
|
# 結果を行に分割
|
|
@@ -112,7 +112,7 @@ module Rufio
|
|
|
112
112
|
end
|
|
113
113
|
|
|
114
114
|
# ウィンドウタイトル
|
|
115
|
-
title = "
|
|
115
|
+
title = "Command Result"
|
|
116
116
|
|
|
117
117
|
# コンテンツ行を構築
|
|
118
118
|
content_lines = [""] + result_lines + ["", "Press any key to close"]
|
|
@@ -207,9 +207,9 @@ module Rufio
|
|
|
207
207
|
# 何も出力がない場合
|
|
208
208
|
if lines.empty?
|
|
209
209
|
if result[:success]
|
|
210
|
-
lines << "
|
|
210
|
+
lines << "Command executed successfully"
|
|
211
211
|
else
|
|
212
|
-
lines << "
|
|
212
|
+
lines << "Command failed"
|
|
213
213
|
end
|
|
214
214
|
end
|
|
215
215
|
|
data/lib/rufio/config.rb
CHANGED
|
@@ -79,71 +79,71 @@ module Rufio
|
|
|
79
79
|
|
|
80
80
|
'ja' => {
|
|
81
81
|
# Application messages
|
|
82
|
-
'app.interrupted' => 'rufio
|
|
83
|
-
'app.error_occurred' => '
|
|
84
|
-
'app.terminated' => 'rufio
|
|
82
|
+
'app.interrupted' => 'rufio interrupted',
|
|
83
|
+
'app.error_occurred' => 'Error occurred',
|
|
84
|
+
'app.terminated' => 'rufio terminated',
|
|
85
85
|
|
|
86
86
|
# File operations
|
|
87
|
-
'file.not_found' => '
|
|
88
|
-
'file.not_readable' => '
|
|
89
|
-
'file.read_error' => '
|
|
90
|
-
'file.binary_file' => '
|
|
91
|
-
'file.cannot_preview' => '
|
|
92
|
-
'file.encoding_error' => '
|
|
93
|
-
'file.preview_error' => '
|
|
94
|
-
'file.error_prefix' => '
|
|
87
|
+
'file.not_found' => 'File not found',
|
|
88
|
+
'file.not_readable' => 'File not readable',
|
|
89
|
+
'file.read_error' => 'File read error',
|
|
90
|
+
'file.binary_file' => 'Binary file',
|
|
91
|
+
'file.cannot_preview' => 'Cannot preview',
|
|
92
|
+
'file.encoding_error' => 'Encoding error - cannot read file',
|
|
93
|
+
'file.preview_error' => 'Preview error',
|
|
94
|
+
'file.error_prefix' => 'Error',
|
|
95
95
|
|
|
96
96
|
# Keybind messages
|
|
97
|
-
'keybind.invalid_key' => '
|
|
98
|
-
'keybind.search_text' => '
|
|
99
|
-
'keybind.no_matches' => '
|
|
100
|
-
'keybind.press_any_key' => '
|
|
101
|
-
'keybind.input_filename' => '
|
|
102
|
-
'keybind.input_dirname' => '
|
|
103
|
-
'keybind.invalid_filename' => '
|
|
104
|
-
'keybind.invalid_dirname' => '
|
|
105
|
-
'keybind.file_exists' => '
|
|
106
|
-
'keybind.directory_exists' => '
|
|
107
|
-
'keybind.file_created' => '
|
|
108
|
-
'keybind.directory_created' => '
|
|
109
|
-
'keybind.creation_error' => '
|
|
97
|
+
'keybind.invalid_key' => 'Invalid key',
|
|
98
|
+
'keybind.search_text' => 'Search: ',
|
|
99
|
+
'keybind.no_matches' => 'No matches found.',
|
|
100
|
+
'keybind.press_any_key' => 'Press any key to continue...',
|
|
101
|
+
'keybind.input_filename' => 'Enter filename: ',
|
|
102
|
+
'keybind.input_dirname' => 'Enter directory name: ',
|
|
103
|
+
'keybind.invalid_filename' => 'Invalid filename (cannot contain / or \\)',
|
|
104
|
+
'keybind.invalid_dirname' => 'Invalid directory name (cannot contain / or \\)',
|
|
105
|
+
'keybind.file_exists' => 'File already exists',
|
|
106
|
+
'keybind.directory_exists' => 'Directory already exists',
|
|
107
|
+
'keybind.file_created' => 'File created',
|
|
108
|
+
'keybind.directory_created' => 'Directory created',
|
|
109
|
+
'keybind.creation_error' => 'Creation error',
|
|
110
110
|
|
|
111
111
|
# UI messages
|
|
112
|
-
'ui.operation_prompt' => '
|
|
112
|
+
'ui.operation_prompt' => 'Operation: ',
|
|
113
113
|
|
|
114
114
|
# Help text
|
|
115
|
-
'help.full' => 'j/k
|
|
116
|
-
'help.short' => 'j/k
|
|
115
|
+
'help.full' => 'j/k:move h:back l:enter o:open g/G:top/end r:refresh f:filter s:search F:content a/A:create m/c/x:ops b:bookmark z:zoxide 1-9:jump q:quit',
|
|
116
|
+
'help.short' => 'j/k:move h:back l:enter o:open f:filter s:search b:bookmark z:zoxide 1-9:jump q:quit',
|
|
117
117
|
|
|
118
118
|
# Health check messages
|
|
119
|
-
'health.title' => 'rufio
|
|
120
|
-
'health.ruby_version' => 'Ruby
|
|
121
|
-
'health.required_gems' => '
|
|
122
|
-
'health.fzf' => 'fzf (
|
|
123
|
-
'health.rga' => 'rga (
|
|
124
|
-
'health.zoxide' => 'zoxide (
|
|
125
|
-
'health.file_opener' => '
|
|
126
|
-
'health.summary' => '
|
|
119
|
+
'health.title' => 'rufio Health Check',
|
|
120
|
+
'health.ruby_version' => 'Ruby version',
|
|
121
|
+
'health.required_gems' => 'Required gems',
|
|
122
|
+
'health.fzf' => 'fzf (file search)',
|
|
123
|
+
'health.rga' => 'rga (content search)',
|
|
124
|
+
'health.zoxide' => 'zoxide (directory history)',
|
|
125
|
+
'health.file_opener' => 'System file opener',
|
|
126
|
+
'health.summary' => 'Summary:',
|
|
127
127
|
'health.ok' => 'OK',
|
|
128
|
-
'health.warnings' => '
|
|
129
|
-
'health.errors' => '
|
|
130
|
-
'health.all_passed' => '
|
|
131
|
-
'health.critical_missing' => '
|
|
132
|
-
'health.optional_missing' => '
|
|
133
|
-
'health.all_gems_installed' => '
|
|
134
|
-
'health.missing_gems' => '
|
|
135
|
-
'health.gem_install_instruction' => '
|
|
136
|
-
'health.tool_not_found' => '
|
|
137
|
-
'health.unknown_platform' => '
|
|
138
|
-
'health.file_open_may_not_work' => '
|
|
139
|
-
'health.macos_opener' => 'macOS
|
|
140
|
-
'health.linux_opener' => 'Linux
|
|
141
|
-
'health.windows_opener' => 'Windows
|
|
142
|
-
'health.install_brew' => '
|
|
143
|
-
'health.install_apt' => '
|
|
144
|
-
'health.install_guide' => '
|
|
145
|
-
'health.rga_releases' => '
|
|
146
|
-
'health.ruby_upgrade_needed' => 'Ruby
|
|
128
|
+
'health.warnings' => 'Warnings',
|
|
129
|
+
'health.errors' => 'Errors',
|
|
130
|
+
'health.all_passed' => 'All checks passed! rufio is ready to use.',
|
|
131
|
+
'health.critical_missing' => 'Critical components missing. rufio may not work properly.',
|
|
132
|
+
'health.optional_missing' => 'Optional features unavailable. Basic features will work.',
|
|
133
|
+
'health.all_gems_installed' => 'All required gems are installed',
|
|
134
|
+
'health.missing_gems' => 'Missing gems',
|
|
135
|
+
'health.gem_install_instruction' => 'Run: gem install',
|
|
136
|
+
'health.tool_not_found' => 'not found',
|
|
137
|
+
'health.unknown_platform' => 'Unknown platform',
|
|
138
|
+
'health.file_open_may_not_work' => 'File open may not work properly',
|
|
139
|
+
'health.macos_opener' => 'macOS file opener',
|
|
140
|
+
'health.linux_opener' => 'Linux file opener',
|
|
141
|
+
'health.windows_opener' => 'Windows file opener',
|
|
142
|
+
'health.install_brew' => 'Install: brew install',
|
|
143
|
+
'health.install_apt' => 'Install: apt install',
|
|
144
|
+
'health.install_guide' => 'Check installation guide for your platform',
|
|
145
|
+
'health.rga_releases' => 'Install: https://github.com/phiresky/ripgrep-all/releases',
|
|
146
|
+
'health.ruby_upgrade_needed' => 'Please upgrade Ruby to version 2.7.0 or higher'
|
|
147
147
|
}
|
|
148
148
|
}.freeze
|
|
149
149
|
|