Terminal: Pull upstream shellintegration scripts

Change-Id: Ic0fed1a56ec635351716dca1e410050990d2dd98
Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
Reviewed-by: Alessandro Portale <alessandro.portale@qt.io>
This commit is contained in:
Marcus Tillmanns
2023-09-28 16:07:17 +02:00
parent fc93f7d1b7
commit 43f770b087
4 changed files with 185 additions and 29 deletions

View File

@@ -3,7 +3,7 @@
# Prevent the script recursing when setting up
if [[ -n "$VSCODE_SHELL_INTEGRATION" ]]; then
if [[ -n "${VSCODE_SHELL_INTEGRATION:-}" ]]; then
builtin return
fi
@@ -32,7 +32,7 @@ if [ "$VSCODE_INJECTION" == "1" ]; then
builtin unset VSCODE_SHELL_LOGIN
# Apply any explicit path prefix (see #99878)
if [ -n "$VSCODE_PATH_PREFIX" ]; then
if [ -n "${VSCODE_PATH_PREFIX:-}" ]; then
export PATH=$VSCODE_PATH_PREFIX$PATH
builtin unset VSCODE_PATH_PREFIX
fi
@@ -44,6 +44,35 @@ if [ -z "$VSCODE_SHELL_INTEGRATION" ]; then
builtin return
fi
# Apply EnvironmentVariableCollections if needed
if [ -n "${VSCODE_ENV_REPLACE:-}" ]; then
IFS=':' read -ra ADDR <<< "$VSCODE_ENV_REPLACE"
for ITEM in "${ADDR[@]}"; do
VARNAME="$(echo $ITEM | cut -d "=" -f 1)"
VALUE="$(echo -e "$ITEM" | cut -d "=" -f 2)"
export $VARNAME="$VALUE"
done
builtin unset VSCODE_ENV_REPLACE
fi
if [ -n "${VSCODE_ENV_PREPEND:-}" ]; then
IFS=':' read -ra ADDR <<< "$VSCODE_ENV_PREPEND"
for ITEM in "${ADDR[@]}"; do
VARNAME="$(echo $ITEM | cut -d "=" -f 1)"
VALUE="$(echo -e "$ITEM" | cut -d "=" -f 2)"
export $VARNAME="$VALUE${!VARNAME}"
done
builtin unset VSCODE_ENV_PREPEND
fi
if [ -n "${VSCODE_ENV_APPEND:-}" ]; then
IFS=':' read -ra ADDR <<< "$VSCODE_ENV_APPEND"
for ITEM in "${ADDR[@]}"; do
VARNAME="$(echo $ITEM | cut -d "=" -f 1)"
VALUE="$(echo -e "$ITEM" | cut -d "=" -f 2)"
export $VARNAME="${!VARNAME}$VALUE"
done
builtin unset VSCODE_ENV_APPEND
fi
__vsc_get_trap() {
# 'trap -p DEBUG' outputs a shell command like `trap -- '…shellcode…' DEBUG`.
# The terms are quoted literals, but are not guaranteed to be on a single line.
@@ -110,6 +139,10 @@ __vsc_custom_PS2=""
__vsc_in_command_execution="1"
__vsc_current_command=""
# It's fine this is in the global scope as it getting at it requires access to the shell environment
__vsc_nonce="$VSCODE_NONCE"
unset VSCODE_NONCE
__vsc_prompt_start() {
builtin printf '\e]633;A\a'
}
@@ -124,7 +157,7 @@ __vsc_update_cwd() {
__vsc_command_output_start() {
builtin printf '\e]633;C\a'
builtin printf '\e]633;E;%s\a' "$(__vsc_escape_value "${__vsc_current_command}")"
builtin printf '\e]633;E;%s;%s\a' "$(__vsc_escape_value "${__vsc_current_command}")" $__vsc_nonce
}
__vsc_continuation_start() {
@@ -241,10 +274,10 @@ __vsc_prompt_cmd() {
# PROMPT_COMMAND arrays and strings seem to be handled the same (handling only the first entry of
# the array?)
__vsc_original_prompt_command=$PROMPT_COMMAND
__vsc_original_prompt_command=${PROMPT_COMMAND:-}
if [[ -z "${bash_preexec_imported:-}" ]]; then
if [[ -n "$__vsc_original_prompt_command" && "$__vsc_original_prompt_command" != "__vsc_prompt_cmd" ]]; then
if [[ -n "${__vsc_original_prompt_command:-}" && "${__vsc_original_prompt_command:-}" != "__vsc_prompt_cmd" ]]; then
PROMPT_COMMAND=__vsc_prompt_cmd_original
else
PROMPT_COMMAND=__vsc_prompt_cmd

View File

@@ -37,6 +37,32 @@ if [ -z "$VSCODE_SHELL_INTEGRATION" ]; then
builtin return
fi
# Apply EnvironmentVariableCollections if needed
if [ -n "${VSCODE_ENV_REPLACE:-}" ]; then
IFS=':' read -rA ADDR <<< "$VSCODE_ENV_REPLACE"
for ITEM in "${ADDR[@]}"; do
VARNAME="$(echo ${ITEM%%=*})"
export $VARNAME="$(echo -e ${ITEM#*=})"
done
unset VSCODE_ENV_REPLACE
fi
if [ -n "${VSCODE_ENV_PREPEND:-}" ]; then
IFS=':' read -rA ADDR <<< "$VSCODE_ENV_PREPEND"
for ITEM in "${ADDR[@]}"; do
VARNAME="$(echo ${ITEM%%=*})"
export $VARNAME="$(echo -e ${ITEM#*=})${(P)VARNAME}"
done
unset VSCODE_ENV_PREPEND
fi
if [ -n "${VSCODE_ENV_APPEND:-}" ]; then
IFS=':' read -rA ADDR <<< "$VSCODE_ENV_APPEND"
for ITEM in "${ADDR[@]}"; do
VARNAME="$(echo ${ITEM%%=*})"
export $VARNAME="${(P)VARNAME}$(echo -e ${ITEM#*=})"
done
unset VSCODE_ENV_APPEND
fi
# The property (P) and command (E) codes embed values which require escaping.
# Backslashes are doubled. Non-alphanumeric characters are converted to escaped hex.
__vsc_escape_value() {
@@ -66,6 +92,10 @@ __vsc_escape_value() {
__vsc_in_command_execution="1"
__vsc_current_command=""
# It's fine this is in the global scope as it getting at it requires access to the shell environment
__vsc_nonce="$VSCODE_NONCE"
unset VSCODE_NONCE
__vsc_prompt_start() {
builtin printf '\e]633;A\a'
}
@@ -80,7 +110,7 @@ __vsc_update_cwd() {
__vsc_command_output_start() {
builtin printf '\e]633;C\a'
builtin printf '\e]633;E;%s\a' "${__vsc_current_command}"
builtin printf '\e]633;E;%s;%s\a' "$(__vsc_escape_value "${__vsc_current_command}")" $__vsc_nonce
}
__vsc_continuation_start() {
@@ -149,6 +179,7 @@ __vsc_preexec() {
RPROMPT="$__vsc_prior_rprompt"
fi
__vsc_in_command_execution="1"
# For some reason Qt Creator needs this to be $2 instead of $1
__vsc_current_command=$2
__vsc_command_output_start
}

View File

@@ -26,16 +26,48 @@ if status --is-login; and set -q VSCODE_PATH_PREFIX
end
set -e VSCODE_PATH_PREFIX
# Apply EnvironmentVariableCollections if needed
if test -n "$VSCODE_ENV_REPLACE"
set ITEMS (string split : $VSCODE_ENV_REPLACE)
for B in $ITEMS
set split (string split = $B)
set -gx "$split[1]" (echo -e "$split[2]")
end
set -e VSCODE_ENV_REPLACE
end
if test -n "$VSCODE_ENV_PREPEND"
set ITEMS (string split : $VSCODE_ENV_PREPEND)
for B in $ITEMS
set split (string split = $B)
set -gx "$split[1]" (echo -e "$split[2]")"$$split[1]" # avoid -p as it adds a space
end
set -e VSCODE_ENV_PREPEND
end
if test -n "$VSCODE_ENV_APPEND"
set ITEMS (string split : $VSCODE_ENV_APPEND)
for B in $ITEMS
set split (string split = $B)
set -gx "$split[1]" "$$split[1]"(echo -e "$split[2]") # avoid -a as it adds a space
end
set -e VSCODE_ENV_APPEND
end
# Handle the shell integration nonce
if set -q VSCODE_NONCE
set -l __vsc_nonce $VSCODE_NONCE
set -e VSCODE_NONCE
end
# Helper function
function __vsc_esc -d "Emit escape sequences for VS Code shell integration"
builtin printf "\e]633;%s\a" (string join ";" $argv)
builtin printf "\e]633;%s\a" (string join ";" -- $argv)
end
# Sent right before executing an interactive command.
# Marks the beginning of command output.
function __vsc_cmd_executed --on-event fish_preexec
__vsc_esc C
__vsc_esc E (__vsc_escape_value "$argv")
__vsc_esc E (__vsc_escape_value "$argv") $__vsc_nonce
# Creates a marker to indicate a command was run.
set --global _vsc_has_cmd
@@ -64,6 +96,31 @@ function __vsc_cmd_clear --on-event fish_cancel
__vsc_esc D
end
# Preserve the user's existing prompt, to wrap in our escape sequences.
function __preserve_fish_prompt --on-event fish_prompt
if functions --query fish_prompt
if functions --query __vsc_fish_prompt
# Erase the fallback so it can be set to the user's prompt
functions --erase __vsc_fish_prompt
end
functions --copy fish_prompt __vsc_fish_prompt
functions --erase __preserve_fish_prompt
# Now __vsc_fish_prompt is guaranteed to be defined
__init_vscode_shell_integration
else
if functions --query __vsc_fish_prompt
functions --erase __preserve_fish_prompt
__init_vscode_shell_integration
else
# There is no fish_prompt set, so stick with the default
# Now __vsc_fish_prompt is guaranteed to be defined
function __vsc_fish_prompt
echo -n (whoami)@(prompt_hostname) (prompt_pwd) '~> '
end
end
end
end
# Sent whenever a new fish prompt is about to be displayed.
# Updates the current working directory.
function __vsc_update_cwd --on-event fish_prompt
@@ -94,29 +151,29 @@ function __vsc_fish_has_mode_prompt -d "Returns true if fish_mode_prompt is defi
functions fish_mode_prompt | string match -rvq '^ *(#|function |end$|$)'
end
# Preserve the user's existing prompt, to wrap in our escape sequences.
functions --copy fish_prompt __vsc_fish_prompt
# Preserve and wrap fish_mode_prompt (which appears to the left of the regular
# prompt), but only if it's not defined as an empty function (which is the
# officially documented way to disable that feature).
if __vsc_fish_has_mode_prompt
functions --copy fish_mode_prompt __vsc_fish_mode_prompt
function __init_vscode_shell_integration
if __vsc_fish_has_mode_prompt
functions --copy fish_mode_prompt __vsc_fish_mode_prompt
function fish_mode_prompt
__vsc_fish_prompt_start
__vsc_fish_mode_prompt
end
function fish_mode_prompt
__vsc_fish_prompt_start
__vsc_fish_mode_prompt
__vsc_fish_cmd_start
end
function fish_prompt
__vsc_fish_prompt
__vsc_fish_cmd_start
end
else
# No fish_mode_prompt, so put everything in fish_prompt.
function fish_prompt
__vsc_fish_prompt_start
__vsc_fish_prompt
__vsc_fish_cmd_start
function fish_prompt
__vsc_fish_prompt
end
else
# No fish_mode_prompt, so put everything in fish_prompt.
function fish_prompt
__vsc_fish_prompt_start
__vsc_fish_prompt
__vsc_fish_cmd_start
end
end
end
__preserve_fish_prompt

View File

@@ -15,6 +15,35 @@ $Global:__VSCodeOriginalPrompt = $function:Prompt
$Global:__LastHistoryId = -1
# Store the nonce in script scope and unset the global
$Nonce = $env:VSCODE_NONCE
$env:VSCODE_NONCE = $null
if ($env:VSCODE_ENV_REPLACE) {
$Split = $env:VSCODE_ENV_REPLACE.Split(":")
foreach ($Item in $Split) {
$Inner = $Item.Split('=')
[Environment]::SetEnvironmentVariable($Inner[0], $Inner[1].Replace('\x3a', ':'))
}
$env:VSCODE_ENV_REPLACE = $null
}
if ($env:VSCODE_ENV_PREPEND) {
$Split = $env:VSCODE_ENV_PREPEND.Split(":")
foreach ($Item in $Split) {
$Inner = $Item.Split('=')
[Environment]::SetEnvironmentVariable($Inner[0], $Inner[1].Replace('\x3a', ':') + [Environment]::GetEnvironmentVariable($Inner[0]))
}
$env:VSCODE_ENV_PREPEND = $null
}
if ($env:VSCODE_ENV_APPEND) {
$Split = $env:VSCODE_ENV_APPEND.Split(":")
foreach ($Item in $Split) {
$Inner = $Item.Split('=')
[Environment]::SetEnvironmentVariable($Inner[0], [Environment]::GetEnvironmentVariable($Inner[0]) + $Inner[1].Replace('\x3a', ':'))
}
$env:VSCODE_ENV_APPEND = $null
}
function Global:__VSCode-Escape-Value([string]$value) {
# NOTE: In PowerShell v6.1+, this can be written `$value -replace '…', { … }` instead of `[regex]::Replace`.
# Replace any non-alphanumeric characters.
@@ -40,7 +69,7 @@ function Global:Prompt() {
$Result += "$([char]0x1b)]633;D`a"
} else {
# Command finished command line
# OSC 633 ; A ; <CommandLine?> ST
# OSC 633 ; E ; <CommandLine?> ; <Nonce?> ST
$Result = "$([char]0x1b)]633;E;"
# Sanitize the command line to ensure it can get transferred to the terminal and can be parsed
# correctly. This isn't entirely safe but good for most cases, it's important for the Pt parameter
@@ -51,6 +80,7 @@ function Global:Prompt() {
$CommandLine = ""
}
$Result += $(__VSCode-Escape-Value $CommandLine)
$Result += ";$Nonce"
$Result += "`a"
# Command finished exit code
# OSC 633 ; D [; <ExitCode>] ST
@@ -88,7 +118,12 @@ if (Get-Module -Name PSReadLine) {
}
# Set IsWindows property
[Console]::Write("$([char]0x1b)]633;P;IsWindows=$($IsWindows)`a")
if ($PSVersionTable.PSVersion -lt "6.0") {
# Windows PowerShell is only available on Windows
[Console]::Write("$([char]0x1b)]633;P;IsWindows=$true`a")
} else {
[Console]::Write("$([char]0x1b)]633;P;IsWindows=$IsWindows`a")
}
# Set always on key handlers which map to default VS Code keybindings
function Set-MappedKeyHandler {