Skip to content

Commit ef46d64

Browse files
authored
Merge pull request #3043 from cmderdev/copilot/add-osc-133-d-exit-code
Add OSC 133 shell integration support across PowerShell, Bash, and CMD.exe
2 parents a8d897f + eabadf9 commit ef46d64

File tree

4 files changed

+63
-20
lines changed

4 files changed

+63
-20
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -354,7 +354,7 @@ However, Cmder can in fact run in a variety of other terminal emulators, and eve
354354

355355
*Note:* Cmder includes built-in support for Windows Terminal directory tracking via OSC 9;9 sequences. This enables "Duplicate Tab" and "Split Pane" features to preserve the current working directory for both `cmd.exe` and PowerShell sessions.
356356

357-
*Note:* Cmder also includes built-in support for [Windows Terminal shell integration](https://learn.microsoft.com/en-us/windows/terminal/tutorials/shell-integration) via OSC 133 sequences (A, B, C) for PowerShell sessions. This enables features like command navigation (jump between commands), command selection, visual command separators, and improved command history management in Windows Terminal.
357+
*Note:* Cmder also includes built-in support for [Windows Terminal shell integration](https://learn.microsoft.com/en-us/windows/terminal/tutorials/shell-integration) via OSC 133 sequences (A, B, C, D) for PowerShell sessions. This enables features like command navigation (jump between commands), command selection, visual command separators, command exit code tracking, and improved command history management in Windows Terminal.
358358

359359
For instructions on how to integrate Cmder with your IDE, please read our [Wiki section](https://github.com/cmderdev/cmder/wiki#cmder-integration).
360360

vendor/git-prompt.sh

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,41 @@ then
4747
. ~/.config/git/git-prompt.sh
4848
fi
4949
else
50+
51+
# Setup OSC 133 shell integration for Windows Terminal
52+
if [ -n "$WT_SESSION" ]; then
53+
__cmder_prompt_command() {
54+
local exit_code=$?
55+
# Emit OSC 133;D to mark the end of command execution with exit code
56+
printf '\e]133;D;%s\a' "$exit_code"
57+
return $exit_code
58+
}
59+
60+
__cmder_preexec() {
61+
# Emit OSC 133;C to mark the start of command execution
62+
printf '\e]133;C\a'
63+
}
64+
65+
# Append to PROMPT_COMMAND to emit sequences just before each prompt
66+
if [ -z "$PROMPT_COMMAND" ]; then
67+
PROMPT_COMMAND="__cmder_prompt_command"
68+
else
69+
PROMPT_COMMAND="__cmder_prompt_command;$PROMPT_COMMAND"
70+
fi
71+
72+
# Use DEBUG trap to emit OSC 133;C before command execution
73+
trap '__cmder_preexec' DEBUG
74+
fi
75+
5076
# Source: github.com/git-for-windows/build-extra/blob/main/git-extra/git-prompt.sh
5177
PS1='\[\033]0;${TITLEPREFIX:+$TITLEPREFIX:}${PWD//[^[:ascii:]]/?}\007\]' # set window title to TITLEPREFIX (if set) and current working directory
5278
# PS1="$PS1"'\n' # new line (disabled)
79+
80+
if [ -n "$WT_SESSION" ]; then
81+
# Emit OSC 133;A to mark the start of prompt
82+
PS1="$PS1"'\e]133;A\a'
83+
fi
84+
5385
PS1="$PS1"'\[\033[32m\]' # change to green and bold
5486
PS1="$PS1"'\u@\h ' # user@host<space>
5587
PS1="$PS1${MSYSTEM:+\[\033[35m\]$MSYSTEM }" # show MSYSTEM in purple (if set)
@@ -80,6 +112,11 @@ else
80112
PS1="$PS1"'\[\033[30;1m\]' # change color to grey in bold
81113
PS1="$PS1"'λ ' # prompt: Cmder uses λ
82114
PS1="$PS1"'\[\033[0m\]' # reset color
115+
116+
if [ -n "$WT_SESSION" ]; then
117+
# Emit OSC 133;B to mark the end of prompt
118+
PS1="$PS1"'\[\e]133;B\a\]'
119+
fi
83120
fi
84121

85122
MSYS2_PS1="$PS1" # for detection by MSYS2 SDK's bash.basrc

vendor/init.bat

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,9 @@ goto :SKIP_CLINK
222222

223223
:: Revert back to plain cmd.exe prompt without clink
224224
prompt $E[1;32;49m$P$S$_$E[1;30;49mλ$S$E[0m
225+
226+
:: Add Windows Terminal shell integration support (OSC 133 sequences)
227+
if defined WT_SESSION (prompt $e]133;D$e\$e]133;A$e\$e]9;9;$P$e\%PROMPT%$e]133;B$e\)
225228

226229
chcp %cp%>nul
227230

vendor/profile.ps1

Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -98,8 +98,7 @@ if (Get-Module PSReadline -ErrorAction "SilentlyContinue") {
9898
# Display an extra prompt line between the prompt and the command input
9999
Set-PSReadlineOption -ExtraPromptLineCount 1
100100

101-
# Add OSC 133;C support for Windows Terminal shell integration
102-
# This marks the start of command output (emitted when Enter is pressed)
101+
# Invoked when Enter is pressed to submit a command
103102
if ($env:WT_SESSION) {
104103
Set-PSReadLineKeyHandler -Key Enter -ScriptBlock {
105104
# Get the current command line
@@ -110,7 +109,7 @@ if (Get-Module PSReadline -ErrorAction "SilentlyContinue") {
110109
# Accept the line first
111110
[Microsoft.PowerShell.PSConsoleReadLine]::AcceptLine()
112111

113-
# Emit OSC 133;C sequence to mark start of command output
112+
# Emit OSC 133;C to mark start of command output
114113
# This is written directly to the console after the command is accepted
115114
[Console]::Write("$([char]0x1B)]133;C$([char]7)")
116115
}
@@ -221,20 +220,25 @@ if ( $(Get-Command prompt).Definition -match 'PS \$\(\$executionContext.SessionS
221220
$lastSUCCESS = $?
222221
$realLastExitCode = $LastExitCode
223222

224-
# Emit OSC 9;9 sequence for Windows Terminal directory tracking
225-
# This enables "Duplicate Tab" and "Split Pane" to preserve the working directory
226-
# Only active in Windows Terminal ($env:WT_SESSION) or ConEmu ($env:ConEmuPID)
227-
$loc = $executionContext.SessionState.Path.CurrentLocation
228-
if (($env:WT_SESSION -or $env:ConEmuPID) -and $loc.Provider.Name -eq "FileSystem") {
229-
Microsoft.PowerShell.Utility\Write-Host -NoNewline "$([char]0x1B)]9;9;`"$($loc.ProviderPath)`"$([char]0x1B)\"
230-
}
231-
232-
# Emit OSC 133;A sequence for Windows Terminal shell integration
233-
# This marks the start of the prompt
234-
# Enables features like command navigation, selection, and visual separators
235-
# Only active in Windows Terminal ($env:WT_SESSION)
236-
if ($env:WT_SESSION) {
237-
Microsoft.PowerShell.Utility\Write-Host -NoNewline "$([char]0x1B)]133;A$([char]7)"
223+
# Terminal-specific escape sequences for Windows Terminal and ConEmu
224+
if ($env:WT_SESSION -or $env:ConEmuPID) {
225+
# Emit OSC 133;D to mark the end of command execution with exit code
226+
if ($env:WT_SESSION) {
227+
Microsoft.PowerShell.Utility\Write-Host -NoNewline "$([char]0x1B)]133;D;$realLastExitCode$([char]7)"
228+
}
229+
230+
# Emit OSC 9;9 to enable directory tracking
231+
# Enables "Duplicate Tab" and "Split Pane" to preserve the working directory
232+
$loc = $executionContext.SessionState.Path.CurrentLocation
233+
if ($loc.Provider.Name -eq "FileSystem") {
234+
Microsoft.PowerShell.Utility\Write-Host -NoNewline "$([char]0x1B)]9;9;`"$($loc.ProviderPath)`"$([char]0x1B)\"
235+
}
236+
237+
# Emit OSC 133;A to mark the start of the prompt
238+
# Enables features like command navigation, selection, and visual separators
239+
if ($env:WT_SESSION) {
240+
Microsoft.PowerShell.Utility\Write-Host -NoNewline "$([char]0x1B)]133;A$([char]7)"
241+
}
238242
}
239243

240244
$host.UI.RawUI.WindowTitle = Microsoft.PowerShell.Management\Split-Path $pwd.ProviderPath -Leaf
@@ -246,8 +250,7 @@ if ( $(Get-Command prompt).Definition -match 'PS \$\(\$executionContext.SessionS
246250
CmderPrompt
247251
PostPrompt | Microsoft.PowerShell.Utility\Write-Host -NoNewline
248252

249-
# Emit OSC 133;B sequence for Windows Terminal shell integration
250-
# This marks the start of command input (after prompt, before user types)
253+
# Emit OSC 133;B to mark the start of command input (after prompt, before user types)
251254
if ($env:WT_SESSION) {
252255
Microsoft.PowerShell.Utility\Write-Host -NoNewline "$([char]0x1B)]133;B$([char]7)"
253256
}

0 commit comments

Comments
 (0)