rufio 0.60.0 → 0.62.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 +56 -0
- data/README.md +221 -590
- data/README_ja.md +331 -0
- data/examples/bookmarks.yml +14 -0
- data/examples/config.rb +68 -0
- data/examples/script_paths.yml +11 -0
- data/lib/rufio/application.rb +1 -1
- data/lib/rufio/bookmark.rb +6 -30
- data/lib/rufio/bookmark_manager.rb +15 -1
- data/lib/rufio/bookmark_storage.rb +149 -0
- data/lib/rufio/command_mode.rb +4 -4
- data/lib/rufio/command_mode_ui.rb +8 -8
- data/lib/rufio/config.rb +268 -54
- data/lib/rufio/config_loader.rb +149 -26
- data/lib/rufio/keybind_handler.rb +14 -9
- data/lib/rufio/script_config_loader.rb +27 -12
- data/lib/rufio/script_path_manager.rb +50 -89
- data/lib/rufio/terminal_ui.rb +2 -2
- data/lib/rufio/version.rb +1 -1
- data/lib/rufio.rb +1 -0
- metadata +10 -17
- data/README_EN.md +0 -610
- data/config_example.rb +0 -88
- data/examples/config.yml +0 -8
- data/scripts/test_jobs/build_simulation.sh +0 -29
- data/scripts/test_jobs/deploy_simulation.sh +0 -37
- data/scripts/test_jobs/quick.sh +0 -11
- data/scripts/test_jobs/random_result.sh +0 -23
- data/scripts/test_jobs/slow_fail.sh +0 -10
- data/scripts/test_jobs/slow_success.sh +0 -10
- data/scripts/test_jobs/very_slow.sh +0 -19
- data/test_delete/test1.txt +0 -1
- data/test_delete/test2.txt +0 -1
|
@@ -51,7 +51,7 @@ module Rufio
|
|
|
51
51
|
# Log viewer mode
|
|
52
52
|
@in_log_viewer_mode = false
|
|
53
53
|
@pre_log_viewer_directory = nil
|
|
54
|
-
@log_dir = File.join(Dir.home, '.config', 'rufio', '
|
|
54
|
+
@log_dir = File.join(Dir.home, '.config', 'rufio', 'logs')
|
|
55
55
|
|
|
56
56
|
# Preview pane focus and scroll
|
|
57
57
|
@preview_focused = false
|
|
@@ -62,9 +62,8 @@ module Rufio
|
|
|
62
62
|
@job_manager = JobManager.new(notification_manager: @notification_manager)
|
|
63
63
|
@job_mode = JobMode.new(job_manager: @job_manager)
|
|
64
64
|
|
|
65
|
-
# Script path manager
|
|
66
|
-
|
|
67
|
-
@script_path_manager = File.exist?(config_file) ? ScriptPathManager.new(config_file) : nil
|
|
65
|
+
# Script path manager (新形式: script_paths.yml)
|
|
66
|
+
@script_path_manager = ScriptPathManager.new(Config::SCRIPT_PATHS_YML)
|
|
68
67
|
end
|
|
69
68
|
|
|
70
69
|
def set_directory_listing(directory_listing)
|
|
@@ -1446,8 +1445,16 @@ module Rufio
|
|
|
1446
1445
|
when '3'
|
|
1447
1446
|
show_script_paths_manager
|
|
1448
1447
|
when '4'
|
|
1449
|
-
#
|
|
1448
|
+
# ブックマーク一覧表示
|
|
1449
|
+
selected_bookmark = @bookmark_manager.list_interactive
|
|
1450
1450
|
@terminal_ui&.refresh_display
|
|
1451
|
+
if selected_bookmark
|
|
1452
|
+
if @bookmark_manager.path_exists?(selected_bookmark)
|
|
1453
|
+
navigate_to_directory(selected_bookmark[:path])
|
|
1454
|
+
else
|
|
1455
|
+
show_error_and_wait('bookmark.path_not_exist', selected_bookmark[:path])
|
|
1456
|
+
end
|
|
1457
|
+
end
|
|
1451
1458
|
else
|
|
1452
1459
|
@terminal_ui&.refresh_display
|
|
1453
1460
|
end
|
|
@@ -1460,10 +1467,8 @@ module Rufio
|
|
|
1460
1467
|
current_path = @directory_listing&.current_path || Dir.pwd
|
|
1461
1468
|
|
|
1462
1469
|
unless @script_path_manager
|
|
1463
|
-
# ScriptPathManager
|
|
1464
|
-
|
|
1465
|
-
FileUtils.mkdir_p(File.dirname(config_file))
|
|
1466
|
-
@script_path_manager = ScriptPathManager.new(config_file)
|
|
1470
|
+
# ScriptPathManagerがない場合は作成(新形式: script_paths.yml)
|
|
1471
|
+
@script_path_manager = ScriptPathManager.new(Config::SCRIPT_PATHS_YML)
|
|
1467
1472
|
end
|
|
1468
1473
|
|
|
1469
1474
|
if @script_path_manager.paths.include?(current_path)
|
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require 'yaml'
|
|
4
|
+
require_relative 'config'
|
|
4
5
|
|
|
5
6
|
module Rufio
|
|
6
7
|
# 複数の設定ファイルからscript_pathsをロード・マージするクラス
|
|
7
8
|
# 優先順位: ローカル > ユーザー > システム
|
|
8
9
|
class ScriptConfigLoader
|
|
9
|
-
#
|
|
10
|
-
DEFAULT_LOCAL_PATH =
|
|
11
|
-
DEFAULT_USER_PATH =
|
|
12
|
-
DEFAULT_SYSTEM_PATH = '/etc/rufio/
|
|
10
|
+
# デフォルトの設定ファイルパス(新形式: script_paths.yml)
|
|
11
|
+
DEFAULT_LOCAL_PATH = Config::LOCAL_YAML_PATH
|
|
12
|
+
DEFAULT_USER_PATH = Config::SCRIPT_PATHS_YML
|
|
13
|
+
DEFAULT_SYSTEM_PATH = '/etc/rufio/script_paths.yml'
|
|
13
14
|
|
|
14
15
|
# @param local_path [String, nil] ローカル設定ファイルのパス
|
|
15
16
|
# @param user_path [String, nil] ユーザー設定ファイルのパス
|
|
@@ -63,25 +64,39 @@ module Rufio
|
|
|
63
64
|
|
|
64
65
|
private
|
|
65
66
|
|
|
66
|
-
# 設定ファイルからscript_paths
|
|
67
|
+
# 設定ファイルからscript_pathsを読み込む(新形式対応)
|
|
67
68
|
# @param path [String] 設定ファイルのパス
|
|
68
69
|
# @return [Array<String>] パスの配列
|
|
69
70
|
def load_paths_from_file(path)
|
|
71
|
+
# 新形式: script_paths.yml(リスト形式)
|
|
72
|
+
if path.end_with?('script_paths.yml')
|
|
73
|
+
return Config.load_script_paths(path)
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
# 後方互換: 古いconfig.yml形式(ハッシュ形式)
|
|
70
77
|
config = load_config(path)
|
|
71
78
|
config['script_paths'] || []
|
|
72
79
|
end
|
|
73
80
|
|
|
74
|
-
#
|
|
81
|
+
# 設定ファイルを読み込む(後方互換用)
|
|
75
82
|
# @param path [String] 設定ファイルのパス
|
|
76
83
|
# @return [Hash] 設定内容
|
|
77
84
|
def load_config(path)
|
|
78
|
-
|
|
85
|
+
config = Config.load_yaml_config(path)
|
|
86
|
+
stringify_keys(config)
|
|
87
|
+
end
|
|
79
88
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
89
|
+
def stringify_keys(hash)
|
|
90
|
+
hash.transform_keys(&:to_s).transform_values do |value|
|
|
91
|
+
case value
|
|
92
|
+
when Hash
|
|
93
|
+
stringify_keys(value)
|
|
94
|
+
when Array
|
|
95
|
+
value.map { |v| v.is_a?(Hash) ? stringify_keys(v) : v }
|
|
96
|
+
else
|
|
97
|
+
value
|
|
98
|
+
end
|
|
99
|
+
end
|
|
85
100
|
end
|
|
86
101
|
|
|
87
102
|
# ハッシュを深くマージ
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require 'yaml'
|
|
4
|
+
require_relative 'config'
|
|
4
5
|
|
|
5
6
|
module Rufio
|
|
6
7
|
# スクリプトパスを管理するクラス
|
|
@@ -14,22 +15,43 @@ module Rufio
|
|
|
14
15
|
# 履歴の最大サイズ
|
|
15
16
|
MAX_HISTORY_SIZE = 100
|
|
16
17
|
|
|
17
|
-
# @param config_path [String]
|
|
18
|
-
def initialize(config_path)
|
|
19
|
-
@config_path = config_path
|
|
20
|
-
@
|
|
21
|
-
@paths = expand_paths(@config['script_paths'] || [])
|
|
18
|
+
# @param config_path [String] 設定ファイルのパス(script_paths.yml または config.yml)
|
|
19
|
+
def initialize(config_path = nil)
|
|
20
|
+
@config_path = config_path || Config::SCRIPT_PATHS_YML
|
|
21
|
+
@paths = load_paths_from_config
|
|
22
22
|
@cache = {}
|
|
23
23
|
@scripts_cache = nil
|
|
24
24
|
@execution_history = []
|
|
25
25
|
@execution_count = Hash.new(0)
|
|
26
26
|
end
|
|
27
27
|
|
|
28
|
+
private
|
|
29
|
+
|
|
30
|
+
# 設定ファイルからパスを読み込む(新旧形式対応)
|
|
31
|
+
def load_paths_from_config
|
|
32
|
+
# 新形式: script_paths.yml(リスト形式)
|
|
33
|
+
if @config_path.end_with?('script_paths.yml')
|
|
34
|
+
return Config.load_script_paths(@config_path)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# 後方互換: 古いconfig.yml形式
|
|
38
|
+
return [] unless File.exist?(@config_path)
|
|
39
|
+
|
|
40
|
+
yaml = YAML.safe_load(File.read(@config_path), symbolize_names: false)
|
|
41
|
+
return [] unless yaml.is_a?(Hash)
|
|
42
|
+
|
|
43
|
+
paths = yaml['script_paths'] || []
|
|
44
|
+
paths.map { |p| File.expand_path(p) }
|
|
45
|
+
rescue StandardError
|
|
46
|
+
[]
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
public
|
|
50
|
+
|
|
28
51
|
# スクリプト名で解決
|
|
29
52
|
# @param command_name [String] スクリプト名(拡張子あり/なし)
|
|
30
53
|
# @return [String, nil] スクリプトのフルパス、見つからない場合はnil
|
|
31
54
|
def resolve(command_name)
|
|
32
|
-
# キャッシュをチェック
|
|
33
55
|
return @cache[command_name] if @cache.key?(command_name)
|
|
34
56
|
|
|
35
57
|
scripts = find_scripts(command_name)
|
|
@@ -40,7 +62,6 @@ module Rufio
|
|
|
40
62
|
when 1
|
|
41
63
|
@cache[command_name] = scripts.first
|
|
42
64
|
else
|
|
43
|
-
# 複数見つかった場合は最初のものを返す(on_multiple_match: 'first')
|
|
44
65
|
@cache[command_name] = scripts.first
|
|
45
66
|
end
|
|
46
67
|
end
|
|
@@ -98,20 +119,12 @@ module Rufio
|
|
|
98
119
|
!!result
|
|
99
120
|
end
|
|
100
121
|
|
|
101
|
-
# --- Phase 4: 複数マッチ ---
|
|
102
|
-
|
|
103
122
|
# すべてのマッチを取得(複数マッチ対応)
|
|
104
|
-
# @param command_name [String] コマンド名
|
|
105
|
-
# @return [Array<String>] マッチしたスクリプトのパス
|
|
106
123
|
def find_all_matches(command_name)
|
|
107
124
|
find_scripts_all_paths(command_name)
|
|
108
125
|
end
|
|
109
126
|
|
|
110
|
-
# --- Phase 4: タブ補完 ---
|
|
111
|
-
|
|
112
127
|
# スクリプト名を補完
|
|
113
|
-
# @param prefix [String] 入力中の文字列
|
|
114
|
-
# @return [Array<String>] 補完候補(拡張子なし)
|
|
115
128
|
def complete(prefix)
|
|
116
129
|
scripts = all_scripts
|
|
117
130
|
return scripts if prefix.empty?
|
|
@@ -119,87 +132,63 @@ module Rufio
|
|
|
119
132
|
scripts.select { |name| name.downcase.start_with?(prefix.downcase) }
|
|
120
133
|
end
|
|
121
134
|
|
|
122
|
-
# --- Phase 4: fuzzy matching ---
|
|
123
|
-
|
|
124
135
|
# fuzzy matchingで候補を取得
|
|
125
|
-
# @param query [String] 検索クエリ
|
|
126
|
-
# @return [Array<String>] マッチしたスクリプト名
|
|
127
136
|
def fuzzy_match(query)
|
|
128
137
|
return all_scripts if query.empty?
|
|
129
138
|
|
|
130
139
|
scripts = all_scripts
|
|
131
140
|
query_chars = query.downcase.chars
|
|
132
141
|
|
|
133
|
-
# スコア計算してソート
|
|
134
142
|
scored = scripts.map do |name|
|
|
135
143
|
score = fuzzy_score(name.downcase, query_chars)
|
|
136
144
|
[name, score]
|
|
137
145
|
end
|
|
138
146
|
|
|
139
|
-
# スコアが0より大きいものをスコア降順で返す
|
|
140
147
|
scored.select { |_, score| score > 0 }
|
|
141
148
|
.sort_by { |_, score| -score }
|
|
142
149
|
.map { |name, _| name }
|
|
143
150
|
end
|
|
144
151
|
|
|
145
|
-
#
|
|
146
|
-
|
|
147
|
-
# キャッシュを無効化(public)
|
|
152
|
+
# キャッシュを無効化
|
|
148
153
|
def invalidate_cache
|
|
149
154
|
@cache.clear
|
|
150
155
|
@scripts_cache = nil
|
|
151
156
|
end
|
|
152
157
|
|
|
153
|
-
# --- Phase 4: 実行履歴 ---
|
|
154
|
-
|
|
155
158
|
# 実行を記録
|
|
156
|
-
# @param script_name [String] スクリプト名
|
|
157
159
|
def record_execution(script_name)
|
|
158
|
-
# 履歴の先頭に追加
|
|
159
160
|
@execution_history.unshift(script_name)
|
|
160
161
|
@execution_history = @execution_history.take(MAX_HISTORY_SIZE)
|
|
161
|
-
|
|
162
|
-
# カウントを増やす
|
|
163
162
|
@execution_count[script_name] += 1
|
|
164
163
|
end
|
|
165
164
|
|
|
166
165
|
# 実行履歴を取得
|
|
167
|
-
# @return [Array<String>] 最近実行したスクリプト名(新しい順)
|
|
168
166
|
def execution_history
|
|
169
167
|
@execution_history.dup
|
|
170
168
|
end
|
|
171
169
|
|
|
172
170
|
# 実行頻度順にスクリプトを取得
|
|
173
|
-
# @return [Array<String>] スクリプト名(頻度順)
|
|
174
171
|
def scripts_by_frequency
|
|
175
172
|
scripts = all_scripts
|
|
176
173
|
scripts.sort_by { |name| -@execution_count[name] }
|
|
177
174
|
end
|
|
178
175
|
|
|
179
|
-
# --- セクション9: エラーハンドリング ---
|
|
180
|
-
|
|
181
176
|
# 類似スクリプトの候補を取得
|
|
182
|
-
# @param query [String] 検索クエリ(typoを含む可能性あり)
|
|
183
|
-
# @return [Array<String>] 類似スクリプト名
|
|
184
177
|
def suggest(query)
|
|
185
178
|
scripts = all_scripts
|
|
186
179
|
return [] if scripts.empty?
|
|
187
180
|
|
|
188
|
-
# レーベンシュタイン距離でソート
|
|
189
181
|
scored = scripts.map do |name|
|
|
190
182
|
distance = levenshtein_distance(query.downcase, name.downcase)
|
|
191
183
|
[name, distance]
|
|
192
184
|
end
|
|
193
185
|
|
|
194
|
-
# 距離が3以下のものを距離順で返す
|
|
195
186
|
scored.select { |_, dist| dist <= 3 }
|
|
196
187
|
.sort_by { |_, dist| dist }
|
|
197
188
|
.map { |name, _| name }
|
|
198
189
|
end
|
|
199
190
|
|
|
200
191
|
# ファイルが実行可能かどうかをチェック
|
|
201
|
-
# @param path [String] ファイルパス
|
|
202
|
-
# @return [Boolean]
|
|
203
192
|
def executable?(path)
|
|
204
193
|
return false unless File.exist?(path)
|
|
205
194
|
|
|
@@ -207,13 +196,11 @@ module Rufio
|
|
|
207
196
|
end
|
|
208
197
|
|
|
209
198
|
# ファイルに実行権限を付与
|
|
210
|
-
# @param path [String] ファイルパス
|
|
211
|
-
# @return [Boolean] 成功した場合true
|
|
212
199
|
def fix_permissions(path)
|
|
213
200
|
return false unless File.exist?(path)
|
|
214
201
|
|
|
215
202
|
current_mode = File.stat(path).mode
|
|
216
|
-
new_mode = current_mode | 0111
|
|
203
|
+
new_mode = current_mode | 0111
|
|
217
204
|
File.chmod(new_mode, path)
|
|
218
205
|
true
|
|
219
206
|
rescue StandardError
|
|
@@ -222,34 +209,29 @@ module Rufio
|
|
|
222
209
|
|
|
223
210
|
private
|
|
224
211
|
|
|
225
|
-
#
|
|
226
|
-
# @return [Hash] 設定内容
|
|
227
|
-
def load_config
|
|
228
|
-
return {} unless File.exist?(@config_path)
|
|
229
|
-
|
|
230
|
-
yaml = YAML.safe_load(File.read(@config_path), symbolize_names: false)
|
|
231
|
-
yaml || {}
|
|
232
|
-
rescue StandardError => e
|
|
233
|
-
warn "Failed to load config: #{e.message}"
|
|
234
|
-
{}
|
|
235
|
-
end
|
|
236
|
-
|
|
237
|
-
# 設定ファイルを保存
|
|
212
|
+
# 設定ファイルにスクリプトパスを保存(新旧形式対応)
|
|
238
213
|
def save_config
|
|
239
|
-
|
|
240
|
-
|
|
214
|
+
# 新形式: script_paths.yml
|
|
215
|
+
if @config_path.end_with?('script_paths.yml')
|
|
216
|
+
Config.save_script_paths(@config_path, @paths)
|
|
217
|
+
return
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
# 後方互換: 古いconfig.yml形式
|
|
221
|
+
existing = if File.exist?(@config_path)
|
|
222
|
+
YAML.safe_load(File.read(@config_path), symbolize_names: false) || {}
|
|
223
|
+
else
|
|
224
|
+
{}
|
|
225
|
+
end
|
|
226
|
+
existing['script_paths'] = @paths
|
|
227
|
+
FileUtils.mkdir_p(File.dirname(@config_path))
|
|
228
|
+
File.write(@config_path, YAML.dump(existing))
|
|
241
229
|
end
|
|
242
230
|
|
|
243
|
-
# パスを展開(チルダ展開)
|
|
244
|
-
# @param paths [Array<String>] パスの配列
|
|
245
|
-
# @return [Array<String>] 展開済みのパス
|
|
246
231
|
def expand_paths(paths)
|
|
247
232
|
paths.map { |p| File.expand_path(p) }
|
|
248
233
|
end
|
|
249
234
|
|
|
250
|
-
# スクリプトを検索
|
|
251
|
-
# @param command_name [String] コマンド名
|
|
252
|
-
# @return [Array<String>] 見つかったスクリプトのパス
|
|
253
235
|
def find_scripts(command_name)
|
|
254
236
|
scripts = []
|
|
255
237
|
basename_without_ext = command_name.sub(/\.[^.]+$/, '')
|
|
@@ -266,25 +248,19 @@ module Rufio
|
|
|
266
248
|
next unless executable_script?(file)
|
|
267
249
|
|
|
268
250
|
if has_extension
|
|
269
|
-
# 拡張子付きで完全一致
|
|
270
251
|
scripts << file if file_basename.downcase == command_name.downcase
|
|
271
252
|
else
|
|
272
|
-
# 拡張子なしで比較
|
|
273
253
|
file_name_without_ext = File.basename(file, '.*')
|
|
274
254
|
scripts << file if file_name_without_ext.downcase == basename_without_ext.downcase
|
|
275
255
|
end
|
|
276
256
|
end
|
|
277
257
|
|
|
278
|
-
# 最初のパスで見つかったらそれを優先(on_multiple_match: 'first'相当)
|
|
279
258
|
return scripts unless scripts.empty?
|
|
280
259
|
end
|
|
281
260
|
|
|
282
261
|
scripts
|
|
283
262
|
end
|
|
284
263
|
|
|
285
|
-
# 実行可能なスクリプトかどうかを判定
|
|
286
|
-
# @param path [String] ファイルパス
|
|
287
|
-
# @return [Boolean]
|
|
288
264
|
def executable_script?(path)
|
|
289
265
|
ext = File.extname(path).downcase
|
|
290
266
|
return true if SUPPORTED_EXTENSIONS.include?(ext)
|
|
@@ -292,9 +268,6 @@ module Rufio
|
|
|
292
268
|
File.executable?(path)
|
|
293
269
|
end
|
|
294
270
|
|
|
295
|
-
# すべてのパスからスクリプトを検索(最初のパスで止まらない)
|
|
296
|
-
# @param command_name [String] コマンド名
|
|
297
|
-
# @return [Array<String>] 見つかったスクリプトのパス
|
|
298
271
|
def find_scripts_all_paths(command_name)
|
|
299
272
|
scripts = []
|
|
300
273
|
basename_without_ext = command_name.sub(/\.[^.]+$/, '')
|
|
@@ -322,17 +295,12 @@ module Rufio
|
|
|
322
295
|
scripts
|
|
323
296
|
end
|
|
324
297
|
|
|
325
|
-
# レーベンシュタイン距離を計算
|
|
326
|
-
# @param s1 [String] 文字列1
|
|
327
|
-
# @param s2 [String] 文字列2
|
|
328
|
-
# @return [Integer] 編集距離
|
|
329
298
|
def levenshtein_distance(s1, s2)
|
|
330
299
|
m = s1.length
|
|
331
300
|
n = s2.length
|
|
332
301
|
return n if m == 0
|
|
333
302
|
return m if n == 0
|
|
334
303
|
|
|
335
|
-
# 動的計画法でテーブルを構築
|
|
336
304
|
d = Array.new(m + 1) { Array.new(n + 1, 0) }
|
|
337
305
|
|
|
338
306
|
(0..m).each { |i| d[i][0] = i }
|
|
@@ -342,9 +310,9 @@ module Rufio
|
|
|
342
310
|
(1..n).each do |j|
|
|
343
311
|
cost = s1[i - 1] == s2[j - 1] ? 0 : 1
|
|
344
312
|
d[i][j] = [
|
|
345
|
-
d[i - 1][j] + 1,
|
|
346
|
-
d[i][j - 1] + 1,
|
|
347
|
-
d[i - 1][j - 1] + cost
|
|
313
|
+
d[i - 1][j] + 1,
|
|
314
|
+
d[i][j - 1] + 1,
|
|
315
|
+
d[i - 1][j - 1] + cost
|
|
348
316
|
].min
|
|
349
317
|
end
|
|
350
318
|
end
|
|
@@ -352,27 +320,20 @@ module Rufio
|
|
|
352
320
|
d[m][n]
|
|
353
321
|
end
|
|
354
322
|
|
|
355
|
-
# fuzzy matchingのスコアを計算
|
|
356
|
-
# @param text [String] 対象テキスト
|
|
357
|
-
# @param query_chars [Array<String>] クエリの文字配列
|
|
358
|
-
# @return [Integer] スコア(マッチしない場合は0)
|
|
359
323
|
def fuzzy_score(text, query_chars)
|
|
360
324
|
score = 0
|
|
361
325
|
text_index = 0
|
|
362
326
|
|
|
363
327
|
query_chars.each do |char|
|
|
364
|
-
# テキスト内で文字を探す
|
|
365
328
|
found_index = text.index(char, text_index)
|
|
366
|
-
return 0 unless found_index
|
|
329
|
+
return 0 unless found_index
|
|
367
330
|
|
|
368
|
-
# 連続していればボーナス
|
|
369
331
|
if found_index == text_index
|
|
370
332
|
score += 2
|
|
371
333
|
else
|
|
372
334
|
score += 1
|
|
373
335
|
end
|
|
374
336
|
|
|
375
|
-
# 単語の先頭ならボーナス
|
|
376
337
|
if found_index == 0 || text[found_index - 1] == '_' || text[found_index - 1] == '-'
|
|
377
338
|
score += 1
|
|
378
339
|
end
|
data/lib/rufio/terminal_ui.rb
CHANGED
|
@@ -1228,7 +1228,7 @@ module Rufio
|
|
|
1228
1228
|
|
|
1229
1229
|
# バックグラウンドコマンドの場合は結果表示をスキップ
|
|
1230
1230
|
# (完了通知は別途メインループで表示される)
|
|
1231
|
-
if result && !result.to_s.include?("🔄
|
|
1231
|
+
if result && !result.to_s.include?("🔄 Running in background")
|
|
1232
1232
|
# コマンド実行結果をフローティングウィンドウで表示
|
|
1233
1233
|
@command_mode_ui.show_result(result)
|
|
1234
1234
|
end
|
|
@@ -1266,7 +1266,7 @@ module Rufio
|
|
|
1266
1266
|
|
|
1267
1267
|
# 補完候補を一時的に表示
|
|
1268
1268
|
def show_completion_candidates(candidates)
|
|
1269
|
-
title = "
|
|
1269
|
+
title = "Completions (#{candidates.size})"
|
|
1270
1270
|
|
|
1271
1271
|
# 候補を表示用にフォーマット(最大20件)
|
|
1272
1272
|
display_candidates = candidates.first(20)
|
data/lib/rufio/version.rb
CHANGED
data/lib/rufio.rb
CHANGED
|
@@ -8,6 +8,7 @@ require_relative "rufio/directory_listing"
|
|
|
8
8
|
require_relative "rufio/filter_manager"
|
|
9
9
|
require_relative "rufio/selection_manager"
|
|
10
10
|
require_relative "rufio/file_operations"
|
|
11
|
+
require_relative "rufio/bookmark_storage"
|
|
11
12
|
require_relative "rufio/bookmark_manager"
|
|
12
13
|
require_relative "rufio/bookmark"
|
|
13
14
|
require_relative "rufio/zoxide_integration"
|
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.62.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-01-
|
|
11
|
+
date: 2026-01-31 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: io-console
|
|
@@ -108,8 +108,8 @@ dependencies:
|
|
|
108
108
|
- - "~>"
|
|
109
109
|
- !ruby/object:Gem::Version
|
|
110
110
|
version: '1.21'
|
|
111
|
-
description:
|
|
112
|
-
|
|
111
|
+
description: Runtime Unified Flow I/O Operator - A TUI file manager as a unified runtime
|
|
112
|
+
environment for Ruby/Python/PowerShell scripts and external tools.
|
|
113
113
|
email:
|
|
114
114
|
- masisz.1567@gmail.com
|
|
115
115
|
executables:
|
|
@@ -119,10 +119,9 @@ extra_rdoc_files: []
|
|
|
119
119
|
files:
|
|
120
120
|
- CHANGELOG.md
|
|
121
121
|
- README.md
|
|
122
|
-
-
|
|
122
|
+
- README_ja.md
|
|
123
123
|
- Rakefile
|
|
124
124
|
- bin/rufio
|
|
125
|
-
- config_example.rb
|
|
126
125
|
- docs/CHANGELOG_v0.10.0.md
|
|
127
126
|
- docs/CHANGELOG_v0.20.0.md
|
|
128
127
|
- docs/CHANGELOG_v0.21.0.md
|
|
@@ -139,7 +138,9 @@ files:
|
|
|
139
138
|
- docs/CHANGELOG_v0.7.0.md
|
|
140
139
|
- docs/CHANGELOG_v0.8.0.md
|
|
141
140
|
- docs/CHANGELOG_v0.9.0.md
|
|
142
|
-
- examples/
|
|
141
|
+
- examples/bookmarks.yml
|
|
142
|
+
- examples/config.rb
|
|
143
|
+
- examples/script_paths.yml
|
|
143
144
|
- info/help.md
|
|
144
145
|
- info/keybindings.md
|
|
145
146
|
- info/welcome.md
|
|
@@ -150,6 +151,7 @@ files:
|
|
|
150
151
|
- lib/rufio/background_command_executor.rb
|
|
151
152
|
- lib/rufio/bookmark.rb
|
|
152
153
|
- lib/rufio/bookmark_manager.rb
|
|
154
|
+
- lib/rufio/bookmark_storage.rb
|
|
153
155
|
- lib/rufio/builtin_commands.rb
|
|
154
156
|
- lib/rufio/color_helper.rb
|
|
155
157
|
- lib/rufio/command_completion.rb
|
|
@@ -197,15 +199,6 @@ files:
|
|
|
197
199
|
- lib_zig/rufio_native/src/main.zig
|
|
198
200
|
- lib_zig/rufio_native/src/main.zig.sync
|
|
199
201
|
- retag.sh
|
|
200
|
-
- scripts/test_jobs/build_simulation.sh
|
|
201
|
-
- scripts/test_jobs/deploy_simulation.sh
|
|
202
|
-
- scripts/test_jobs/quick.sh
|
|
203
|
-
- scripts/test_jobs/random_result.sh
|
|
204
|
-
- scripts/test_jobs/slow_fail.sh
|
|
205
|
-
- scripts/test_jobs/slow_success.sh
|
|
206
|
-
- scripts/test_jobs/very_slow.sh
|
|
207
|
-
- test_delete/test1.txt
|
|
208
|
-
- test_delete/test2.txt
|
|
209
202
|
homepage: https://github.com/masisz/rufio
|
|
210
203
|
licenses:
|
|
211
204
|
- MIT
|
|
@@ -232,5 +225,5 @@ requirements: []
|
|
|
232
225
|
rubygems_version: 3.4.19
|
|
233
226
|
signing_key:
|
|
234
227
|
specification_version: 4
|
|
235
|
-
summary:
|
|
228
|
+
summary: Runtime Unified Flow I/O Operator - TUI file manager as a unified tool runtime
|
|
236
229
|
test_files: []
|