diff --git a/keyboard.zsh b/keyboard.zsh index 36dc8453..dbcb6503 100644 --- a/keyboard.zsh +++ b/keyboard.zsh @@ -124,199 +124,202 @@ function prepend-sudo() { } zle -N prepend-sudo -zstyle -s ':omz:editor' keymap 'keymap' -if [[ "$keymap" == (emacs|) ]]; then - # Use Emacs key bindings. - bindkey -e - - [[ -n "$keyinfo[Escape]" ]] && \ - for key in "$keyinfo[Escape]"{B,b}; \ - bindkey -M emacs "$key" emacs-backward-word - [[ -n "$keyinfo[Escape]" ]] && \ - for key in "$keyinfo[Escape]"{F,f}; \ - bindkey -M emacs "$key" emacs-forward-word - [[ -n "$keyinfo[Escape]" && -n "$keyinfo[Left]" ]] && \ - bindkey -M emacs "$keyinfo[Escape]$keyinfo[Left]" emacs-backward-word - [[ -n "$keyinfo[Escape]" && -n "$keyinfo[Right]" ]] && \ - bindkey -M emacs "$keyinfo[Escape]$keyinfo[Right]" emacs-forward-word - - # Kill to the beginning of the line. - [[ -n "$keyinfo[Escape]" ]] && \ - for key in "$keyinfo[Escape]"{K,k}; \ - bindkey -M emacs "$key" backward-kill-line +# Emacs key bindings. +[[ -n "$keyinfo[Escape]" ]] && \ + for key in "$keyinfo[Escape]"{B,b}; \ + bindkey -M emacs "$key" emacs-backward-word +[[ -n "$keyinfo[Escape]" ]] && \ + for key in "$keyinfo[Escape]"{F,f}; \ + bindkey -M emacs "$key" emacs-forward-word +[[ -n "$keyinfo[Escape]" && -n "$keyinfo[Left]" ]] && \ + bindkey -M emacs "$keyinfo[Escape]$keyinfo[Left]" emacs-backward-word +[[ -n "$keyinfo[Escape]" && -n "$keyinfo[Right]" ]] && \ + bindkey -M emacs "$keyinfo[Escape]$keyinfo[Right]" emacs-forward-word + +# Kill to the beginning of the line. +[[ -n "$keyinfo[Escape]" ]] && \ + for key in "$keyinfo[Escape]"{K,k}; \ + bindkey -M emacs "$key" backward-kill-line - # Redo. - [[ -n "$keyinfo[Escape]" ]] && \ - bindkey -M emacs "$keyinfo[Escape]_" redo +# Redo. +[[ -n "$keyinfo[Escape]" ]] && \ + bindkey -M emacs "$keyinfo[Escape]_" redo - # Search previous character. - [[ -n "$keyinfo[Control]" ]] && \ - bindkey -M emacs "$keyinfo[Control]X$keyinfo[Control]B" vi-find-prev-char +# Search previous character. +[[ -n "$keyinfo[Control]" ]] && \ + bindkey -M emacs "$keyinfo[Control]X$keyinfo[Control]B" vi-find-prev-char - # Match bracket. - [[ -n "$keyinfo[Control]" ]] && \ - bindkey -M emacs "$keyinfo[Control]X$keyinfo[Control]]" vi-match-bracket +# Match bracket. +[[ -n "$keyinfo[Control]" ]] && \ + bindkey -M emacs "$keyinfo[Control]X$keyinfo[Control]]" vi-match-bracket - # Edit command in an external editor. - [[ -n "$keyinfo[Control]" ]] && \ - bindkey -M emacs "$keyinfo[Control]X$keyinfo[Control]E" edit-command-line +# Edit command in an external editor. +[[ -n "$keyinfo[Control]" ]] && \ + bindkey -M emacs "$keyinfo[Control]X$keyinfo[Control]E" edit-command-line - # Expand .... to ../.. - if zstyle -t ':omz:editor' dot-expansion; then - bindkey -M emacs "." expand-dot-to-parent-directory-path - fi +# Expand .... to ../.. +if zstyle -t ':omz:editor' dot-expansion; then + bindkey -M emacs "." expand-dot-to-parent-directory-path +fi - # Bind to history substring search plugin if enabled; - # otherwise, bind to built-in Zsh history search. - if (( $+widgets[history-incremental-pattern-search-backward] )); then - [[ -n "$keyinfo[Control]" ]] && \ - bindkey -M emacs "$keyinfo[Control]R" \ - history-incremental-pattern-search-backward - [[ -n "$keyinfo[Control]" ]] && \ - bindkey -M emacs "$keyinfo[Control]S" \ - history-incremental-pattern-search-forward - else - [[ -n "$keyinfo[Control]" ]] && \ - bindkey -M emacs "$keyinfo[Control]R" \ - history-incremental-search-backward - [[ -n "$keyinfo[Control]" ]] && \ - bindkey -M emacs "$keyinfo[Control]S" \ - history-incremental-search-forward - fi -elif [[ "$keymap" == vi ]]; then - # Use vi key bindings. - bindkey -v +# Bind to history substring search plugin if enabled; +# otherwise, bind to built-in Zsh history search. +if (( $+widgets[history-incremental-pattern-search-backward] )); then + [[ -n "$keyinfo[Control]" ]] && \ + bindkey -M emacs "$keyinfo[Control]R" \ + history-incremental-pattern-search-backward + [[ -n "$keyinfo[Control]" ]] && \ + bindkey -M emacs "$keyinfo[Control]S" \ + history-incremental-pattern-search-forward +else + [[ -n "$keyinfo[Control]" ]] && \ + bindkey -M emacs "$keyinfo[Control]R" \ + history-incremental-search-backward + [[ -n "$keyinfo[Control]" ]] && \ + bindkey -M emacs "$keyinfo[Control]S" \ + history-incremental-search-forward +fi - # Edit command in an external editor. - bindkey -M vicmd "v" edit-command-line +# Vi key bindings. - # Show cursor position. - bindkey -M vicmd "ga" what-cursor-position +# Edit command in an external editor. +bindkey -M vicmd "v" edit-command-line - # Undo/Redo - bindkey -M vicmd "u" undo - [[ -n "$keyinfo[Control]" ]] && \ - bindkey -M vicmd "$keyinfo[Control]R" redo +# Show cursor position. +bindkey -M vicmd "ga" what-cursor-position - # Expand .... to ../.. - if zstyle -t ':omz:editor' dot-expansion; then - bindkey -M viins "." expand-dot-to-parent-directory-path - fi +# Undo/Redo +bindkey -M vicmd "u" undo +[[ -n "$keyinfo[Control]" ]] && \ + bindkey -M vicmd "$keyinfo[Control]R" redo - # Switch to command mode. - bindkey -M viins "jk" vi-cmd-mode - bindkey -M viins "kj" vi-cmd-mode +# Expand .... to ../.. +if zstyle -t ':omz:editor' dot-expansion; then + bindkey -M viins "." expand-dot-to-parent-directory-path +fi - # History - bindkey -M vicmd "gg" beginning-of-history - bindkey -M vicmd "G" end-of-history +# Switch to command mode. +bindkey -M viins "jk" vi-cmd-mode +bindkey -M viins "kj" vi-cmd-mode - # Bind to history substring search plugin if enabled; - # otherwise, bind to built-in Zsh history search. - if (( $+plugins[(er)history-substring-search] )); then - bindkey -M vicmd "k" history-substring-search-up - bindkey -M vicmd "j" history-substring-search-down - else - bindkey -M vicmd "k" up-line-or-history - bindkey -M vicmd "j" down-line-or-history - fi +# History +bindkey -M vicmd "gg" beginning-of-history +bindkey -M vicmd "G" end-of-history - if (( $+widgets[history-incremental-pattern-search-backward] )); then - bindkey -M vicmd "?" history-incremental-pattern-search-backward - bindkey -M vicmd "/" history-incremental-pattern-search-forward - else - bindkey -M vicmd "?" history-incremental-search-backward - bindkey -M vicmd "/" history-incremental-search-forward - fi +# Bind to history substring search plugin if enabled; +# otherwise, bind to built-in Zsh history search. +if (( $+plugins[(er)history-substring-search] )); then + bindkey -M vicmd "k" history-substring-search-up + bindkey -M vicmd "j" history-substring-search-down else - print "omz: invalid keymap: $keymap" >&2 - unset keymap - return 1 + bindkey -M vicmd "k" up-line-or-history + bindkey -M vicmd "j" down-line-or-history fi -unset keymap - -# The next key bindings are for both Emacs and Vi. -[[ -n "$keyinfo[Home]" ]] && \ - bindkey "$keyinfo[Home]" beginning-of-line -[[ -n "$keyinfo[End]" ]] && \ - bindkey "$keyinfo[End]" end-of-line -[[ -n "$keyinfo[Insert]" ]] && \ - bindkey "$keyinfo[Insert]" overwrite-mode -[[ -n "$keyinfo[Delete]" ]] && \ - bindkey "$keyinfo[Delete]" delete-char -[[ -n "$keyinfo[Backspace]" ]] && \ - bindkey "$keyinfo[Backspace]" backward-delete-char && \ - stty erase "$keyinfo[Backspace]" +if (( $+widgets[history-incremental-pattern-search-backward] )); then + bindkey -M vicmd "?" history-incremental-pattern-search-backward + bindkey -M vicmd "/" history-incremental-pattern-search-forward +else + bindkey -M vicmd "?" history-incremental-search-backward + bindkey -M vicmd "/" history-incremental-search-forward +fi -[[ -n "$keyinfo[Left]" ]] && \ - bindkey "$keyinfo[Left]" backward-char -[[ -n "$keyinfo[Right]" ]] && \ - bindkey "$keyinfo[Right]" forward-char +# Emacs and Vi key bindings. +for keymap in 'emacs' 'viins'; do + [[ -n "$keyinfo[Home]" ]] && \ + bindkey -M "$keymap" "$keyinfo[Home]" beginning-of-line + [[ -n "$keyinfo[End]" ]] && \ + bindkey -M "$keymap" "$keyinfo[End]" end-of-line + + [[ -n "$keyinfo[Insert]" ]] && \ + bindkey -M "$keymap" "$keyinfo[Insert]" overwrite-mode + [[ -n "$keyinfo[Delete]" ]] && \ + bindkey -M "$keymap" "$keyinfo[Delete]" delete-char + [[ -n "$keyinfo[Backspace]" ]] && \ + bindkey -M "$keymap" "$keyinfo[Backspace]" backward-delete-char && \ + stty erase "$keyinfo[Backspace]" + + [[ -n "$keyinfo[Left]" ]] && \ + bindkey -M "$keymap" "$keyinfo[Left]" backward-char + [[ -n "$keyinfo[Right]" ]] && \ + bindkey -M "$keymap" "$keyinfo[Right]" forward-char + + # Expand history on space. + bindkey -M "$keymap" ' ' magic-space -# Expand history on space. -bindkey ' ' magic-space + if (( $+plugins[(er)history-substring-search] )); then + [[ -n "$keyinfo[Up]" ]] && \ + bindkey -M "$keymap" "$keyinfo[Up]" history-substring-search-up + [[ -n "$keyinfo[Down]" ]] && \ + bindkey -M "$keymap" "$keyinfo[Down]" history-substring-search-down + [[ -n "$keyinfo[Control]" ]] && \ + bindkey -M "$keymap" "$keyinfo[Control]P" history-substring-search-up + [[ -n "$keyinfo[Control]" ]] && \ + bindkey -M "$keymap" "$keyinfo[Control]N" history-substring-search-down + else + [[ -n "$keyinfo[Up]" ]] && \ + bindkey -M "$keymap" "$keyinfo[Up]" up-line-or-history + [[ -n "$keyinfo[Down]" ]] && \ + bindkey -M "$keymap" "$keyinfo[Down]" down-line-or-history + [[ -n "$keyinfo[Control]" ]] && \ + bindkey -M "$keymap" "$keyinfo[Control]P" up-line-or-history + [[ -n "$keyinfo[Control]" ]] && \ + bindkey -M "$keymap" "$keyinfo[Control]N" down-line-or-history + fi -if (( $+plugins[(er)history-substring-search] )); then - [[ -n "$keyinfo[Up]" ]] && \ - bindkey "$keyinfo[Up]" history-substring-search-up - [[ -n "$keyinfo[Down]" ]] && \ - bindkey "$keyinfo[Down]" history-substring-search-down - [[ -n "$keyinfo[Control]" ]] && \ - bindkey "$keyinfo[Control]P" history-substring-search-up + # Clear screen. [[ -n "$keyinfo[Control]" ]] && \ - bindkey "$keyinfo[Control]N" history-substring-search-down -else - [[ -n "$keyinfo[Up]" ]] && \ - bindkey "$keyinfo[Up]" up-line-or-history - [[ -n "$keyinfo[Down]" ]] && \ - bindkey "$keyinfo[Down]" down-line-or-history - [[ -n "$keyinfo[Control]" ]] && \ - bindkey "$keyinfo[Control]P" up-line-or-history - [[ -n "$keyinfo[Control]" ]] && \ - bindkey "$keyinfo[Control]N" down-line-or-history -fi + bindkey -M "$keymap" "$keyinfo[Control]L" clear-screen -# Clear screen. -[[ -n "$keyinfo[Control]" ]] && \ - bindkey "$keyinfo[Control]L" clear-screen + # Expand command name to full path. + [[ -n "$keyinfo[Escape]" ]] && \ + for key in "$keyinfo[Escape]"{E,e}; \ + bindkey -M "$keymap" "$key" expand-cmd-path -# Expand command name to full path. -[[ -n "$keyinfo[Escape]" ]] && \ - for key in "$keyinfo[Escape]"{E,e}; \ - bindkey "$key" expand-cmd-path + # Duplicate the previous word. + [[ -n "$keyinfo[Escape]" ]] && \ + for key in "$keyinfo[Escape]"{M,m}; \ + bindkey -M "$keymap" "$key" copy-prev-shell-word -# Duplicate the previous word. -[[ -n "$keyinfo[Escape]" ]] && \ - for key in "$keyinfo[Escape]"{M,m}; \ - bindkey "$key" copy-prev-shell-word + # Use a more flexible push-line. + [[ -n "$keyinfo[Control]" && -n "$keyinfo[Escape]" ]] && \ + for key in "$keyinfo[Control]Q" "$keyinfo[Escape]"{q,Q}; \ + bindkey -M "$keymap" "$key" push-line-or-edit -# Bind Shift + Tab to go to the previous menu item. -[[ -n "$keyinfo[BackTab]" ]] && \ - bindkey "$keyinfo[BackTab]" reverse-menu-complete + # Bind Shift + Tab to go to the previous menu item. + [[ -n "$keyinfo[BackTab]" ]] && \ + bindkey -M "$keymap" "$keyinfo[BackTab]" reverse-menu-complete -# Complete in the middle of word. -[[ -n "$keyinfo[Control]" ]] && \ - bindkey "$keyinfo[Control]I" expand-or-complete-prefix + # Complete in the middle of word. + [[ -n "$keyinfo[Control]" ]] && \ + bindkey -M "$keymap" "$keyinfo[Control]I" expand-or-complete-prefix -# Convert .... to ../.. automatically. -if zstyle -t ':omz:editor' dot-expansion; then - # Do not expand during incremental search. - bindkey -M isearch . self-insert 2>/dev/null -fi + # Convert .... to ../.. automatically. + if zstyle -t ':omz:editor' dot-expansion; then + # Do not expand during incremental search. + bindkey -M "$keymap" -M isearch . self-insert 2>/dev/null + fi -# Display an indicator when completing. -[[ -n "$keyinfo[Control]" ]] && \ - bindkey "$keyinfo[Control]I" expand-or-complete-prefix-with-indicator + # Display an indicator when completing. + [[ -n "$keyinfo[Control]" ]] && \ + bindkey -M "$keymap" "$keyinfo[Control]I" \ + expand-or-complete-prefix-with-indicator -# Use a more flexible push-line. -[[ -n "$keyinfo[Control]" && -n "$keyinfo[Escape]" ]] && \ - for key in "$keyinfo[Control]Q" "$keyinfo[Escape]"{q,Q}; \ - bindkey "$key" push-line-or-edit + # Insert 'sudo ' at the beginning of the line. + [[ -n "$keyinfo[Control]" ]] && \ + bindkey -M "$keymap" "$keyinfo[Control]X$keyinfo[Control]S" prepend-sudo +done -# Insert 'sudo ' at the beginning of the line. -[[ -n "$keyinfo[Control]" ]] && \ - bindkey "$keyinfo[Control]X$keyinfo[Control]S" prepend-sudo +# Set the key layout. +zstyle -s ':omz:editor' keymap 'keymap' +if [[ "$keymap" == (emacs|) ]]; then + bindkey -e +elif [[ "$keymap" == vi ]]; then + bindkey -v +else + print "omz: invalid keymap: $keymap" >&2 +fi +unset keymap unset key