ruby-shell 3.4.4 → 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.
Files changed (5) hide show
  1. checksums.yaml +4 -4
  2. data/PLUGIN_GUIDE.md +107 -0
  3. data/README.md +21 -0
  4. data/bin/rsh +119 -38
  5. metadata +5 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 587406cf97c8f8aeba405779d229d073b0c8963b24c224edd1a24d72441411d5
4
- data.tar.gz: aa4ea0471988e2004e057c575684f6d2a3f2b3875872e49ee769f22045d52bd5
3
+ metadata.gz: 8180bf48f336b9667d34fc01d5df5ddf7a3412ff5f35cfc443d10846a81f6686
4
+ data.tar.gz: acd063a28be3a5bfe7ccb9ec6623ddb7e061deba44806725c1b76781fcf45acb
5
5
  SHA512:
6
- metadata.gz: 8fc3e11246348f5eae8bec22ac1d62d990a5ab2727573202363a9c04d6f6e8448bb265fd776ae664004249ac9133baf12a78042da5045b8fe3589e8484414221
7
- data.tar.gz: a4305bfba19e86a643440a4d6727e71c3e5d74467fdb9ccf5070345f66a5792256276b299e04714e389d6801e5aadf0253b3da645203bb4135412f5ffa9ec9a2
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/README.md CHANGED
@@ -476,6 +476,27 @@ Also, a special variable for better LS_COLOR setup:
476
476
  ```
477
477
  Point `@lscolors` to a file that sets your LS_COLORS variable. Use [my extended LS_COLORS setup](https://github.com/isene/LS_COLORS) to make this really fancy.
478
478
 
479
+ ### Directory Colors in Prompt
480
+
481
+ **rsh is fully LS_COLORS compliant** - both tab completion and prompt paths use LS_COLORS for consistent theming.
482
+
483
+ You can override directory colors in the prompt using pattern matching (like RTFM's @topmatch):
484
+ ```ruby
485
+ @dir_colors = [
486
+ ["PassionFruit", 171], # Paths containing "PassionFruit" -> magenta
487
+ ["Dualog", 72], # Paths containing "Dualog" -> cyan
488
+ ["/G", 172], # Paths containing "/G" -> orange
489
+ ]
490
+ ```
491
+
492
+ How it works:
493
+ - Array of `[pattern, color]` pairs
494
+ - First matching pattern wins (uses Ruby's `include?` method)
495
+ - If no pattern matches, uses LS_COLORS 'di' value (your configured directory color)
496
+ - Pattern matching is simple substring matching: "/G" matches "/home/user/Main/G/..."
497
+
498
+ This lets you visually distinguish different project directories at a glance in your prompt.
499
+
479
500
  You can add any Ruby code to your .rshrc.
480
501
 
481
502
  # Enter the world of Ruby
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.4" # Split .rshrc/.rshstate, performance improvements, symlink colors, auto-migration
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
- @plugin_disabled = [] # List of disabled plugin names
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 @prompt
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
- until @history[0][@pos - 1] == " " or @pos == 0
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
- if @history[0][@pos - 1] == " "
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 @prompt + line_display
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 info]
649
- # Add plugin names for enable/disable/info
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
- if @plugin_disabled.any?
655
- @tabarray += @plugin_disabled.map { |p| "enable #{p}" }
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 @prompt + line1 + tabline + line2 # Print the commandline
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
@@ -1262,6 +1272,18 @@ def get_file_color(filename) # Get color for a file based on LS_COLORS
1262
1272
  file_color = 7 if file_color == 0 # 0 means "reset to default" in LS_COLORS
1263
1273
  file_color
1264
1274
  end
1275
+ def get_dir_color(path) # Get color for directory path in prompt
1276
+ # Check pattern matches first (like RTFM's @topmatch)
1277
+ # Set @dir_colors in .rshrc as array of [pattern, color] pairs
1278
+ # Example: @dir_colors = [["PassionFruit", 171], ["Dualog", 72], ["/G", 172], ["", 33]]
1279
+ if @dir_colors && @dir_colors.is_a?(Array)
1280
+ match = @dir_colors.find { |pattern, _| pattern.empty? || path.include?(pattern) }
1281
+ return match.last if match
1282
+ end
1283
+
1284
+ # Fall back to LS_COLORS directory color
1285
+ @ls_colors['di'] || 33
1286
+ end
1265
1287
  def format_tab_item(item, show_metadata: false) # Format tab item with color and optional metadata
1266
1288
  color = get_file_color(item)
1267
1289
  formatted = item
@@ -1335,7 +1357,12 @@ def cmd_check(str) # Check if each element on the readline matches commands, nic
1335
1357
  # Color bookmarks (after commands and nicks)
1336
1358
  el.c(@c_bookmark)
1337
1359
  elsif File.exist?(clean_el)
1338
- el.c(@c_path)
1360
+ # Use directory color matching for directories, @c_path for files
1361
+ if File.directory?(clean_el)
1362
+ el.c(get_dir_color(File.expand_path(clean_el)))
1363
+ else
1364
+ el.c(@c_path)
1365
+ end
1339
1366
  elsif el[0] == "-"
1340
1367
  el.c(@c_switch)
1341
1368
  else
@@ -1372,8 +1399,8 @@ def rshrc # Write user configuration to .rshrc (portable between machines)
1372
1399
  conf += "@completion_learning = #{@completion_learning}\n" unless @completion_learning
1373
1400
  conf.sub!(/^@completion_show_metadata.*(\n|$)/, "")
1374
1401
  conf += "@completion_show_metadata = #{@completion_show_metadata}\n" if @completion_show_metadata
1375
- conf.sub!(/^@plugin_disabled.*(\n|$)/, "")
1376
- conf += "@plugin_disabled = #{@plugin_disabled}\n" unless @plugin_disabled.empty?
1402
+ conf.sub!(/^@plugin_enabled.*(\n|$)/, "")
1403
+ conf += "@plugin_enabled = #{@plugin_enabled}\n" unless @plugin_enabled.empty?
1377
1404
  conf.sub!(/^@validation_rules.*(\n|$)/, "")
1378
1405
  conf += "@validation_rules = #{@validation_rules}\n" unless @validation_rules.empty?
1379
1406
 
@@ -2233,8 +2260,8 @@ def load_plugins # Load all plugins from plugin directory
2233
2260
  plugin_files.each do |plugin_file|
2234
2261
  plugin_name = File.basename(plugin_file, '.rb')
2235
2262
 
2236
- # Skip if disabled
2237
- next if @plugin_disabled.include?(plugin_name)
2263
+ # Only load if explicitly enabled (whitelist)
2264
+ next unless @plugin_enabled.include?(plugin_name)
2238
2265
 
2239
2266
  begin
2240
2267
  # Load the plugin file
@@ -2304,22 +2331,26 @@ def call_plugin_hook(hook_name, *args) # Call a lifecycle hook for all plugins
2304
2331
  end
2305
2332
  def plugins(*args) # Plugin management command
2306
2333
  if args.empty?
2307
- # List all plugins
2308
- if @plugins.empty?
2309
- puts "\nNo plugins loaded"
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"
2310
2339
  puts "Place .rb files in #{@plugin_dir}"
2311
2340
  return
2312
2341
  end
2313
2342
 
2314
- puts "\n Loaded Plugins:".c(@c_prompt).b
2315
- @plugins.each do |plugin|
2316
- status = @plugin_disabled.include?(plugin[:name]) ? '[disabled]'.c(196) : '[enabled]'.c(@c_path)
2317
- puts " #{plugin[:name].ljust(20)} #{status} (#{plugin[:class]})"
2318
- end
2319
-
2320
- unless @plugin_disabled.empty?
2321
- puts "\n Disabled Plugins:".c(@c_stamp)
2322
- @plugin_disabled.each { |name| puts " #{name}" }
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}"
2323
2354
  end
2324
2355
  puts
2325
2356
  elsif args[0] == 'reload'
@@ -2331,15 +2362,15 @@ def plugins(*args) # Plugin management command
2331
2362
  elsif args[0] == 'enable' && args[1]
2332
2363
  # Enable a plugin
2333
2364
  plugin_name = args[1]
2334
- @plugin_disabled.delete(plugin_name)
2365
+ unless @plugin_enabled.include?(plugin_name)
2366
+ @plugin_enabled << plugin_name
2367
+ end
2335
2368
  puts "Plugin '#{plugin_name}' enabled. Use :plugins reload to load it"
2336
2369
  rshrc
2337
2370
  elsif args[0] == 'disable' && args[1]
2338
2371
  # Disable a plugin
2339
2372
  plugin_name = args[1]
2340
- unless @plugin_disabled.include?(plugin_name)
2341
- @plugin_disabled << plugin_name
2342
- end
2373
+ @plugin_enabled.delete(plugin_name)
2343
2374
  @plugins.reject! { |p| p[:name] == plugin_name }
2344
2375
  puts "Plugin '#{plugin_name}' disabled"
2345
2376
  rshrc
@@ -2365,6 +2396,51 @@ def plugins(*args) # Plugin management command
2365
2396
  else
2366
2397
  puts "Plugin '#{plugin_name}' not found"
2367
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
2368
2444
  else
2369
2445
  puts "Usage:"
2370
2446
  puts " :plugins List all plugins"
@@ -2372,6 +2448,7 @@ def plugins(*args) # Plugin management command
2372
2448
  puts " :plugins enable NAME Enable a plugin"
2373
2449
  puts " :plugins disable NAME Disable a plugin"
2374
2450
  puts " :plugins info NAME Show plugin details"
2451
+ puts " :plugins help NAME Show plugin help/usage"
2375
2452
  end
2376
2453
  end
2377
2454
  def validate_command(cmd) # Syntax validation before execution
@@ -2982,7 +3059,7 @@ def load_rshrc_safe
2982
3059
  @session_autosave = 0 unless @session_autosave.is_a?(Integer)
2983
3060
  @auto_correct = false unless [@auto_correct].any? { |v| v == true || v == false }
2984
3061
  @slow_command_threshold = 0 unless @slow_command_threshold.is_a?(Integer)
2985
- @plugin_disabled = [] unless @plugin_disabled.is_a?(Array)
3062
+ @plugin_enabled = [] unless @plugin_enabled.is_a?(Array)
2986
3063
  @plugins = [] unless @plugins.is_a?(Array)
2987
3064
  @plugin_commands = {} unless @plugin_commands.is_a?(Hash)
2988
3065
  @validation_rules = [] unless @validation_rules.is_a?(Array)
@@ -3137,7 +3214,7 @@ def load_defaults
3137
3214
  @session_autosave ||= 0
3138
3215
  @auto_correct ||= false
3139
3216
  @slow_command_threshold ||= 0
3140
- @plugin_disabled ||= []
3217
+ @plugin_enabled ||= []
3141
3218
  @plugins ||= []
3142
3219
  @plugin_commands ||= {}
3143
3220
  @validation_rules ||= []
@@ -3211,6 +3288,8 @@ begin # Load .rshrc and populate @history
3211
3288
  exit
3212
3289
  end
3213
3290
  firstrun unless File.exist?(Dir.home+'/.rshrc') # Initial loading - to get history
3291
+ # Initialize @ls_colors with defaults so get_dir_color() works in .rshrc prompt
3292
+ @ls_colors = { 'di' => 33, 'ex' => 2, 'ln' => 14, 'fi' => 7 }
3214
3293
  load_rshrc_safe
3215
3294
  migrate_to_split_config # Migrate from old format if needed (v3.4.3+)
3216
3295
  # Load login shell files if rsh is running as login shell
@@ -3235,6 +3314,7 @@ begin # Load .rshrc and populate @history
3235
3314
  ENV["TERM"] = "rxvt-unicode-256color"
3236
3315
  ENV["PATH"] ? ENV["PATH"] += ":" : ENV["PATH"] = ""
3237
3316
  ENV["PATH"] += "/home/#{@user}/bin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
3317
+ # Load actual LS_COLORS from file (now that @lscolors is set from .rshrc)
3238
3318
  if @lscolors and File.exist?(@lscolors)
3239
3319
  ls = File.read(@lscolors)
3240
3320
  ls.sub!(/export.*/, '')
@@ -3273,9 +3353,10 @@ loop do
3273
3353
  load_plugins
3274
3354
  @plugins_loaded = true
3275
3355
  end
3276
- # Append plugin prompt additions (after plugins loaded)
3356
+ # Build display prompt with plugin additions (don't modify @prompt)
3277
3357
  plugin_prompts = call_plugin_hook(:on_prompt)
3278
- @prompt += plugin_prompts.join if plugin_prompts.any?
3358
+ @display_prompt = @prompt.dup
3359
+ @display_prompt += plugin_prompts.join if plugin_prompts.any?
3279
3360
  # Auto-save session if enabled and interval elapsed
3280
3361
  if @session_autosave && @session_autosave > 0
3281
3362
  current_time = Time.now.to_i
@@ -3322,7 +3403,7 @@ loop do
3322
3403
  # Move cursor to end of line and print the full command before clearing
3323
3404
  @c.row(@row0)
3324
3405
  @c.clear_line
3325
- print @prompt + cmd_check(@cmd)
3406
+ print @display_prompt + cmd_check(@cmd)
3326
3407
  print "\n"; @c.clear_screen_down
3327
3408
  if @cmd == "r" # Integration with rtfm (https://github.com/isene/RTFM)
3328
3409
  t = Time.now
metadata CHANGED
@@ -1,21 +1,20 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-shell
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.4.4
4
+ version: 3.4.6
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-10-25 00:00:00.000000000 Z
11
+ 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.0: COMPLETION LEARNING - Shell learns which TAB completions you use most and
16
- intelligently ranks them higher. Context-aware learning per command. :completion_stats
17
- shows patterns. Persistent across sessions. Plus all v3.3 features: quote-less syntax,
18
- parametrized nicks, Ctrl-G editing, validation rules, shell scripts!'
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