Adds comprehensive trap support to rush shell:
- Store traps in Context (rush-expand/context.rs)
- Implement trap builtin with full functionality
- Support signal names, numbers, and special traps
Features:
- trap: list all traps
- trap -l: list signal names
- trap -p [SIGNAL]: print trap(s)
- trap COMMAND SIGNAL...: set trap
- trap - SIGNAL...: clear trap
- Normalize signal names (INT, SIGINT, 2 all work)
- Support special traps: EXIT, ERR, DEBUG, RETURN
- Support common Unix signals (HUP, INT, QUIT, TERM, etc.)
Implementation:
- Added traps HashMap to Context
- normalize_signal_name helper for signal name mapping
- builtin_trap with -l, -p flags and trap management
Adds comprehensive alias support to rush shell:
- Store aliases in Context (rush-expand/context.rs)
- Implement alias builtin to create/list aliases
- Implement unalias builtin to remove aliases
- Add alias expansion in command execution pipeline
Features:
- alias: list all aliases
- alias name=value: create/update alias
- alias name: show specific alias
- unalias name: remove alias
- unalias -a: remove all aliases
- Alias expansion happens before builtin/function/PATH lookup
- Supports aliases with arguments (alias ll='ls -la')
Implementation:
- Added aliases HashMap to Context struct
- Alias expansion in execute_command (command.rs)
- Alias expansion in execute_simple_with_redirects (pipeline.rs)
- Both code paths now check aliases before command execution
Add full glob pattern support with dedicated glob module:
Basic patterns:
- * - matches any string
- ? - matches any single character
- [abc] - character class
- [a-z] - character ranges
Advanced features:
- ** - recursive directory matching (globstar)
- src/*.rs - subdirectory patterns
- Dotfile exclusion by default (* doesn't match .hidden)
- Nullglob behavior (returns literal if no match)
Extended glob support:
- Framework for !(pattern), ?(pattern), *(pattern), etc.
- Pattern conversion and matching infrastructure
Integration:
- Created dedicated glob.rs module using globset
- Integrated into word expansion pipeline
- Glob expansion happens after variable/brace expansion
- Works with all shell features (variables, arrays, etc.)
Tested patterns:
- file?.txt, file[1-3].txt, *.rs
- src/*.rs, **/*.rs
- Proper dotfile handling
Implement statement accumulation in execute_file() to handle:
- Balanced brace tracking
- String context (ignore braces in quotes)
- Function definitions with newlines after name/parens
- name() { } with { on next line
- function name { } with { on next line
All function formats now work in script files:
- function name { body }
- function name\n{ body }
- name() { body }
- name()\n{ body }
Implement full multi-line heredoc support with all bash features:
CLI changes:
- Add heredoc.rs module for content collection
- Parse line-by-line in script mode to collect heredoc content
- Detect heredoc markers and collect until delimiter found
- Fill heredoc content into AST after collection
Parser changes:
- Fix heredoc_delimiter parsing (handle wrapper rule)
- Support both quoted and bare delimiters
Executor changes:
- Properly parse heredoc lines for variable expansion
- Use fake "echo" command to leverage existing expansion
- Handle <<EOF (expand), <<'EOF' (literal), <<-EOF (strip tabs)
Features tested and working:
✅ cat <<EOF - basic heredoc
✅ cat <<EOF with $VAR expansion
✅ cat <<'EOF' - quoted delimiter, no expansion
✅ cat <<-EOF - strip leading tabs
✅ cat <<<string - herestrings
All bash heredoc features now fully functional!
Add full support for bash-style brace expansion patterns that expand
a single word into multiple words:
List expansion:
{a,b,c} → a b c
file{1,2,3}.txt → file1.txt file2.txt file3.txt
Numeric sequences:
{1..5} → 1 2 3 4 5
{01..05} → 01 02 03 04 05 (zero-padded)
{5..1} → 5 4 3 2 1 (descending)
Character sequences:
{a..e} → a b c d e
{z..a} → z y x ... a (descending)
Nested/multiple braces:
test{1,2}.{txt,md} → test1.txt test1.md test2.txt test2.md
Implementation:
- Added BraceExpansion AST node type
- Pattern detection in literal strings during expansion
- Recursive expansion for nested braces
- Proper integration with variable/command expansion
This brings rush closer to full bash compatibility for complex
file operations and script generation tasks.
Implement fish-like error messages that provide helpful hints when
commands are not found. Uses string similarity (Levenshtein distance)
to suggest similar commands and recognizes common typos.
Features:
- "Did you mean X?" suggestions for similar commands
- Levenshtein distance algorithm to find close matches
- Common typo detection (sl→ls, gti→git, etc.)
- Hints for executable files in current directory
- Helpful messages for scripts (.sh files)
Example error messages:
$ gti status
command not found: gti
Did you mean 'git'?
Hint: Did you mean 'git'? (Common typo)
$ sl
command not found: sl
Did you mean 'ls'?
Hint: Did you mean 'ls'? (Common typo)
This significantly improves the user experience by reducing
frustration from typos and providing actionable suggestions.
Implement context-aware tab completion that provides intelligent
suggestions based on what the user is typing:
Command completion (first word):
- Searches all executables in PATH
- Includes shell built-ins (cd, pwd, exit, jobs, fg, bg, test)
- Shows all matching commands when Tab is pressed
File/directory completion (arguments):
- Completes paths relative to current directory
- Adds trailing slash for directories
- Supports both relative and absolute paths
- Works with partial paths (e.g., "src/m" → "src/main.rs")
Features:
- Sorted, deduplicated command list
- Automatic whitespace after complete command names
- Directory indicators (trailing /)
- Works seamlessly with existing REPL features
This brings rush's tab completion on par with modern shells
like fish and zsh.
Implement fish-like history-based auto-suggestions that show gray
text hints as users type. Commands persist across sessions using
file-backed history stored in the user's data directory.
Features:
- Persistent history saved to ~/.local/share/rush/history.txt
- Auto-suggestions from command history (gray text)
- Press right arrow to accept suggestions
- History searches for commands starting with current input
- 1000 command history limit
Implementation uses reedline's built-in DefaultHinter for robust
history-based suggestions and FileBackedHistory for persistence.
Complete Phase 5 job control by integrating stopped job detection and
background job monitoring into the shell. Foreground jobs stopped with
Ctrl-Z are now added to the job list, and background jobs are checked
for completion/suspension before each REPL prompt.
Changes:
- Detect stopped jobs in execute_complete_command and add to JobList
- Add build_command_string helper to construct display strings from AST
- Call check_background_jobs before each REPL prompt
- Print job notifications for stopped/completed jobs
- Export check_children from rush-job crate
Job control now fully supports:
- Background execution (&)
- Job suspension (Ctrl-Z)
- Job monitoring (SIGCHLD)
- Job builtins (jobs, fg, bg)
Add JobControlInfo to track stopped foreground processes and enable
proper SIGTSTP (Ctrl-Z) handling. When a foreground job is stopped,
the executor now returns job control metadata (PID, PGID, stopped flag)
so the shell can add it to the job list.
Changes:
- Add JobControlInfo struct with pid, pgid, and stopped fields
- Modify ExecutionResult to include optional job_control field
- Update terminal control to detect WaitStatus::Stopped
- Return job control info when process is suspended via Ctrl-Z
- Update all ExecutionResult construction sites
- Add background.rs module for spawning jobs without waiting
- Implement execute_simple_background for background commands
- Implement execute_pipeline_background for background pipelines
- Set up process groups correctly for job control
- Add jobs to JobList when executed in background
- Print job ID and PID when job starts
- Return success (0) immediately for background jobs
Background execution now works for simple commands and pipelines.
Control flow commands (if/while/for) in background not yet supported.
- Add background_marker rule to grammar to parse trailing &
- Refactor CompleteCommand from enum to struct with command and background fields
- Add CommandType enum to hold the actual command types
- Update parser to track background execution flag
- Update executor and CLI to handle new AST structure
- Add tests for background and foreground execution parsing
Note: Some existing parser tests need updating to use new AST structure
- Add JobList to execution context for managing background jobs
- Implement jobs builtin to list all jobs with their status
- Implement fg builtin to bring jobs to foreground
- Implement bg builtin to continue stopped jobs in background
- Fix grammar separator rule to properly handle single semicolons
- Add context parameter to execute_builtin for job access
Add placeholder implementations for job control builtins:
- jobs: List all background jobs
- fg: Bring job to foreground
- bg: Continue job in background
These are stubs that print 'not yet implemented'. Full implementation
requires:
- JobList integration with executor context
- Terminal control integration
- Signal handling in REPL
Foundation is complete in rush-job crate, ready for integration.
Add comprehensive job control system with:
Job Management:
- Job and JobList data structures for tracking jobs
- JobState enum (Running, Stopped, Done)
- Process group tracking and management
- Job ID assignment and lookup
Terminal Control:
- setup_shell_terminal() - Initialize shell for job control
- give_terminal_to() - Transfer terminal to foreground job
- restore_shell_terminal() - Return terminal to shell
- Proper handling of SIGTTOU, SIGTTIN, SIGTSTP
Signal Handling:
- setup_job_control_signals() - Configure signal handlers
- check_children() - Non-blocking child status polling
- wait_for_process() - Block until process changes state
- wait_for_process_group() - Wait for any process in group
Next steps: Integrate with executor and add fg/bg/jobs builtins
Parser fixes:
- Add closing_keyword check to prevent control flow keywords from being parsed as commands
- Fix separator to not consume ;; (used in case statements)
- Exclude ) from bare_word_part for case pattern matching
- Allow optional separators before closing keywords (fi, done, esac)
- Fix stdin execution to read all input at once (not line-by-line)
All control flow structures now fully working:
- if/elif/else statements ✅
- while loops ✅
- for loops ✅
- case statements ✅ (exact string matching, glob patterns later)
Tested:
- Multiline and single-line syntax
- Nested conditions
- Multiple case clauses
- Commands before/after control flow blocks
- stdin, file, and interactive modes
- Add control_flow.rs module with execution for if/while/for/case statements
- Add Statement::Script variant for multi-line scripts
- Fix grammar to reserve keywords (if, then, fi, while, do, done, for, in, case, esac)
- Fix bare_word_part to exclude semicolons
- Make NEWLINE silent to prevent parse tree pollution
- Update command_line grammar to support multiple commands
- Add keyword_boundary rule for proper keyword matching
- Update CLI to handle Statement::Script and execute all control flow types
- Add parser tests for if statements and multiline scripts
If statements are fully working. While/for/case loops need additional testing and fixes.
- Update execute_line to handle Statement::Complete(CompleteCommand)
- Add execute_complete_command dispatcher for all command types
- Maintain existing Simple and Pipeline execution
- Add TODO placeholders for control flow execution:
- AndOrList (&&, ||)
- If statements
- While loops
- For loops
- Case statements
- Shell remains functional with existing features