From fa3089a6c40924528a3cb946c6c470d6dde43a32 Mon Sep 17 00:00:00 2001 From: Caio Padilha Aguiar Date: Thu, 11 Jan 2024 01:31:27 -0300 Subject: [PATCH] Added Zsh to Shell Integration tutorial --- TerminalDocs/tutorials/shell-integration.md | 54 ++++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-) diff --git a/TerminalDocs/tutorials/shell-integration.md b/TerminalDocs/tutorials/shell-integration.md index c9b8539c..6f84a647 100644 --- a/TerminalDocs/tutorials/shell-integration.md +++ b/TerminalDocs/tutorials/shell-integration.md @@ -71,7 +71,7 @@ To enable these features in the Terminal, you'll want to add the following to yo ] ``` -How you enable these marks in your shell varies from shell to shell. Below are tutorials for CMD and PowerShell. +How you enable these marks in your shell varies from shell to shell. Below are tutorials for CMD, PowerShell and Zsh. ### PowerShell (`pwsh.exe`) @@ -155,6 +155,58 @@ These examples assume your current `PROMPT` is just `$P$G`. You can instead choo PROMPT $e]133;D$e\$e]133;A$e\$e]9;9;$P$e\%PROMPT%$e]133;B$e\ ``` +### Zsh + +Zsh provides the special hook functions `precmd`, `preexec` and `chpwd`: + +* `precmd` - Executed before each prompt. +* `preexec` - Executed just after a command has been read and is about to be executed. +* `chpwd` - Executed whenever the current working directory is changed. + +We'll be using these hooks to mark the start of a prompt, start of command output, end of command output, and to tell the Terminal about the CWD. + +To mark the beginning of a command we can use the Zsh Line Editor special widget `zle-line-init`, which is executed every time the line editor is started to read a new line of input. + +Add the following to your `.zshrc`: + +```zsh +# CWD +keep_current_path() { + printf "\e]9;9;%s\e\\" "$(wslpath -w "$PWD")" +} +chpwd_functions+=(keep_current_path) + +mark_prompt_start() { + printf "\e]133;A\e\\" +} + +mark_command_start() { + # Only emit mark if at the start of a command line + if [[ $CONTEXT == "start" ]]; then + printf "\e]133;B\e\\" + fi +} + +mark_command_executed() { + printf "\e]133;C\e\\" +} + +mark_command_finished() { + # The special variable ? expands to the exit status of the last command + printf "\e]133;D;%s\e\\" $? +} + +# Before each prompt, emit a mark for the end of the previous command +# And after that, a mark for the start of the prompt +precmd_functions+=(mark_command_finished mark_prompt_start) + +# Starting to read new line of input +zle -N zle-line-init mark_command_start + +# Command has been read and is about to be executed +preexec_functions+=(mark_command_executed) +``` + > **Note**: > Don't see your favorite shell here? If you figure it out, feel free to [to contribute a solution for your preferred shell!](https://github.com/MicrosoftDocs/terminal/compare)