mirror of
https://github.com/wavetermdev/waveterm
synced 2026-05-15 04:48:24 +00:00
## Overview This PR implements OSC 7 (current working directory reporting) support for Fish shell and PowerShell, completing the shell integration coverage alongside the existing Bash and Zsh implementations added in #2444. ## What is OSC 7? OSC 7 is an operating system command that allows shells to automatically report their current working directory to the terminal emulator using the format: ``` ESC]7;file://hostname/path BEL ``` This enables the terminal to track the current directory without manual commands, providing better context for AI features and ensuring accurate path information. ## Implementation Details ### Fish Shell (`fish_wavefish.sh`) Added shell integration functions using Fish-native features: - `_waveterm_si_blocked()` - Prevents OSC 7 in tmux/screen environments using `set -q` and `string match -q` - `_waveterm_si_osc7()` - Sends the OSC 7 sequence with built-in URL encoding - Uses `string escape --style=url` for UTF-8 percent-encoding - Hooked to `fish_prompt` event and `PWD` variable changes for automatic updates **Key Features:** - Fish-native checks (`set -q`, `string match`) instead of non-portable `test -o` - Built-in `string escape --style=url` for proper UTF-8 percent-encoding - Simple, portable, and maintainable (32 lines total) ### PowerShell (`pwsh_wavepwsh.sh`) Added simplified shell integration that leverages frontend normalization: - `_waveterm_si_blocked()` - Prevents OSC 7 in tmux/screen environments - `_waveterm_si_osc7()` - Sends OSC 7 with raw path encoding - Uses `[System.Uri]::EscapeDataString()` for proper percent-encoding - Integrated into the prompt function while preserving existing prompts **Key Features:** - **No path rewriting**: Sends raw paths (e.g., `C:\Users\Name` → `C%3A%5CUsers%5CName`) - **UNC support**: Network paths like `\\server\share` encoded as `%5C%5Cserver%5Cshare` - **Hostname fallback**: `$env:COMPUTERNAME` → `$env:HOSTNAME` → empty (produces `file:///path`) - **No DNS lookup**: Avoids potentially slow DNS calls - Simple and efficient (53 lines total) ## Implementation Benefits Both implementations use native, built-in features for maximum compatibility and maintainability: **Fish:** - ✅ Replaced `test -o` with fish-native `set -q` and `string match -q` for better portability - ✅ Replaced manual string replacements with `string escape --style=url` for proper UTF-8 support - ✅ Removed custom URL encoding function (19 lines removed) **PowerShell:** - ✅ Uses built-in `[System.Uri]::EscapeDataString()` for proper percent-encoding - ✅ No path rewriting - frontend handles normalization via `decodeURIComponent()` and backslash conversion - ✅ Proper UNC path support without special-casing - ✅ Removed DNS lookup to avoid slow operations - ✅ Removed custom URL encoding function ## Testing All implementations were tested for: - ✅ URL encoding of special characters (spaces, #, ?, &, ;, +, %) - ✅ Correct OSC 7 format generation - ✅ Fish-native checks work correctly (TMUX, STY, TERM patterns) - ✅ Raw path encoding (PowerShell - no rewriting) - ✅ UNC path support (PowerShell) - ✅ Unix path handling - ✅ Go package compilation - ✅ No security issues (CodeQL) ## Path Handling Examples **Fish:** - `/home/user` → `/home/user` - `/path with spaces` → `/path%20with%20spaces` - `/file#hash` → `/file%23hash` **PowerShell:** - Windows: `C:\Users\Name` → `file://HOST/C%3A%5CUsers%5CName` - UNC: `\\server\share\folder` → `file://HOST/%5C%5Cserver%5Cshare%5Cfolder` - Empty hostname: produces `file:///path` format ## Files Changed - `pkg/util/shellutil/shellintegration/fish_wavefish.sh` (+22 lines, -18 lines = net +4 lines, but 19 lines of custom code removed) - `pkg/util/shellutil/shellintegration/pwsh_wavepwsh.sh` (+26 lines, -51 lines = net -25 lines) Total: 38 fewer lines of code with better functionality and maintainability. Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: sawka <2722291+sawka@users.noreply.github.com>
54 lines
No EOL
1.7 KiB
Bash
54 lines
No EOL
1.7 KiB
Bash
# We source this file with -NoExit -File
|
|
$env:PATH = {{.WSHBINDIR_PWSH}} + "{{.PATHSEP}}" + $env:PATH
|
|
|
|
# Source dynamic script from wsh token
|
|
$waveterm_swaptoken_output = wsh token $env:WAVETERM_SWAPTOKEN pwsh 2>$null | Out-String
|
|
if ($waveterm_swaptoken_output -and $waveterm_swaptoken_output -ne "") {
|
|
Invoke-Expression $waveterm_swaptoken_output
|
|
}
|
|
Remove-Variable -Name waveterm_swaptoken_output
|
|
Remove-Item Env:WAVETERM_SWAPTOKEN
|
|
|
|
# Load Wave completions
|
|
wsh completion powershell | Out-String | Invoke-Expression
|
|
|
|
# shell integration
|
|
function Global:_waveterm_si_blocked {
|
|
# Check if we're in tmux or screen
|
|
return ($env:TMUX -or $env:STY -or $env:TERM -like "tmux*" -or $env:TERM -like "screen*")
|
|
}
|
|
|
|
function Global:_waveterm_si_osc7 {
|
|
if (_waveterm_si_blocked) { return }
|
|
|
|
# Get hostname (allow empty for file:/// format)
|
|
$hostname = $env:COMPUTERNAME
|
|
if (-not $hostname) {
|
|
$hostname = $env:HOSTNAME
|
|
}
|
|
|
|
# Percent-encode the raw path as-is (handles UNC, drive letters, etc.)
|
|
$encoded_pwd = [System.Uri]::EscapeDataString($PWD.Path)
|
|
|
|
# OSC 7 - current directory
|
|
Write-Host -NoNewline "`e]7;file://$hostname/$encoded_pwd`a"
|
|
}
|
|
|
|
# Hook OSC 7 to prompt
|
|
function Global:_waveterm_si_prompt {
|
|
_waveterm_si_osc7
|
|
}
|
|
|
|
# Add the OSC 7 call to the prompt function
|
|
if (Test-Path Function:\prompt) {
|
|
$global:_waveterm_original_prompt = $function:prompt
|
|
function Global:prompt {
|
|
_waveterm_si_prompt
|
|
& $global:_waveterm_original_prompt
|
|
}
|
|
} else {
|
|
function Global:prompt {
|
|
_waveterm_si_prompt
|
|
"PS $($executionContext.SessionState.Path.CurrentLocation)$('>' * ($nestedPromptLevel + 1)) "
|
|
}
|
|
} |