forked from qt-creator/qt-creator
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:
@@ -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
|
||||
|
@@ -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
|
||||
}
|
||||
|
@@ -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
|
||||
|
@@ -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 {
|
||||
|
Reference in New Issue
Block a user