Skip to content

Latest commit

Β 

History

History
100 lines (74 loc) Β· 3.68 KB

hooks.md

File metadata and controls

100 lines (74 loc) Β· 3.68 KB

Hooks

Hooks are arrays of functions that happen automatically when events occur in your shell. The hooks that are frequently used are chpwd, precmd, preexec, and zshaddhistory.

precmd is executed before your prompt is displayed and is often used to set values in your $PROMPT. preexec is executed between when you press enter on a command prompt but before the command is executed.

Each hook is an array of widgets which are executed by zsh. To display what widgets are in each of your hooks you can use the zhooks function.

Set $PROMPT in precmd

One example of using a hook is by changing your $PROMPT using precmd hook. precmd runs before each prompt which makes it a perfect candidate for setting your $PROMPT.

If you want to create a custom function that sets your $RPROMPT variable to your last command exit code you can use this.

# allows parameter expansion, arithmatic, and shell substitution in prompts
setopt prompt_subst

function check_last_exit_code() {
  local LAST_EXIT_CODE=$?
  if [[ $LAST_EXIT_CODE -ne 0 ]]; then
    local EXIT_CODE_PROMPT=' '
    EXIT_CODE_PROMPT+="%{$fg[red]%}-%{$reset_color%}"
    EXIT_CODE_PROMPT+="%{$fg_bold[red]%}$LAST_EXIT_CODE%{$reset_color%}"
    EXIT_CODE_PROMPT+="%{$fg[red]%}-%{$reset_color%}"
    RPROMPT="$EXIT_CODE_PROMPT"
  else
    RPROMPT=' '
  fi
}

typeset -a precmd_functions
# append the function to our array of precmd functions
precmd_functions+=(check_last_exit_code)

This will run the precmd_functions each time you execute a command and get a new prompt. Notice how we set RPROMPT in the function

Likewise you can also use the function directly to set RPROMPT via a subshell but you'll need to make sure your function echos the text instead of setting the variable directly.

setopt prompt_subst

function check_last_exit_code() {
  local LAST_EXIT_CODE=$?
  if [[ $LAST_EXIT_CODE -ne 0 ]]; then
    local EXIT_CODE_PROMPT=' '
    EXIT_CODE_PROMPT+="%{$fg[red]%}-%{$reset_color%}"
    EXIT_CODE_PROMPT+="%{$fg_bold[red]%}$LAST_EXIT_CODE%{$reset_color%}"
    EXIT_CODE_PROMPT+="%{$fg[red]%}-%{$reset_color%}"
    echo "$EXIT_CODE_PROMPT"
  fi
}

# set RPROMT directly. Will override other functions where it gets set
RPROMPT='$(check_last_exit_code)'

Add Function to Hook

If you want to extend your hooks you can easily do it with the add-zsh-hook which should be available in most zsh packages.

# create a do-ls function
# Make sure to use emulate -L zsh or
# your shell settings and a directory
# named 'rm' could be deadly
do-ls() {emulate -L zsh; ls;}

# add do-ls to chpwd hook
add-zsh-hook chpwd do-ls

cd ~/
Desktop     Music
Documents	Pictures
Downloads	Public

You may need to play with which hook to use and your function definition to get it just right. Many prompt themes will automatically install hooks for you.

Adding Custom Hooks

Sometimes it would be helpful if a widget was a hook. This would allow the widget to run multiple functions when invoked.

You could redefine widgets like zle-line-init and zle-keymap-select with user widgets but that makes it hard to combine smaller functions.

Instead, you can create a custom hook and redefine the widget to invoke your hook. Then you can add/remove functions to the hook as needed.

For that you can use hooks-define-hook and hooks-add-hook from the same plugin.


Previous: prompt | home | Next: aliases