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:
@@ -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"
|
||||||
|
'
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
Reference in New Issue
Block a user