ruby-shell 3.4.5 → 3.4.6
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/PLUGIN_GUIDE.md +107 -0
- data/bin/rsh +98 -37
- metadata +4 -5
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 8180bf48f336b9667d34fc01d5df5ddf7a3412ff5f35cfc443d10846a81f6686
|
|
4
|
+
data.tar.gz: acd063a28be3a5bfe7ccb9ec6623ddb7e061deba44806725c1b76781fcf45acb
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 05d07658f8356edad6da19da615170e2423785fc4a3f9074cfb5b9ef3a7f602b3f109172cb6ba799f9b2bc0bbc7363a9c0ff29b4d9d27cfebb05b2883156aad6
|
|
7
|
+
data.tar.gz: 6e1d7c8d6c16c0ce6f2d7cf67a5229b3a31f3e0d096438fd59877c3647dd5f8b1530ff0b0c46cd95bd377d25663e79e7f0cbef8dc8599f61cb281a395c54bc94
|
data/PLUGIN_GUIDE.md
CHANGED
|
@@ -661,6 +661,113 @@ Planned for v4.0:
|
|
|
661
661
|
|
|
662
662
|
---
|
|
663
663
|
|
|
664
|
+
## Included Plugins
|
|
665
|
+
|
|
666
|
+
rsh comes with several useful plugins out of the box. Enable them with `:plugins "enable", "pluginname"`.
|
|
667
|
+
|
|
668
|
+
### venv - Virtual Environment Indicators
|
|
669
|
+
|
|
670
|
+
Shows active Python venv, Ruby rbenv/rvm, Node nvm, and Conda environments in your prompt.
|
|
671
|
+
|
|
672
|
+
**Features:**
|
|
673
|
+
- Detects Python virtualenv: `(py:myenv)`
|
|
674
|
+
- Shows Ruby rbenv/rvm versions: `(rb:3.2.0)`
|
|
675
|
+
- Displays Node version: `(node:18.0.0)`
|
|
676
|
+
- Shows Conda environments: `(conda:base)`
|
|
677
|
+
- Color-coded indicators (green for Python, red for Ruby, yellow for Node, cyan for Conda)
|
|
678
|
+
|
|
679
|
+
**Usage:** Simply enable the plugin, indicators appear automatically when in an active environment.
|
|
680
|
+
|
|
681
|
+
### extract - Universal Archive Handler
|
|
682
|
+
|
|
683
|
+
Extract any archive format with a single command.
|
|
684
|
+
|
|
685
|
+
**Features:**
|
|
686
|
+
- Handles: `.tar.gz`, `.tar.bz2`, `.tar.xz`, `.zip`, `.rar`, `.7z`, `.gz`, `.bz2`, `.xz`, `.Z`, `.deb`, `.rpm`
|
|
687
|
+
- Auto-detects format from extension
|
|
688
|
+
- Success/error feedback with color
|
|
689
|
+
|
|
690
|
+
**Commands:**
|
|
691
|
+
- `extract file.tar.gz` - Extract any supported archive
|
|
692
|
+
|
|
693
|
+
**Example:**
|
|
694
|
+
```ruby
|
|
695
|
+
extract project.tar.gz
|
|
696
|
+
extract backup.zip
|
|
697
|
+
extract archive.7z
|
|
698
|
+
```
|
|
699
|
+
|
|
700
|
+
### docker - Container Integration
|
|
701
|
+
|
|
702
|
+
Quick Docker container management with prompt indicators.
|
|
703
|
+
|
|
704
|
+
**Features:**
|
|
705
|
+
- Shows running container count in prompt: `[docker:3]`
|
|
706
|
+
- Quick container management commands
|
|
707
|
+
- Docker Compose shortcuts
|
|
708
|
+
|
|
709
|
+
**Commands:**
|
|
710
|
+
- `dps` - List running containers (docker ps)
|
|
711
|
+
- `dpsa` - List all containers (docker ps -a)
|
|
712
|
+
- `dex <container>` - Execute bash in container
|
|
713
|
+
- `dlogs <container> [lines]` - Show container logs (default 50 lines)
|
|
714
|
+
- `dstop` - Stop all running containers
|
|
715
|
+
- `dclean` - Remove all stopped containers
|
|
716
|
+
- `dcup` - Docker compose up -d
|
|
717
|
+
- `dcdown` - Docker compose down
|
|
718
|
+
- `dcrestart` - Docker compose restart
|
|
719
|
+
|
|
720
|
+
**Example:**
|
|
721
|
+
```ruby
|
|
722
|
+
dps # List running containers
|
|
723
|
+
dex web_1 # Enter bash in web_1 container
|
|
724
|
+
dlogs nginx 100 # Show last 100 log lines
|
|
725
|
+
```
|
|
726
|
+
|
|
727
|
+
### clipboard - Cross-Platform Clipboard
|
|
728
|
+
|
|
729
|
+
Copy and paste text to/from system clipboard.
|
|
730
|
+
|
|
731
|
+
**Features:**
|
|
732
|
+
- Auto-detects clipboard tool (xclip, xsel, wl-copy/paste, pbcopy/paste, clip.exe)
|
|
733
|
+
- Works on Linux (X11/Wayland), macOS, and Windows WSL
|
|
734
|
+
- Copy last command, arbitrary text, or file contents
|
|
735
|
+
|
|
736
|
+
**Commands:**
|
|
737
|
+
- `clip [text]` - Copy text to clipboard (copies last command if no args)
|
|
738
|
+
- `clipp` - Paste from clipboard and display
|
|
739
|
+
- `clipf <file>` - Copy file contents to clipboard
|
|
740
|
+
|
|
741
|
+
**Example:**
|
|
742
|
+
```ruby
|
|
743
|
+
clip # Copy last command
|
|
744
|
+
clip some text here # Copy this text
|
|
745
|
+
clipf config.yml # Copy file contents
|
|
746
|
+
clipp # Show clipboard contents
|
|
747
|
+
```
|
|
748
|
+
|
|
749
|
+
### git_prompt - Git Branch Indicator
|
|
750
|
+
|
|
751
|
+
Shows current git branch in prompt when in a git repository.
|
|
752
|
+
|
|
753
|
+
**Features:**
|
|
754
|
+
- Displays current branch: `[main]`
|
|
755
|
+
- Only shows when in a git repo
|
|
756
|
+
- Yellow color coding
|
|
757
|
+
|
|
758
|
+
**Usage:** Enable and branch appears automatically in prompt.
|
|
759
|
+
|
|
760
|
+
### command_logger - Command Logging
|
|
761
|
+
|
|
762
|
+
Logs all commands to a file for audit/review.
|
|
763
|
+
|
|
764
|
+
**Features:**
|
|
765
|
+
- Logs commands with timestamp
|
|
766
|
+
- Customizable log file location
|
|
767
|
+
- Useful for command history analysis
|
|
768
|
+
|
|
769
|
+
---
|
|
770
|
+
|
|
664
771
|
## Example Plugin Templates
|
|
665
772
|
|
|
666
773
|
### Minimal Plugin
|
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.4.
|
|
11
|
+
@version = "3.4.6" # Plugin help system, 4 new plugins, plugins disabled by default, Ctrl-W fix
|
|
12
12
|
|
|
13
13
|
# MODULES, CLASSES AND EXTENSIONS
|
|
14
14
|
class String # Add coloring to strings (with escaping for Readline)
|
|
@@ -154,7 +154,7 @@ begin # Initialization
|
|
|
154
154
|
@slow_command_threshold = 0 # Threshold for slow command alerts (0 = disabled)
|
|
155
155
|
@plugin_dir = Dir.home + '/.rsh/plugins' # Plugins directory
|
|
156
156
|
@plugins = [] # Loaded plugin instances
|
|
157
|
-
@
|
|
157
|
+
@plugin_enabled = [] # List of enabled plugin names (whitelist)
|
|
158
158
|
@plugin_commands = {} # Commands added by plugins
|
|
159
159
|
@validation_rules = [] # Custom validation rules
|
|
160
160
|
@completion_weights = {} # Completion learning weights
|
|
@@ -352,7 +352,7 @@ def getstr # A custom Readline-like function
|
|
|
352
352
|
# The actual printing og the command line
|
|
353
353
|
@c.row(@row0)
|
|
354
354
|
@c.clear_line
|
|
355
|
-
print @
|
|
355
|
+
print @display_prompt
|
|
356
356
|
@c.clear_screen_down
|
|
357
357
|
row, @pos0 = @c.pos
|
|
358
358
|
#@history[0] = "" if @history[0].nil?
|
|
@@ -476,11 +476,13 @@ def getstr # A custom Readline-like function
|
|
|
476
476
|
@c.clear_line_after
|
|
477
477
|
when 'WBACK' # Delete one word to the left (Ctrl-W)
|
|
478
478
|
unless @pos == @pos0
|
|
479
|
-
|
|
479
|
+
# Skip over any trailing spaces first
|
|
480
|
+
while @pos > 0 && @history[0][@pos - 1] == " "
|
|
480
481
|
@pos -= 1
|
|
481
482
|
@history[0][@pos] = ""
|
|
482
483
|
end
|
|
483
|
-
|
|
484
|
+
# Delete the word (until we hit a space or start)
|
|
485
|
+
while @pos > 0 && @history[0][@pos - 1] != " "
|
|
484
486
|
@pos -= 1
|
|
485
487
|
@history[0][@pos] = ""
|
|
486
488
|
end
|
|
@@ -622,7 +624,7 @@ def tab(type)
|
|
|
622
624
|
@c_col = @pos0 + @pos
|
|
623
625
|
@c.clear_line
|
|
624
626
|
line_display = cmd_check(@history[0]).to_s
|
|
625
|
-
print @
|
|
627
|
+
print @display_prompt + line_display
|
|
626
628
|
@c.col(@c_col)
|
|
627
629
|
return
|
|
628
630
|
end
|
|
@@ -645,14 +647,22 @@ def tab(type)
|
|
|
645
647
|
@tabarray = @recordings.keys
|
|
646
648
|
when "plugin_args"
|
|
647
649
|
# Completions for :plugins command
|
|
648
|
-
@tabarray = %w[reload
|
|
649
|
-
# Add
|
|
650
|
+
@tabarray = %w[reload]
|
|
651
|
+
# Add help for all available plugins
|
|
652
|
+
if Dir.exist?(@plugin_dir)
|
|
653
|
+
available = Dir.glob(@plugin_dir + '/*.rb').map { |f| File.basename(f, '.rb') }
|
|
654
|
+
@tabarray += available.map { |p| "help #{p}" }
|
|
655
|
+
@tabarray += available.map { |p| "info #{p}" }
|
|
656
|
+
end
|
|
657
|
+
# Add plugin names for enable/disable
|
|
650
658
|
if @plugins.any?
|
|
651
659
|
@tabarray += @plugins.map { |p| "disable #{p[:name]}" }
|
|
652
|
-
@tabarray += @plugins.map { |p| "info #{p[:name]}" }
|
|
653
660
|
end
|
|
654
|
-
|
|
655
|
-
|
|
661
|
+
# Show "enable" for disabled plugins (available but not enabled)
|
|
662
|
+
if Dir.exist?(@plugin_dir)
|
|
663
|
+
available = Dir.glob(@plugin_dir + '/*.rb').map { |f| File.basename(f, '.rb') }
|
|
664
|
+
disabled = available - @plugin_enabled
|
|
665
|
+
@tabarray += disabled.map { |p| "enable #{p}" } if disabled.any?
|
|
656
666
|
end
|
|
657
667
|
when "switch"
|
|
658
668
|
cmdswitch = @pretab.split(/[|, ]/).last.to_s.strip
|
|
@@ -839,7 +849,7 @@ def tab(type)
|
|
|
839
849
|
# Escape regex special characters in @tabstr for pattern matching
|
|
840
850
|
escaped_tabstr = Regexp.escape(@tabstr)
|
|
841
851
|
tabline = display_choice.sub(/(.*)#{escaped_tabstr}(.*)/, '\1'.c(choice_color) + @tabstr.u.c(choice_color) + '\2'.c(choice_color))
|
|
842
|
-
print @
|
|
852
|
+
print @display_prompt + line1 + tabline + line2 # Print the commandline
|
|
843
853
|
@pos = @pretab.length.to_i + tabchoice.length.to_i # Set the position on that commandline
|
|
844
854
|
@c_col = @pos0 + @pos # The cursor position must include the prompt as well
|
|
845
855
|
@c.col(@c_col) # Set the cursor position
|
|
@@ -1389,8 +1399,8 @@ def rshrc # Write user configuration to .rshrc (portable between machines)
|
|
|
1389
1399
|
conf += "@completion_learning = #{@completion_learning}\n" unless @completion_learning
|
|
1390
1400
|
conf.sub!(/^@completion_show_metadata.*(\n|$)/, "")
|
|
1391
1401
|
conf += "@completion_show_metadata = #{@completion_show_metadata}\n" if @completion_show_metadata
|
|
1392
|
-
conf.sub!(/^@
|
|
1393
|
-
conf += "@
|
|
1402
|
+
conf.sub!(/^@plugin_enabled.*(\n|$)/, "")
|
|
1403
|
+
conf += "@plugin_enabled = #{@plugin_enabled}\n" unless @plugin_enabled.empty?
|
|
1394
1404
|
conf.sub!(/^@validation_rules.*(\n|$)/, "")
|
|
1395
1405
|
conf += "@validation_rules = #{@validation_rules}\n" unless @validation_rules.empty?
|
|
1396
1406
|
|
|
@@ -2250,8 +2260,8 @@ def load_plugins # Load all plugins from plugin directory
|
|
|
2250
2260
|
plugin_files.each do |plugin_file|
|
|
2251
2261
|
plugin_name = File.basename(plugin_file, '.rb')
|
|
2252
2262
|
|
|
2253
|
-
#
|
|
2254
|
-
next
|
|
2263
|
+
# Only load if explicitly enabled (whitelist)
|
|
2264
|
+
next unless @plugin_enabled.include?(plugin_name)
|
|
2255
2265
|
|
|
2256
2266
|
begin
|
|
2257
2267
|
# Load the plugin file
|
|
@@ -2321,22 +2331,26 @@ def call_plugin_hook(hook_name, *args) # Call a lifecycle hook for all plugins
|
|
|
2321
2331
|
end
|
|
2322
2332
|
def plugins(*args) # Plugin management command
|
|
2323
2333
|
if args.empty?
|
|
2324
|
-
# List all plugins
|
|
2325
|
-
|
|
2326
|
-
|
|
2334
|
+
# List all available plugins
|
|
2335
|
+
available_plugins = Dir.exist?(@plugin_dir) ? Dir.glob(@plugin_dir + '/*.rb').map { |f| File.basename(f, '.rb') }.sort : []
|
|
2336
|
+
|
|
2337
|
+
if available_plugins.empty?
|
|
2338
|
+
puts "\nNo plugins found"
|
|
2327
2339
|
puts "Place .rb files in #{@plugin_dir}"
|
|
2328
2340
|
return
|
|
2329
2341
|
end
|
|
2330
2342
|
|
|
2331
|
-
puts "\n
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
|
|
2337
|
-
|
|
2338
|
-
|
|
2339
|
-
|
|
2343
|
+
puts "\n Available Plugins:".c(@c_prompt).b
|
|
2344
|
+
available_plugins.each do |name|
|
|
2345
|
+
if @plugin_enabled.include?(name)
|
|
2346
|
+
status = '[enabled]'.c(@c_path)
|
|
2347
|
+
plugin = @plugins.find { |p| p[:name] == name }
|
|
2348
|
+
class_info = plugin ? " (#{plugin[:class]})" : ""
|
|
2349
|
+
else
|
|
2350
|
+
status = '[disabled]'.c(196)
|
|
2351
|
+
class_info = ""
|
|
2352
|
+
end
|
|
2353
|
+
puts " #{name.ljust(20)} #{status}#{class_info}"
|
|
2340
2354
|
end
|
|
2341
2355
|
puts
|
|
2342
2356
|
elsif args[0] == 'reload'
|
|
@@ -2348,15 +2362,15 @@ def plugins(*args) # Plugin management command
|
|
|
2348
2362
|
elsif args[0] == 'enable' && args[1]
|
|
2349
2363
|
# Enable a plugin
|
|
2350
2364
|
plugin_name = args[1]
|
|
2351
|
-
@
|
|
2365
|
+
unless @plugin_enabled.include?(plugin_name)
|
|
2366
|
+
@plugin_enabled << plugin_name
|
|
2367
|
+
end
|
|
2352
2368
|
puts "Plugin '#{plugin_name}' enabled. Use :plugins reload to load it"
|
|
2353
2369
|
rshrc
|
|
2354
2370
|
elsif args[0] == 'disable' && args[1]
|
|
2355
2371
|
# Disable a plugin
|
|
2356
2372
|
plugin_name = args[1]
|
|
2357
|
-
|
|
2358
|
-
@plugin_disabled << plugin_name
|
|
2359
|
-
end
|
|
2373
|
+
@plugin_enabled.delete(plugin_name)
|
|
2360
2374
|
@plugins.reject! { |p| p[:name] == plugin_name }
|
|
2361
2375
|
puts "Plugin '#{plugin_name}' disabled"
|
|
2362
2376
|
rshrc
|
|
@@ -2382,6 +2396,51 @@ def plugins(*args) # Plugin management command
|
|
|
2382
2396
|
else
|
|
2383
2397
|
puts "Plugin '#{plugin_name}' not found"
|
|
2384
2398
|
end
|
|
2399
|
+
elsif args[0] == 'help' && args[1]
|
|
2400
|
+
# Show plugin help
|
|
2401
|
+
plugin_name = args[1]
|
|
2402
|
+
plugin_file = "#{@plugin_dir}/#{plugin_name}.rb"
|
|
2403
|
+
|
|
2404
|
+
if File.exist?(plugin_file)
|
|
2405
|
+
content = File.read(plugin_file)
|
|
2406
|
+
|
|
2407
|
+
# Extract help block (lines starting with # at top of file)
|
|
2408
|
+
help_lines = []
|
|
2409
|
+
in_help = true
|
|
2410
|
+
content.each_line do |line|
|
|
2411
|
+
if in_help && line =~ /^#\s*(.*)$/
|
|
2412
|
+
help_text = $1
|
|
2413
|
+
next if help_text =~ /^-+$/ # Skip separator lines
|
|
2414
|
+
help_lines << help_text
|
|
2415
|
+
elsif line.strip.empty?
|
|
2416
|
+
next
|
|
2417
|
+
else
|
|
2418
|
+
in_help = false
|
|
2419
|
+
break
|
|
2420
|
+
end
|
|
2421
|
+
end
|
|
2422
|
+
|
|
2423
|
+
if help_lines.any?
|
|
2424
|
+
puts "\n#{help_lines.join("\n")}\n"
|
|
2425
|
+
else
|
|
2426
|
+
puts "No help available for plugin '#{plugin_name}'"
|
|
2427
|
+
end
|
|
2428
|
+
|
|
2429
|
+
# Extract and show available commands
|
|
2430
|
+
commands = []
|
|
2431
|
+
content.scan(/def (\w+)\(/) { |match| commands << match[0] unless match[0] == 'initialize' }
|
|
2432
|
+
|
|
2433
|
+
if commands.any?
|
|
2434
|
+
puts "\nCommands: #{commands.join(', ')}".c(@c_nick)
|
|
2435
|
+
puts
|
|
2436
|
+
end
|
|
2437
|
+
else
|
|
2438
|
+
puts "Plugin '#{plugin_name}' not found"
|
|
2439
|
+
puts "Available plugins:"
|
|
2440
|
+
Dir.glob(@plugin_dir + '/*.rb').each do |file|
|
|
2441
|
+
puts " #{File.basename(file, '.rb')}"
|
|
2442
|
+
end
|
|
2443
|
+
end
|
|
2385
2444
|
else
|
|
2386
2445
|
puts "Usage:"
|
|
2387
2446
|
puts " :plugins List all plugins"
|
|
@@ -2389,6 +2448,7 @@ def plugins(*args) # Plugin management command
|
|
|
2389
2448
|
puts " :plugins enable NAME Enable a plugin"
|
|
2390
2449
|
puts " :plugins disable NAME Disable a plugin"
|
|
2391
2450
|
puts " :plugins info NAME Show plugin details"
|
|
2451
|
+
puts " :plugins help NAME Show plugin help/usage"
|
|
2392
2452
|
end
|
|
2393
2453
|
end
|
|
2394
2454
|
def validate_command(cmd) # Syntax validation before execution
|
|
@@ -2999,7 +3059,7 @@ def load_rshrc_safe
|
|
|
2999
3059
|
@session_autosave = 0 unless @session_autosave.is_a?(Integer)
|
|
3000
3060
|
@auto_correct = false unless [@auto_correct].any? { |v| v == true || v == false }
|
|
3001
3061
|
@slow_command_threshold = 0 unless @slow_command_threshold.is_a?(Integer)
|
|
3002
|
-
@
|
|
3062
|
+
@plugin_enabled = [] unless @plugin_enabled.is_a?(Array)
|
|
3003
3063
|
@plugins = [] unless @plugins.is_a?(Array)
|
|
3004
3064
|
@plugin_commands = {} unless @plugin_commands.is_a?(Hash)
|
|
3005
3065
|
@validation_rules = [] unless @validation_rules.is_a?(Array)
|
|
@@ -3154,7 +3214,7 @@ def load_defaults
|
|
|
3154
3214
|
@session_autosave ||= 0
|
|
3155
3215
|
@auto_correct ||= false
|
|
3156
3216
|
@slow_command_threshold ||= 0
|
|
3157
|
-
@
|
|
3217
|
+
@plugin_enabled ||= []
|
|
3158
3218
|
@plugins ||= []
|
|
3159
3219
|
@plugin_commands ||= {}
|
|
3160
3220
|
@validation_rules ||= []
|
|
@@ -3293,9 +3353,10 @@ loop do
|
|
|
3293
3353
|
load_plugins
|
|
3294
3354
|
@plugins_loaded = true
|
|
3295
3355
|
end
|
|
3296
|
-
#
|
|
3356
|
+
# Build display prompt with plugin additions (don't modify @prompt)
|
|
3297
3357
|
plugin_prompts = call_plugin_hook(:on_prompt)
|
|
3298
|
-
@
|
|
3358
|
+
@display_prompt = @prompt.dup
|
|
3359
|
+
@display_prompt += plugin_prompts.join if plugin_prompts.any?
|
|
3299
3360
|
# Auto-save session if enabled and interval elapsed
|
|
3300
3361
|
if @session_autosave && @session_autosave > 0
|
|
3301
3362
|
current_time = Time.now.to_i
|
|
@@ -3342,7 +3403,7 @@ loop do
|
|
|
3342
3403
|
# Move cursor to end of line and print the full command before clearing
|
|
3343
3404
|
@c.row(@row0)
|
|
3344
3405
|
@c.clear_line
|
|
3345
|
-
print @
|
|
3406
|
+
print @display_prompt + cmd_check(@cmd)
|
|
3346
3407
|
print "\n"; @c.clear_screen_down
|
|
3347
3408
|
if @cmd == "r" # Integration with rtfm (https://github.com/isene/RTFM)
|
|
3348
3409
|
t = Time.now
|
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.
|
|
4
|
+
version: 3.4.6
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Geir Isene
|
|
@@ -12,10 +12,9 @@ date: 2025-10-26 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.4.
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
persistent patterns across sessions!'
|
|
15
|
+
v3.4.6: PLUGIN SYSTEM ENHANCED - Plugin help system, 4 new plugins (venv/extract/docker/clipboard),
|
|
16
|
+
plugins disabled by default. Plus v3.4.5: Full LS_COLORS compliance with pattern-based
|
|
17
|
+
directory coloring (@dir_colors like RTFM''s @topmatch)!'
|
|
19
18
|
email: g@isene.com
|
|
20
19
|
executables:
|
|
21
20
|
- rsh
|