ruby-shell 3.4.9 → 3.5.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 +117 -16
- metadata +4 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: bac3cf4ea368be8c2991ee650e1977c7fafd7b1548645c1e3daaa94fd29bae2d
|
|
4
|
+
data.tar.gz: 31b8ae6ffcf460c7a236c72c8188254243879ab8b83ac690fcf8e61fc0aa46ad
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: bb8eb4cef6df5403bc751cf29d440a4289877fd9f7684f153e82196a3f24e425f88fabbe2ccae63c0ef108cae205feb241e84b52f138ad07975d03bd38834a7b
|
|
7
|
+
data.tar.gz: 96eb9e448ffd6c20b469e1b0d0f11e7f8dc274e809c4cc543dea3aa7ff5b5a5121a1aae6de7522cb3af1b3ff59e8e655df7af68ed54322f96844c5df910b4904
|
data/bin/rsh
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
# Web_site: http://isene.com/
|
|
9
9
|
# Github: https://github.com/isene/rsh
|
|
10
10
|
# License: Public domain
|
|
11
|
-
@version = "3.
|
|
11
|
+
@version = "3.5.0" # Polish release: Nick/history export, default nicks, expanded completions, startup tips, validation templates
|
|
12
12
|
|
|
13
13
|
# MODULES, CLASSES AND EXTENSIONS
|
|
14
14
|
class String # Add coloring to strings (with escaping for Readline)
|
|
@@ -137,8 +137,18 @@ begin # Initialization
|
|
|
137
137
|
"cargo" => %w[build run test check clean doc new init add search publish install update],
|
|
138
138
|
"npm" => %w[install uninstall update run build test start init publish],
|
|
139
139
|
"gem" => %w[install uninstall update list search build push],
|
|
140
|
-
"bundle" => %w[install update exec check config]
|
|
140
|
+
"bundle" => %w[install update exec check config],
|
|
141
|
+
"kubectl" => %w[get describe create delete apply edit logs exec port-forward scale rollout top explain diff patch],
|
|
142
|
+
"terraform" => %w[init plan apply destroy import output show],
|
|
143
|
+
"aws" => %w[s3 ec2 lambda cloudformation iam rds dynamodb sns sqs],
|
|
144
|
+
"brew" => %w[install uninstall update upgrade search info list],
|
|
145
|
+
"yarn" => %w[add remove install build test start init],
|
|
146
|
+
"make" => %w[clean install build test all],
|
|
147
|
+
"ansible" => %w[playbook galaxy vault inventory],
|
|
148
|
+
"poetry" => %w[add remove install update build publish],
|
|
149
|
+
"pipenv" => %w[install uninstall update shell run]
|
|
141
150
|
}
|
|
151
|
+
@show_tips = true # Show startup tips (configurable)
|
|
142
152
|
# New v3.0 features initialization
|
|
143
153
|
@switch_cache = {} # Cache for command switches from --help
|
|
144
154
|
@switch_cache_time = {} # Timestamp for cache expiry
|
|
@@ -277,7 +287,9 @@ def firstrun
|
|
|
277
287
|
@completion_show_descriptions = false # Show help text inline
|
|
278
288
|
@completion_fuzzy = true # Enable fuzzy matching
|
|
279
289
|
|
|
280
|
-
@nick = {
|
|
290
|
+
@nick = {
|
|
291
|
+
"ls" => "ls --color -F"
|
|
292
|
+
}
|
|
281
293
|
RSHRC
|
|
282
294
|
File.write(Dir.home+'/.rshrc', rc)
|
|
283
295
|
end
|
|
@@ -1063,11 +1075,25 @@ def suggest_command(cmd) # Smart command suggestions for typos
|
|
|
1063
1075
|
return nil if cmd.nil? || cmd.empty?
|
|
1064
1076
|
return nil if @exe.include?(cmd) || @nick.include?(cmd)
|
|
1065
1077
|
|
|
1078
|
+
max_dist = [cmd.length / 3, 2].max
|
|
1079
|
+
|
|
1080
|
+
# Pre-filter by length and first letter (huge optimization for large @exe)
|
|
1081
|
+
length_range = (cmd.length - max_dist)..(cmd.length + max_dist)
|
|
1082
|
+
first_letter = cmd[0]
|
|
1083
|
+
|
|
1084
|
+
# Filter: similar length AND (same first letter OR within 1 char distance)
|
|
1085
|
+
pool = (@exe + @nick.keys).select do |c|
|
|
1086
|
+
c.length >= 2 &&
|
|
1087
|
+
length_range.include?(c.length) &&
|
|
1088
|
+
(c[0] == first_letter || (c[0].ord - first_letter.ord).abs <= 1)
|
|
1089
|
+
end
|
|
1090
|
+
|
|
1091
|
+
# Hard limit to prevent any hang
|
|
1092
|
+
pool = pool.first(100)
|
|
1093
|
+
|
|
1066
1094
|
# Find commands with small edit distance
|
|
1067
|
-
candidates =
|
|
1068
|
-
next false if c.length < 2
|
|
1095
|
+
candidates = pool.select do |c|
|
|
1069
1096
|
dist = levenshtein_distance(cmd, c)
|
|
1070
|
-
max_dist = [cmd.length / 3, 2].max
|
|
1071
1097
|
dist <= max_dist && dist > 0
|
|
1072
1098
|
end
|
|
1073
1099
|
|
|
@@ -1115,6 +1141,7 @@ def config(*args) # Configure rsh settings
|
|
|
1115
1141
|
puts " auto_correct: #{@auto_correct ? 'on' : 'off'}"
|
|
1116
1142
|
puts " slow_command_threshold: #{@slow_command_threshold}s #{@slow_command_threshold > 0 ? '(enabled)' : '(disabled)'}"
|
|
1117
1143
|
puts " completion_learning: #{@completion_learning ? 'on' : 'off'}"
|
|
1144
|
+
puts " show_tips: #{@show_tips ? 'on' : 'off'}"
|
|
1118
1145
|
puts " completion_limit: #{@completion_limit}"
|
|
1119
1146
|
puts " completion_fuzzy: #{@completion_fuzzy}"
|
|
1120
1147
|
puts " completion_case_sensitive: #{@completion_case_sensitive}"
|
|
@@ -1155,9 +1182,13 @@ def config(*args) # Configure rsh settings
|
|
|
1155
1182
|
@completion_show_metadata = %w[on true yes 1].include?(value.to_s.downcase)
|
|
1156
1183
|
puts "Completion metadata display #{@completion_show_metadata ? 'enabled' : 'disabled'}"
|
|
1157
1184
|
rshrc
|
|
1185
|
+
when 'show_tips'
|
|
1186
|
+
@show_tips = %w[on true yes 1].include?(value.to_s.downcase)
|
|
1187
|
+
puts "Startup tips #{@show_tips ? 'enabled' : 'disabled'}"
|
|
1188
|
+
rshrc
|
|
1158
1189
|
else
|
|
1159
1190
|
puts "Unknown setting '#{setting}'"
|
|
1160
|
-
puts "Available: history_dedup, session_autosave, auto_correct, slow_command_threshold, completion_learning,
|
|
1191
|
+
puts "Available: history_dedup, session_autosave, auto_correct, slow_command_threshold, completion_learning, show_tips, completion_limit"
|
|
1161
1192
|
end
|
|
1162
1193
|
end
|
|
1163
1194
|
def env(*args) # Environment variable management
|
|
@@ -1588,15 +1619,38 @@ def help
|
|
|
1588
1619
|
end
|
|
1589
1620
|
puts
|
|
1590
1621
|
end
|
|
1591
|
-
def info
|
|
1592
|
-
|
|
1622
|
+
def info(*args)
|
|
1623
|
+
option = args[0]
|
|
1624
|
+
|
|
1625
|
+
if option == '--quick'
|
|
1626
|
+
puts "\nrsh v#{@version} - Ruby SHell"
|
|
1627
|
+
puts "Type :help for commands, :info for full intro"
|
|
1628
|
+
elsif option == '--features'
|
|
1629
|
+
puts "\nKey Features:"
|
|
1630
|
+
puts "• Nicks (aliases) with {{parameters}}"
|
|
1631
|
+
puts "• Completion learning (adapts to you)"
|
|
1632
|
+
puts "• Command recording & replay"
|
|
1633
|
+
puts "• Plugin system"
|
|
1634
|
+
puts "• Stats & analytics"
|
|
1635
|
+
puts "• 6 color themes"
|
|
1636
|
+
puts "• AI integration"
|
|
1637
|
+
puts "Type :help for details"
|
|
1638
|
+
else
|
|
1639
|
+
puts @info
|
|
1640
|
+
end
|
|
1593
1641
|
end
|
|
1594
1642
|
def version
|
|
1595
1643
|
puts "rsh version = #{@version} (latest RubyGems version is #{Gem.latest_version_for("ruby-shell").version} - https://github.com/isene/rsh)"
|
|
1596
1644
|
end
|
|
1597
|
-
def history # Show most recent history (up to 50 entries)
|
|
1598
|
-
|
|
1599
|
-
|
|
1645
|
+
def history(*args) # Show most recent history (up to 50 entries)
|
|
1646
|
+
if args[0] == '--export'
|
|
1647
|
+
filename = args[1] || 'history.txt'
|
|
1648
|
+
File.write(filename, @history.join("\n"))
|
|
1649
|
+
puts "History exported to #{filename} (#{@history.length} commands)"
|
|
1650
|
+
else
|
|
1651
|
+
puts "History:"
|
|
1652
|
+
@history.each_with_index {|h,i| puts i.to_s + "; " + h if i < 50}
|
|
1653
|
+
end
|
|
1600
1654
|
end
|
|
1601
1655
|
def rmhistory # Delete history
|
|
1602
1656
|
@history = []
|
|
@@ -1620,6 +1674,19 @@ def nick(nick_str = nil) # Define a new nick like this: `:nick "ls = ls --color
|
|
|
1620
1674
|
@nick.sort.each {|key, value| puts " #{key.c(@c_nick)} = #{value}"}
|
|
1621
1675
|
end
|
|
1622
1676
|
puts
|
|
1677
|
+
elsif nick_str =~ /^--export\s*(.*)/
|
|
1678
|
+
filename = $1.strip.empty? ? 'nicks.json' : $1.strip
|
|
1679
|
+
require 'json' unless defined?(JSON)
|
|
1680
|
+
File.write(filename, JSON.pretty_generate(@nick))
|
|
1681
|
+
puts "Nicks exported to #{filename}"
|
|
1682
|
+
elsif nick_str =~ /^--import\s+(.*)/
|
|
1683
|
+
filename = $1.strip
|
|
1684
|
+
return puts "File '#{filename}' not found" unless File.exist?(filename)
|
|
1685
|
+
require 'json' unless defined?(JSON)
|
|
1686
|
+
imported = JSON.parse(File.read(filename))
|
|
1687
|
+
imported.each { |k, v| @nick[k] = v }
|
|
1688
|
+
puts "Imported #{imported.length} nicks"
|
|
1689
|
+
rshrc
|
|
1623
1690
|
elsif nick_str.match(/^\s*-/)
|
|
1624
1691
|
source = nick_str.sub(/^\s*-/, '')
|
|
1625
1692
|
if @nick.delete(source)
|
|
@@ -2537,10 +2604,10 @@ def calc(*args) # Inline calculator using Ruby's Math library
|
|
|
2537
2604
|
rescue ZeroDivisionError
|
|
2538
2605
|
puts "Error: Division by zero"
|
|
2539
2606
|
rescue NameError => e
|
|
2540
|
-
# Extract the undefined name
|
|
2541
|
-
if e.message =~ /undefined
|
|
2607
|
+
# Extract the undefined name (sandbox format)
|
|
2608
|
+
if e.message =~ /undefined method `(\w+)'/
|
|
2542
2609
|
undefined = $1
|
|
2543
|
-
puts "Error: Unknown function
|
|
2610
|
+
puts "Error: Unknown function '#{undefined}'"
|
|
2544
2611
|
puts "Available Math functions: sqrt, sin, cos, tan, log, exp, abs, ceil, floor, round"
|
|
2545
2612
|
puts "Constants: PI, E"
|
|
2546
2613
|
else
|
|
@@ -2564,6 +2631,7 @@ def validate(rule_str = nil) # Custom validation rule management
|
|
|
2564
2631
|
puts "\nNo validation rules defined"
|
|
2565
2632
|
puts "Usage: :validate pattern = action"
|
|
2566
2633
|
puts "Actions: block, confirm, warn, log"
|
|
2634
|
+
puts "Or try: :validate --templates"
|
|
2567
2635
|
return
|
|
2568
2636
|
end
|
|
2569
2637
|
puts "\n Validation Rules:".c(@c_prompt).b
|
|
@@ -2571,6 +2639,21 @@ def validate(rule_str = nil) # Custom validation rule management
|
|
|
2571
2639
|
puts " #{i+1}. #{rule[:pattern].inspect} → #{rule[:action]}"
|
|
2572
2640
|
end
|
|
2573
2641
|
puts
|
|
2642
|
+
elsif rule_str == '--templates'
|
|
2643
|
+
puts "\n Common Validation Rule Templates:".c(@c_prompt).b
|
|
2644
|
+
puts " Safety:"
|
|
2645
|
+
puts " :validate rm -rf / = block"
|
|
2646
|
+
puts " :validate DROP TABLE = block"
|
|
2647
|
+
puts " Confirmation:"
|
|
2648
|
+
puts " :validate git push --force = confirm"
|
|
2649
|
+
puts " :validate npm publish = confirm"
|
|
2650
|
+
puts " Warnings:"
|
|
2651
|
+
puts " :validate sudo = warn"
|
|
2652
|
+
puts " :validate chmod 777 = warn"
|
|
2653
|
+
puts " Logging:"
|
|
2654
|
+
puts " :validate npm install = log"
|
|
2655
|
+
puts " :validate pip install = log"
|
|
2656
|
+
puts
|
|
2574
2657
|
elsif rule_str =~ /^-(\d+)$/
|
|
2575
2658
|
# Delete rule by index
|
|
2576
2659
|
index = $1.to_i - 1
|
|
@@ -3395,6 +3478,20 @@ loop do
|
|
|
3395
3478
|
unless @plugins_loaded
|
|
3396
3479
|
load_plugins
|
|
3397
3480
|
@plugins_loaded = true
|
|
3481
|
+
# Show startup tip (30% chance, if enabled)
|
|
3482
|
+
if @show_tips && rand < 0.3
|
|
3483
|
+
tips = [
|
|
3484
|
+
"Tip: Use :nick gp={{branch}} for parametrized aliases!",
|
|
3485
|
+
"Tip: Press Ctrl-G to edit commands in $EDITOR",
|
|
3486
|
+
"Tip: :stats --graph shows visual analytics",
|
|
3487
|
+
"Tip: :record your workflows and :replay them later",
|
|
3488
|
+
"Tip: :validate rm -rf / = block for safety rules",
|
|
3489
|
+
"Tip: :completion_stats shows what you use most",
|
|
3490
|
+
"Tip: Type :help for quick reference",
|
|
3491
|
+
"Tip: Disable tips with: :config show_tips off"
|
|
3492
|
+
]
|
|
3493
|
+
puts tips.sample.c(244)
|
|
3494
|
+
end
|
|
3398
3495
|
end
|
|
3399
3496
|
# Build display prompt with plugin additions (don't modify @prompt)
|
|
3400
3497
|
plugin_prompts = call_plugin_hook(:on_prompt)
|
|
@@ -3622,11 +3719,12 @@ loop do
|
|
|
3622
3719
|
puts "Bookmark '#{@cmd}' points to non-existent directory: #{bm_dir}".c(196)
|
|
3623
3720
|
end
|
|
3624
3721
|
else
|
|
3625
|
-
puts "#{Time.now.strftime("%H:%M:%S")}: #{@cmd}".c(@c_stamp)
|
|
3626
3722
|
if @cmd == "f" # fzf integration (https://github.com/junegunn/fzf)
|
|
3723
|
+
puts "#{Time.now.strftime("%H:%M:%S")}: #{@cmd}".c(@c_stamp)
|
|
3627
3724
|
res = `fzf`.chomp
|
|
3628
3725
|
Dir.chdir(File.dirname(res))
|
|
3629
3726
|
elsif File.exist?(@cmd) and not File.executable?(@cmd) and not @cmd.include?(" ")
|
|
3727
|
+
puts "#{Time.now.strftime("%H:%M:%S")}: #{@cmd}".c(@c_stamp)
|
|
3630
3728
|
# Only auto-open files if it's a single filename (no spaces = no command with args)
|
|
3631
3729
|
if File.read(@cmd).force_encoding("UTF-8").valid_encoding?
|
|
3632
3730
|
system("#{ENV['EDITOR']} #{@cmd}") # Try open with user's editor
|
|
@@ -3644,6 +3742,9 @@ loop do
|
|
|
3644
3742
|
# Apply auto-correct if enabled (before validation)
|
|
3645
3743
|
@cmd = apply_auto_correct(@cmd)
|
|
3646
3744
|
|
|
3745
|
+
# Print timestamp AFTER auto-correct (shows what actually executes)
|
|
3746
|
+
puts "#{Time.now.strftime("%H:%M:%S")}: #{@cmd}".c(@c_stamp)
|
|
3747
|
+
|
|
3647
3748
|
# Validate command after auto-correction
|
|
3648
3749
|
warnings = validate_command(@cmd)
|
|
3649
3750
|
if warnings && !warnings.empty?
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: ruby-shell
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 3.
|
|
4
|
+
version: 3.5.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Geir Isene
|
|
@@ -12,9 +12,9 @@ date: 2025-10-30 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
|
-
v3.
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
v3.5.0: Nick/history export, 9 new tool completions (kubectl, terraform, aws, brew,
|
|
16
|
+
etc.), validation templates, startup tips, improved :info, aggressive suggest_command
|
|
17
|
+
optimization for huge PATHs (18K+ executables), timestamp shows corrected commands!'
|
|
18
18
|
email: g@isene.com
|
|
19
19
|
executables:
|
|
20
20
|
- rsh
|