feat: zsh+atuin prefix search
This commit is contained in:
parent
a027558058
commit
05873b37d6
348
data/zsh/zshrc
348
data/zsh/zshrc
|
@ -1,134 +1,50 @@
|
|||
|
||||
# Use emacs-like key bindings by default:
|
||||
bindkey -e
|
||||
|
||||
# Autoloading
|
||||
autoload colors && colors
|
||||
autoload add-zsh-hook
|
||||
autoload zmv
|
||||
autoload zed
|
||||
if autoload history-search-end; then
|
||||
zle -N history-beginning-search-backward-end history-search-end
|
||||
zle -N history-beginning-search-forward-end history-search-end
|
||||
fi
|
||||
|
||||
|
||||
function bind2maps() {
|
||||
local i sequence widget
|
||||
local -a maps
|
||||
|
||||
while [[ "$1" != "--" ]]; do
|
||||
maps+=( "$1" )
|
||||
shift
|
||||
done
|
||||
shift
|
||||
|
||||
if [[ "$1" == "-s" ]]; then
|
||||
shift
|
||||
sequence="$1"
|
||||
else
|
||||
sequence="${key[$1]}"
|
||||
fi
|
||||
widget="$2"
|
||||
|
||||
[[ -z "$sequence" ]] && return 1
|
||||
|
||||
for i in "${maps[@]}"; do
|
||||
bindkey -M "$i" "$sequence" "$widget"
|
||||
function str_to_hex() {
|
||||
local str="$1"
|
||||
for (( i=0; i<${#str}; i++ )); do
|
||||
printf "%02x" "'${str:$i:1}"
|
||||
done
|
||||
}
|
||||
|
||||
typeset -A key
|
||||
key=(
|
||||
Home "${terminfo[khome]}"
|
||||
End "${terminfo[kend]}"
|
||||
Insert "${terminfo[kich1]}"
|
||||
Delete "${terminfo[kdch1]}"
|
||||
Up "${terminfo[kcuu1]}"
|
||||
Down "${terminfo[kcud1]}"
|
||||
Left "${terminfo[kcub1]}"
|
||||
Right "${terminfo[kcuf1]}"
|
||||
PageUp "${terminfo[kpp]}"
|
||||
PageDown "${terminfo[knp]}"
|
||||
BackTab "${terminfo[kcbt]}"
|
||||
)
|
||||
|
||||
bind2maps emacs -- Home beginning-of-line
|
||||
bind2maps emacs -- End end-of-line
|
||||
bind2maps viins vicmd -- Home vi-beginning-of-line
|
||||
bind2maps viins vicmd -- End vi-end-of-line
|
||||
bind2maps emacs viins -- Insert overwrite-mode
|
||||
bind2maps vicmd -- Insert vi-insert
|
||||
bind2maps emacs -- Delete delete-char
|
||||
bind2maps viins vicmd -- Delete vi-delete-char
|
||||
bind2maps emacs -- Left backward-char
|
||||
bind2maps viins vicmd -- Left vi-backward-char
|
||||
bind2maps emacs -- Right forward-char
|
||||
bind2maps viins vicmd -- Right vi-forward-char
|
||||
bind2maps emacs viins -- -s '^xp' history-beginning-search-backward-end
|
||||
bind2maps emacs viins -- -s '^xP' history-beginning-search-forward-end
|
||||
bind2maps emacs viins -- PageUp history-beginning-search-backward-end
|
||||
bind2maps emacs viins -- PageDown history-beginning-search-forward-end
|
||||
bind2maps emacs viins -- -s ' ' magic-space
|
||||
function atuin-prefix-search-any-end() {
|
||||
|
||||
# Use Ctrl-left-arrow and Ctrl-right-arrow for jumping to word-beginnings on
|
||||
# the command line.
|
||||
# kitty: Shift-Left/Right
|
||||
bind2maps emacs viins vicmd -- -s '\e[1;2C' forward-word
|
||||
bind2maps emacs viins vicmd -- -s '\e[1;2D' backward-word
|
||||
# kitty: Alt-Left/Right
|
||||
bind2maps emacs viins vicmd -- -s '\e[1;3C' forward-word
|
||||
bind2maps emacs viins vicmd -- -s '\e[1;3D' backward-word
|
||||
# kitty: Ctrl-Del
|
||||
bind2maps emacs viins vicmd -- -s '\e[3;5~' kill-line
|
||||
# Key bindings
|
||||
bind2maps emacs viins vicmd -- -s '^H' backward-kill-line
|
||||
bind2maps emacs viins vicmd -- -s '^P' expand-or-complete-prefix
|
||||
if [[ -v _atuin_search_prev_buffer ]] && [[ $_atuin_search_prev_buffer == $BUFFER ]]; then
|
||||
_atuin_search_offset=$((_atuin_search_offset + $direction))
|
||||
else
|
||||
[[ "$direction" == -1 ]] && return 1
|
||||
_atuin_search_offset=0
|
||||
_atuin_search_prefix=$LBUFFER
|
||||
_atuin_search_orig_buffer=$BUFFER
|
||||
_atuin_search_orig_cursor=$CURSOR
|
||||
fi
|
||||
if [[ "$_atuin_search_offset" -ge 0 ]] && zle atuin-prefix-search; then
|
||||
zle .end-of-line
|
||||
_atuin_search_prev_buffer=$BUFFER
|
||||
else
|
||||
if [[ $_atuin_search_offset -lt 0 ]];then
|
||||
_atuin_search_offset=0
|
||||
BUFFER=$_atuin_search_orig_buffer
|
||||
CURSOR=$_atuin_search_orig_cursor
|
||||
else
|
||||
_atuin_search_offset=$((_atuin_search_offset - 1))
|
||||
fi
|
||||
return 1
|
||||
fi
|
||||
zle reset-prompt
|
||||
|
||||
# Enable partial search using up and down keys for completion
|
||||
bind2maps emacs viins vicmd -- -s '^[[A' history-beginning-search-backward-end
|
||||
bind2maps emacs viins vicmd -- -s '^[[B' history-beginning-search-forward-end
|
||||
bind2maps emacs viins vicmd -- -s '\eOA' history-beginning-search-backward-end
|
||||
bind2maps emacs viins vicmd -- -s '\eOB' history-beginning-search-forward-end
|
||||
}; zle -N atuin-prefix-search-any-end
|
||||
|
||||
# Completion
|
||||
autoload -Uz compinit
|
||||
compinit
|
||||
function atuin-prefix-search-backward-end() {
|
||||
direction=1 atuin-prefix-search-any-end
|
||||
}; zle -N atuin-prefix-search-backward-end
|
||||
|
||||
# Make sure the completion system is initialised
|
||||
(( ${+_comps} )) || return 1
|
||||
function atuin-prefix-search-forward-end() {
|
||||
direction=-1 atuin-prefix-search-any-end
|
||||
}; zle -N atuin-prefix-search-forward-end
|
||||
|
||||
# Don't insert tabs when there is no completion (e.g. beginning of line)
|
||||
zstyle ':completion:*' insert-tab false
|
||||
|
||||
# allow one error for every three characters typed in approximate completer
|
||||
zstyle ':completion:*:approximate:' max-errors 'reply=( $((($#PREFIX+$#SUFFIX)/3 )) numeric )'
|
||||
|
||||
# don't complete backup files as executables
|
||||
zstyle ':completion:*:complete:-command-::commands' ignored-patterns '(aptitude-*|*\~)'
|
||||
|
||||
# start menu completion only if it could find no unambiguous initial string
|
||||
zstyle ':completion:*:correct:*' insert-unambiguous true
|
||||
zstyle ':completion:*:corrections' format $'%{\e[0;31m%}%d (errors: %e)%{\e[0m%}'
|
||||
zstyle ':completion:*:correct:*' original true
|
||||
|
||||
# activate color-completion
|
||||
zstyle ':completion:*:default' list-colors ${(s.:.)LS_COLORS}
|
||||
|
||||
# format on completion
|
||||
zstyle ':completion:*:descriptions' format $'\e[0;31mcompleting \e[1m%d\e[0m'
|
||||
|
||||
# insert all expansions for expand completer
|
||||
zstyle ':completion:*:expand:*' tag-order all-expansions
|
||||
zstyle ':completion:*:history-words' list false
|
||||
|
||||
# activate menu
|
||||
zstyle ':completion:*:history-words' menu yes
|
||||
|
||||
# ignore duplicate entries
|
||||
zstyle ':completion:*:history-words' remove-all-dups yes
|
||||
zstyle ':completion:*:history-words' stop yes
|
||||
|
||||
# match uppercase from lowercase
|
||||
zstyle ':completion:*' matcher-list 'm:{a-z}={A-Z}'
|
||||
|
||||
|
@ -136,14 +52,6 @@ zstyle ':completion:*' matcher-list 'm:{a-z}={A-Z}'
|
|||
zstyle ':completion:*:matches' group 'yes'
|
||||
zstyle ':completion:*' group-name ''
|
||||
|
||||
if [[ "$NOMENU" -eq 0 ]] ; then
|
||||
# if there are more than 5 options allow selecting from a menu
|
||||
zstyle ':completion:*' menu select=5
|
||||
else
|
||||
# don't use any menus at all
|
||||
setopt no_auto_menu
|
||||
fi
|
||||
|
||||
zstyle ':completion:*:messages' format '%d'
|
||||
zstyle ':completion:*:options' auto-description '%d'
|
||||
|
||||
|
@ -153,24 +61,9 @@ zstyle ':completion:*:options' description 'yes'
|
|||
# on processes completion complete all user processes
|
||||
zstyle ':completion:*:processes' command 'ps -au$USER'
|
||||
|
||||
# offer indexes before parameters in subscripts
|
||||
zstyle ':completion:*:*:-subscript-:*' tag-order indexes parameters
|
||||
|
||||
# provide verbose completion information
|
||||
zstyle ':completion:*' verbose true
|
||||
|
||||
# recent (as of Dec 2007) zsh versions are able to provide descriptions
|
||||
# for commands (read: 1st word in the line) that it will list for the user
|
||||
# to choose from. The following disables that, because it's not exactly fast.
|
||||
zstyle ':completion:*:-command-:*:' verbose false
|
||||
|
||||
# set format for warnings
|
||||
zstyle ':completion:*:warnings' format $'%{\e[0;31m%}No matches for:%{\e[0m%} %d'
|
||||
|
||||
# define files to ignore for zcompile
|
||||
zstyle ':completion:*:*:zcompile:*' ignored-patterns '(*~|*.zwc)'
|
||||
zstyle ':completion:correct:' prompt 'correct to: %e'
|
||||
|
||||
# Ignore completion functions for commands you don't have:
|
||||
zstyle ':completion::(^approximate*):*:functions' ignored-patterns '_*'
|
||||
|
||||
|
@ -182,57 +75,28 @@ zstyle ':completion:*:manuals' separate-sections true
|
|||
zstyle ':completion:*:manuals.*' insert-sections true
|
||||
zstyle ':completion:*:man:*' menu yes select
|
||||
|
||||
# Search path for sudo completion
|
||||
zstyle ':completion:*:sudo:*' command-path \
|
||||
/usr/local/sbin \
|
||||
/usr/local/bin \
|
||||
/usr/sbin \
|
||||
/usr/bin \
|
||||
/sbin \
|
||||
/bin
|
||||
|
||||
# provide .. as a completion
|
||||
zstyle ':completion:*' special-dirs ..
|
||||
|
||||
# run rehash on completion so new installed program are found automatically:
|
||||
function _force_rehash() {
|
||||
(( CURRENT == 1 )) && rehash
|
||||
return 1
|
||||
}
|
||||
|
||||
# No correction
|
||||
zstyle ':completion:*' completer _oldlist _expand _force_rehash _complete _files _ignored
|
||||
zstyle ':completion:*' completer _oldlist _expand _complete _files _ignored
|
||||
|
||||
# use generic completion system for programs not yet defined; (_gnu_generic works
|
||||
# with commands that provide a --help option with "standard" gnu-like output.)
|
||||
for compcom in cp deborphan df feh fetchipac gpasswd head hnb ipacsum mv pal stow uname ; do
|
||||
[[ -z ${_comps[$compcom]} ]] && compdef _gnu_generic ${compcom}
|
||||
done; unset compcom
|
||||
# treat multiple slash as one
|
||||
zstyle ':completion:*' squeeze-slashes true
|
||||
|
||||
# see upgrade function in this file
|
||||
compdef _hosts upgrade
|
||||
# disable sort when completing `git checkout`
|
||||
zstyle ':completion:*:git-checkout:*' sort false
|
||||
# set descriptions format to enable group support
|
||||
zstyle ':completion:*:descriptions' format '[%d]'
|
||||
# set list-colors to enable filename colorizing
|
||||
zstyle ':completion:*' list-colors ${(s.:.)LS_COLORS}
|
||||
# preview directory's content with ls when completing cd
|
||||
zstyle ':fzf-tab:complete:cd:*' fzf-preview 'ls -lhF --group-directories-first --show-control-chars --quoting-style=escape --color=auto $realpath';
|
||||
# preview windown min size
|
||||
zstyle ':fzf-tab:complete:cd:*' popup_pad 20 0
|
||||
|
||||
# History settings
|
||||
unset HISTFILE=~/.zsh_history
|
||||
HISTSIZE=1000000
|
||||
SAVEHIST=1005000
|
||||
|
||||
# Append history when zsh exits
|
||||
setopt append_history
|
||||
# Also save timestamp and duration
|
||||
setopt extended_history
|
||||
# Ignore commands beginning with a space
|
||||
setopt hist_ignore_space
|
||||
# Remove repeated duplicates
|
||||
setopt hist_ignore_dups
|
||||
# Remove trailing whitespace from history
|
||||
setopt hist_reduce_blanks
|
||||
# Save history after each command
|
||||
setopt inc_append_history
|
||||
# If history is full, delete oldest duplicate commands first
|
||||
setopt hist_expire_dups_first
|
||||
# When a history line is selected from expansion, don't execute but fill line buffer
|
||||
setopt hist_verify
|
||||
unset HISTFILE
|
||||
|
||||
# Emit an error when a glob has no match
|
||||
setopt nomatch
|
||||
|
@ -263,8 +127,6 @@ setopt nobeep
|
|||
|
||||
# Don't try to correct inputs
|
||||
setopt nocorrect
|
||||
# Allow in-word completion
|
||||
setopt completeinword
|
||||
# Don't autocorrect commands
|
||||
setopt no_correct_all
|
||||
# Allow completion from within a word/phrase
|
||||
|
@ -283,6 +145,118 @@ function zshaddhistory() {
|
|||
[[ ! $1 =~ "$HISTORY_IGNORE_REGEX" ]]
|
||||
}
|
||||
|
||||
# Delete all keybinds and use emacs-like key bindings by default:
|
||||
bindkey -d
|
||||
bindkey -e
|
||||
|
||||
function nop() {
|
||||
true
|
||||
}; zle -N nop
|
||||
|
||||
function bindkeys() {
|
||||
[[ $# -eq 2 ]] || return
|
||||
local keys="$1";
|
||||
for key in ${(P)keys}; do
|
||||
bindkey "$key" "$2"
|
||||
done
|
||||
}
|
||||
|
||||
function setup_keybinds() {
|
||||
local keys_Home=( "${terminfo[khome]}" "\eOH" "\e[H" )
|
||||
local keys_End=( "${terminfo[kend]}" "\eOF" "\e[F" )
|
||||
local keys_Insert=( "${terminfo[kich1]}" )
|
||||
|
||||
local keys_Tab=( "${terminfo[ht]}" )
|
||||
local keys_ShiftTab=( "${terminfo[kcbt]}" )
|
||||
|
||||
local keys_Backspace=( "${terminfo[kbs]}" )
|
||||
local keys_CtrlBackspace=( "${terminfo[cub1]}" )
|
||||
|
||||
local keys_Delete=( "${terminfo[kdch1]}" )
|
||||
local keys_ShiftDelete=( "${terminfo[kDC]}" )
|
||||
local keys_CtrlDelete=( '\e[3;5~' )
|
||||
local keys_AltDelete=( '\e[3;3~' )
|
||||
|
||||
local keys_Up=( "${terminfo[kcuu1]}" "\eOA" "\e[A")
|
||||
local keys_ShiftUp=( "${terminfo[kri]}" )
|
||||
local keys_CtrlUp=( '\e[1;5A' )
|
||||
local keys_AltUp=( '\e[1;3A' )
|
||||
|
||||
local keys_Down=( "${terminfo[kcud1]}" "\eOB" "\e[B")
|
||||
local keys_ShiftDown=( "${terminfo[kind]}" )
|
||||
local keys_CtrlDown=( '\e[1;5B' )
|
||||
local keys_AltDown=( '\e[1;3B' )
|
||||
|
||||
local keys_Right=( "${terminfo[kcuf1]}" )
|
||||
local keys_ShiftRight=( "${terminfo[kRIT]}" )
|
||||
local keys_CtrlRight=( '\e[1;5C' )
|
||||
local keys_AltRight=( '\e[1;3C' )
|
||||
|
||||
local keys_Left=( "${terminfo[kcub1]}" )
|
||||
local keys_ShiftLeft=( "${terminfo[kLFT]}" )
|
||||
local keys_CtrlLeft=( '\e[1;5D' )
|
||||
local keys_AltLeft=( '\e[1;3D' )
|
||||
|
||||
local keys_PageUp=( "${terminfo[kpp]}" )
|
||||
local keys_ShiftPageUp=( "${terminfo[kPRV]}" )
|
||||
|
||||
local keys_PageDown=( "${terminfo[knp]}" )
|
||||
local keys_ShiftPageDown=( "${terminfo[kNXT]}" )
|
||||
|
||||
bindkeys keys_Home beginning-of-line
|
||||
bindkeys keys_End end-of-line
|
||||
bindkeys keys_Insert nop
|
||||
|
||||
bindkeys keys_Tab fzf-tab-complete
|
||||
bindkeys keys_ShiftTab nop
|
||||
|
||||
bindkeys keys_ShiftBackspace backward-kill-word
|
||||
bindkeys keys_CtrlBackspace backward-kill-line
|
||||
|
||||
bindkeys keys_Delete delete-char
|
||||
bindkeys keys_ShiftDelete delete-word
|
||||
bindkeys keys_CtrlDelete kill-line
|
||||
bindkeys keys_AltDelete delete-word
|
||||
|
||||
bindkeys keys_Up atuin-prefix-search-backward-end
|
||||
bindkeys keys_ShiftUp up-line
|
||||
bindkeys keys_CtrlUp nop
|
||||
bindkeys keys_AltUp nop
|
||||
|
||||
bindkeys keys_Down atuin-prefix-search-forward-end
|
||||
bindkeys keys_ShiftDown down-line
|
||||
bindkeys keys_CtrlDown nop
|
||||
bindkeys keys_AltDown nop
|
||||
|
||||
bindkeys keys_Right forward-char
|
||||
bindkeys keys_ShiftRight forward-word
|
||||
bindkeys keys_CtrlRight nop
|
||||
bindkeys keys_AltRight nop
|
||||
|
||||
bindkeys keys_Left backward-char
|
||||
bindkeys keys_ShiftLeft backward-word
|
||||
bindkeys keys_CtrlLeft nop
|
||||
bindkeys keys_AltLeft nop
|
||||
|
||||
bindkeys keys_PageUp nop
|
||||
bindkeys keys_ShiftPageUp nop
|
||||
|
||||
bindkeys keys_PageDown nop
|
||||
bindkeys keys_ShiftPageDown nop
|
||||
|
||||
# atuin
|
||||
bindkey '^r' _atuin_search_widget
|
||||
|
||||
# fzf file and directory related expansions and functions
|
||||
bindkey '\ef' fzf-select-file-or-dir
|
||||
bindkey '\eF' fzf-select-file-or-dir-hidden
|
||||
bindkey '\ed' fzf-select-dir
|
||||
bindkey '\eD' fzf-select-dir-hidden
|
||||
bindkey '\ec' fzf-cd
|
||||
}
|
||||
setup_keybinds
|
||||
unfunction bindkeys
|
||||
unfunction setup_keybinds
|
||||
|
||||
# Set umask
|
||||
umask 077
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
{
|
||||
config,
|
||||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}: {
|
||||
imports = [
|
||||
|
@ -12,7 +13,20 @@
|
|||
};
|
||||
programs.zsh = {
|
||||
enable = true;
|
||||
#initExtra = builtins.readFile ../../../data/zsh/zshrc;
|
||||
dotDir = ".config/zsh";
|
||||
initExtra = lib.mkAfter (''
|
||||
function atuin-prefix-search() {
|
||||
if out=$(${pkgs.sqlite}/bin/sqlite3 -readonly ~/.local/share/atuin/history.db \
|
||||
'SELECT command FROM history WHERE command LIKE cast('"x'$(str_to_hex "$_atuin_search_prefix")'"' as text) || "%" ORDER BY timestamp DESC LIMIT 1 OFFSET '"$_atuin_search_offset"); then
|
||||
[[ -z "$out" ]] && return 1
|
||||
BUFFER=$out
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
|
||||
}; zle -N atuin-prefix-search
|
||||
''
|
||||
+ (builtins.readFile ../../../data/zsh/zshrc));
|
||||
plugins = [
|
||||
{
|
||||
name = "fzf-tab";
|
||||
|
|
Loading…
Reference in a new issue