rufio 0.9.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 +7 -0
- data/CHANGELOG.md +188 -0
- data/CHANGELOG_v0.4.0.md +146 -0
- data/CHANGELOG_v0.5.0.md +26 -0
- data/CHANGELOG_v0.6.0.md +182 -0
- data/CHANGELOG_v0.7.0.md +280 -0
- data/CHANGELOG_v0.8.0.md +267 -0
- data/CHANGELOG_v0.9.0.md +279 -0
- data/README.md +631 -0
- data/README_EN.md +561 -0
- data/Rakefile +156 -0
- data/bin/rufio +34 -0
- data/config_example.rb +88 -0
- data/docs/PLUGIN_GUIDE.md +431 -0
- data/docs/plugin_example.rb +119 -0
- data/lib/rufio/application.rb +32 -0
- data/lib/rufio/bookmark.rb +115 -0
- data/lib/rufio/bookmark_manager.rb +173 -0
- data/lib/rufio/color_helper.rb +150 -0
- data/lib/rufio/command_mode.rb +72 -0
- data/lib/rufio/command_mode_ui.rb +168 -0
- data/lib/rufio/config.rb +199 -0
- data/lib/rufio/config_loader.rb +110 -0
- data/lib/rufio/dialog_renderer.rb +127 -0
- data/lib/rufio/directory_listing.rb +113 -0
- data/lib/rufio/file_opener.rb +140 -0
- data/lib/rufio/file_operations.rb +231 -0
- data/lib/rufio/file_preview.rb +200 -0
- data/lib/rufio/filter_manager.rb +114 -0
- data/lib/rufio/health_checker.rb +246 -0
- data/lib/rufio/keybind_handler.rb +828 -0
- data/lib/rufio/logger.rb +103 -0
- data/lib/rufio/plugin.rb +89 -0
- data/lib/rufio/plugin_config.rb +59 -0
- data/lib/rufio/plugin_manager.rb +84 -0
- data/lib/rufio/plugins/file_operations.rb +44 -0
- data/lib/rufio/selection_manager.rb +79 -0
- data/lib/rufio/terminal_ui.rb +630 -0
- data/lib/rufio/text_utils.rb +108 -0
- data/lib/rufio/version.rb +5 -0
- data/lib/rufio/zoxide_integration.rb +188 -0
- data/lib/rufio.rb +33 -0
- data/publish_gem.zsh +131 -0
- data/rufio.gemspec +40 -0
- data/test_delete/test1.txt +1 -0
- data/test_delete/test2.txt +1 -0
- metadata +189 -0
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Rufio
|
|
4
|
+
# Text utility methods for display width calculation and string manipulation
|
|
5
|
+
# Handles multi-byte characters (Japanese, etc.) correctly
|
|
6
|
+
module TextUtils
|
|
7
|
+
module_function
|
|
8
|
+
|
|
9
|
+
# Character width constants
|
|
10
|
+
FULLWIDTH_CHAR_WIDTH = 2
|
|
11
|
+
HALFWIDTH_CHAR_WIDTH = 1
|
|
12
|
+
MULTIBYTE_THRESHOLD = 1
|
|
13
|
+
|
|
14
|
+
# Truncation constants
|
|
15
|
+
ELLIPSIS_MIN_WIDTH = 3
|
|
16
|
+
ELLIPSIS = '...'
|
|
17
|
+
|
|
18
|
+
# Line break constants
|
|
19
|
+
BREAK_POINT_THRESHOLD = 0.5 # Break after 50% of max_width
|
|
20
|
+
|
|
21
|
+
# Calculate display width of a string
|
|
22
|
+
# Full-width characters (Japanese, etc.) count as 2, half-width as 1
|
|
23
|
+
def display_width(string)
|
|
24
|
+
string.each_char.map do |char|
|
|
25
|
+
case char
|
|
26
|
+
when /[\u3000-\u303F\u3040-\u309F\u30A0-\u30FF\u4E00-\u9FAF\uFF00-\uFFEF\u2500-\u257F\u2580-\u259F]/
|
|
27
|
+
FULLWIDTH_CHAR_WIDTH # Japanese characters (hiragana, katakana, kanji, full-width symbols, box drawing, block elements)
|
|
28
|
+
when /[\u0020-\u007E]/
|
|
29
|
+
HALFWIDTH_CHAR_WIDTH # ASCII characters
|
|
30
|
+
else
|
|
31
|
+
char.bytesize > MULTIBYTE_THRESHOLD ? FULLWIDTH_CHAR_WIDTH : HALFWIDTH_CHAR_WIDTH
|
|
32
|
+
end
|
|
33
|
+
end.sum
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Truncate string to fit within max_width
|
|
37
|
+
def truncate_to_width(string, max_width)
|
|
38
|
+
return string if display_width(string) <= max_width
|
|
39
|
+
|
|
40
|
+
# If max_width is enough for ellipsis, truncate and add ellipsis
|
|
41
|
+
if max_width >= ELLIPSIS_MIN_WIDTH
|
|
42
|
+
result = ''
|
|
43
|
+
current_width = 0
|
|
44
|
+
target_width = max_width - ELLIPSIS_MIN_WIDTH
|
|
45
|
+
|
|
46
|
+
string.each_char do |char|
|
|
47
|
+
char_width = display_width(char)
|
|
48
|
+
break if current_width + char_width > target_width
|
|
49
|
+
|
|
50
|
+
result += char
|
|
51
|
+
current_width += char_width
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
result + ELLIPSIS
|
|
55
|
+
else
|
|
56
|
+
# Not enough room for ellipsis, just truncate
|
|
57
|
+
result = ''
|
|
58
|
+
current_width = 0
|
|
59
|
+
|
|
60
|
+
string.each_char do |char|
|
|
61
|
+
char_width = display_width(char)
|
|
62
|
+
break if current_width + char_width > max_width
|
|
63
|
+
|
|
64
|
+
result += char
|
|
65
|
+
current_width += char_width
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
result
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# Pad string to target_width with spaces
|
|
73
|
+
def pad_string_to_width(string, target_width)
|
|
74
|
+
current_width = display_width(string)
|
|
75
|
+
if current_width >= target_width
|
|
76
|
+
truncate_to_width(string, target_width)
|
|
77
|
+
else
|
|
78
|
+
string + ' ' * (target_width - current_width)
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# Find the best break point for wrapping text within max_width
|
|
83
|
+
def find_break_point(line, max_width)
|
|
84
|
+
return line.length if display_width(line) <= max_width
|
|
85
|
+
|
|
86
|
+
current_width = 0
|
|
87
|
+
best_break_point = 0
|
|
88
|
+
space_break_point = nil
|
|
89
|
+
punct_break_point = nil
|
|
90
|
+
|
|
91
|
+
line.each_char.with_index do |char, index|
|
|
92
|
+
char_width = display_width(char)
|
|
93
|
+
break if current_width + char_width > max_width
|
|
94
|
+
|
|
95
|
+
current_width += char_width
|
|
96
|
+
best_break_point = index + 1
|
|
97
|
+
|
|
98
|
+
# Record break point at space
|
|
99
|
+
space_break_point = index + 1 if char == ' ' && current_width > max_width * BREAK_POINT_THRESHOLD
|
|
100
|
+
|
|
101
|
+
# Record break point at Japanese punctuation
|
|
102
|
+
punct_break_point = index + 1 if char.match?(/[、。,.!?]/) && current_width > max_width * BREAK_POINT_THRESHOLD
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
space_break_point || punct_break_point || best_break_point
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
end
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'shellwords'
|
|
4
|
+
|
|
5
|
+
module Rufio
|
|
6
|
+
# Integrates with zoxide for directory history navigation
|
|
7
|
+
class ZoxideIntegration
|
|
8
|
+
# Dialog size constants
|
|
9
|
+
DIALOG_WIDTH = 45
|
|
10
|
+
DIALOG_BORDER_HEIGHT = 4
|
|
11
|
+
|
|
12
|
+
def initialize(dialog_renderer = nil)
|
|
13
|
+
@dialog_renderer = dialog_renderer
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# Check if zoxide is available
|
|
17
|
+
# @return [Boolean]
|
|
18
|
+
def available?
|
|
19
|
+
system('which zoxide > /dev/null 2>&1')
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Get zoxide history
|
|
23
|
+
# @return [Array<Hash>] Array of { path: String, score: Float }
|
|
24
|
+
def get_history
|
|
25
|
+
return [] unless available?
|
|
26
|
+
|
|
27
|
+
begin
|
|
28
|
+
# Get zoxide history with scores
|
|
29
|
+
output = `zoxide query --list --score 2>/dev/null`.strip
|
|
30
|
+
return [] if output.empty?
|
|
31
|
+
|
|
32
|
+
# Parse each line into path and score
|
|
33
|
+
lines = output.split("\n")
|
|
34
|
+
history = lines.map do |line|
|
|
35
|
+
# zoxide output format: "score path"
|
|
36
|
+
if line.match(/^\s*(\d+(?:\.\d+)?)\s+(.+)$/)
|
|
37
|
+
score = ::Regexp.last_match(1).to_f
|
|
38
|
+
path = ::Regexp.last_match(2).strip
|
|
39
|
+
{ path: path, score: score }
|
|
40
|
+
else
|
|
41
|
+
# No score (backward compatibility)
|
|
42
|
+
{ path: line.strip, score: 0.0 }
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# Filter to only existing directories
|
|
47
|
+
history.select { |entry| Dir.exist?(entry[:path]) }
|
|
48
|
+
rescue StandardError
|
|
49
|
+
[]
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# Show zoxide history menu and let user select
|
|
54
|
+
# @return [String, nil] Selected path or nil if cancelled
|
|
55
|
+
def show_menu
|
|
56
|
+
return nil unless @dialog_renderer
|
|
57
|
+
|
|
58
|
+
history = get_history
|
|
59
|
+
|
|
60
|
+
if history.empty?
|
|
61
|
+
show_no_history_message
|
|
62
|
+
return nil
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
select_from_history(history)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# Add directory to zoxide history
|
|
69
|
+
# @param path [String] Directory path
|
|
70
|
+
# @return [Boolean] Success status
|
|
71
|
+
def add_to_history(path)
|
|
72
|
+
return false unless available?
|
|
73
|
+
return false unless Dir.exist?(path)
|
|
74
|
+
|
|
75
|
+
begin
|
|
76
|
+
system("zoxide add #{Shellwords.escape(path)} > /dev/null 2>&1")
|
|
77
|
+
true
|
|
78
|
+
rescue StandardError
|
|
79
|
+
false
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
private
|
|
84
|
+
|
|
85
|
+
# Show message when no history is available
|
|
86
|
+
def show_no_history_message
|
|
87
|
+
return unless @dialog_renderer
|
|
88
|
+
|
|
89
|
+
title = 'Zoxide'
|
|
90
|
+
content_lines = [
|
|
91
|
+
'',
|
|
92
|
+
'No zoxide history found.',
|
|
93
|
+
'',
|
|
94
|
+
'Zoxide learns from your directory navigation.',
|
|
95
|
+
'Use zoxide more to build up history.',
|
|
96
|
+
'',
|
|
97
|
+
'Press any key to continue...'
|
|
98
|
+
]
|
|
99
|
+
|
|
100
|
+
dialog_width = DIALOG_WIDTH
|
|
101
|
+
dialog_height = DIALOG_BORDER_HEIGHT + content_lines.length
|
|
102
|
+
x, y = @dialog_renderer.calculate_center(dialog_width, dialog_height)
|
|
103
|
+
|
|
104
|
+
@dialog_renderer.draw_floating_window(x, y, dialog_width, dialog_height, title, content_lines, {
|
|
105
|
+
border_color: "\e[33m", # Yellow
|
|
106
|
+
title_color: "\e[1;33m", # Bold yellow
|
|
107
|
+
content_color: "\e[37m" # White
|
|
108
|
+
})
|
|
109
|
+
|
|
110
|
+
STDIN.getch
|
|
111
|
+
@dialog_renderer.clear_area(x, y, dialog_width, dialog_height)
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
# Select from zoxide history
|
|
115
|
+
# @param history [Array<Hash>] History entries
|
|
116
|
+
# @return [String, nil] Selected path or nil
|
|
117
|
+
def select_from_history(history)
|
|
118
|
+
return nil unless @dialog_renderer
|
|
119
|
+
|
|
120
|
+
title = 'Zoxide History'
|
|
121
|
+
|
|
122
|
+
# Format history for display (max 20 items)
|
|
123
|
+
display_history = history.first(20)
|
|
124
|
+
content_lines = ['']
|
|
125
|
+
|
|
126
|
+
display_history.each_with_index do |entry, index|
|
|
127
|
+
# Shorten path display (replace home directory with ~)
|
|
128
|
+
display_path = entry[:path].gsub(ENV['HOME'], '~')
|
|
129
|
+
line = " #{index + 1}. #{display_path}"
|
|
130
|
+
# Truncate if too long
|
|
131
|
+
line = line[0...60] + '...' if line.length > 63
|
|
132
|
+
content_lines << line
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
content_lines << ''
|
|
136
|
+
content_lines << 'Enter number (1-' + display_history.length.to_s + ') or ESC to cancel'
|
|
137
|
+
|
|
138
|
+
dialog_width = 70
|
|
139
|
+
dialog_height = [4 + content_lines.length, 25].min
|
|
140
|
+
x, y = @dialog_renderer.calculate_center(dialog_width, dialog_height)
|
|
141
|
+
|
|
142
|
+
@dialog_renderer.draw_floating_window(x, y, dialog_width, dialog_height, title, content_lines, {
|
|
143
|
+
border_color: "\e[36m", # Cyan
|
|
144
|
+
title_color: "\e[1;36m", # Bold cyan
|
|
145
|
+
content_color: "\e[37m" # White
|
|
146
|
+
})
|
|
147
|
+
|
|
148
|
+
# Number input mode
|
|
149
|
+
input_buffer = ''
|
|
150
|
+
|
|
151
|
+
loop do
|
|
152
|
+
char = STDIN.getch
|
|
153
|
+
|
|
154
|
+
case char
|
|
155
|
+
when "\e", "\x03" # ESC, Ctrl+C
|
|
156
|
+
@dialog_renderer.clear_area(x, y, dialog_width, dialog_height)
|
|
157
|
+
return nil
|
|
158
|
+
when "\r", "\n" # Enter
|
|
159
|
+
unless input_buffer.empty?
|
|
160
|
+
number = input_buffer.to_i
|
|
161
|
+
if number > 0 && number <= display_history.length
|
|
162
|
+
selected_entry = display_history[number - 1]
|
|
163
|
+
@dialog_renderer.clear_area(x, y, dialog_width, dialog_height)
|
|
164
|
+
return selected_entry[:path]
|
|
165
|
+
end
|
|
166
|
+
end
|
|
167
|
+
# Invalid input, ask again
|
|
168
|
+
input_buffer = ''
|
|
169
|
+
when "\u007f", "\b" # Backspace
|
|
170
|
+
input_buffer = input_buffer[0...-1] unless input_buffer.empty?
|
|
171
|
+
when /[0-9]/
|
|
172
|
+
input_buffer += char
|
|
173
|
+
# Max 2 digits
|
|
174
|
+
input_buffer = input_buffer[-2..-1] if input_buffer.length > 2
|
|
175
|
+
|
|
176
|
+
# If number is within range, select immediately
|
|
177
|
+
number = input_buffer.to_i
|
|
178
|
+
if number > 0 && number <= display_history.length &&
|
|
179
|
+
(number >= 10 || input_buffer.length == 1)
|
|
180
|
+
selected_entry = display_history[number - 1]
|
|
181
|
+
@dialog_renderer.clear_area(x, y, dialog_width, dialog_height)
|
|
182
|
+
return selected_entry[:path]
|
|
183
|
+
end
|
|
184
|
+
end
|
|
185
|
+
end
|
|
186
|
+
end
|
|
187
|
+
end
|
|
188
|
+
end
|
data/lib/rufio.rb
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "rufio/version"
|
|
4
|
+
require_relative "rufio/config"
|
|
5
|
+
require_relative "rufio/config_loader"
|
|
6
|
+
require_relative "rufio/color_helper"
|
|
7
|
+
require_relative "rufio/directory_listing"
|
|
8
|
+
require_relative "rufio/filter_manager"
|
|
9
|
+
require_relative "rufio/selection_manager"
|
|
10
|
+
require_relative "rufio/file_operations"
|
|
11
|
+
require_relative "rufio/bookmark_manager"
|
|
12
|
+
require_relative "rufio/bookmark"
|
|
13
|
+
require_relative "rufio/zoxide_integration"
|
|
14
|
+
require_relative "rufio/dialog_renderer"
|
|
15
|
+
require_relative "rufio/text_utils"
|
|
16
|
+
require_relative "rufio/logger"
|
|
17
|
+
require_relative "rufio/keybind_handler"
|
|
18
|
+
require_relative "rufio/file_preview"
|
|
19
|
+
require_relative "rufio/terminal_ui"
|
|
20
|
+
require_relative "rufio/application"
|
|
21
|
+
require_relative "rufio/file_opener"
|
|
22
|
+
require_relative "rufio/health_checker"
|
|
23
|
+
|
|
24
|
+
# プラグインシステム
|
|
25
|
+
require_relative "rufio/plugin_config"
|
|
26
|
+
require_relative "rufio/plugin"
|
|
27
|
+
require_relative "rufio/plugin_manager"
|
|
28
|
+
require_relative "rufio/command_mode"
|
|
29
|
+
require_relative "rufio/command_mode_ui"
|
|
30
|
+
|
|
31
|
+
module Rufio
|
|
32
|
+
class Error < StandardError; end
|
|
33
|
+
end
|
data/publish_gem.zsh
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
#!/bin/zsh
|
|
2
|
+
|
|
3
|
+
# Gem Build & Push Script
|
|
4
|
+
# Usage: ./publish_gem.zsh [version]
|
|
5
|
+
|
|
6
|
+
set -e # Exit on any error
|
|
7
|
+
|
|
8
|
+
# Colors for output
|
|
9
|
+
RED='\033[0;31m'
|
|
10
|
+
GREEN='\033[0;32m'
|
|
11
|
+
YELLOW='\033[1;33m'
|
|
12
|
+
BLUE='\033[0;34m'
|
|
13
|
+
NC='\033[0m' # No Color
|
|
14
|
+
|
|
15
|
+
# Function to print colored output
|
|
16
|
+
print_status() {
|
|
17
|
+
echo -e "${BLUE}[INFO]${NC} $1"
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
print_success() {
|
|
21
|
+
echo -e "${GREEN}[SUCCESS]${NC} $1"
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
print_warning() {
|
|
25
|
+
echo -e "${YELLOW}[WARNING]${NC} $1"
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
print_error() {
|
|
29
|
+
echo -e "${RED}[ERROR]${NC} $1"
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
# Check if we're in the correct directory
|
|
33
|
+
if [[ ! -f "rufio.gemspec" ]]; then
|
|
34
|
+
print_error "rufio.gemspec not found. Please run this script from the project root directory."
|
|
35
|
+
exit 1
|
|
36
|
+
fi
|
|
37
|
+
|
|
38
|
+
# Get current version from version.rb
|
|
39
|
+
CURRENT_VERSION=$(ruby -r ./lib/rufio/version -e "puts Rufio::VERSION")
|
|
40
|
+
print_status "Current version: $CURRENT_VERSION"
|
|
41
|
+
|
|
42
|
+
# Use provided version or current version
|
|
43
|
+
VERSION=${1:-$CURRENT_VERSION}
|
|
44
|
+
print_status "Publishing version: $VERSION"
|
|
45
|
+
|
|
46
|
+
# Confirm before proceeding
|
|
47
|
+
echo
|
|
48
|
+
read "REPLY?Do you want to proceed with publishing version $VERSION? (y/N): "
|
|
49
|
+
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
|
50
|
+
print_warning "Aborted by user."
|
|
51
|
+
exit 0
|
|
52
|
+
fi
|
|
53
|
+
|
|
54
|
+
echo
|
|
55
|
+
print_status "Starting gem publication process..."
|
|
56
|
+
|
|
57
|
+
# Step 1: Run tests
|
|
58
|
+
print_status "Running tests..."
|
|
59
|
+
if ! bundle exec rake test; then
|
|
60
|
+
print_error "Tests failed. Aborting publication."
|
|
61
|
+
exit 1
|
|
62
|
+
fi
|
|
63
|
+
print_success "All tests passed!"
|
|
64
|
+
|
|
65
|
+
# Step 2: Clean up old gem files
|
|
66
|
+
print_status "Cleaning up old gem files..."
|
|
67
|
+
rm -f *.gem
|
|
68
|
+
print_success "Cleanup completed."
|
|
69
|
+
|
|
70
|
+
# Step 3: Build gem
|
|
71
|
+
print_status "Building gem..."
|
|
72
|
+
if ! bundle exec gem build rufio.gemspec; then
|
|
73
|
+
print_error "Gem build failed."
|
|
74
|
+
exit 1
|
|
75
|
+
fi
|
|
76
|
+
|
|
77
|
+
# Find the built gem file
|
|
78
|
+
GEM_FILE=$(ls rufio-*.gem | head -n 1)
|
|
79
|
+
if [[ -z "$GEM_FILE" ]]; then
|
|
80
|
+
print_error "No gem file found after build."
|
|
81
|
+
exit 1
|
|
82
|
+
fi
|
|
83
|
+
|
|
84
|
+
print_success "Gem built successfully: $GEM_FILE"
|
|
85
|
+
|
|
86
|
+
# Step 4: Verify gem contents (optional)
|
|
87
|
+
print_status "Gem contents:"
|
|
88
|
+
gem contents $GEM_FILE | head -10
|
|
89
|
+
echo "..."
|
|
90
|
+
|
|
91
|
+
# Step 5: Final confirmation
|
|
92
|
+
echo
|
|
93
|
+
read "REPLY?Push $GEM_FILE to RubyGems? (y/N): "
|
|
94
|
+
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
|
95
|
+
print_warning "Gem build completed but not published."
|
|
96
|
+
print_status "You can manually push later with: gem push $GEM_FILE"
|
|
97
|
+
exit 0
|
|
98
|
+
fi
|
|
99
|
+
|
|
100
|
+
# Step 6: Push to RubyGems
|
|
101
|
+
print_status "Pushing gem to RubyGems..."
|
|
102
|
+
if ! gem push $GEM_FILE; then
|
|
103
|
+
print_error "Gem push failed."
|
|
104
|
+
exit 1
|
|
105
|
+
fi
|
|
106
|
+
|
|
107
|
+
print_success "Gem published successfully!"
|
|
108
|
+
|
|
109
|
+
# Step 7: Create git tag if version was provided
|
|
110
|
+
if [[ -n "$1" ]]; then
|
|
111
|
+
print_status "Creating git tag v$VERSION..."
|
|
112
|
+
if git tag "v$VERSION" 2>/dev/null; then
|
|
113
|
+
print_success "Tag v$VERSION created."
|
|
114
|
+
read "REPLY?Push tag to remote? (y/N): "
|
|
115
|
+
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
|
116
|
+
git push origin "v$VERSION"
|
|
117
|
+
print_success "Tag pushed to remote."
|
|
118
|
+
fi
|
|
119
|
+
else
|
|
120
|
+
print_warning "Tag v$VERSION already exists or failed to create."
|
|
121
|
+
fi
|
|
122
|
+
fi
|
|
123
|
+
|
|
124
|
+
# Step 8: Cleanup
|
|
125
|
+
print_status "Cleaning up gem file..."
|
|
126
|
+
rm -f $GEM_FILE
|
|
127
|
+
|
|
128
|
+
echo
|
|
129
|
+
print_success "Publication completed!"
|
|
130
|
+
print_status "Gem should be available at: https://rubygems.org/gems/rufio"
|
|
131
|
+
print_status "Install with: gem install rufio"
|
data/rufio.gemspec
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'lib/rufio/version'
|
|
4
|
+
|
|
5
|
+
Gem::Specification.new do |spec|
|
|
6
|
+
spec.name = 'rufio'
|
|
7
|
+
spec.version = Rufio::VERSION
|
|
8
|
+
spec.authors = ['masisz']
|
|
9
|
+
spec.email = ['masisz.1567@gmail.com']
|
|
10
|
+
|
|
11
|
+
spec.summary = 'Ruby file manager'
|
|
12
|
+
spec.description = 'A terminal-based file manager inspired by Yazi, written in Ruby with plugin support'
|
|
13
|
+
spec.homepage = 'https://github.com/masisz/rufio'
|
|
14
|
+
spec.license = 'MIT'
|
|
15
|
+
spec.required_ruby_version = '>= 2.7.0'
|
|
16
|
+
|
|
17
|
+
spec.metadata['allowed_push_host'] = 'https://rubygems.org'
|
|
18
|
+
spec.metadata['homepage_uri'] = spec.homepage
|
|
19
|
+
spec.metadata['source_code_uri'] = 'https://github.com/masisz/rufio'
|
|
20
|
+
spec.metadata['changelog_uri'] = 'https://github.com/masisz/rufio/blob/main/CHANGELOG.md'
|
|
21
|
+
|
|
22
|
+
spec.files = Dir.chdir(__dir__) do
|
|
23
|
+
`git ls-files -z`.split("\x0").reject do |f|
|
|
24
|
+
(File.expand_path(f) == __FILE__) ||
|
|
25
|
+
f.start_with?(*%w[test/ spec/ features/ .git .circleci appveyor Gemfile])
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
spec.bindir = 'bin'
|
|
29
|
+
spec.executables = spec.files.grep(%r{\Abin/}) { |f| File.basename(f) }
|
|
30
|
+
spec.require_paths = ['lib']
|
|
31
|
+
|
|
32
|
+
spec.add_dependency 'io-console', '~> 0.6'
|
|
33
|
+
spec.add_dependency 'pastel', '~> 0.8'
|
|
34
|
+
spec.add_dependency 'tty-cursor', '~> 0.7'
|
|
35
|
+
spec.add_dependency 'tty-screen', '~> 0.8'
|
|
36
|
+
|
|
37
|
+
spec.add_development_dependency 'minitest', '~> 5.0'
|
|
38
|
+
spec.add_development_dependency 'rake', '~> 13.0'
|
|
39
|
+
spec.add_development_dependency 'rubocop', '~> 1.21'
|
|
40
|
+
end
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
test content 1
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
test content 2
|
metadata
ADDED
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: rufio
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.9.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- masisz
|
|
8
|
+
bindir: bin
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 2025-12-20 00:00:00.000000000 Z
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: io-console
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - "~>"
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '0.6'
|
|
19
|
+
type: :runtime
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - "~>"
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: '0.6'
|
|
26
|
+
- !ruby/object:Gem::Dependency
|
|
27
|
+
name: pastel
|
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
|
29
|
+
requirements:
|
|
30
|
+
- - "~>"
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: '0.8'
|
|
33
|
+
type: :runtime
|
|
34
|
+
prerelease: false
|
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
36
|
+
requirements:
|
|
37
|
+
- - "~>"
|
|
38
|
+
- !ruby/object:Gem::Version
|
|
39
|
+
version: '0.8'
|
|
40
|
+
- !ruby/object:Gem::Dependency
|
|
41
|
+
name: tty-cursor
|
|
42
|
+
requirement: !ruby/object:Gem::Requirement
|
|
43
|
+
requirements:
|
|
44
|
+
- - "~>"
|
|
45
|
+
- !ruby/object:Gem::Version
|
|
46
|
+
version: '0.7'
|
|
47
|
+
type: :runtime
|
|
48
|
+
prerelease: false
|
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
50
|
+
requirements:
|
|
51
|
+
- - "~>"
|
|
52
|
+
- !ruby/object:Gem::Version
|
|
53
|
+
version: '0.7'
|
|
54
|
+
- !ruby/object:Gem::Dependency
|
|
55
|
+
name: tty-screen
|
|
56
|
+
requirement: !ruby/object:Gem::Requirement
|
|
57
|
+
requirements:
|
|
58
|
+
- - "~>"
|
|
59
|
+
- !ruby/object:Gem::Version
|
|
60
|
+
version: '0.8'
|
|
61
|
+
type: :runtime
|
|
62
|
+
prerelease: false
|
|
63
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
64
|
+
requirements:
|
|
65
|
+
- - "~>"
|
|
66
|
+
- !ruby/object:Gem::Version
|
|
67
|
+
version: '0.8'
|
|
68
|
+
- !ruby/object:Gem::Dependency
|
|
69
|
+
name: minitest
|
|
70
|
+
requirement: !ruby/object:Gem::Requirement
|
|
71
|
+
requirements:
|
|
72
|
+
- - "~>"
|
|
73
|
+
- !ruby/object:Gem::Version
|
|
74
|
+
version: '5.0'
|
|
75
|
+
type: :development
|
|
76
|
+
prerelease: false
|
|
77
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
78
|
+
requirements:
|
|
79
|
+
- - "~>"
|
|
80
|
+
- !ruby/object:Gem::Version
|
|
81
|
+
version: '5.0'
|
|
82
|
+
- !ruby/object:Gem::Dependency
|
|
83
|
+
name: rake
|
|
84
|
+
requirement: !ruby/object:Gem::Requirement
|
|
85
|
+
requirements:
|
|
86
|
+
- - "~>"
|
|
87
|
+
- !ruby/object:Gem::Version
|
|
88
|
+
version: '13.0'
|
|
89
|
+
type: :development
|
|
90
|
+
prerelease: false
|
|
91
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
92
|
+
requirements:
|
|
93
|
+
- - "~>"
|
|
94
|
+
- !ruby/object:Gem::Version
|
|
95
|
+
version: '13.0'
|
|
96
|
+
- !ruby/object:Gem::Dependency
|
|
97
|
+
name: rubocop
|
|
98
|
+
requirement: !ruby/object:Gem::Requirement
|
|
99
|
+
requirements:
|
|
100
|
+
- - "~>"
|
|
101
|
+
- !ruby/object:Gem::Version
|
|
102
|
+
version: '1.21'
|
|
103
|
+
type: :development
|
|
104
|
+
prerelease: false
|
|
105
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
106
|
+
requirements:
|
|
107
|
+
- - "~>"
|
|
108
|
+
- !ruby/object:Gem::Version
|
|
109
|
+
version: '1.21'
|
|
110
|
+
description: A terminal-based file manager inspired by Yazi, written in Ruby with
|
|
111
|
+
plugin support
|
|
112
|
+
email:
|
|
113
|
+
- masisz.1567@gmail.com
|
|
114
|
+
executables:
|
|
115
|
+
- rufio
|
|
116
|
+
extensions: []
|
|
117
|
+
extra_rdoc_files: []
|
|
118
|
+
files:
|
|
119
|
+
- CHANGELOG.md
|
|
120
|
+
- CHANGELOG_v0.4.0.md
|
|
121
|
+
- CHANGELOG_v0.5.0.md
|
|
122
|
+
- CHANGELOG_v0.6.0.md
|
|
123
|
+
- CHANGELOG_v0.7.0.md
|
|
124
|
+
- CHANGELOG_v0.8.0.md
|
|
125
|
+
- CHANGELOG_v0.9.0.md
|
|
126
|
+
- README.md
|
|
127
|
+
- README_EN.md
|
|
128
|
+
- Rakefile
|
|
129
|
+
- bin/rufio
|
|
130
|
+
- config_example.rb
|
|
131
|
+
- docs/PLUGIN_GUIDE.md
|
|
132
|
+
- docs/plugin_example.rb
|
|
133
|
+
- lib/rufio.rb
|
|
134
|
+
- lib/rufio/application.rb
|
|
135
|
+
- lib/rufio/bookmark.rb
|
|
136
|
+
- lib/rufio/bookmark_manager.rb
|
|
137
|
+
- lib/rufio/color_helper.rb
|
|
138
|
+
- lib/rufio/command_mode.rb
|
|
139
|
+
- lib/rufio/command_mode_ui.rb
|
|
140
|
+
- lib/rufio/config.rb
|
|
141
|
+
- lib/rufio/config_loader.rb
|
|
142
|
+
- lib/rufio/dialog_renderer.rb
|
|
143
|
+
- lib/rufio/directory_listing.rb
|
|
144
|
+
- lib/rufio/file_opener.rb
|
|
145
|
+
- lib/rufio/file_operations.rb
|
|
146
|
+
- lib/rufio/file_preview.rb
|
|
147
|
+
- lib/rufio/filter_manager.rb
|
|
148
|
+
- lib/rufio/health_checker.rb
|
|
149
|
+
- lib/rufio/keybind_handler.rb
|
|
150
|
+
- lib/rufio/logger.rb
|
|
151
|
+
- lib/rufio/plugin.rb
|
|
152
|
+
- lib/rufio/plugin_config.rb
|
|
153
|
+
- lib/rufio/plugin_manager.rb
|
|
154
|
+
- lib/rufio/plugins/file_operations.rb
|
|
155
|
+
- lib/rufio/selection_manager.rb
|
|
156
|
+
- lib/rufio/terminal_ui.rb
|
|
157
|
+
- lib/rufio/text_utils.rb
|
|
158
|
+
- lib/rufio/version.rb
|
|
159
|
+
- lib/rufio/zoxide_integration.rb
|
|
160
|
+
- publish_gem.zsh
|
|
161
|
+
- rufio.gemspec
|
|
162
|
+
- test_delete/test1.txt
|
|
163
|
+
- test_delete/test2.txt
|
|
164
|
+
homepage: https://github.com/masisz/rufio
|
|
165
|
+
licenses:
|
|
166
|
+
- MIT
|
|
167
|
+
metadata:
|
|
168
|
+
allowed_push_host: https://rubygems.org
|
|
169
|
+
homepage_uri: https://github.com/masisz/rufio
|
|
170
|
+
source_code_uri: https://github.com/masisz/rufio
|
|
171
|
+
changelog_uri: https://github.com/masisz/rufio/blob/main/CHANGELOG.md
|
|
172
|
+
rdoc_options: []
|
|
173
|
+
require_paths:
|
|
174
|
+
- lib
|
|
175
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
176
|
+
requirements:
|
|
177
|
+
- - ">="
|
|
178
|
+
- !ruby/object:Gem::Version
|
|
179
|
+
version: 2.7.0
|
|
180
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
181
|
+
requirements:
|
|
182
|
+
- - ">="
|
|
183
|
+
- !ruby/object:Gem::Version
|
|
184
|
+
version: '0'
|
|
185
|
+
requirements: []
|
|
186
|
+
rubygems_version: 3.6.6
|
|
187
|
+
specification_version: 4
|
|
188
|
+
summary: Ruby file manager
|
|
189
|
+
test_files: []
|