feat: add multi-line command support for tmux panes

- Refactor `send_command` to handle multi-line input
- Implement `send_multiline_command` to execute temp scripts
- Create temporary bash scripts for multi-line commands
- Add documentation and examples for multi-line commands
This commit is contained in:
Mahmoud-Emad
2025-09-02 16:02:46 +03:00
parent 49f15d46bb
commit b3fe4dd2cd
3 changed files with 170 additions and 2 deletions

View File

@@ -0,0 +1,74 @@
#!/usr/bin/env hero
// Demonstration of multi-line command support in tmux heroscripts
// This example shows how to use multi-line commands in pane configurations
// Create a development session
!!tmux.session_create
name:"dev_multiline"
reset:true
// Create a 4-pane development workspace
!!tmux.window_ensure
name:"dev_multiline|workspace"
cat:"4pane"
// Pane 1: Development environment setup
!!tmux.pane_ensure
name:"dev_multiline|workspace|1"
label:"dev_setup"
cmd:'
echo "=== Development Environment Setup ==="
echo "Current directory: $(pwd)"
echo "Git status:"
git status --porcelain || echo "Not a git repository"
echo "Available disk space:"
df -h .
echo "Development setup complete"
'
// Pane 2: System monitoring
!!tmux.pane_ensure
name:"dev_multiline|workspace|2"
label:"monitoring"
cmd:'
echo "=== System Monitoring ==="
echo "System uptime:"
uptime
echo "Memory usage:"
free -h 2>/dev/null || vm_stat | head -5
echo "CPU info:"
sysctl -n machdep.cpu.brand_string 2>/dev/null || cat /proc/cpuinfo | grep "model name" | head -1
echo "Monitoring setup complete"
'
// Pane 3: Network diagnostics
!!tmux.pane_ensure
name:"dev_multiline|workspace|3"
label:"network"
cmd:'
echo "=== Network Diagnostics ==="
echo "Network interfaces:"
ifconfig | grep -E "^[a-z]|inet " | head -10
echo "DNS configuration:"
cat /etc/resolv.conf 2>/dev/null || scutil --dns | head -10
echo "Network diagnostics complete"
'
// Pane 4: File operations and cleanup
!!tmux.pane_ensure
name:"dev_multiline|workspace|4"
label:"file_ops"
cmd:'
echo "=== File Operations ==="
echo "Creating temporary workspace..."
mkdir -p /tmp/dev_workspace
cd /tmp/dev_workspace
echo "Current location: $(pwd)"
echo "Creating sample files..."
echo "Sample content" > sample.txt
echo "Another file" > another.txt
echo "Files created:"
ls -la
echo "File operations complete"
'

View File

@@ -164,6 +164,59 @@ hero run -p <heroscript_file>
label:'editor' // Optional: descriptive label label:'editor' // Optional: descriptive label
cmd:'vim' // Optional: command to run cmd:'vim' // Optional: command to run
env:'EDITOR=vim' // Optional: environment variables env:'EDITOR=vim' // Optional: environment variables
// Multi-line commands are supported using proper heroscript syntax
!!tmux.pane_ensure
name:"mysession|mywindow|2"
label:'setup'
cmd:'
echo "Starting setup..."
mkdir -p /tmp/workspace
cd /tmp/workspace
echo "Setup complete"
'
```
### Multi-line Commands
The tmux module supports multi-line commands in heroscripts using proper multi-line parameter syntax. Multi-line commands are automatically converted to temporary shell scripts for execution.
#### Syntax
Use the multi-line parameter format with quotes:
```heroscript
!!tmux.pane_ensure
name:"session|window|pane"
cmd:'
command1
command2
command3
'
```
#### Features
- **Automatic Script Generation**: Multi-line commands are converted to temporary shell scripts
- **Sequential Execution**: All commands execute in order within the same shell context
- **Error Handling**: Scripts include proper bash shebang and error handling
- **Temporary Files**: Scripts are stored in `/tmp/tmux/{session}/pane_{id}_script.sh`
#### Example
```heroscript
!!tmux.pane_ensure
name:"dev|workspace|1"
label:"setup"
cmd:'
echo "Setting up development environment..."
mkdir -p /tmp/dev_workspace
cd /tmp/dev_workspace
git clone https://github.com/example/repo.git
cd repo
npm install
echo "Development environment ready!"
'
``` ```
### Pane Layout Categories ### Pane Layout Categories

View File

@@ -146,9 +146,50 @@ pub fn (mut p Pane) processinfo_main() !osal.ProcessInfo {
} }
// Send a command to this pane // Send a command to this pane
// Supports both single-line and multi-line commands
pub fn (mut p Pane) send_command(command string) ! { pub fn (mut p Pane) send_command(command string) ! {
cmd := 'tmux send-keys -t ${p.window.session.name}:@${p.window.id}.%${p.id} "${command}" Enter' // Check if command contains multiple lines
osal.execute_silent(cmd) or { return error('Cannot send command to pane %${p.id}: ${err}') } if command.contains('\n') {
// Multi-line command - create temporary script
p.send_multiline_command(command)!
} else {
// Single-line command - send directly
cmd := 'tmux send-keys -t ${p.window.session.name}:@${p.window.id}.%${p.id} "${command}" Enter'
osal.execute_silent(cmd) or { return error('Cannot send command to pane %${p.id}: ${err}') }
}
}
// Handle multi-line commands by creating a temporary script
fn (mut p Pane) send_multiline_command(command string) ! {
// Create temporary directory for tmux scripts
script_dir := '/tmp/tmux/${p.window.session.name}'
os.mkdir_all(script_dir) or { return error('Cannot create script directory: ${err}') }
// Create unique script file for this pane
script_path := '${script_dir}/pane_${p.id}_script.sh'
// Prepare script content with proper shebang and commands
script_content := '#!/bin/bash\n' + command.trim_space()
// Write script to file
os.write_file(script_path, script_content) or {
return error('Cannot write script file ${script_path}: ${err}')
}
// Make script executable
os.chmod(script_path, 0o755) or {
return error('Cannot make script executable ${script_path}: ${err}')
}
// Execute the script in the pane
cmd := 'tmux send-keys -t ${p.window.session.name}:@${p.window.id}.%${p.id} "${script_path}" Enter'
osal.execute_silent(cmd) or { return error('Cannot execute script in pane %${p.id}: ${err}') }
// Optional: Clean up script after a delay (commented out for debugging)
// spawn {
// time.sleep(5 * time.second)
// os.rm(script_path) or {}
// }
} }
// Send raw keys to this pane (without Enter) // Send raw keys to this pane (without Enter)