ruby-shell 3.4.6 → 3.4.8

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 (4) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -0
  3. data/bin/rsh +87 -66
  4. metadata +4 -5
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8180bf48f336b9667d34fc01d5df5ddf7a3412ff5f35cfc443d10846a81f6686
4
- data.tar.gz: acd063a28be3a5bfe7ccb9ec6623ddb7e061deba44806725c1b76781fcf45acb
3
+ metadata.gz: 35dd4b1b6792ae0a66b0da2efd24bf78af5f2ba268fd933bd0af2b43e7fb0b23
4
+ data.tar.gz: 6c1f6026a8870e178788190f702de82f3845364ebaa4e42a9952a8f9b61d9d0e
5
5
  SHA512:
6
- metadata.gz: 05d07658f8356edad6da19da615170e2423785fc4a3f9074cfb5b9ef3a7f602b3f109172cb6ba799f9b2bc0bbc7363a9c0ff29b4d9d27cfebb05b2883156aad6
7
- data.tar.gz: 6e1d7c8d6c16c0ce6f2d7cf67a5229b3a31f3e0d096438fd59877c3647dd5f8b1530ff0b0c46cd95bd377d25663e79e7f0cbef8dc8599f61cb281a395c54bc94
6
+ metadata.gz: e9a950baff3af17ae641fe67a9782b5888c4e1ce93a94354558ec39adecbbe9254710a5719a000254c326eb71d9b91b098edea77dcdedcf773baff269448fa5c
7
+ data.tar.gz: a84ce4e143a9237549affdb6befd894adf032737ae949edd4e326fe8858a127158f976760bfb43e41b6e51f8b58cf62e0271ebfec1cfa41e6b8f67763ecbe957
data/README.md CHANGED
@@ -136,6 +136,7 @@ Special commands:
136
136
  * `:nick` lists all command nicks, `:gnick` lists general nicks
137
137
  * `:nick -name` delete a command nick, `:gnick -name` delete a general nick
138
138
  * `:history` will list the command history, while `:rmhistory` will delete the history
139
+ * `:rehash` rebuilds the executable cache (useful after installing new commands)
139
140
  * `:jobs` will list background jobs, `:fg [job_id]` brings jobs to foreground, `:bg [job_id]` resumes stopped jobs
140
141
  * `:defun func(args) = code` defines Ruby functions callable as shell commands (persistent!)
141
142
  * `:defun` lists all user-defined functions, `:defun -func` removes functions
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.6" # Plugin help system, 4 new plugins, plugins disabled by default, Ctrl-W fix
11
+ @version = "3.4.8" # Code refactoring: DRY helpers, nick/gnick feedback, bug fixes
12
12
 
13
13
  # MODULES, CLASSES AND EXTENSIONS
14
14
  class String # Add coloring to strings (with escaping for Readline)
@@ -1077,6 +1077,16 @@ def suggest_command(cmd) # Smart command suggestions for typos
1077
1077
  candidates.sort_by! { |c| levenshtein_distance(cmd, c) }
1078
1078
  candidates.first(3)
1079
1079
  end
1080
+ def ensure_type(var_name, type, default) # Helper to ensure instance variable has correct type
1081
+ var = instance_variable_get(var_name)
1082
+ instance_variable_set(var_name, default) unless var.is_a?(type)
1083
+ end
1084
+ def persist_var(conf, var_name, value, condition = true) # Helper to persist variable to config
1085
+ return conf unless condition
1086
+ conf.sub!(/^#{Regexp.escape(var_name)}.*(\n|$)/, "")
1087
+ conf += "#{var_name} = #{value.inspect}\n"
1088
+ conf
1089
+ end
1080
1090
  def hist_clean # Clean up @history
1081
1091
  @history.compact!
1082
1092
  @history.delete("")
@@ -1378,31 +1388,19 @@ def rshrc # Write user configuration to .rshrc (portable between machines)
1378
1388
  conf = ""
1379
1389
  end
1380
1390
 
1381
- # Only update user-editable items in .rshrc
1382
- conf.sub!(/^@nick.*(\n|$)/, "")
1383
- conf += "@nick = #{@nick}\n"
1384
- conf.sub!(/^@gnick.*(\n|$)/, "")
1385
- conf += "@gnick = #{@gnick}\n"
1386
- conf.sub!(/^@bookmarks.*(\n|$)/, "")
1387
- conf += "@bookmarks = #{@bookmarks}\n" unless @bookmarks.empty?
1388
- conf.sub!(/^@defuns.*(\n|$)/, "")
1389
- conf += "@defuns = #{@defuns}\n" unless @defuns.empty?
1390
- conf.sub!(/^@history_dedup.*(\n|$)/, "")
1391
- conf += "@history_dedup = '#{@history_dedup}'\n" if @history_dedup && @history_dedup != 'smart'
1392
- conf.sub!(/^@session_autosave.*(\n|$)/, "")
1393
- conf += "@session_autosave = #{@session_autosave}\n" if @session_autosave && @session_autosave > 0
1394
- conf.sub!(/^@auto_correct.*(\n|$)/, "")
1395
- conf += "@auto_correct = #{@auto_correct}\n" if @auto_correct
1396
- conf.sub!(/^@slow_command_threshold.*(\n|$)/, "")
1397
- conf += "@slow_command_threshold = #{@slow_command_threshold}\n" if @slow_command_threshold && @slow_command_threshold > 0
1398
- conf.sub!(/^@completion_learning.*(\n|$)/, "")
1399
- conf += "@completion_learning = #{@completion_learning}\n" unless @completion_learning
1400
- conf.sub!(/^@completion_show_metadata.*(\n|$)/, "")
1401
- conf += "@completion_show_metadata = #{@completion_show_metadata}\n" if @completion_show_metadata
1402
- conf.sub!(/^@plugin_enabled.*(\n|$)/, "")
1403
- conf += "@plugin_enabled = #{@plugin_enabled}\n" unless @plugin_enabled.empty?
1404
- conf.sub!(/^@validation_rules.*(\n|$)/, "")
1405
- conf += "@validation_rules = #{@validation_rules}\n" unless @validation_rules.empty?
1391
+ # Persist user-editable configuration using helper
1392
+ conf = persist_var(conf, '@nick', @nick)
1393
+ conf = persist_var(conf, '@gnick', @gnick)
1394
+ conf = persist_var(conf, '@bookmarks', @bookmarks, !@bookmarks.empty?)
1395
+ conf = persist_var(conf, '@defuns', @defuns, !@defuns.empty?)
1396
+ conf = persist_var(conf, '@history_dedup', @history_dedup, @history_dedup && @history_dedup != 'smart')
1397
+ conf = persist_var(conf, '@session_autosave', @session_autosave, @session_autosave && @session_autosave > 0)
1398
+ conf = persist_var(conf, '@auto_correct', @auto_correct, @auto_correct)
1399
+ conf = persist_var(conf, '@slow_command_threshold', @slow_command_threshold, @slow_command_threshold && @slow_command_threshold > 0)
1400
+ conf = persist_var(conf, '@completion_learning', @completion_learning, !@completion_learning)
1401
+ conf = persist_var(conf, '@completion_show_metadata', @completion_show_metadata, @completion_show_metadata)
1402
+ conf = persist_var(conf, '@plugin_disabled', @plugin_disabled, !@plugin_disabled.empty?)
1403
+ conf = persist_var(conf, '@validation_rules', @validation_rules, !@validation_rules.empty?)
1406
1404
 
1407
1405
  File.write(Dir.home+'/.rshrc', conf)
1408
1406
  rshstate # Also save runtime state
@@ -1562,6 +1560,8 @@ def help
1562
1560
  col3 << ":help This help"
1563
1561
  col3 << ":info About rsh"
1564
1562
  col3 << ":version Version info"
1563
+ col3 << ":history Show history"
1564
+ col3 << ":rehash Rebuild cache"
1565
1565
 
1566
1566
  # Pad columns to same length
1567
1567
  max_lines = [col1.length, col2.length, col3.length].max
@@ -1602,6 +1602,14 @@ def rmhistory # Delete history
1602
1602
  @history = []
1603
1603
  puts "History deleted."
1604
1604
  end
1605
+ def rehash # Force rebuild of executable cache
1606
+ @exe_cache = nil
1607
+ @exe_cache_path = nil
1608
+ @exe_cache_time = 0
1609
+ @exe_cache_paths = ""
1610
+ cache_executables
1611
+ puts "Executable cache rebuilt (#{@exe.length} commands cached)."
1612
+ end
1605
1613
  def nick(nick_str = nil) # Define a new nick like this: `:nick "ls = ls --color"`
1606
1614
  if nick_str.nil? || nick_str.empty?
1607
1615
  # List all nicks
@@ -1614,12 +1622,17 @@ def nick(nick_str = nil) # Define a new nick like this: `:nick "ls = ls --color
1614
1622
  puts
1615
1623
  elsif nick_str.match(/^\s*-/)
1616
1624
  source = nick_str.sub(/^\s*-/, '')
1617
- @nick.delete(source)
1618
- rshrc
1625
+ if @nick.delete(source)
1626
+ puts "Nick '#{source}' deleted"
1627
+ rshrc
1628
+ else
1629
+ puts "Nick '#{source}' not found"
1630
+ end
1619
1631
  else
1620
1632
  source = nick_str.sub(/ =.*/, '')
1621
1633
  target = nick_str.sub(/.*= /, '')
1622
1634
  @nick[source] = target
1635
+ puts "Nick '#{source}' → '#{target}'"
1623
1636
  rshrc
1624
1637
  end
1625
1638
  end
@@ -1635,12 +1648,17 @@ def gnick(nick_str = nil) # Define a generic/global nick to match not only comma
1635
1648
  puts
1636
1649
  elsif nick_str.match(/^\s*-/)
1637
1650
  source = nick_str.sub(/^\s*-/, '')
1638
- @gnick.delete(source)
1639
- rshrc
1651
+ if @gnick.delete(source)
1652
+ puts "Gnick '#{source}' deleted"
1653
+ rshrc
1654
+ else
1655
+ puts "Gnick '#{source}' not found"
1656
+ end
1640
1657
  else
1641
1658
  source = nick_str.sub(/ =.*/, '')
1642
1659
  target = nick_str.sub(/.*= /, '')
1643
1660
  @gnick[source] = target
1661
+ puts "Gnick '#{source}' → '#{target}'"
1644
1662
  rshrc
1645
1663
  end
1646
1664
  end
@@ -3047,26 +3065,26 @@ def load_rshrc_safe
3047
3065
  # Try to load the .rshrc file
3048
3066
  load(Dir.home+'/.rshrc')
3049
3067
 
3050
- # Validate critical variables
3051
- @history = [] unless @history.is_a?(Array)
3052
- @nick = {} unless @nick.is_a?(Hash)
3053
- @gnick = {} unless @gnick.is_a?(Hash)
3054
- @cmd_frequency = {} unless @cmd_frequency.is_a?(Hash)
3055
- @cmd_stats = {} unless @cmd_stats.is_a?(Hash)
3056
- @bookmarks = {} unless @bookmarks.is_a?(Hash)
3057
- @defuns = {} unless @defuns.is_a?(Hash)
3058
- @history_dedup = 'smart' unless @history_dedup.is_a?(String)
3059
- @session_autosave = 0 unless @session_autosave.is_a?(Integer)
3060
- @auto_correct = false unless [@auto_correct].any? { |v| v == true || v == false }
3061
- @slow_command_threshold = 0 unless @slow_command_threshold.is_a?(Integer)
3062
- @plugin_enabled = [] unless @plugin_enabled.is_a?(Array)
3063
- @plugins = [] unless @plugins.is_a?(Array)
3064
- @plugin_commands = {} unless @plugin_commands.is_a?(Hash)
3065
- @validation_rules = [] unless @validation_rules.is_a?(Array)
3066
- @completion_weights = {} unless @completion_weights.is_a?(Hash)
3068
+ # Validate critical variables using helper
3069
+ ensure_type(:@history, Array, [])
3070
+ ensure_type(:@nick, Hash, {})
3071
+ ensure_type(:@gnick, Hash, {})
3072
+ ensure_type(:@cmd_frequency, Hash, {})
3073
+ ensure_type(:@cmd_stats, Hash, {})
3074
+ ensure_type(:@bookmarks, Hash, {})
3075
+ ensure_type(:@defuns, Hash, {})
3076
+ ensure_type(:@history_dedup, String, 'smart')
3077
+ ensure_type(:@session_autosave, Integer, 0)
3078
+ ensure_type(:@slow_command_threshold, Integer, 0)
3079
+ ensure_type(:@plugin_disabled, Array, []) # FIXED: was @plugin_enabled
3080
+ ensure_type(:@plugins, Array, [])
3081
+ ensure_type(:@plugin_commands, Hash, {})
3082
+ ensure_type(:@validation_rules, Array, [])
3083
+ ensure_type(:@completion_weights, Hash, {})
3084
+ ensure_type(:@recording, Hash, {active: false, name: nil, commands: []})
3085
+ ensure_type(:@recordings, Hash, {})
3086
+ @auto_correct = false unless [true, false].include?(@auto_correct)
3067
3087
  @completion_learning = true if @completion_learning.nil?
3068
- @recording = {active: false, name: nil, commands: []} unless @recording.is_a?(Hash)
3069
- @recordings = {} unless @recordings.is_a?(Hash)
3070
3088
 
3071
3089
  # Restore defuns from .rshrc
3072
3090
  if @defuns && !@defuns.empty?
@@ -3197,31 +3215,34 @@ def auto_heal_rshrc
3197
3215
  end
3198
3216
 
3199
3217
  def load_defaults
3200
- @history ||= []
3201
- @nick ||= {"ls" => "ls --color -F"}
3202
- @gnick ||= {}
3218
+ # Use ensure_type for consistency
3219
+ ensure_type(:@history, Array, [])
3220
+ ensure_type(:@nick, Hash, {"ls" => "ls --color -F"})
3221
+ ensure_type(:@gnick, Hash, {})
3222
+ ensure_type(:@cmd_frequency, Hash, {})
3223
+ ensure_type(:@cmd_stats, Hash, {})
3224
+ ensure_type(:@bookmarks, Hash, {})
3225
+ ensure_type(:@defuns, Hash, {})
3226
+ ensure_type(:@switch_cache, Hash, {})
3227
+ ensure_type(:@switch_cache_time, Hash, {})
3228
+ ensure_type(:@plugin_disabled, Array, []) # FIXED: was @plugin_enabled
3229
+ ensure_type(:@plugins, Array, [])
3230
+ ensure_type(:@plugin_commands, Hash, {})
3231
+ ensure_type(:@validation_rules, Array, [])
3232
+ ensure_type(:@completion_weights, Hash, {})
3233
+ ensure_type(:@recording, Hash, {active: false, name: nil, commands: []})
3234
+ ensure_type(:@recordings, Hash, {})
3235
+
3203
3236
  @completion_limit ||= 10
3204
3237
  @completion_case_sensitive ||= false
3205
3238
  @completion_show_descriptions ||= false
3206
3239
  @completion_fuzzy ||= true
3207
- @cmd_frequency ||= {}
3208
- @cmd_stats ||= {}
3209
- @bookmarks ||= {}
3210
- @defuns ||= {}
3211
- @switch_cache ||= {}
3212
- @switch_cache_time ||= {}
3213
3240
  @history_dedup ||= 'smart'
3214
3241
  @session_autosave ||= 0
3215
3242
  @auto_correct ||= false
3216
3243
  @slow_command_threshold ||= 0
3217
- @plugin_enabled ||= []
3218
- @plugins ||= []
3219
- @plugin_commands ||= {}
3220
- @validation_rules ||= []
3221
- @completion_weights ||= {}
3222
3244
  @completion_learning = true if @completion_learning.nil?
3223
- @recording ||= {active: false, name: nil, commands: []}
3224
- @recordings ||= {}
3245
+
3225
3246
  puts "Loaded with default configuration."
3226
3247
  end
3227
3248
 
@@ -3458,7 +3479,7 @@ loop do
3458
3479
  save_session load_session list_sessions delete_session rmsession
3459
3480
  validate completion_stats completion_reset
3460
3481
  record replay
3461
- history rmhistory jobs fg bg dirs help info version]
3482
+ history rmhistory rehash jobs fg bg dirs help info version]
3462
3483
 
3463
3484
  # Try to call as rsh method
3464
3485
  if known_commands.include?(cmd_name)
metadata CHANGED
@@ -1,20 +1,19 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-shell
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.4.6
4
+ version: 3.4.8
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-26 00:00:00.000000000 Z
11
+ date: 2025-10-29 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.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)!'
15
+ v3.4.8: Code refactoring with DRY helpers (ensure_type, persist_var), nick/gnick
16
+ feedback messages, fixed @plugin_enabled bug. Cleaner, more maintainable codebase!'
18
17
  email: g@isene.com
19
18
  executables:
20
19
  - rsh