Initial commit, 90% there

This commit is contained in:
mdares
2025-12-02 16:27:21 +00:00
commit 755028af7e
7353 changed files with 1759505 additions and 0 deletions

View File

@@ -0,0 +1,64 @@
#!/bin/bash
function get_total_cpu_time() {
# Read the first line of /proc/stat and remove the cpu prefix
CPU=(`sed -n 's/^cpu\s//p' /proc/stat`)
# Sum all of the values in CPU to get total time
for VALUE in "${CPU[@]}"; do
let $1=$1+$VALUE
done
}
TOTAL_TIME_BEFORE=0
get_total_cpu_time TOTAL_TIME_BEFORE
# Loop over the arguments, which are a list of PIDs
# The 13th and 14th words in /proc/<PID>/stat are the user and system time
# the process has used, so sum these to get total process run time
declare -a PROCESS_BEFORE_TIMES
ITER=0
for PID in "$@"; do
if [ -f /proc/$PID/stat ]
then
PROCESS_STATS=`cat /proc/$PID/stat`
PROCESS_STAT_ARRAY=($PROCESS_STATS)
let PROCESS_TIME_BEFORE="${PROCESS_STAT_ARRAY[13]}+${PROCESS_STAT_ARRAY[14]}"
else
let PROCESS_TIME_BEFORE=0
fi
PROCESS_BEFORE_TIMES[$ITER]=$PROCESS_TIME_BEFORE
((++ITER))
done
# Wait for a second
sleep 1
TOTAL_TIME_AFTER=0
get_total_cpu_time TOTAL_TIME_AFTER
# Check the user and system time sum of each process again and compute the change
# in process time used over total system time
ITER=0
for PID in "$@"; do
if [ -f /proc/$PID/stat ]
then
PROCESS_STATS=`cat /proc/$PID/stat`
PROCESS_STAT_ARRAY=($PROCESS_STATS)
let PROCESS_TIME_AFTER="${PROCESS_STAT_ARRAY[13]}+${PROCESS_STAT_ARRAY[14]}"
else
let PROCESS_TIME_AFTER=${PROCESS_BEFORE_TIMES[$ITER]}
fi
PROCESS_TIME_BEFORE=${PROCESS_BEFORE_TIMES[$ITER]}
let PROCESS_DELTA=$PROCESS_TIME_AFTER-$PROCESS_TIME_BEFORE
let TOTAL_DELTA=$TOTAL_TIME_AFTER-$TOTAL_TIME_BEFORE
CPU_USAGE=`echo "$((100*$PROCESS_DELTA/$TOTAL_DELTA))"`
# Parent script reads from stdout, so echo result to be read
echo $CPU_USAGE
((++ITER))
done

View File

@@ -0,0 +1,39 @@
#!/bin/sh
PAGESIZE=`getconf PAGESIZE`;
TOTAL_MEMORY=`cat /proc/meminfo | head -n 1 | awk '{print $2}'`;
# Mimic the output of ps -ax -o pid=,ppid=,pcpu=,pmem=,command=
# Read all numeric subdirectories in /proc
for pid in `cd /proc && ls -d [0-9]*`
do {
if [ -e /proc/$pid/stat ]
then
echo $pid;
# ppid is the word at index 4 in the stat file for the process
awk '{print $4}' /proc/$pid/stat;
# pcpu - calculation will be done later, this is a placeholder value
echo "0.0"
# pmem - ratio of the process's working set size to total memory.
# use the page size to convert to bytes, total memory is in KB
# multiplied by 100 to get percentage, extra 10 to be able to move
# the decimal over by one place
RESIDENT_SET_SIZE=`awk '{print $24}' /proc/$pid/stat`;
PERCENT_MEMORY=$(((1000 * $PAGESIZE * $RESIDENT_SET_SIZE) / ($TOTAL_MEMORY * 1024)));
if [ $PERCENT_MEMORY -lt 10 ]
then
# replace the last character with 0. the last character
echo $PERCENT_MEMORY | sed 's/.$/0.&/'; #pmem
else
# insert . before the last character
echo $PERCENT_MEMORY | sed 's/.$/.&/';
fi
# cmdline
xargs -0 < /proc/$pid/cmdline;
fi
} | tr "\n" "\t"; # Replace newlines with tab so that all info for a process is shown on one line
echo; # But add new lines between processes
done

View File

@@ -0,0 +1,478 @@
# ---------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for license information.
# ---------------------------------------------------------------------------------------------
# Prevent the script recursing when setting up
if [[ -n "${VSCODE_SHELL_INTEGRATION:-}" ]]; then
builtin return
fi
VSCODE_SHELL_INTEGRATION=1
vsc_env_keys=()
vsc_env_values=()
use_associative_array=0
bash_major_version=${BASH_VERSINFO[0]}
__vscode_shell_env_reporting="${VSCODE_SHELL_ENV_REPORTING:-}"
unset VSCODE_SHELL_ENV_REPORTING
envVarsToReport=()
IFS=',' read -ra envVarsToReport <<< "$__vscode_shell_env_reporting"
if (( BASH_VERSINFO[0] >= 4 )); then
use_associative_array=1
# Associative arrays are only available in bash 4.0+
declare -A vsc_aa_env
fi
# Run relevant rc/profile only if shell integration has been injected, not when run manually
if [ "$VSCODE_INJECTION" == "1" ]; then
if [ -z "$VSCODE_SHELL_LOGIN" ]; then
if [ -r ~/.bashrc ]; then
. ~/.bashrc
fi
else
# Imitate -l because --init-file doesn't support it:
# run the first of these files that exists
if [ -r /etc/profile ]; then
. /etc/profile
fi
# execute the first that exists
if [ -r ~/.bash_profile ]; then
. ~/.bash_profile
elif [ -r ~/.bash_login ]; then
. ~/.bash_login
elif [ -r ~/.profile ]; then
. ~/.profile
fi
builtin unset VSCODE_SHELL_LOGIN
# Apply any explicit path prefix (see #99878)
if [ -n "${VSCODE_PATH_PREFIX:-}" ]; then
export PATH="$VSCODE_PATH_PREFIX$PATH"
builtin unset VSCODE_PATH_PREFIX
fi
fi
builtin unset VSCODE_INJECTION
fi
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
# Register Python shell activate hooks
# Prevent multiple activation with guard
if [ -z "${VSCODE_PYTHON_AUTOACTIVATE_GUARD:-}" ]; then
export VSCODE_PYTHON_AUTOACTIVATE_GUARD=1
if [ -n "${VSCODE_PYTHON_BASH_ACTIVATE:-}" ] && [ "$TERM_PROGRAM" = "vscode" ]; then
# Prevent crashing by negating exit code
if ! builtin eval "$VSCODE_PYTHON_BASH_ACTIVATE"; then
__vsc_activation_status=$?
builtin printf '\x1b[0m\x1b[7m * \x1b[0;103m VS Code Python bash activation failed with exit code %d \x1b[0m' "$__vsc_activation_status"
fi
fi
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.
# (Consider a trap like $'echo foo\necho \'bar\'').
# To parse, we splice those terms into an expression capturing them into an array.
# This preserves the quoting of those terms: when we `eval` that expression, they are preserved exactly.
# This is different than simply exploding the string, which would split everything on IFS, oblivious to quoting.
builtin local -a terms
builtin eval "terms=( $(trap -p "${1:-DEBUG}") )"
# |________________________|
# |
# \-------------------*--------------------/
# terms=( trap -- '…arbitrary shellcode…' DEBUG )
# |____||__| |_____________________| |_____|
# | | | |
# 0 1 2 3
# |
# \--------*----/
builtin printf '%s' "${terms[2]:-}"
}
__vsc_escape_value_fast() {
builtin local LC_ALL=C out
out=${1//\\/\\\\}
out=${out//;/\\x3b}
builtin printf '%s\n' "${out}"
}
# 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() {
# If the input being too large, switch to the faster function
if [ "${#1}" -ge 2000 ]; then
__vsc_escape_value_fast "$1"
builtin return
fi
# Process text byte by byte, not by codepoint.
builtin local -r LC_ALL=C
builtin local -r str="${1}"
builtin local -ir len="${#str}"
builtin local -i i
builtin local -i val
builtin local byte
builtin local token
builtin local out=''
for (( i=0; i < "${#str}"; ++i )); do
# Escape backslashes, semi-colons specially, then special ASCII chars below space (0x20).
byte="${str:$i:1}"
builtin printf -v val '%d' "'$byte"
if (( val < 31 )); then
builtin printf -v token '\\x%02x' "'$byte"
elif (( val == 92 )); then # \
token="\\\\"
elif (( val == 59 )); then # ;
token="\\x3b"
else
token="$byte"
fi
out+="$token"
done
builtin printf '%s\n' "$out"
}
# Send the IsWindows property if the environment looks like Windows
__vsc_regex_environment="^CYGWIN*|MINGW*|MSYS*"
if [[ "$(uname -s)" =~ $__vsc_regex_environment ]]; then
builtin printf '\e]633;P;IsWindows=True\a'
__vsc_is_windows=1
else
__vsc_is_windows=0
fi
# Allow verifying $BASH_COMMAND doesn't have aliases resolved via history when the right HISTCONTROL
# configuration is used
__vsc_regex_histcontrol=".*(erasedups|ignoreboth|ignoredups).*"
if [[ "${HISTCONTROL:-}" =~ $__vsc_regex_histcontrol ]]; then
__vsc_history_verify=0
else
__vsc_history_verify=1
fi
builtin unset __vsc_regex_environment
builtin unset __vsc_regex_histcontrol
__vsc_initialized=0
__vsc_original_PS1="$PS1"
__vsc_original_PS2="$PS2"
__vsc_custom_PS1=""
__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
# Some features should only work in Insiders
__vsc_stable="$VSCODE_STABLE"
unset VSCODE_STABLE
# Report continuation prompt
if [ "$__vsc_stable" = "0" ]; then
builtin printf "\e]633;P;ContinuationPrompt=$(echo "$PS2" | sed 's/\x1b/\\\\x1b/g')\a"
fi
if [ -n "$STARSHIP_SESSION_KEY" ]; then
builtin printf '\e]633;P;PromptType=starship\a'
elif [ -n "$POSH_SESSION_ID" ]; then
builtin printf '\e]633;P;PromptType=oh-my-posh\a'
fi
# Report this shell supports rich command detection
builtin printf '\e]633;P;HasRichCommandDetection=True\a'
__vsc_report_prompt() {
# Expand the original PS1 similarly to how bash would normally
# See https://stackoverflow.com/a/37137981 for technique
if ((BASH_VERSINFO[0] >= 5 || (BASH_VERSINFO[0] == 4 && BASH_VERSINFO[1] >= 4))); then
__vsc_prompt=${__vsc_original_PS1@P}
else
__vsc_prompt=${__vsc_original_PS1}
fi
__vsc_prompt="$(builtin printf "%s" "${__vsc_prompt//[$'\001'$'\002']}")"
builtin printf "\e]633;P;Prompt=%s\a" "$(__vsc_escape_value "${__vsc_prompt}")"
}
__vsc_prompt_start() {
builtin printf '\e]633;A\a'
}
__vsc_prompt_end() {
builtin printf '\e]633;B\a'
}
__vsc_update_cwd() {
if [ "$__vsc_is_windows" = "1" ]; then
__vsc_cwd="$(cygpath -m "$PWD")"
else
__vsc_cwd="$PWD"
fi
builtin printf '\e]633;P;Cwd=%s\a' "$(__vsc_escape_value "$__vsc_cwd")"
}
__updateEnvCacheAA() {
local key="$1"
local value="$2"
if [ "$use_associative_array" = 1 ]; then
if [[ "${vsc_aa_env[$key]}" != "$value" ]]; then
vsc_aa_env["$key"]="$value"
builtin printf '\e]633;EnvSingleEntry;%s;%s;%s\a' "$key" "$(__vsc_escape_value "$value")" "$__vsc_nonce"
fi
fi
}
__updateEnvCache() {
local key="$1"
local value="$2"
for i in "${!vsc_env_keys[@]}"; do
if [[ "${vsc_env_keys[$i]}" == "$key" ]]; then
if [[ "${vsc_env_values[$i]}" != "$value" ]]; then
vsc_env_values[$i]="$value"
builtin printf '\e]633;EnvSingleEntry;%s;%s;%s\a' "$key" "$(__vsc_escape_value "$value")" "$__vsc_nonce"
fi
return
fi
done
vsc_env_keys+=("$key")
vsc_env_values+=("$value")
builtin printf '\e]633;EnvSingleEntry;%s;%s;%s\a' "$key" "$(__vsc_escape_value "$value")" "$__vsc_nonce"
}
__vsc_update_env() {
if [[ ${#envVarsToReport[@]} -gt 0 ]]; then
builtin printf '\e]633;EnvSingleStart;%s;%s\a' 0 $__vsc_nonce
if [ "$use_associative_array" = 1 ]; then
if [ ${#vsc_aa_env[@]} -eq 0 ]; then
# Associative array is empty, do not diff, just add
for key in "${envVarsToReport[@]}"; do
if [ -n "${!key+x}" ]; then
local value="${!key}"
vsc_aa_env["$key"]="$value"
builtin printf '\e]633;EnvSingleEntry;%s;%s;%s\a' "$key" "$(__vsc_escape_value "$value")" "$__vsc_nonce"
fi
done
else
# Diff approach for associative array
for key in "${envVarsToReport[@]}"; do
if [ -n "${!key+x}" ]; then
local value="${!key}"
__updateEnvCacheAA "$key" "$value"
fi
done
# Track missing env vars not needed for now, as we are only tracking pre-defined env var from terminalEnvironment.
fi
else
if [[ -z ${vsc_env_keys[@]} ]] && [[ -z ${vsc_env_values[@]} ]]; then
# Non associative arrays are both empty, do not diff, just add
for key in "${envVarsToReport[@]}"; do
if [ -n "${!key+x}" ]; then
local value="${!key}"
vsc_env_keys+=("$key")
vsc_env_values+=("$value")
builtin printf '\e]633;EnvSingleEntry;%s;%s;%s\a' "$key" "$(__vsc_escape_value "$value")" "$__vsc_nonce"
fi
done
else
# Diff approach for non-associative arrays
for key in "${envVarsToReport[@]}"; do
if [ -n "${!key+x}" ]; then
local value="${!key}"
__updateEnvCache "$key" "$value"
fi
done
# Track missing env vars not needed for now, as we are only tracking pre-defined env var from terminalEnvironment.
fi
fi
builtin printf '\e]633;EnvSingleEnd;%s;\a' $__vsc_nonce
fi
}
__vsc_command_output_start() {
if [[ -z "${__vsc_first_prompt-}" ]]; then
builtin return
fi
builtin printf '\e]633;E;%s;%s\a' "$(__vsc_escape_value "${__vsc_current_command}")" $__vsc_nonce
builtin printf '\e]633;C\a'
}
__vsc_continuation_start() {
builtin printf '\e]633;F\a'
}
__vsc_continuation_end() {
builtin printf '\e]633;G\a'
}
__vsc_command_complete() {
if [[ -z "${__vsc_first_prompt-}" ]]; then
__vsc_update_cwd
builtin return
fi
if [ "$__vsc_current_command" = "" ]; then
builtin printf '\e]633;D\a'
else
builtin printf '\e]633;D;%s\a' "$__vsc_status"
fi
__vsc_update_cwd
}
__vsc_update_prompt() {
# in command execution
if [ "$__vsc_in_command_execution" = "1" ]; then
# Wrap the prompt if it is not yet wrapped, if the PS1 changed this this was last set it
# means the user re-exported the PS1 so we should re-wrap it
if [[ "$__vsc_custom_PS1" == "" || "$__vsc_custom_PS1" != "$PS1" ]]; then
__vsc_original_PS1=$PS1
__vsc_custom_PS1="\[$(__vsc_prompt_start)\]$__vsc_original_PS1\[$(__vsc_prompt_end)\]"
PS1="$__vsc_custom_PS1"
fi
if [[ "$__vsc_custom_PS2" == "" || "$__vsc_custom_PS2" != "$PS2" ]]; then
__vsc_original_PS2=$PS2
__vsc_custom_PS2="\[$(__vsc_continuation_start)\]$__vsc_original_PS2\[$(__vsc_continuation_end)\]"
PS2="$__vsc_custom_PS2"
fi
__vsc_in_command_execution="0"
fi
}
__vsc_precmd() {
__vsc_command_complete "$__vsc_status"
__vsc_current_command=""
# Report prompt is a work in progress, currently encoding is too slow
if [ "$__vsc_stable" = "0" ]; then
__vsc_report_prompt
fi
__vsc_first_prompt=1
__vsc_update_prompt
__vsc_update_env
}
__vsc_preexec() {
__vsc_initialized=1
if [[ ! $BASH_COMMAND == __vsc_prompt* ]]; then
# Use history if it's available to verify the command as BASH_COMMAND comes in with aliases
# resolved
if [ "$__vsc_history_verify" = "1" ]; then
__vsc_current_command="$(builtin history 1 | sed 's/ *[0-9]* *//')"
else
__vsc_current_command=$BASH_COMMAND
fi
else
__vsc_current_command=""
fi
__vsc_command_output_start
}
# Debug trapping/preexec inspired by starship (ISC)
if [[ -n "${bash_preexec_imported:-}" ]]; then
__vsc_preexec_only() {
if [ "$__vsc_in_command_execution" = "0" ]; then
__vsc_in_command_execution="1"
__vsc_preexec
fi
}
precmd_functions+=(__vsc_prompt_cmd)
preexec_functions+=(__vsc_preexec_only)
else
__vsc_dbg_trap="$(__vsc_get_trap DEBUG)"
if [[ -z "$__vsc_dbg_trap" ]]; then
__vsc_preexec_only() {
if [ "$__vsc_in_command_execution" = "0" ]; then
__vsc_in_command_execution="1"
__vsc_preexec
fi
}
trap '__vsc_preexec_only "$_"' DEBUG
elif [[ "$__vsc_dbg_trap" != '__vsc_preexec "$_"' && "$__vsc_dbg_trap" != '__vsc_preexec_all "$_"' ]]; then
__vsc_preexec_all() {
if [ "$__vsc_in_command_execution" = "0" ]; then
__vsc_in_command_execution="1"
__vsc_preexec
builtin eval "${__vsc_dbg_trap}"
fi
}
trap '__vsc_preexec_all "$_"' DEBUG
fi
fi
__vsc_update_prompt
__vsc_restore_exit_code() {
return "$1"
}
__vsc_prompt_cmd_original() {
__vsc_status="$?"
builtin local cmd
__vsc_restore_exit_code "${__vsc_status}"
# Evaluate the original PROMPT_COMMAND similarly to how bash would normally
# See https://unix.stackexchange.com/a/672843 for technique
for cmd in "${__vsc_original_prompt_command[@]}"; do
eval "${cmd:-}"
done
__vsc_precmd
}
__vsc_prompt_cmd() {
__vsc_status="$?"
__vsc_precmd
}
# 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:-}
if [[ -z "${bash_preexec_imported:-}" ]]; 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
fi
fi

View File

@@ -0,0 +1,16 @@
# ---------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for license information.
# ---------------------------------------------------------------------------------------------
if [[ -f $USER_ZDOTDIR/.zshenv ]]; then
VSCODE_ZDOTDIR=$ZDOTDIR
ZDOTDIR=$USER_ZDOTDIR
# prevent recursion
if [[ $USER_ZDOTDIR != $VSCODE_ZDOTDIR ]]; then
. $USER_ZDOTDIR/.zshenv
fi
USER_ZDOTDIR=$ZDOTDIR
ZDOTDIR=$VSCODE_ZDOTDIR
fi

View File

@@ -0,0 +1,15 @@
# ---------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for license information.
# ---------------------------------------------------------------------------------------------
# Prevent recursive sourcing
if [[ -n "$VSCODE_LOGIN_INITIALIZED" ]]; then
return
fi
export VSCODE_LOGIN_INITIALIZED=1
ZDOTDIR=$USER_ZDOTDIR
if [[ $options[norcs] = off && -o "login" && -f $ZDOTDIR/.zlogin ]]; then
. $ZDOTDIR/.zlogin
fi

View File

@@ -0,0 +1,25 @@
# ---------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for license information.
# ---------------------------------------------------------------------------------------------
# Prevent recursive sourcing
if [[ -n "$VSCODE_PROFILE_INITIALIZED" ]]; then
return
fi
export VSCODE_PROFILE_INITIALIZED=1
if [[ $options[norcs] = off && -o "login" ]]; then
if [[ -f $USER_ZDOTDIR/.zprofile ]]; then
VSCODE_ZDOTDIR=$ZDOTDIR
ZDOTDIR=$USER_ZDOTDIR
. $USER_ZDOTDIR/.zprofile
ZDOTDIR=$VSCODE_ZDOTDIR
fi
# Apply any explicit path prefix (see #99878)
if (( ${+VSCODE_PATH_PREFIX} )); then
export PATH="$VSCODE_PATH_PREFIX$PATH"
fi
builtin unset VSCODE_PATH_PREFIX
fi

View File

@@ -0,0 +1,321 @@
# ---------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for license information.
# ---------------------------------------------------------------------------------------------
builtin autoload -Uz add-zsh-hook is-at-least
# Prevent the script recursing when setting up
if [ -n "$VSCODE_SHELL_INTEGRATION" ]; then
ZDOTDIR=$USER_ZDOTDIR
builtin return
fi
# This variable allows the shell to both detect that VS Code's shell integration is enabled as well
# as disable it by unsetting the variable.
VSCODE_SHELL_INTEGRATION=1
# By default, zsh will set the $HISTFILE to the $ZDOTDIR location automatically. In the case of the
# shell integration being injected, this means that the terminal will use a different history file
# to other terminals. To fix this issue, set $HISTFILE back to the default location before ~/.zshrc
# is called as that may depend upon the value.
if [[ "$VSCODE_INJECTION" == "1" ]]; then
HISTFILE=$USER_ZDOTDIR/.zsh_history
fi
# Only fix up ZDOTDIR if shell integration was injected (not manually installed) and has not been called yet
if [[ "$VSCODE_INJECTION" == "1" ]]; then
if [[ $options[norcs] = off && -f $USER_ZDOTDIR/.zshrc ]]; then
VSCODE_ZDOTDIR=$ZDOTDIR
ZDOTDIR=$USER_ZDOTDIR
# A user's custom HISTFILE location might be set when their .zshrc file is sourced below
. $USER_ZDOTDIR/.zshrc
fi
fi
__vsc_use_aa=0
__vsc_env_keys=()
__vsc_env_values=()
# Associative array are only available in zsh 4.3 or later
if is-at-least 4.3; then
__vsc_use_aa=1
typeset -A vsc_aa_env
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
# Register Python shell activate hooks
# Prevent multiple activation with guard
if [ -z "${VSCODE_PYTHON_AUTOACTIVATE_GUARD:-}" ]; then
export VSCODE_PYTHON_AUTOACTIVATE_GUARD=1
if [ -n "${VSCODE_PYTHON_ZSH_ACTIVATE:-}" ] && [ "$TERM_PROGRAM" = "vscode" ]; then
# Prevent crashing by negating exit code
if ! builtin eval "$VSCODE_PYTHON_ZSH_ACTIVATE"; then
__vsc_activation_status=$?
builtin printf '\x1b[0m\x1b[7m * \x1b[0;103m VS Code Python zsh activation failed with exit code %d \x1b[0m' "$__vsc_activation_status"
fi
fi
fi
# Report prompt type
if [ -n "${P9K_SSH:-}" ] || [ -n "${P9K_TTY:-}" ]; then
builtin printf '\e]633;P;PromptType=p10k\a'
# Force shell integration on for p10k
# typeset -g POWERLEVEL9K_TERM_SHELL_INTEGRATION=true
elif [ -n "${ZSH:-}" ] && [ -n "$ZSH_VERSION" ] && (( ${+functions[omz]} )); then
builtin printf '\e]633;P;PromptType=oh-my-zsh\a'
elif [ -n "${STARSHIP_SESSION_KEY:-}" ]; then
builtin printf '\e]633;P;PromptType=starship\a'
fi
# Shell integration was disabled by the shell, exit without warning assuming either the shell has
# explicitly disabled shell integration as it's incompatible or it implements the protocol.
if [ -z "$VSCODE_SHELL_INTEGRATION" ]; then
builtin return
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() {
builtin emulate -L zsh
# Process text byte by byte, not by codepoint.
builtin local LC_ALL=C str="$1" i byte token out='' val
for (( i = 0; i < ${#str}; ++i )); do
# Escape backslashes, semi-colons specially, then special ASCII chars below space (0x20).
byte="${str:$i:1}"
val=$(printf "%d" "'$byte")
if (( val < 31 )); then
# For control characters, use hex encoding
token=$(printf "\\\\x%02x" "'$byte")
elif [ "$byte" = "\\" ]; then
token="\\\\"
elif [ "$byte" = ";" ]; then
token="\\x3b"
else
token="$byte"
fi
out+="$token"
done
builtin print -r -- "$out"
}
__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
__vscode_shell_env_reporting="${VSCODE_SHELL_ENV_REPORTING:-}"
unset VSCODE_SHELL_ENV_REPORTING
envVarsToReport=()
IFS=',' read -rA envVarsToReport <<< "$__vscode_shell_env_reporting"
builtin printf "\e]633;P;ContinuationPrompt=%s\a" "$(echo "$PS2" | sed 's/\x1b/\\\\x1b/g')"
# Report this shell supports rich command detection
builtin printf '\e]633;P;HasRichCommandDetection=True\a'
__vsc_prompt_start() {
builtin printf '\e]633;A\a'
}
__vsc_prompt_end() {
builtin printf '\e]633;B\a'
}
__vsc_update_cwd() {
builtin printf '\e]633;P;Cwd=%s\a' "$(__vsc_escape_value "${PWD}")"
}
__update_env_cache_aa() {
local key="$1"
local value="$2"
if [ $__vsc_use_aa -eq 1 ]; then
if [[ "${vsc_aa_env["$key"]}" != "$value" ]]; then
vsc_aa_env["$key"]="$value"
builtin printf '\e]633;EnvSingleEntry;%s;%s;%s\a' "$key" "$(__vsc_escape_value "$value")" "$__vsc_nonce"
fi
fi
}
__update_env_cache() {
local key="$1"
local value="$2"
for (( i=1; i <= $#__vsc_env_keys; i++ )); do
if [[ "${__vsc_env_keys[$i]}" == "$key" ]]; then
if [[ "${__vsc_env_values[$i]}" != "$value" ]]; then
__vsc_env_values[$i]="$value"
builtin printf '\e]633;EnvSingleEntry;%s;%s;%s\a' "$key" "$(__vsc_escape_value "$value")" "$__vsc_nonce"
fi
return
fi
done
# Key does not exist so add key, value pair
__vsc_env_keys+=("$key")
__vsc_env_values+=("$value")
builtin printf '\e]633;EnvSingleEntry;%s;%s;%s\a' "$key" "$(__vsc_escape_value "$value")" "$__vsc_nonce"
}
__vsc_update_env() {
if [[ ${#envVarsToReport[@]} -gt 0 ]]; then
builtin printf '\e]633;EnvSingleStart;%s;%s;\a' 0 $__vsc_nonce
if [ $__vsc_use_aa -eq 1 ]; then
if [[ ${#vsc_aa_env[@]} -eq 0 ]]; then
# Associative array is empty, do not diff, just add
for key in "${envVarsToReport[@]}"; do
if [[ -n "$key" && -n "${(P)key+_}" ]]; then
vsc_aa_env["$key"]="${(P)key}"
builtin printf '\e]633;EnvSingleEntry;%s;%s;%s\a' "$key" "$(__vsc_escape_value "${(P)key}")" "$__vsc_nonce"
fi
done
else
# Diff approach for associative array
for var in "${envVarsToReport[@]}"; do
if [[ -n "$var" && -n "${(P)var+_}" ]]; then
value="${(P)var}"
__update_env_cache_aa "$var" "$value"
fi
done
# Track missing env vars not needed for now, as we are only tracking pre-defined env var from terminalEnvironment.
fi
else
# Two arrays approach
if [[ ${#__vsc_env_keys[@]} -eq 0 ]] && [[ ${#__vsc_env_values[@]} -eq 0 ]]; then
# Non-associative arrays are both empty, do not diff, just add
for key in "${envVarsToReport[@]}"; do
if [[ -n "$key" && -n "${(P)key+_}" ]]; then
value="${(P)key}"
__vsc_env_keys+=("$key")
__vsc_env_values+=("$value")
builtin printf '\e]633;EnvSingleEntry;%s;%s;%s\a' "$key" "$(__vsc_escape_value "$value")" "$__vsc_nonce"
fi
done
else
# Diff approach for non-associative arrays
for var in "${envVarsToReport[@]}"; do
if [[ -n "$var" && -n "${(P)var+_}" ]]; then
value="${(P)var}"
__update_env_cache "$var" "$value"
fi
done
# Track missing env vars not needed for now, as we are only tracking pre-defined env var from terminalEnvironment.
fi
fi
builtin printf '\e]633;EnvSingleEnd;%s;\a' $__vsc_nonce
fi
}
__vsc_command_output_start() {
builtin printf '\e]633;E;%s;%s\a' "$(__vsc_escape_value "${__vsc_current_command}")" $__vsc_nonce
builtin printf '\e]633;C\a'
}
__vsc_continuation_start() {
builtin printf '\e]633;F\a'
}
__vsc_continuation_end() {
builtin printf '\e]633;G\a'
}
__vsc_right_prompt_start() {
builtin printf '\e]633;H\a'
}
__vsc_right_prompt_end() {
builtin printf '\e]633;I\a'
}
__vsc_command_complete() {
if [[ "$__vsc_current_command" == "" ]]; then
builtin printf '\e]633;D\a'
else
builtin printf '\e]633;D;%s\a' "$__vsc_status"
fi
__vsc_update_cwd
}
if [[ -o NOUNSET ]]; then
if [ -z "${RPROMPT-}" ]; then
RPROMPT=""
fi
fi
__vsc_update_prompt() {
__vsc_prior_prompt="$PS1"
__vsc_prior_prompt2="$PS2"
__vsc_in_command_execution=""
PS1="%{$(__vsc_prompt_start)%}$PS1%{$(__vsc_prompt_end)%}"
PS2="%{$(__vsc_continuation_start)%}$PS2%{$(__vsc_continuation_end)%}"
if [ -n "$RPROMPT" ]; then
__vsc_prior_rprompt="$RPROMPT"
RPROMPT="%{$(__vsc_right_prompt_start)%}$RPROMPT%{$(__vsc_right_prompt_end)%}"
fi
}
__vsc_precmd() {
builtin local __vsc_status="$?"
if [ -z "${__vsc_in_command_execution-}" ]; then
# not in command execution
__vsc_command_output_start
fi
__vsc_command_complete "$__vsc_status"
__vsc_current_command=""
# in command execution
if [ -n "$__vsc_in_command_execution" ]; then
# non null
__vsc_update_prompt
fi
__vsc_update_env
}
__vsc_preexec() {
PS1="$__vsc_prior_prompt"
PS2="$__vsc_prior_prompt2"
if [ -n "$RPROMPT" ]; then
RPROMPT="$__vsc_prior_rprompt"
fi
__vsc_in_command_execution="1"
__vsc_current_command=$1
__vsc_command_output_start
}
add-zsh-hook precmd __vsc_precmd
add-zsh-hook preexec __vsc_preexec
if [[ $options[login] = off && $USER_ZDOTDIR != $VSCODE_ZDOTDIR ]]; then
ZDOTDIR=$USER_ZDOTDIR
fi

View File

@@ -0,0 +1,252 @@
# ---------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for license information.
# ---------------------------------------------------------------------------------------------
#
# Visual Studio Code terminal integration for fish
#
# Manual installation:
#
# (1) Add the following to the end of `$__fish_config_dir/config.fish`:
#
# string match -q "$TERM_PROGRAM" "vscode"
# and . (code --locate-shell-integration-path fish)
#
# (2) Restart fish.
# Don't run in scripts, other terminals, or more than once per session.
status is-interactive
and string match --quiet "$TERM_PROGRAM" "vscode"
and ! set --query VSCODE_SHELL_INTEGRATION
or exit
set --global VSCODE_SHELL_INTEGRATION 1
set --global __vscode_shell_env_reporting $VSCODE_SHELL_ENV_REPORTING
set -e VSCODE_SHELL_ENV_REPORTING
set -g envVarsToReport
if test -n "$__vscode_shell_env_reporting"
set envVarsToReport (string split "," "$__vscode_shell_env_reporting")
end
# Apply any explicit path prefix (see #99878)
# On fish, '$fish_user_paths' is always prepended to the PATH, for both login and non-login shells, so we need
# to apply the path prefix fix always, not only for login shells (see #232291)
if set -q VSCODE_PATH_PREFIX
set -gx PATH "$VSCODE_PATH_PREFIX$PATH"
end
set -e VSCODE_PATH_PREFIX
set -g vsc_env_keys
set -g vsc_env_values
# Tracks if the shell has been initialized, this prevents
set -g vsc_initialized 0
set -g __vsc_applied_env_vars 0
function __vsc_apply_env_vars
if test $__vsc_applied_env_vars -eq 1;
return
end
set -l __vsc_applied_env_vars 1
# 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 -m1 = $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 -m1 = $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 -m1 = $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
end
# Register Python shell activate hooks
# Prevent multiple activation with guard
if not set -q VSCODE_PYTHON_AUTOACTIVATE_GUARD
set -gx VSCODE_PYTHON_AUTOACTIVATE_GUARD 1
if test -n "$VSCODE_PYTHON_FISH_ACTIVATE"; and test "$TERM_PROGRAM" = "vscode"
# Fish does not crash on eval failure, so don't need negation.
eval $VSCODE_PYTHON_FISH_ACTIVATE
set __vsc_activation_status $status
if test $__vsc_activation_status -ne 0
builtin printf '\x1b[0m\x1b[7m * \x1b[0;103m VS Code Python fish activation failed with exit code %d \x1b[0m \n' "$__vsc_activation_status"
end
end
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)
end
# Sent right before executing an interactive command.
# Marks the beginning of command output.
function __vsc_cmd_executed --on-event fish_preexec
__vsc_esc E (__vsc_escape_value "$argv") $__vsc_nonce
__vsc_esc C
# Creates a marker to indicate a command was run.
set --global _vsc_has_cmd
end
# Escape a value for use in the 'P' ("Property") or 'E' ("Command Line") sequences.
# Backslashes are doubled and non-alphanumeric characters are hex encoded.
function __vsc_escape_value
# Escape backslashes and semi-colons
echo $argv \
| string replace --all '\\' '\\\\' \
| string replace --all ';' '\\x3b' \
;
end
# Sent right after an interactive command has finished executing.
# Marks the end of command output.
function __vsc_cmd_finished --on-event fish_postexec
__vsc_esc D $status
end
# Sent when a command line is cleared or reset, but no command was run.
# Marks the cleared line with neither success nor failure.
function __vsc_cmd_clear --on-event fish_cancel
if test $vsc_initialized -eq 0;
return
end
__vsc_esc E "" $__vsc_nonce
__vsc_esc C
__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
__vsc_esc P Cwd=(__vsc_escape_value "$PWD")
# If a command marker exists, remove it.
# Otherwise, the commandline is empty and no command was run.
if set --query _vsc_has_cmd
set --erase _vsc_has_cmd
else
__vsc_cmd_clear
end
end
if test -n "$__vscode_shell_env_reporting"
function __vsc_update_env --on-event fish_prompt
if test (count $envVarsToReport) -gt 0
__vsc_esc EnvSingleStart 1
for key in $envVarsToReport
if set -q $key
set -l value $$key
__vsc_esc EnvSingleEntry $key (__vsc_escape_value "$value")
end
end
__vsc_esc EnvSingleEnd
end
end
end
# Sent at the start of the prompt.
# Marks the beginning of the prompt (and, implicitly, a new line).
function __vsc_fish_prompt_start
# Applying environment variables is deferred to after config.fish has been
# evaluated
__vsc_apply_env_vars
__vsc_esc A
set -g vsc_initialized 1
end
# Sent at the end of the prompt.
# Marks the beginning of the user's command input.
function __vsc_fish_cmd_start
__vsc_esc B
end
function __vsc_fish_has_mode_prompt -d "Returns true if fish_mode_prompt is defined and not empty"
functions fish_mode_prompt | string match -rvq '^ *(#|function |end$|$)'
end
# 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).
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_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
end
end
end
# Report prompt type
if set -q POSH_SESSION_ID
__vsc_esc P PromptType=oh-my-posh
end
# Report this shell supports rich command detection
__vsc_esc P HasRichCommandDetection=True
__preserve_fish_prompt

View File

@@ -0,0 +1,262 @@
# ---------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for license information.
# ---------------------------------------------------------------------------------------------
# Prevent installing more than once per session
if ((Test-Path variable:global:__VSCodeState) -and $null -ne $Global:__VSCodeState.OriginalPrompt) {
return;
}
# Disable shell integration when the language mode is restricted
if ($ExecutionContext.SessionState.LanguageMode -ne "FullLanguage") {
return;
}
$Global:__VSCodeState = @{
OriginalPrompt = $function:Prompt
LastHistoryId = -1
IsInExecution = $false
EnvVarsToReport = @()
Nonce = $null
IsStable = $null
IsA11yMode = $null
IsWindows10 = $false
}
# Store the nonce in a regular variable and unset the environment variable. It's by design that
# anything that can execute PowerShell code can read the nonce, as it's basically impossible to hide
# in PowerShell. The most important thing is getting it out of the environment.
$Global:__VSCodeState.Nonce = $env:VSCODE_NONCE
$env:VSCODE_NONCE = $null
$Global:__VSCodeState.IsStable = $env:VSCODE_STABLE
$env:VSCODE_STABLE = $null
$Global:__VSCodeState.IsA11yMode = $env:VSCODE_A11Y_MODE
$env:VSCODE_A11Y_MODE = $null
$__vscode_shell_env_reporting = $env:VSCODE_SHELL_ENV_REPORTING
$env:VSCODE_SHELL_ENV_REPORTING = $null
if ($__vscode_shell_env_reporting) {
$Global:__VSCodeState.EnvVarsToReport = $__vscode_shell_env_reporting.Split(',')
}
Remove-Variable -Name __vscode_shell_env_reporting -ErrorAction SilentlyContinue
$osVersion = [System.Environment]::OSVersion.Version
$Global:__VSCodeState.IsWindows10 = $IsWindows -and $osVersion.Major -eq 10 -and $osVersion.Minor -eq 0 -and $osVersion.Build -lt 22000
Remove-Variable -Name osVersion -ErrorAction SilentlyContinue
if ($env:VSCODE_ENV_REPLACE) {
$Split = $env:VSCODE_ENV_REPLACE.Split(":")
foreach ($Item in $Split) {
$Inner = $Item.Split('=', 2)
[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('=', 2)
[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('=', 2)
[Environment]::SetEnvironmentVariable($Inner[0], [Environment]::GetEnvironmentVariable($Inner[0]) + $Inner[1].Replace('\x3a', ':'))
}
$env:VSCODE_ENV_APPEND = $null
}
# Register Python shell activate hooks
# Prevent multiple activation with guard
if (-not $env:VSCODE_PYTHON_AUTOACTIVATE_GUARD) {
$env:VSCODE_PYTHON_AUTOACTIVATE_GUARD = '1'
if ($env:VSCODE_PYTHON_PWSH_ACTIVATE -and $env:TERM_PROGRAM -eq 'vscode') {
$activateScript = $env:VSCODE_PYTHON_PWSH_ACTIVATE
Remove-Item Env:VSCODE_PYTHON_PWSH_ACTIVATE
try {
Invoke-Expression $activateScript
$Global:__VSCodeState.OriginalPrompt = $function:Prompt
}
catch {
$activationError = $_
Write-Host "`e[0m`e[7m * `e[0;103m VS Code Python powershell activation failed with exit code $($activationError.Exception.Message) `e[0m"
}
}
}
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.
[regex]::Replace($value, "[$([char]0x00)-$([char]0x1f)\\\n;]", { param($match)
# Encode the (ascii) matches as `\x<hex>`
-Join (
[System.Text.Encoding]::UTF8.GetBytes($match.Value) | ForEach-Object { '\x{0:x2}' -f $_ }
)
})
}
function Global:Prompt() {
$FakeCode = [int]!$global:?
# NOTE: We disable strict mode for the scope of this function because it unhelpfully throws an
# error when $LastHistoryEntry is null, and is not otherwise useful.
Set-StrictMode -Off
$LastHistoryEntry = Get-History -Count 1
$Result = ""
# Skip finishing the command if the first command has not yet started or an execution has not
# yet begun
if ($Global:__VSCodeState.LastHistoryId -ne -1 -and ($Global:__VSCodeState.HasPSReadLine -eq $false -or $Global:__VSCodeState.IsInExecution -eq $true)) {
$Global:__VSCodeState.IsInExecution = $false
if ($LastHistoryEntry.Id -eq $Global:__VSCodeState.LastHistoryId) {
# Don't provide a command line or exit code if there was no history entry (eg. ctrl+c, enter on no command)
$Result += "$([char]0x1b)]633;D`a"
}
else {
# Command finished exit code
# OSC 633 ; D [; <ExitCode>] ST
$Result += "$([char]0x1b)]633;D;$FakeCode`a"
}
}
# Prompt started
# OSC 633 ; A ST
$Result += "$([char]0x1b)]633;A`a"
# Current working directory
# OSC 633 ; <Property>=<Value> ST
$Result += if ($pwd.Provider.Name -eq 'FileSystem') { "$([char]0x1b)]633;P;Cwd=$(__VSCode-Escape-Value $pwd.ProviderPath)`a" }
# Send current environment variables as JSON
# OSC 633 ; EnvJson ; <Environment> ; <Nonce>
if ($Global:__VSCodeState.EnvVarsToReport.Count -gt 0) {
$envMap = @{}
foreach ($varName in $Global:__VSCodeState.EnvVarsToReport) {
if (Test-Path "env:$varName") {
$envMap[$varName] = (Get-Item "env:$varName").Value
}
}
$envJson = $envMap | ConvertTo-Json -Compress
$Result += "$([char]0x1b)]633;EnvJson;$(__VSCode-Escape-Value $envJson);$($Global:__VSCodeState.Nonce)`a"
}
# Before running the original prompt, put $? back to what it was:
if ($FakeCode -ne 0) {
Write-Error "failure" -ea ignore
}
# Run the original prompt
$OriginalPrompt += $Global:__VSCodeState.OriginalPrompt.Invoke()
$Result += $OriginalPrompt
# Prompt
# OSC 633 ; <Property>=<Value> ST
if ($Global:__VSCodeState.IsStable -eq "0") {
$Result += "$([char]0x1b)]633;P;Prompt=$(__VSCode-Escape-Value $OriginalPrompt)`a"
}
# Write command started
$Result += "$([char]0x1b)]633;B`a"
$Global:__VSCodeState.LastHistoryId = $LastHistoryEntry.Id
return $Result
}
# Report prompt type
if ($env:STARSHIP_SESSION_KEY) {
[Console]::Write("$([char]0x1b)]633;P;PromptType=starship`a")
}
elseif ($env:POSH_SESSION_ID) {
[Console]::Write("$([char]0x1b)]633;P;PromptType=oh-my-posh`a")
}
elseif ((Test-Path variable:global:GitPromptSettings) -and $Global:GitPromptSettings) {
[Console]::Write("$([char]0x1b)]633;P;PromptType=posh-git`a")
}
if ($Global:__VSCodeState.IsA11yMode -eq "1") {
if (-not (Get-Module -Name PSReadLine)) {
$scriptRoot = Split-Path -Parent $MyInvocation.MyCommand.Path
$specialPsrlPath = Join-Path $scriptRoot 'psreadline'
Import-Module $specialPsrlPath
if (Get-Module -Name PSReadLine) {
Set-PSReadLineOption -EnableScreenReaderMode
}
}
}
# Only send the command executed sequence when PSReadLine is loaded, if not shell integration should
# still work thanks to the command line sequence
$Global:__VSCodeState.HasPSReadLine = $false
if (Get-Module -Name PSReadLine) {
$Global:__VSCodeState.HasPSReadLine = $true
[Console]::Write("$([char]0x1b)]633;P;HasRichCommandDetection=True`a")
$Global:__VSCodeState.OriginalPSConsoleHostReadLine = $function:PSConsoleHostReadLine
function Global:PSConsoleHostReadLine {
$CommandLine = $Global:__VSCodeState.OriginalPSConsoleHostReadLine.Invoke()
$Global:__VSCodeState.IsInExecution = $true
# Command line
# OSC 633 ; E [; <CommandLine> [; <Nonce>]] ST
$Result = "$([char]0x1b)]633;E;"
$Result += $(__VSCode-Escape-Value $CommandLine)
# Only send the nonce if the OS is not Windows 10 as it seems to echo to the terminal
# sometimes
if ($Global:__VSCodeState.IsWindows10 -eq $false) {
$Result += ";$($Global:__VSCodeState.Nonce)"
}
$Result += "`a"
# Command executed
# OSC 633 ; C ST
$Result += "$([char]0x1b)]633;C`a"
# Write command executed sequence directly to Console to avoid the new line from Write-Host
[Console]::Write($Result)
$CommandLine
}
# Set ContinuationPrompt property
$Global:__VSCodeState.ContinuationPrompt = (Get-PSReadLineOption).ContinuationPrompt
if ($Global:__VSCodeState.ContinuationPrompt) {
[Console]::Write("$([char]0x1b)]633;P;ContinuationPrompt=$(__VSCode-Escape-Value $Global:__VSCodeState.ContinuationPrompt)`a")
}
}
# Set IsWindows property
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 {
param ([string[]] $Chord, [string[]]$Sequence)
try {
$Handler = Get-PSReadLineKeyHandler -Chord $Chord | Select-Object -First 1
}
catch [System.Management.Automation.ParameterBindingException] {
# PowerShell 5.1 ships with PSReadLine 2.0.0 which does not have -Chord,
# so we check what's bound and filter it.
$Handler = Get-PSReadLineKeyHandler -Bound | Where-Object -FilterScript { $_.Key -eq $Chord } | Select-Object -First 1
}
if ($Handler) {
Set-PSReadLineKeyHandler -Chord $Sequence -Function $Handler.Function
}
}
function Set-MappedKeyHandlers {
Set-MappedKeyHandler -Chord Ctrl+Spacebar -Sequence 'F12,a'
Set-MappedKeyHandler -Chord Alt+Spacebar -Sequence 'F12,b'
Set-MappedKeyHandler -Chord Shift+Enter -Sequence 'F12,c'
Set-MappedKeyHandler -Chord Shift+End -Sequence 'F12,d'
}
if ($Global:__VSCodeState.HasPSReadLine) {
Set-MappedKeyHandlers
}