mirror of
https://github.com/JanDeDobbeleer/oh-my-posh.git
synced 2026-08-24 10:14:12 -05:00
feat(shell): add cmdline_url to the FTCS command executed mark
Extend the OSC 133;C emission with the just-submitted command line, percent-encoded as kitty's cmdline_url= shell-integration extension. Terminals and multiplexers no longer need process-tree inspection to know what command a pane runs - a primitive Windows lacks entirely. Encoding happens in-shell with builtins only, so no extra process spawn per prompt; terminals that ignore the parameter still see the bare mark. Closes #7536 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Entire-Checkpoint: 7f155fd83428
This commit is contained in:
committed by
Jan De Dobbeleer
co-authored by
Claude Fable 5
parent
cbcc61be82
commit
ba1b9eb125
@@ -65,10 +65,48 @@ function _omp_milliseconds() {
|
||||
"$_omp_executable" get millis
|
||||
}
|
||||
|
||||
# percent-encode $1, byte-wise, keeping RFC 3986 unreserved characters literal
|
||||
function _omp_urlencode() {
|
||||
local LC_ALL=C
|
||||
local str=$1 encoded='' ch i
|
||||
for ((i = 0; i < ${#str}; i++)); do
|
||||
ch=${str:i:1}
|
||||
case $ch in
|
||||
[A-Za-z0-9._~-])
|
||||
encoded+=$ch
|
||||
;;
|
||||
*)
|
||||
printf -v ch '%%%02X' "'$ch"
|
||||
encoded+=$ch
|
||||
;;
|
||||
esac
|
||||
done
|
||||
printf '%s' "$encoded"
|
||||
}
|
||||
|
||||
function _omp_ftcs_command_start() {
|
||||
if [[ $_omp_ftcs_marks == 1 ]]; then
|
||||
printf '\e]133;C\a'
|
||||
if [[ $_omp_ftcs_marks != 1 ]]; then
|
||||
return
|
||||
fi
|
||||
|
||||
# the command comes from history: format is " 501 command", or
|
||||
# " 501* command" when the entry was modified; commands are missing
|
||||
# entirely when history is off or HISTCONTROL ignores them
|
||||
local cmd=''
|
||||
if [[ -o history ]]; then
|
||||
cmd=$(HISTTIMEFORMAT='' builtin history 1)
|
||||
cmd=${cmd#"${cmd%%[![:space:]]*}"} # strip the leading padding
|
||||
cmd=${cmd#"${cmd%%[!0-9]*}"} # strip the history number
|
||||
cmd=${cmd#??} # strip the modified flag and separator
|
||||
fi
|
||||
|
||||
if [[ -n $cmd ]]; then
|
||||
# advertise the command line via kitty's cmdline_url= extension
|
||||
printf '\e]133;C;cmdline_url=%s\a' "$(_omp_urlencode "$cmd")"
|
||||
return
|
||||
fi
|
||||
|
||||
printf '\e]133;C\a'
|
||||
}
|
||||
|
||||
# template function for context loading
|
||||
|
||||
@@ -578,9 +578,17 @@ function _omp_postexec --on-event fish_postexec
|
||||
end
|
||||
|
||||
function _omp_preexec --on-event fish_preexec
|
||||
if test $_omp_ftcs_marks = 1
|
||||
echo -ne "\e]133;C\a"
|
||||
if test $_omp_ftcs_marks != 1
|
||||
return
|
||||
end
|
||||
|
||||
if test -n "$argv"
|
||||
# advertise the command line via kitty's cmdline_url= extension
|
||||
echo -ne "\e]133;C;cmdline_url="(string escape --style=url -- "$argv")"\a"
|
||||
return
|
||||
end
|
||||
|
||||
echo -ne "\e]133;C\a"
|
||||
end
|
||||
|
||||
# perform cleanup so a new initialization in current session works
|
||||
|
||||
@@ -391,13 +391,29 @@ local function display_cached_prompt()
|
||||
cached_prompt.only_use_cache = nil
|
||||
end
|
||||
|
||||
local function url_encode(str)
|
||||
-- percent-encode everything but RFC 3986 unreserved characters
|
||||
return (string.gsub(str, '[^%w%-%._~]', function(ch)
|
||||
return string.format('%%%02X', string.byte(ch))
|
||||
end))
|
||||
end
|
||||
|
||||
local function command_executed_mark(input)
|
||||
if string.gsub(input, '^%s*(.-)%s*$', '%1') ~= '' then
|
||||
no_exit_code = false
|
||||
end
|
||||
if ftcs_marks_enabled then
|
||||
clink.print('\x1b]133;C\007', NONL)
|
||||
|
||||
if not ftcs_marks_enabled then
|
||||
return
|
||||
end
|
||||
|
||||
-- advertise the command line via kitty's cmdline_url= extension
|
||||
local cmdline = ''
|
||||
if input and input ~= '' then
|
||||
cmdline = ';cmdline_url=' .. url_encode(input)
|
||||
end
|
||||
|
||||
clink.print('\x1b]133;C' .. cmdline .. '\007', NONL)
|
||||
end
|
||||
|
||||
-- set priority lower than z.lua
|
||||
|
||||
@@ -1107,8 +1107,9 @@ New-Module -Name "oh-my-posh-core" -ScriptBlock {
|
||||
return {
|
||||
try {
|
||||
$Streaming.State = 'NEW'
|
||||
$ast = $null
|
||||
$parseErrors = $null
|
||||
[Microsoft.PowerShell.PSConsoleReadLine]::GetBufferState([ref]$null, [ref]$null, [ref]$parseErrors, [ref]$null)
|
||||
[Microsoft.PowerShell.PSConsoleReadLine]::GetBufferState([ref]$ast, [ref]$null, [ref]$parseErrors, [ref]$null)
|
||||
$executingCommand = $parseErrors.Count -eq 0
|
||||
if ($global:_ompTransientPrompt -and $executingCommand) {
|
||||
Set-TransientPrompt
|
||||
@@ -1117,8 +1118,15 @@ New-Module -Name "oh-my-posh-core" -ScriptBlock {
|
||||
finally {
|
||||
& $AcceptLineFunction
|
||||
if ($global:_ompFTCSMarks -and $executingCommand) {
|
||||
# Write FTCS_COMMAND_EXECUTED after accepting the input - it should still happen before execution
|
||||
Write-Host "$([char]27)]133;C$([char]7)" -NoNewline
|
||||
# Write FTCS_COMMAND_EXECUTED after accepting the input - it should still happen before execution.
|
||||
# The command line rides along as kitty's cmdline_url= extension, percent-encoded.
|
||||
# Windows PowerShell's Uri.EscapeDataString throws beyond 32766 characters, hence the length cap.
|
||||
$cmdline = ''
|
||||
$command = $ast.Extent.Text
|
||||
if ($command -and $command.Length -lt 32000) {
|
||||
$cmdline = ";cmdline_url=$([Uri]::EscapeDataString($command))"
|
||||
}
|
||||
Write-Host "$([char]27)]133;C$cmdline$([char]7)" -NoNewline
|
||||
}
|
||||
}
|
||||
}.GetNewClosure()
|
||||
|
||||
@@ -18,10 +18,23 @@ _omp_executable=::OMP::
|
||||
# switches to enable/disable features
|
||||
_omp_ftcs_marks=0
|
||||
|
||||
# percent-encode every byte of $1; over-encoding is still valid URL encoding
|
||||
_omp_urlencode() {
|
||||
printf '%s' "$1" | od -v -An -tx1 | tr -d ' \n' | sed 's/../%&/g'
|
||||
}
|
||||
|
||||
_omp_ftcs_command_start() {
|
||||
if [ "$_omp_ftcs_marks" = 1 ]; then
|
||||
printf '\033]133;C\007'
|
||||
if [ "$_omp_ftcs_marks" != 1 ]; then
|
||||
return
|
||||
fi
|
||||
|
||||
if [ -n "$COMMAND" ]; then
|
||||
# advertise the command line via kitty's cmdline_url= extension
|
||||
printf '\033]133;C;cmdline_url=%s\007' "$(_omp_urlencode "$COMMAND")"
|
||||
return
|
||||
fi
|
||||
|
||||
printf '\033]133;C\007'
|
||||
}
|
||||
|
||||
# template function for context loading
|
||||
|
||||
@@ -389,9 +389,34 @@ function _omp_milliseconds() {
|
||||
_omp_millis=$($_omp_executable get millis)
|
||||
}
|
||||
|
||||
# percent-encode $1 into REPLY, byte-wise, keeping RFC 3986 unreserved characters literal
|
||||
function _omp_urlencode() {
|
||||
emulate -L zsh
|
||||
setopt no_multibyte
|
||||
local str=$1 ch
|
||||
local -i i
|
||||
REPLY=''
|
||||
for (( i = 1; i <= ${#str}; i++ )); do
|
||||
ch=$str[i]
|
||||
if [[ $ch == [A-Za-z0-9._~-] ]]; then
|
||||
REPLY+=$ch
|
||||
continue
|
||||
fi
|
||||
printf -v ch '%%%02X' "'$ch"
|
||||
REPLY+=$ch
|
||||
done
|
||||
}
|
||||
|
||||
function _omp_preexec() {
|
||||
if [[ $_omp_ftcs_marks == 1 ]]; then
|
||||
printf '\033]133;C\007'
|
||||
if [[ -n $1 ]]; then
|
||||
# advertise the command line via kitty's cmdline_url= extension
|
||||
local REPLY
|
||||
_omp_urlencode "$1"
|
||||
printf '\033]133;C;cmdline_url=%s\007' "$REPLY"
|
||||
else
|
||||
printf '\033]133;C\007'
|
||||
fi
|
||||
fi
|
||||
|
||||
_omp_milliseconds
|
||||
|
||||
@@ -133,7 +133,7 @@ For example, the following is a valid `--config` flag:
|
||||
| `terminal_background` | `string` | | [color][colors] - terminal background color, set to your terminal's background color when you notice black elements in Windows Terminal or the Visual Studio Code integrated terminal |
|
||||
| `accent_color` | `string` | | [color][colors] - accent color, used as a fallback when the `accent` [color][accent] is not supported |
|
||||
| `var` | `map[string]any` | | config variables to use in [templates][templates]. Can be any value |
|
||||
| `shell_integration` | `boolean` | `false` | enable shell integration using FinalTerm's OSC sequences. Works in bash, cmd (Clink v1.14.25+), fish, powershell and zsh |
|
||||
| `shell_integration` | `boolean` | `false` | enable shell integration using FinalTerm's OSC sequences. Works in bash, cmd (Clink v1.14.25+), fish, powershell and zsh. The `FTCS_COMMAND_EXECUTED` mark carries the command line as kitty's `cmdline_url=` parameter |
|
||||
| `enable_cursor_positioning` | `boolean` | `false` | enable fetching the cursor position in bash, zsh, and fish to allow automatic hiding of leading newlines when at the top of the shell |
|
||||
| `patch_pwsh_bleed` | `boolean` | `false` | patch a PowerShell bug where the background colors bleed into the next line at the end of the buffer (can be removed when [this][pwsh-bleed] is merged) |
|
||||
| `upgrade` | `Upgrade` | | enable auto upgrade or the upgrade notice. See [Upgrade] |
|
||||
|
||||
Reference in New Issue
Block a user