ruby-shell 2.9.1 → 2.10.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/bin/rsh +148 -14
- metadata +6 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5f20098ee7a4e00745916fb1830834273a00dbc5e92bea6b5f1cbd0f66b48639
|
4
|
+
data.tar.gz: 135135d2f788b75eb9e51cebd3dd3d680c4f07717819bf6fc9232bf8b4a32943
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c3494e59f58963262f8142850dbda9a76c50e6367a681389cd921a8db1bc47d2e68a6490799696c8b8e3437234934070364194f3aa81568a1f8bfdcfc61d9c0d
|
7
|
+
data.tar.gz: 8586e7cda13c597863e1d93cb978f0e5815b554a177b6977e41e0f2bc0f1d5a6017e0c04dbf32e45369a2a16180eface4bd67831f8be74b6dc7129f5664e63ed
|
data/bin/rsh
CHANGED
@@ -32,15 +32,20 @@ module Cursor # Terminal cursor movement ANSI codes (thanks to https://github.co
|
|
32
32
|
end
|
33
33
|
def pos # Query cursor current position
|
34
34
|
res = ''
|
35
|
-
|
36
|
-
$
|
37
|
-
|
38
|
-
|
39
|
-
|
35
|
+
begin
|
36
|
+
$stdin.raw do |stdin|
|
37
|
+
$stdout << CSI + '6n' # Tha actual ANSI get-position
|
38
|
+
$stdout.flush
|
39
|
+
while (c = stdin.getc) != 'R'
|
40
|
+
res << c if c
|
41
|
+
end
|
40
42
|
end
|
43
|
+
rescue Errno::ENOTTY
|
44
|
+
# Not a TTY, return default values
|
45
|
+
return 25, 80
|
41
46
|
end
|
42
47
|
m = res.match /(?<row>\d+);(?<col>\d+)/
|
43
|
-
return m[:row].to_i, m[:col].to_i
|
48
|
+
return m ? [m[:row].to_i, m[:col].to_i] : [25, 80]
|
44
49
|
end
|
45
50
|
def rowget
|
46
51
|
row, col = self.pos
|
@@ -596,12 +601,19 @@ def rshrc # Write updates to .rshrc
|
|
596
601
|
else
|
597
602
|
conf = ""
|
598
603
|
end
|
599
|
-
conf.sub!(/^@nick.*\n/, "")
|
604
|
+
conf.sub!(/^@nick.*\n/, "")
|
600
605
|
conf += "@nick = #{@nick}\n"
|
601
|
-
conf.sub!(/^@gnick.*\n/, "")
|
606
|
+
conf.sub!(/^@gnick.*\n/, "")
|
602
607
|
conf += "@gnick = #{@gnick}\n"
|
603
|
-
conf.sub!(/^@history.*\n/, "")
|
604
|
-
|
608
|
+
conf.sub!(/^@history.*\n/, "")
|
609
|
+
# Ensure history is properly formatted as valid Ruby array
|
610
|
+
begin
|
611
|
+
history_str = @history.last(@histsize).inspect
|
612
|
+
conf += "@history = #{history_str}\n"
|
613
|
+
rescue => e
|
614
|
+
conf += "@history = []\n"
|
615
|
+
puts "Warning: Error saving history: #{e.message}"
|
616
|
+
end
|
605
617
|
File.write(Dir.home+'/.rshrc', conf)
|
606
618
|
puts "\n.rshrc updated"
|
607
619
|
end
|
@@ -1104,18 +1116,140 @@ def ai_setup_help
|
|
1104
1116
|
end
|
1105
1117
|
|
1106
1118
|
# INITIAL SETUP
|
1119
|
+
def load_rshrc_safe
|
1120
|
+
return unless File.exist?(Dir.home+'/.rshrc')
|
1121
|
+
|
1122
|
+
begin
|
1123
|
+
# Try to load the .rshrc file
|
1124
|
+
load(Dir.home+'/.rshrc')
|
1125
|
+
|
1126
|
+
# Validate critical variables
|
1127
|
+
@history = [] unless @history.is_a?(Array)
|
1128
|
+
@nick = {} unless @nick.is_a?(Hash)
|
1129
|
+
@gnick = {} unless @gnick.is_a?(Hash)
|
1130
|
+
|
1131
|
+
rescue SyntaxError => e
|
1132
|
+
puts "\n\033[31mERROR: Syntax error in .rshrc:\033[0m"
|
1133
|
+
puts e.message
|
1134
|
+
puts "\n\033[33mAttempting to auto-heal .rshrc...\033[0m\n"
|
1135
|
+
|
1136
|
+
if auto_heal_rshrc
|
1137
|
+
puts "\033[32m.rshrc has been healed! Retrying...\033[0m\n"
|
1138
|
+
begin
|
1139
|
+
load(Dir.home+'/.rshrc')
|
1140
|
+
rescue => e2
|
1141
|
+
puts "\033[31mAuto-heal failed. Loading with defaults.\033[0m"
|
1142
|
+
load_defaults
|
1143
|
+
end
|
1144
|
+
else
|
1145
|
+
puts "\033[31mAuto-heal failed. Loading with defaults.\033[0m"
|
1146
|
+
load_defaults
|
1147
|
+
end
|
1148
|
+
|
1149
|
+
rescue => e
|
1150
|
+
puts "\n\033[31mERROR loading .rshrc: #{e.message}\033[0m"
|
1151
|
+
puts "\033[33mLoading with defaults...\033[0m\n"
|
1152
|
+
load_defaults
|
1153
|
+
end
|
1154
|
+
end
|
1155
|
+
|
1156
|
+
def auto_heal_rshrc
|
1157
|
+
begin
|
1158
|
+
rshrc_path = Dir.home + '/.rshrc'
|
1159
|
+
return false unless File.exist?(rshrc_path)
|
1160
|
+
|
1161
|
+
# Backup the corrupted file
|
1162
|
+
backup_path = rshrc_path + '.backup.' + Time.now.strftime('%Y%m%d_%H%M%S')
|
1163
|
+
File.write(backup_path, File.read(rshrc_path))
|
1164
|
+
puts "Backed up corrupted .rshrc to #{backup_path}"
|
1165
|
+
|
1166
|
+
content = File.read(rshrc_path)
|
1167
|
+
original_content = content.dup
|
1168
|
+
healed = false
|
1169
|
+
|
1170
|
+
# Fix common history array issues
|
1171
|
+
if content =~ /^@history\s*=\s*\[.*\]\s*\n\s*,/m
|
1172
|
+
# Fix case where array ends with ] followed by comma on next line
|
1173
|
+
content.gsub!(/^(@history\s*=\s*\[.*\])\s*\n\s*,(.*)$/m) do |match|
|
1174
|
+
# Remove the extra closing bracket and merge the lines
|
1175
|
+
history_line = $1
|
1176
|
+
continuation = $2
|
1177
|
+
# Remove trailing ] from first part
|
1178
|
+
history_line = history_line.sub(/\]\s*$/, '')
|
1179
|
+
# Combine and close properly
|
1180
|
+
"#{history_line}, #{continuation}]"
|
1181
|
+
end
|
1182
|
+
healed = true
|
1183
|
+
end
|
1184
|
+
|
1185
|
+
# Fix unclosed arrays
|
1186
|
+
['@history', '@nick', '@gnick'].each do |var|
|
1187
|
+
if content =~ /^#{var}\s*=\s*[[{](?!.*[}\]]\s*$)/m
|
1188
|
+
content.sub!(/^(#{var}\s*=\s*)(\[.*?)$/m) { "#{$1}#{$2}]" }
|
1189
|
+
content.sub!(/^(#{var}\s*=\s*)({.*?)$/m) { "#{$1}#{$2}}" }
|
1190
|
+
healed = true
|
1191
|
+
end
|
1192
|
+
end
|
1193
|
+
|
1194
|
+
# Validate Ruby syntax of the healed content
|
1195
|
+
begin
|
1196
|
+
# Try to parse the content
|
1197
|
+
eval("BEGIN {return true}\n" + content)
|
1198
|
+
rescue SyntaxError => e
|
1199
|
+
# If still has syntax errors, extract only valid parts
|
1200
|
+
new_content = ""
|
1201
|
+
|
1202
|
+
# Extract valid variable assignments
|
1203
|
+
content.each_line do |line|
|
1204
|
+
if line =~ /^(@\w+|\w+)\s*=\s*.+$/
|
1205
|
+
begin
|
1206
|
+
eval(line)
|
1207
|
+
new_content += line
|
1208
|
+
rescue
|
1209
|
+
# Skip invalid lines
|
1210
|
+
end
|
1211
|
+
elsif line =~ /^(def|class|module|end|if|else|elsif|when|case|begin|rescue)/
|
1212
|
+
new_content += line
|
1213
|
+
elsif line.strip.start_with?('#') || line.strip.empty?
|
1214
|
+
new_content += line
|
1215
|
+
end
|
1216
|
+
end
|
1217
|
+
|
1218
|
+
content = new_content
|
1219
|
+
healed = true
|
1220
|
+
end
|
1221
|
+
|
1222
|
+
if healed && content != original_content
|
1223
|
+
File.write(rshrc_path, content)
|
1224
|
+
return true
|
1225
|
+
end
|
1226
|
+
|
1227
|
+
false
|
1228
|
+
rescue => e
|
1229
|
+
puts "Error during auto-heal: #{e.message}"
|
1230
|
+
false
|
1231
|
+
end
|
1232
|
+
end
|
1233
|
+
|
1234
|
+
def load_defaults
|
1235
|
+
@history ||= []
|
1236
|
+
@nick ||= {"ls" => "ls --color -F"}
|
1237
|
+
@gnick ||= {}
|
1238
|
+
puts "Loaded with default configuration."
|
1239
|
+
end
|
1240
|
+
|
1107
1241
|
begin # Load .rshrc and populate @history
|
1108
1242
|
trap "SIGINT" do end
|
1109
|
-
trap "SIGHUP" do
|
1243
|
+
trap "SIGHUP" do
|
1110
1244
|
rshrc
|
1111
1245
|
exit
|
1112
1246
|
end
|
1113
|
-
trap "SIGTERM" do
|
1247
|
+
trap "SIGTERM" do
|
1114
1248
|
rshrc
|
1115
1249
|
exit
|
1116
1250
|
end
|
1117
1251
|
firstrun unless File.exist?(Dir.home+'/.rshrc') # Initial loading - to get history
|
1118
|
-
|
1252
|
+
load_rshrc_safe
|
1119
1253
|
# Load login shell files if rsh is running as login shell
|
1120
1254
|
if ENV['LOGIN_SHELL'] or $0 == "-rsh" or ARGV.include?('-l') or ARGV.include?('--login')
|
1121
1255
|
['/etc/profile', Dir.home+'/.profile', Dir.home+'/.bash_profile', Dir.home+'/.bashrc'].each do |f|
|
@@ -1159,7 +1293,7 @@ loop do
|
|
1159
1293
|
begin
|
1160
1294
|
@user = Etc.getpwuid(Process.euid).name # For use in @prompt
|
1161
1295
|
@node = Etc.uname[:nodename] # For use in @prompt
|
1162
|
-
h = @history;
|
1296
|
+
h = @history; load_rshrc_safe; @history = h # reload prompt but not history safely
|
1163
1297
|
@prompt.gsub!(/#{Dir.home}/, '~') # Simplify path in prompt
|
1164
1298
|
system("printf \"\033]0;rsh: #{Dir.pwd}\007\"") # Set Window title to path
|
1165
1299
|
@history[0] = "" unless @history[0]
|
metadata
CHANGED
@@ -1,21 +1,21 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby-shell
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.10.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Geir Isene
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-09-
|
11
|
+
date: 2025-09-16 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: 'A shell written in Ruby with extensive tab completions, aliases/nicks,
|
14
14
|
history, syntax highlighting, theming, auto-cd, auto-opening files and more. UPDATE
|
15
|
-
v2.
|
16
|
-
|
17
|
-
|
18
|
-
command
|
15
|
+
v2.10.0: Auto-healing for corrupted .rshrc files and robust error handling. v2.9.0:
|
16
|
+
AI integration! Use @ for AI text responses and @@ for AI command suggestions. Works
|
17
|
+
with local Ollama or external providers like OpenAI. v2.8.0: Enhanced help system,
|
18
|
+
:info command, and easier nick management.'
|
19
19
|
email: g@isene.com
|
20
20
|
executables:
|
21
21
|
- rsh
|