Skip to content

Instantly share code, notes, and snippets.

@Goku-San
Last active January 11, 2022 19:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Goku-San/10a90204b80091823ebd9117b01d3a73 to your computer and use it in GitHub Desktop.
Save Goku-San/10a90204b80091823ebd9117b01d3a73 to your computer and use it in GitHub Desktop.
custom z shell vim mode, no plugins needed...
#!/bin/zsh
# The shebang is just for syntax highlight of the gist!
# Dependencies:
# Terminal emulator that supports true color and unicode symbols!!
# For the x11-clip-wrap-widgets() function, if on Linux you will need xclip or xsel cli, if on MacOS pbcopy!
# Copy and paste to your .zshrc
setopt PROMPT_SUBST # Enable substitution in prompt
directory='%F{cyan}%c%f'
new_line=$'\n'
lvl=$(printf '$%.0s' {1..$SHLVL}) # Increments $ sign if you've started another shell within the main one
# You can add ${vim_mode} and ${vim_mode_tail} to your own left side prompt!
# This is just example of how it will look.
PS1='${vim_mode}%B%F{green}%n@%M%f ${directory}%b${new_line}${vim_mode_tail} '
# Enable vim mode
bindkey -v
export KEYTIMEOUT=1 # Short response time when esc/ins, etc...
# Key bindings
bindkey "^?" backward-delete-char # Set backspace key to delete characters
# Use vim keys in tab complete menu:
bindkey -M menuselect 'h' vi-backward-char
bindkey -M menuselect 'k' vi-up-line-or-history
bindkey -M menuselect 'l' vi-forward-char
bindkey -M menuselect 'j' vi-down-line-or-history
# Yank(copy) and Paste text to system clipboard with xclip(cli clipboard program), from/to vicmd
# Found on
# https://unix.stackexchange.com/questions/25765/pasting-from-clipboard-to-vi-enabled-zsh-or-bash-shell
function x11-clip-wrap-widgets() {
local copy_or_paste=$1
shift
for widget in $@; do
if [[ $copy_or_paste == "copy" ]]; then
eval "
function _x11-clip-wrapped-$widget() {
zle .$widget
xclip -in -selection clipboard <<<\$CUTBUFFER
}
"
else
eval "
function _x11-clip-wrapped-$widget() {
CUTBUFFER=\$(xclip -out -selection clipboard)
zle .$widget
}
"
fi
zle -N $widget _x11-clip-wrapped-$widget
done
}
local copy_widgets=(
vi-yank vi-yank-eol vi-delete vi-backward-kill-word vi-change-whole-line
)
local paste_widgets=(
vi-put-{before,after}
)
x11-clip-wrap-widgets copy $copy_widgets
x11-clip-wrap-widgets paste $paste_widgets
# Edit line in vim insert mode with ctrl-e(its bound to $EDITOR):
autoload edit-command-line; zle -N edit-command-line
bindkey '^e' edit-command-line
# Draw vim mode in PS1
vim_ins_mode='%B%F{green}╭─🔓%f%b'
vim_cmd_mode='%B%F{red}╭─🔒%f%b'
vim_mode=$vim_ins_mode
end_ps_ins_mode="%B%F{green}╰─${lvl}%f%b"
end_ps_cmd_mode="%B%F{red}╰─${lvl}%f%b"
vim_mode_tail=$end_ps_ins_mode
# Change mode visully when entering a <newline>
# prior to completing a command line in an interactive shell.
# Ex. $ "some
# continue~> string"
# or $ whatever long \
# continue~> command
PS2=' ${vim_quote_mode} '
vim_ins_quote="%B%F{green}continue~>%f%b"
vim_cmd_quote="%B%F{red}continue~>%f%b"
function zle-keymap-select {
vim_quote_mode="${${KEYMAP/vicmd/${vim_cmd_quote}}/(main|viins)/${vim_ins_quote}}"
vim_mode="${${KEYMAP/vicmd/${vim_cmd_mode}}/(main|viins)/${vim_ins_mode}}"
vim_mode_tail="${${KEYMAP/vicmd/${end_ps_cmd_mode}}/(main|viins)/${end_ps_ins_mode}}"
zle reset-prompt
}
zle -N zle-keymap-select
# The shell starts in cmd mode
# To change to ins mode, change vicmd to viins
function zle-line-init {
vim_quote_mode=$vim_cmd_quote
vim_mode=$vim_cmd_mode
vim_mode_tail=$end_ps_cmd_mode
zle -K vicmd
}
zle -N zle-line-init
# Found at https://github.com/BrodieRobertson/dotfiles/blob/master/.zshrc
# ci", ci', ci`, di", etc
autoload -U select-quoted
zle -N select-quoted
for m in visual viopp; do
for c in {a,i}{\',\",\`}; do
bindkey -M $m $c select-quoted
done
done
# ci{, ci(, ci<, di{, etc
autoload -U select-bracketed
zle -N select-bracketed
for m in visual viopp; do
for c in {a,i}${(s..)^:-'()[]{}<>bB'}; do
bindkey -M $m $c select-bracketed
done
done
# Bind q letter to exit command
function goodbye() {
bye
}
zle -N goodbye
bindkey -M vicmd 'q' goodbye
# Reload .zshrc and bind it to Alt + r
function reload_zshrc() {
echo "zshrc reloaded!"
source $HOME/.zshrc
zle .accept-line
}
zle -N reload_zshrc
bindkey -M vicmd '^[r' reload_zshrc
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment