ruby-shell 3.4.0 → 3.4.2

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 +94 -91
  3. data/bin/rsh +70 -8
  4. metadata +1 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5b86a585bea4b0c41a27de5679365d3ddce7b7a33481927cbf0de9bd89dcf27b
4
- data.tar.gz: f346b777aa2863b06ef610a8e9c13325711058452f8986e5d4565aecb8ae21d4
3
+ metadata.gz: 77bd4af1f0ec04f25fb48fc4bde5b1b18a50b02e046698c9cb660dafa6caa59c
4
+ data.tar.gz: 807220a097167fb1338c52ce8868d3fcf0a022d8cec7963cf23654daafd72e8d
5
5
  SHA512:
6
- metadata.gz: 181420e5e35ca971f44affd54dbf9cadf1b13d658627d5cf2aa062b1d17678ed8521911b1208a5f3072eaa06a6e8840db1317e5a15d1e1d2de672fbaf66552cb
7
- data.tar.gz: '084bb4b4227110ea0a2230e8455527ed8259fdcf8285ae6fd3dac571315f662c6e0243ee66caad5dc0bacb8157f82c47cf56a1213900ed3fe4f14a15fb4bcefa'
6
+ metadata.gz: 6e84bedcc95db51816bcfd6c5ed560914898a3e661767bcd810c6dab22d8aec7fffb8904877a606e3cf9cdc1129307fd50c1db848f429165aa935d8a57f5b46d
7
+ data.tar.gz: 0d939b9668cd56581466acf659cc99b75652522ee5f05d5d6fdcf7eb70930da766a818dcbeef6d81597ce24e4dc9f720a6364bc5792ccad05231ba216e9fdcb2
data/README.md CHANGED
@@ -19,97 +19,100 @@ Or simply `gem install ruby-shell`.
19
19
 
20
20
  # Features
21
21
 
22
- ## Core Shell Features
23
- * Aliases (called nicks in rsh) - both for commands and general nicks
24
- * Syntax highlighting, matching nicks, system commands and valid dirs/files
25
- * Tab completions for nicks, system commands, command switches and dirs/files
26
- * Tab completion presents matches in a list to pick from
27
- * When you start to write a command, rsh will suggest the first match in the history and present that in "toned down" letters - press the arrow right key to accept the suggestion.
28
- * Writing a partial command and pressing `UP` will search history for matches. Go down/up in the list and press `TAB` or `ENTER` to accept, `Ctrl-g` or `Ctrl-c` to discard
29
- * History with editing, search and repeat a history command (with `!`)
30
- * Config file (.rshrc) updates on exit (with Ctrl-d) or not (with Ctrl-e)
31
- * Set of simple rsh specific commands like nick, nick?, history and rmhistory
32
- * rsh specific commands and full set of Ruby commands available via :<command>
33
- * All colors are themeable in .rshrc (see github link for possibilities)
34
- * Copy current command line to primary selection (paste w/middle button) with `Ctrl-y`
35
-
36
- ## NEW in v3.4.0 - Intelligent Completion Learning ⭐⭐
37
- * **Smart TAB Completion**: Shell learns which completions you use most and ranks them higher
38
- * **Context-Aware Learning**: Separate learning for git, ls, docker, and all other commands
39
- * **Completion Statistics**: `:completion_stats` shows learned patterns with visual charts
40
- * **Manageable**: `:config completion_learning on|off`, `:completion_reset` to clear data
41
- * **Persistent**: Learning data saves to .rshrc, works across sessions
42
- * **Works Everywhere**: Commands, switches, subcommands - all get smarter over time
43
-
44
- ## v3.3.0 - Quote-less Syntax, Parametrized Nicks & More ⭐⭐⭐
45
- * **No More Quotes**: Simplified syntax - `:nick la = ls -la` instead of `:nick "la = ls -la"`
46
- * **Parametrized Nicks**: `:nick gp = git push origin {{branch}}` then use `gp branch=main`
47
- * **Ctrl-G Multi-line Edit**: Press Ctrl-G to edit command in $EDITOR for complex scripts
48
- * **Custom Validation Rules**: `:validate rm -rf / = block` prevents dangerous commands
49
- * **Shell Script Support**: for/while/if loops work with full bash syntax
50
- * **Cleaner Commands**: `:config auto_correct on`, `:bm work /tmp #dev`, `:theme dracula`
51
- * **Simplified Architecture**: Removed :template (merged into :nick for simplicity)
52
- * **Backward Compatible**: Old quote syntax still works for existing .rshrc files
53
- * **Better UX**: Less typing, more powerful, feels more natural
54
-
55
- ## v3.2.0 - Plugin System & Productivity ⭐⭐⭐
56
- * **Plugin Architecture**: Extensible plugin system with lifecycle hooks and extension points
57
- * **Lifecycle Hooks**: on_startup, on_command_before, on_command_after, on_prompt
58
- * **Extension Points**: add_completions (TAB completion), add_commands (custom commands)
59
- * **Plugin Management**: `:plugins` list/reload/enable/disable/info commands
60
- * **Auto-loading**: Plugins in `~/.rsh/plugins/` load automatically on startup
61
- * **Safe Execution**: Isolated plugin execution with error handling, no shell crashes
62
- * **Example Plugins**: git_prompt (branch in prompt), command_logger (audit log), kubectl_completion (k8s shortcuts)
63
- * **Auto-correct Typos**: `:config "auto_correct", "on"` with user confirmation (Y/n) before applying
64
- * **Command Timing Alerts**: `:config "slow_command_threshold", "5"` warns on commands > 5 seconds
65
- * **Inline Calculator**: `:calc 2 + 2`, `:calc "Math::PI"` - full Ruby Math library support
66
- * **Enhanced History**: `!!` (last), `!-2` (2nd to last), `!5:7` (chain commands 5-7)
67
- * **Stats Visualization**: `:stats --graph` for colorful ASCII bar charts with intensity colors
68
- * **Documentation**: Complete PLUGIN_GUIDE.md with API reference and examples
69
-
70
- ## v3.1.0 - Quick Wins & Polish
71
- * **Multiple Named Sessions**: Save/load different sessions - `:save_session "project"`, `:load_session "project"`
72
- * **Stats Export**: Export analytics to CSV/JSON - `:stats --csv` or `:stats --json`
73
- * **Session Auto-save**: Set `@session_autosave = 300` in .rshrc for automatic 5-minute saves
74
- * **Bookmark Import/Export**: Share bookmarks - `:bm --export bookmarks.json`, `:bm --import bookmarks.json`
75
- * **Bookmark Statistics**: See usage patterns - `:bm --stats` shows tag distribution and analytics
76
- * **Color Themes**: 6 preset themes - `:theme solarized|dracula|gruvbox|nord|monokai|default`
77
- * **Config Management**: `:config` shows/sets history_dedup, session_autosave, completion settings
78
- * **Environment Variables**: `:env` lists/sets/exports environment variables
79
- * **Bookmark TAB Completion**: Bookmarks appear in TAB completion alongside commands
80
- * **List Sessions**: `:list_sessions` shows all saved sessions with timestamps and paths
81
-
82
- ## v3.0.0 - Major Feature Release ⭐⭐⭐
83
- * **Persistent Ruby Functions**: defun functions now save to .rshrc and persist across sessions
84
- * **Smart Command Suggestions**: Typo detection with "Did you mean...?" suggestions using Levenshtein distance
85
- * **Command Analytics**: New `:stats` command shows usage statistics, performance metrics, and most-used commands
86
- * **Switch Completion Caching**: Command switches from --help are cached for instant completion
87
- * **Enhanced Bookmarks**: Bookmark directories with tags - `:bookmark name path #tag1,tag2`
88
- * **Session Management**: Save and restore entire shell sessions with `:save_session` and `:load_session`
89
- * **Syntax Validation**: Pre-execution warnings for common mistakes, dangerous commands, and typos
90
- * **Option Value Completion**: TAB completion for option values like `--format=<TAB>` → json, yaml, xml
91
- * **Command Performance Tracking**: Automatically tracks execution time and shows slowest commands
92
-
93
- ## AI Integration (v2.9.0) ⭐
94
- * **AI-powered command assistance**: Get help with commands using natural language
95
- * **`@ <question>`**: Ask questions and get AI-generated text responses
96
- * **`@@ <request>`**: Describe what you want to do, and AI suggests the command
97
- * **Smart command suggestion**: AI suggestions appear directly on the command line, ready to execute
98
- * **Local AI support**: Works with Ollama for privacy-focused local AI
99
- * **External AI support**: Configure OpenAI or other providers via `.rshrc`
100
- * **Syntax highlighting**: @ and @@ commands are highlighted in blue
101
-
102
- ## Enhanced Help System & Nick Management (v2.8.0)
103
- * **Two-column help display**: Compact, organized help that fits on one screen
104
- * **New `:info` command**: Shows introduction and feature overview
105
- * **`:nickdel` and `:gnickdel`**: Intuitive commands to delete nicks and gnicks
106
- * **Improved help organization**: Quick reference for keyboard shortcuts, commands, and features
107
-
108
- ## Ruby Functions (v2.7.0)
22
+ ## Key Features
23
+
24
+ ### Aliases (Nicks)
25
+ **rsh uses "nicks" for aliases** - both simple command shortcuts and powerful parametrized templates:
26
+
27
+ ```bash
28
+ # Simple aliases
29
+ :nick la = ls -la
30
+ :nick gs = git status
31
+
32
+ # Parametrized nicks (templates with {{placeholders}})
33
+ :nick gp = git push origin {{branch}}
34
+ gp branch=main # Executes: git push origin main
35
+
36
+ :nick deploy = ssh {{user}}@{{host}} 'systemctl restart {{app}}'
37
+ deploy user=admin host=prod app=api
38
+
39
+ # List and manage
40
+ :nick # List all nicks
41
+ :nick -la # Delete a nick
42
+ ```
43
+
44
+ ### Intelligence & Learning
45
+ * **Completion Learning**: Shell learns which TAB completions you use and ranks them higher
46
+ * **Smart Suggestions**: "Did you mean...?" for typos
47
+ * **Auto-correct**: Optional auto-fix with confirmation
48
+ * **Command Analytics**: `:stats` shows usage patterns and performance
49
+
50
+ ### Productivity
51
+ * **Command Recording**: `:record start name` run commands → `:record stop` → `:replay name`
52
+ * **Sessions**: Save/load entire shell state with bookmarks, history, and functions
53
+ * **Bookmarks**: Tag directories and jump instantly
54
+ * **Multi-line Editing**: Press Ctrl-G to edit in $EDITOR
55
+ * **Shell Scripts**: Full bash support for for/while/if loops
56
+
57
+ ### Extensibility
58
+ * **Plugin System**: Add custom commands, completions, and hooks
59
+ * **Ruby Functions**: Define callable functions - `:defun hello(name) = puts "Hello, #{name}!"`
60
+ * **Validation Rules**: `:validate rm -rf / = block` prevents dangerous commands
61
+ * **6 Color Themes**: solarized, dracula, gruvbox, nord, monokai, default
62
+
63
+ ### Integrations
64
+ * **AI Support**: @ for questions, @@ for command suggestions (Ollama or OpenAI)
65
+ * **RTFM**: Launch file manager with `r`
66
+ * **fzf**: Fuzzy finder with `f`
67
+ * **XRPN**: Calculator with `= expression`
68
+
69
+ ### Tab Completion
70
+ * Smart context-aware completion for git, apt, docker, systemctl, cargo, npm, gem
71
+ * Command switches from --help
72
+ * Option values (--format=json, --level=debug)
73
+ * Learns your patterns and adapts
74
+
75
+ ### Core Shell
76
+ * Syntax highlighting for nicks, commands, paths, bookmarks
77
+ * History with search, edit, and repeat (!, !!, !-2, !5:7)
78
+ * Job control (background jobs, suspend, resume)
79
+ * Config file (.rshrc) updates on exit
80
+ * All colors themeable
81
+
82
+ ---
83
+
84
+ ## Quick Start
85
+
86
+ ```bash
87
+ # Install
88
+ gem install ruby-shell
89
+
90
+ # Run
91
+ rsh
92
+
93
+ # Create an alias
94
+ :nick ll = ls -l
95
+ ll
96
+
97
+ # Create parametrized alias
98
+ :nick gp = git push origin {{branch}}
99
+ gp branch=main
100
+
101
+ # Get help
102
+ :help
103
+ :info
104
+
105
+ # See version and changelog
106
+ :version
107
+ ```
108
+
109
+ ---
110
+
111
+ ## Latest Features (v3.4)
109
112
  * **Define Ruby functions as shell commands**: `:defun 'weather(*args) = system("curl -s wttr.in/#{args[0] || \"oslo\"}")'`
110
113
  * **Call like any shell command**: `weather london`
111
114
  * **Full Ruby power**: Access to Ruby stdlib, file operations, JSON parsing, web requests, etc.
112
- * **Function management**: `:defun?` to list, `:defun '-name'` to remove
115
+ * **Function management**: `:defun` to list, `:defun -name` to remove
113
116
  * **Syntax highlighting**: Ruby functions highlighted in bold
114
117
 
115
118
  ## Advanced Shell Features
@@ -135,7 +138,7 @@ Special commands:
135
138
  * `:history` will list the command history, while `:rmhistory` will delete the history
136
139
  * `:jobs` will list background jobs, `:fg [job_id]` brings jobs to foreground, `:bg [job_id]` resumes stopped jobs
137
140
  * `:defun func(args) = code` defines Ruby functions callable as shell commands (persistent!)
138
- * `:defun?` lists all user-defined functions, `:defun -func` removes functions
141
+ * `:defun` lists all user-defined functions, `:defun -func` removes functions
139
142
  * `:stats` shows command execution statistics, `:stats --graph` for visual charts, `:stats --clear` to reset
140
143
  * `:bm name` or `:bookmark name` bookmark current directory, `:bm name path #tags` with tags
141
144
  * `:bm` lists all bookmarks, just type bookmark name to jump (e.g., `work`)
@@ -306,8 +309,8 @@ weather london
306
309
 
307
310
  ### Function Management
308
311
  ```bash
309
- :defun? # List all defined functions
310
- :defun '-myls' # Remove a function
312
+ :defun # List all defined functions
313
+ :defun -myls # Remove a function
311
314
  ```
312
315
 
313
316
  Ruby functions have access to:
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.0" # Completion learning: Shell learns your patterns and boosts frequently-used completions
11
+ @version = "3.4.2" # Improved defun syntax: :defun lists, :defun -name removes, enhanced :help
12
12
 
13
13
  # MODULES, CLASSES AND EXTENSIONS
14
14
  class String # Add coloring to strings (with escaping for Readline)
@@ -155,6 +155,8 @@ begin # Initialization
155
155
  @completion_learning = true # Enable completion learning (default: on)
156
156
  @recording = {active: false, name: nil, commands: []} # Command recording state
157
157
  @recordings = {} # Saved recordings
158
+ @command_cache = {} # Cache for expensive shell command outputs
159
+ @last_prompt_dir = nil # Track directory for .rshrc reload optimization
158
160
  # Built-in rsh commands are called with : prefix, so no need for separate tracking
159
161
  Dir.mkdir(Dir.home + '/.rsh') unless Dir.exist?(Dir.home + '/.rsh')
160
162
  Dir.mkdir(@session_dir) unless Dir.exist?(@session_dir)
@@ -1157,6 +1159,15 @@ def rshrc # Write updates to .rshrc
1157
1159
  conf += "@completion_learning = #{@completion_learning}\n" unless @completion_learning
1158
1160
  conf.sub!(/^@recordings.*(\n|$)/, "")
1159
1161
  conf += "@recordings = #{@recordings}\n" unless @recordings.empty?
1162
+ # Persist executable cache for faster startup
1163
+ if @exe && @exe.length > 100
1164
+ conf.sub!(/^@exe_cache.*(\n|$)/, "")
1165
+ conf += "@exe_cache = #{@exe.inspect}\n"
1166
+ conf.sub!(/^@exe_cache_path.*(\n|$)/, "")
1167
+ conf += "@exe_cache_path = #{ENV['PATH'].inspect}\n"
1168
+ conf.sub!(/^@exe_cache_time.*(\n|$)/, "")
1169
+ conf += "@exe_cache_time = #{Time.now.to_i}\n"
1170
+ end
1160
1171
  # Only write @cmd_completions if user has customized it
1161
1172
  unless conf =~ /^@cmd_completions\s*=/
1162
1173
  # Don't write default completions to avoid cluttering .rshrc
@@ -1199,10 +1210,13 @@ def help
1199
1210
  col1 << "Shift-TAB History search"
1200
1211
  col1 << ""
1201
1212
  col1 << "CORE COMMANDS:".c(@c_prompt).b
1202
- col1 << ":nick a = b Alias"
1203
- col1 << ":nick gp={{br}} Parametrized"
1213
+ col1 << ":nick a = b Create alias"
1214
+ col1 << ":nick List all"
1215
+ col1 << ":nick -a Delete"
1216
+ col1 << ":defun f()=x Create function"
1217
+ col1 << ":defun List all"
1218
+ col1 << ":defun -f Delete"
1204
1219
  col1 << ":bm name Bookmark"
1205
- col1 << ":defun f()=x Function"
1206
1220
  col1 << ":stats Analytics"
1207
1221
  col1 << ":validate p=a Safety rules"
1208
1222
  col1 << ":calc expr Calculator"
@@ -1404,10 +1418,23 @@ def bg(job_id = nil)
1404
1418
  puts "Job #{job_id} no longer exists"
1405
1419
  end
1406
1420
  end
1407
- def defun(func_def) # Define a Ruby function like: `:defun "myls(*args) = Dir.glob('*').each {|f| puts f}"`
1408
- if func_def.match(/^\s*-/)
1421
+ def defun(func_def = nil) # Define a Ruby function like: `:defun myls(*args) = Dir.glob('*').each {|f| puts f}`
1422
+ if func_def.nil? || func_def.strip.empty?
1423
+ # List all defined functions
1424
+ puts "User-defined Ruby functions:"
1425
+ all_methods = singleton_class.instance_methods(false)
1426
+ excluded = [:defun, :defun?, :execute_conditional, :expand_braces]
1427
+ methods = all_methods - excluded
1428
+ if methods.empty?
1429
+ puts " (none defined)"
1430
+ else
1431
+ methods.each do |method|
1432
+ puts " #{method}"
1433
+ end
1434
+ end
1435
+ elsif func_def.match(/^\s*-/)
1409
1436
  # Remove function
1410
- func_name = func_def.sub(/^\s*-/, '')
1437
+ func_name = func_def.sub(/^\s*-/, '').strip
1411
1438
  if self.respond_to?(func_name)
1412
1439
  singleton_class.remove_method(func_name.to_sym)
1413
1440
  @defuns.delete(func_name)
@@ -2862,10 +2889,40 @@ def load_defaults
2862
2889
  puts "Loaded with default configuration."
2863
2890
  end
2864
2891
 
2892
+ def cached_command(cmd, ttl = 300) # Cache expensive command outputs
2893
+ key = cmd.hash
2894
+ now = Time.now.to_i
2895
+
2896
+ if @command_cache[key] && (now - @command_cache[key][:time]) < ttl
2897
+ return @command_cache[key][:result]
2898
+ end
2899
+
2900
+ result = `#{cmd}`.chomp
2901
+ @command_cache[key] = {result: result, time: now}
2902
+
2903
+ # Limit cache size
2904
+ if @command_cache.length > 50
2905
+ # Remove oldest entry
2906
+ oldest = @command_cache.min_by { |k, v| v[:time] }
2907
+ @command_cache.delete(oldest[0])
2908
+ end
2909
+
2910
+ result
2911
+ end
2865
2912
  def cache_executables
2866
2913
  current_path = ENV["PATH"]
2867
2914
  current_time = Time.now.to_i
2868
2915
 
2916
+ # Use persisted cache if valid (from .rshrc)
2917
+ if @exe_cache && @exe_cache_path == current_path
2918
+ cache_age = current_time - (@exe_cache_time || 0)
2919
+ if cache_age < 3600 # 1 hour
2920
+ @exe = @exe_cache
2921
+ @exe_cache_paths = current_path
2922
+ return
2923
+ end
2924
+ end
2925
+
2869
2926
  # Only rebuild cache if PATH changed or cache is older than 60 seconds
2870
2927
  return if @exe_cache_paths == current_path && (current_time - @exe_cache_time) < 60
2871
2928
 
@@ -2940,7 +2997,12 @@ loop do
2940
2997
  begin
2941
2998
  @user = Etc.getpwuid(Process.euid).name # For use in @prompt
2942
2999
  @node = Etc.uname[:nodename] # For use in @prompt
2943
- h = @history; f = @cmd_frequency; s = @cmd_stats; b = @bookmarks; d = @defuns; load_rshrc_safe; @history = h; @cmd_frequency = f; @cmd_stats = s; @bookmarks = b; @defuns = d # reload prompt but preserve runtime data
3000
+ # Only reload .rshrc if directory changed (optimization)
3001
+ current_dir = Dir.pwd
3002
+ if @last_prompt_dir != current_dir
3003
+ h = @history; f = @cmd_frequency; s = @cmd_stats; b = @bookmarks; d = @defuns; load_rshrc_safe; @history = h; @cmd_frequency = f; @cmd_stats = s; @bookmarks = b; @defuns = d
3004
+ @last_prompt_dir = current_dir
3005
+ end
2944
3006
  @prompt.gsub!(/#{Dir.home}/, '~') # Simplify path in prompt
2945
3007
  system("printf \"\033]0;rsh: #{Dir.pwd}\007\"") # Set Window title to path
2946
3008
  @history[0] = "" unless @history[0]
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.0
4
+ version: 3.4.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Geir Isene