#!/usr/bin/env zsh autoload -U add-zsh-hook autoload -U add-zle-hook-widget _cursor_beam() { echo -ne "\\033[5 q" } _cursor_block() { echo -ne "\\033[1 q" } # Change cursor shape for different vi modes. # From `ZSHZLE (1)`: # > Executed every time the keymap changes, i.e. the special parameter KEYMAP is set to a different value, # > while the line editor is active. Initialising the keymap when the line editor starts does # > not cause the widget to be called. # > # > The value $KEYMAP within the function reflects the new keymap. The old keymap is passed as the sole argument. # > # > This can be used for detecting switches between the vi command (vicmd) and insert (usually main) keymaps. _cursor_zle-keymap-select() { : keymap select case "$KEYMAP" in "vicmd" | "block") _cursor_block ;; "main" | "viins" | "" | "beam") _cursor_beam ;; esac } add-zle-hook-widget keymap-select _cursor_zle-keymap-select # From `ZSHZLE(1)`: # > Executed every time the line editor is started to read a new line of input. # > The following example puts the line editor into vi command mode when it starts up. # > # > zle-line-init() { zle -K vicmd; } # > zle -N zle-line-init # > # > (The command inside the function sets the keymap directly; it is equivalent to zle vi-cmd-mode.) _cursor_zle-line-init() { : zle line init _cursor_beam } # > This is similar to zle-line-init but is executed every time the line editor has finished reading a line of input. _cursor_zle-line-finish() { : zle line finish _cursor_block } add-zle-hook-widget line-init _cursor_zle-line-init add-zle-hook-widget line-finish _cursor_zle-line-finish # Use beam shape cursor on startup. _cursor_beam