Skip to content

Commit

Permalink
feat: shell integration
Browse files Browse the repository at this point in the history
  • Loading branch information
CyanSalt committed Aug 10, 2022
1 parent 4db2705 commit 06282d2
Show file tree
Hide file tree
Showing 14 changed files with 491 additions and 18 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ You can clone or download the repository and build Commas locally.
- [@vue/reactivity](https://github.com/vuejs/vue-next/tree/master/packages/reactivity)
- [electron](https://github.com/electron/electron)
- [node-pty](https://github.com/microsoft/node-pty)
- [vscode](https://github.com/microsoft/vscode)
- [xterm](https://github.com/xtermjs/xterm.js)

## License
Expand Down
9 changes: 6 additions & 3 deletions addons/settings/locales/zh-CN.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@
"Arguments of shell command line#!settings.comments.0.terminal.shell.args": "Shell 命令行的参数",
"Shell Args#!settings.label.terminal.shell.windowsArgs": "Shell 命令行参数",
"Arguments of shell command line (for Windows)#!settings.comments.0.terminal.shell.windowsArgs": "Shell 命令行的参数 (用于 Windows)",
"Extra environment variables#!settings.label.terminal.shell.env": "额外环境变量",
"Extra Environment Variables#!settings.label.terminal.shell.env": "额外环境变量",
"Extra environment variables#!settings.comments.0.terminal.shell.env": "额外的环境变量",
"Enable Shell Integration#!settings.label.terminal.shell.integration": "启用 Shell 集成",
"Allow the terminal to inject scripts into the shell for enhanced functionality#!settings.comments.0.terminal.shell.integration": "允许终端向 Shell 注入脚本以增强功能",
"External#!settings.group.terminal.external": "外部",
"Open External Path In#!settings.label.terminal.external.openPathIn": "打开外部路径于",
"Specify how to open external paths#!settings.comments.0.terminal.external.openPathIn": "指定如何打开外部路径",
Expand All @@ -25,10 +27,11 @@
"Tab#!settings.group.terminal.tab": "标签页",
"Enable Live CWD#!settings.label.terminal.tab.liveCwd": "启用实时工作路径",
"Support dynamic \\w and \\W in formatting#!settings.comments.0.terminal.tab.liveCwd": "在格式中支持动态的 \\w 和 \\W",
"Disabling this feature will slightly improved performance.#!settings.comments.1.terminal.tab.liveCwd": "禁用此特性将略微提升性能",
"Disabling this feature will slightly improved performance#!settings.comments.1.terminal.tab.liveCwd": "禁用此特性将略微提升性能",
"This will be automatically disabled when shell integration is enabled#!settings.comments.2.terminal.tab.liveCwd": "此功能会在 Shell 集成启用时自动禁用",
"Enable Live Icon#!settings.label.terminal.tab.liveIcon": "启用实时图标",
"Support real-time icon (currently for macOS only)#!settings.comments.0.terminal.tab.liveIcon": "支持实时的图标 (目前仅支持 macOS)",
"Disabling this feature will slightly improved performance.#!settings.comments.1.terminal.tab.liveIcon": "禁用此特性将略微提升性能",
"Disabling this feature will slightly improved performance#!settings.comments.1.terminal.tab.liveIcon": "禁用此特性将略微提升性能",
"Enable Live Preview#!settings.label.terminal.tab.livePreview": "启用实时预览",
"Preview latest output in list#!settings.comments.0.terminal.tab.livePreview": "在列表中预览最新输出",
"Tab Title Format#!settings.label.terminal.tab.titleFormat": "标签页标题格式",
Expand Down
184 changes: 184 additions & 0 deletions bin/.shell-integration/bash.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
# Inspired by microsoft/vscode

# Prevent the script recursing when setting up
if [[ -n "$COMMAS_SHELL_INTEGRATION_RUNNING" ]]; then
builtin return
fi

COMMAS_SHELL_INTEGRATION_RUNNING=1

# Run relevant rc/profile only if shell integration has been injected, not when run manually
if [ "$COMMAS_SHELL_INTEGRATION" == "1" ]; then
if [ -z "$COMMAS_SHELL_LOGIN" ]; then
. ~/.bashrc
else
# Imitate -l because --init-file doesn't support it:
# run the first of these files that exists
if [ -f /etc/profile ]; then
. /etc/profile
fi
# exceute the first that exists
if [ -f ~/.bash_profile ]; then
. ~/.bash_profile
elif [ -f ~/.bash_login ]; then
. ~/.bash_login
elif [ -f ~/.profile ]; then
. ~/.profile
fi
builtin unset COMMAS_SHELL_LOGIN
fi
builtin unset COMMAS_SHELL_INTEGRATION
fi

if [ -z "$COMMAS_SHELL_INTEGRATION_RUNNING" ]; then
builtin return
fi

__commas_initialized=0
__commas_original_PS1="$PS1"
__commas_original_PS2="$PS2"
__commas_custom_PS1=""
__commas_custom_PS2=""
__commas_in_command_execution="1"
__commas_current_command=""

__commas_prompt_start() {
builtin printf "\033]633;A\007"
}

__commas_prompt_end() {
builtin printf "\033]633;B\007"
}

__commas_update_cwd() {
builtin printf "\033]633;P;Cwd=%s\007" "$PWD"
}

__commas_command_output_start() {
builtin printf "\033]633;C\007"
builtin printf "\033]633;E;%s\007" "$__commas_current_command"
}

__commas_continuation_start() {
builtin printf "\033]633;F\007"
}

__commas_continuation_end() {
builtin printf "\033]633;G\007"
}

__commas_command_complete() {
if [ "$__commas_current_command" = "" ]; then
builtin printf "\033]633;D\007"
else
builtin printf "\033]633;D;%s\007" "$__commas_status"
fi
__commas_update_cwd
}
__commas_update_prompt() {
# in command execution
if [ "$__commas_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 [[ "$__commas_custom_PS1" == "" || "$__commas_custom_PS1" != "$PS1" ]]; then
__commas_original_PS1=$PS1
__commas_custom_PS1="\[$(__commas_prompt_start)\]$PREFIX$__commas_original_PS1\[$(__commas_prompt_end)\]"
PS1="$__commas_custom_PS1"
fi
if [[ "$__commas_custom_PS2" == "" || "$__commas_custom_PS2" != "$PS2" ]]; then
__commas_original_PS2=$PS2
__commas_custom_PS2="\[$(__commas_continuation_start)\]$__commas_original_PS2\[$(__commas_continuation_end)\]"
PS2="$__commas_custom_PS2"
fi
__commas_in_command_execution="0"
fi
}

__commas_precmd() {
__commas_command_complete "$__commas_status"
__commas_current_command=""
__commas_update_prompt
}

__commas_preexec() {
__commas_initialized=1
if [[ ! "$BASH_COMMAND" =~ ^__commas_prompt* ]]; then
__commas_current_command=$BASH_COMMAND
else
__commas_current_command=""
fi
__commas_command_output_start
}

# Debug trapping/preexec inspired by starship (ISC)
if [[ -n "${bash_preexec_imported:-}" ]]; then
__commas_preexec_only() {
if [ "$__commas_in_command_execution" = "0" ]; then
__commas_in_command_execution="1"
__commas_preexec
fi
}
precmd_functions+=(__commas_prompt_cmd)
preexec_functions+=(__commas_preexec_only)
else
__commas_dbg_trap="$(trap -p DEBUG)"
if [[ "$__commas_db_trap" =~ .*\[\[.* ]]; then
#HACK - is there a better way to do this?
__commas_dbg_trap=${__commas_dbg_trap#'trap -- '*}
__commas_dbg_trap=${__commas_dbg_trap%'DEBUG'}
else
__commas_dbg_trap="$(trap -p DEBUG | cut -d' ' -f3 | tr -d \')"
fi
if [[ -z "$__commas_dbg_trap" ]]; then
__commas_preexec_only() {
if [ "$__commas_in_command_execution" = "0" ]; then
__commas_in_command_execution="1"
__commas_preexec
fi
}
trap '__commas_preexec_only "$_"' DEBUG
elif [[ "$__commas_dbg_trap" != '__commas_preexec "$_"' && "$__commas_dbg_trap" != '__commas_preexec_all "$_"' ]]; then
__commas_preexec_all() {
if [ "$__commas_in_command_execution" = "0" ]; then
__commas_in_command_execution="1"
builtin eval ${__commas_dbg_trap}
__commas_preexec
fi
}
trap '__commas_preexec_all "$_"' DEBUG
fi
fi

__commas_update_prompt

__commas_prompt_cmd_original() {
__commas_status="$?"
# Evaluate the original PROMPT_COMMAND similarly to how bash would normally
# See https://unix.stackexchange.com/a/672843 for technique
if [[ ${#__commas_original_prompt_command[@]} -gt 1 ]]; then
for cmd in "${__commas_original_prompt_command[@]}"; do
__commas_status="$?"
eval "${cmd:-}"
done
else
eval "${__commas_original_prompt_command:-}"
fi
__commas_precmd
}

__commas_prompt_cmd() {
__commas_status="$?"
__commas_precmd
}

# PROMPT_COMMAND arrays and strings seem to be handled the same (handling only the first entry of
# the array?)
__commas_original_prompt_command=$PROMPT_COMMAND

if [[ -z "${bash_preexec_imported:-}" ]]; then
if [[ -n "$__commas_original_prompt_command" && "$__commas_original_prompt_command" != "__commas_prompt_cmd" ]]; then
PROMPT_COMMAND=__commas_prompt_cmd_original
else
PROMPT_COMMAND=__commas_prompt_cmd
fi
fi
7 changes: 7 additions & 0 deletions bin/.shell-integration/zsh/.zlogin
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Inspired by microsoft/vscode

if [[ $options[norcs] = off && -o "login" && -f $USER_ZDOTDIR/.zlogin ]]; then
COMMAS_ZDOTDIR=$ZDOTDIR
ZDOTDIR=$USER_ZDOTDIR
. $USER_ZDOTDIR/.zlogin
fi
8 changes: 8 additions & 0 deletions bin/.shell-integration/zsh/.zprofile
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Inspired by microsoft/vscode

if [[ $options[norcs] = off && -o "login" && -f $USER_ZDOTDIR/.zprofile ]]; then
COMMAS_ZDOTDIR=$ZDOTDIR
ZDOTDIR=$USER_ZDOTDIR
. $USER_ZDOTDIR/.zprofile
ZDOTDIR=$COMMAS_ZDOTDIR
fi
12 changes: 12 additions & 0 deletions bin/.shell-integration/zsh/.zshenv
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Inspired by microsoft/vscode

COMMAS_ZDOTDIR=$ZDOTDIR
if [[ -f ~/.zshenv ]]; then
. ~/.zshenv
fi
if [[ "$ZDOTDIR" != "$COMMAS_ZDOTDIR" ]]; then
USER_ZDOTDIR=$ZDOTDIR
ZDOTDIR=$COMMAS_ZDOTDIR
else
USER_ZDOTDIR=$HOME
fi
130 changes: 130 additions & 0 deletions bin/.shell-integration/zsh/.zshrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
# Inspired by microsoft/vscode

builtin autoload -Uz add-zsh-hook

# Prevent the script recursing when setting up
if [ -n "$COMMAS_SHELL_INTEGRATION_RUNNING" ]; then
builtin return
fi

# This variable allows the shell to both detect that Commas' shell integration is enabled as well
# as disable it by unsetting the variable.
COMMAS_SHELL_INTEGRATION_RUNNING=1

# Only fix up ZDOTDIR if shell integration was injected (not manually installed) and has not been called yet
if [[ "$COMMAS_SHELL_INTEGRATION" == "1" ]]; then
if [[ $options[norcs] = off && -f $USER_ZDOTDIR/.zshrc ]]; then
COMMAS_ZDOTDIR=$ZDOTDIR
ZDOTDIR=$USER_ZDOTDIR
. $USER_ZDOTDIR/.zshrc
ZDOTDIR=$COMMAS_ZDOTDIR
fi

if [[ -f $USER_ZDOTDIR/.zsh_history ]]; then
HISTFILE=$USER_ZDOTDIR/.zsh_history
fi
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 "$COMMAS_SHELL_INTEGRATION_RUNNING" ]; then
builtin return
fi

__commas_in_command_execution="1"
__commas_current_command=""

__commas_prompt_start() {
builtin printf "\033]633;A\007"
}

__commas_prompt_end() {
builtin printf "\033]633;B\007"
}

__commas_update_cwd() {
builtin printf "\033]633;P;Cwd=%s\007" "$PWD"
}

__commas_command_output_start() {
builtin printf "\033]633;C\007"
# Send command line, escaping printf format chars %
builtin printf "\033]633;E;%s\007" "$__commas_current_command"
}

__commas_continuation_start() {
builtin printf "\033]633;F\007"
}

__commas_continuation_end() {
builtin printf "\033]633;G\007"
}

__commas_right_prompt_start() {
builtin printf "\033]633;H\007"
}

__commas_right_prompt_end() {
builtin printf "\033]633;I\007"
}

__commas_command_complete() {
if [[ "$__commas_current_command" == "" ]]; then
builtin printf "\033]633;D\007"
else
builtin printf "\033]633;D;%s\007" "$__commas_status"
fi
__commas_update_cwd
}

if [[ -o NOUNSET ]]; then
if [ -z "${RPROMPT-}" ]; then
RPROMPT=""
fi
if [ -z "${PREFIX-}" ]; then
PREFIX=""
fi
fi
__commas_update_prompt() {
__commas_prior_prompt="$PS1"
__commas_in_command_execution=""
PS1="%{$(__commas_prompt_start)%}$PREFIX$PS1%{$(__commas_prompt_end)%}"
PS2="%{$(__commas_continuation_start)%}$PS2%{$(__commas_continuation_end)%}"
if [ -n "$RPROMPT" ]; then
__commas_prior_rprompt="$RPROMPT"
RPROMPT="%{$(__commas_right_prompt_start)%}$RPROMPT%{$(__commas_right_prompt_end)%}"
fi
}

__commas_precmd() {
local __commas_status="$?"
if [ -z "${__commas_in_command_execution-}" ]; then
# not in command execution
__commas_command_output_start
fi

__commas_command_complete "$__commas_status"
__commas_current_command=""

# in command execution
if [ -n "$__commas_in_command_execution" ]; then
# non null
__commas_update_prompt
fi
}

__commas_preexec() {
PS1="$__commas_prior_prompt"
if [ -n "$RPROMPT" ]; then
RPROMPT="$__commas_prior_rprompt"
fi
__commas_in_command_execution="1"
__commas_current_command=$1
__commas_command_output_start
}
add-zsh-hook precmd __commas_precmd
add-zsh-hook preexec __commas_preexec

if [[ $options[login] = off ]]; then
ZDOTDIR=$USER_ZDOTDIR
fi
Loading

0 comments on commit 06282d2

Please sign in to comment.