diff options
author | Alen <alen@dotfiles.xyz> | 2025-01-19 03:26:44 +0400 |
---|---|---|
committer | Alen <alen@dotfiles.xyz> | 2025-01-19 03:26:44 +0400 |
commit | 43c982798c902315aba2f8865d0407c6ff70a180 (patch) | |
tree | 469de00c188d60d2859066cfa94bf2880b16eb46 /dot_local/share | |
parent | 6e8b63f101e056f80cf6b7d17d07161bead1ceeb (diff) |
Add batch of zsh plugins and kitting out
Diffstat (limited to 'dot_local/share')
-rw-r--r-- | dot_local/share/man/man1/symlink_fasd.1.tmpl | 1 | ||||
-rw-r--r-- | dot_local/share/zsh/bindings/bindings.plugins.zsh | 147 | ||||
-rw-r--r-- | dot_local/share/zsh/brew/brew.plugin.zsh | 29 | ||||
-rw-r--r-- | dot_local/share/zsh/clipboard/clipboard.plugins.zsh | 67 | ||||
-rw-r--r-- | dot_local/share/zsh/coloured-man/coloured-man.plugin.zsh | 13 | ||||
-rw-r--r-- | dot_local/share/zsh/completion/completion.plugin.zsh | 64 | ||||
-rw-r--r-- | dot_local/share/zsh/fzf/fzf.plugin.zsh | 90 | ||||
-rw-r--r-- | dot_local/share/zsh/git/git.plugin.zsh | 16 |
8 files changed, 427 insertions, 0 deletions
diff --git a/dot_local/share/man/man1/symlink_fasd.1.tmpl b/dot_local/share/man/man1/symlink_fasd.1.tmpl new file mode 100644 index 0000000..37a7294 --- /dev/null +++ b/dot_local/share/man/man1/symlink_fasd.1.tmpl @@ -0,0 +1 @@ +../../fasd/fasd.1 diff --git a/dot_local/share/zsh/bindings/bindings.plugins.zsh b/dot_local/share/zsh/bindings/bindings.plugins.zsh new file mode 100644 index 0000000..5c1b8cd --- /dev/null +++ b/dot_local/share/zsh/bindings/bindings.plugins.zsh @@ -0,0 +1,147 @@ +# http://zsh.sourceforge.net/Doc/Release/Zsh-Line-Editor.html +# http://zsh.sourceforge.net/Doc/Release/Zsh-Line-Editor.html#Zle-Builtins +# http://zsh.sourceforge.net/Doc/Release/Zsh-Line-Editor.html#Standard-Widgets + +# Make sure that the terminal is in application mode when zle is active, since +# only then values from $terminfo are valid +if (( ${+terminfo[smkx]} )) && (( ${+terminfo[rmkx]} )); then + function zle-line-init() { + echoti smkx + } + function zle-line-finish() { + echoti rmkx + } + zle -N zle-line-init + zle -N zle-line-finish +fi + +# Use emacs key bindings +bindkey -e + +# [PageUp] - Up a line of history +if [[ -n "${terminfo[kpp]}" ]]; then + bindkey -M emacs "${terminfo[kpp]}" up-line-or-history + bindkey -M viins "${terminfo[kpp]}" up-line-or-history + bindkey -M vicmd "${terminfo[kpp]}" up-line-or-history +fi +# [PageDown] - Down a line of history +if [[ -n "${terminfo[knp]}" ]]; then + bindkey -M emacs "${terminfo[knp]}" down-line-or-history + bindkey -M viins "${terminfo[knp]}" down-line-or-history + bindkey -M vicmd "${terminfo[knp]}" down-line-or-history +fi + +# Start typing + [Up-Arrow] - fuzzy find history forward +if [[ -n "${terminfo[kcuu1]}" ]]; then + autoload -U up-line-or-beginning-search + zle -N up-line-or-beginning-search + + bindkey -M emacs "${terminfo[kcuu1]}" up-line-or-beginning-search + bindkey -M viins "${terminfo[kcuu1]}" up-line-or-beginning-search + bindkey -M vicmd "${terminfo[kcuu1]}" up-line-or-beginning-search +fi +# Start typing + [Down-Arrow] - fuzzy find history backward +if [[ -n "${terminfo[kcud1]}" ]]; then + autoload -U down-line-or-beginning-search + zle -N down-line-or-beginning-search + + bindkey -M emacs "${terminfo[kcud1]}" down-line-or-beginning-search + bindkey -M viins "${terminfo[kcud1]}" down-line-or-beginning-search + bindkey -M vicmd "${terminfo[kcud1]}" down-line-or-beginning-search +fi + +# [Home] - Go to beginning of line +if [[ -n "${terminfo[khome]}" ]]; then + bindkey -M emacs "${terminfo[khome]}" beginning-of-line + bindkey -M viins "${terminfo[khome]}" beginning-of-line + bindkey -M vicmd "${terminfo[khome]}" beginning-of-line +fi +# [End] - Go to end of line +if [[ -n "${terminfo[kend]}" ]]; then + bindkey -M emacs "${terminfo[kend]}" end-of-line + bindkey -M viins "${terminfo[kend]}" end-of-line + bindkey -M vicmd "${terminfo[kend]}" end-of-line +fi + +# [Shift-Tab] - move through the completion menu backwards +if [[ -n "${terminfo[kcbt]}" ]]; then + bindkey -M emacs "${terminfo[kcbt]}" reverse-menu-complete + bindkey -M viins "${terminfo[kcbt]}" reverse-menu-complete + bindkey -M vicmd "${terminfo[kcbt]}" reverse-menu-complete +fi + +# [Backspace] - delete backward +bindkey -M emacs '^?' backward-delete-char +bindkey -M viins '^?' backward-delete-char +bindkey -M vicmd '^?' backward-delete-char +# [Delete] - delete forward +if [[ -n "${terminfo[kdch1]}" ]]; then + bindkey -M emacs "${terminfo[kdch1]}" delete-char + bindkey -M viins "${terminfo[kdch1]}" delete-char + bindkey -M vicmd "${terminfo[kdch1]}" delete-char +else + bindkey -M emacs "^[[3~" delete-char + bindkey -M viins "^[[3~" delete-char + bindkey -M vicmd "^[[3~" delete-char + + bindkey -M emacs "^[3;5~" delete-char + bindkey -M viins "^[3;5~" delete-char + bindkey -M vicmd "^[3;5~" delete-char +fi + +# [Ctrl-Delete] - delete whole forward-word +bindkey -M emacs '^[[3;5~' kill-word +bindkey -M viins '^[[3;5~' kill-word +bindkey -M vicmd '^[[3;5~' kill-word + +# [Ctrl-RightArrow] - move forward one word +bindkey -M emacs '^[[1;5C' forward-word +bindkey -M viins '^[[1;5C' forward-word +bindkey -M vicmd '^[[1;5C' forward-word +# [Ctrl-LeftArrow] - move backward one word +bindkey -M emacs '^[[1;5D' backward-word +bindkey -M viins '^[[1;5D' backward-word +bindkey -M vicmd '^[[1;5D' backward-word + + +bindkey '\ew' kill-region # [Esc-w] - Kill from the cursor to the mark +bindkey -s '\el' 'ls\n' # [Esc-l] - run command: ls +bindkey '^r' history-incremental-search-backward # [Ctrl-r] - Search backward incrementally for a specified string. The string may begin with ^ to anchor the search to the beginning of the line. +bindkey ' ' magic-space # [Space] - don't do history expansion + + +# Edit the current command line in $EDITOR +autoload -U edit-command-line +zle -N edit-command-line +bindkey '\C-x\C-e' edit-command-line + +# file rename magick +bindkey "^[m" copy-prev-shell-word + +# consider emacs keybindings: + +#bindkey -e ## emacs key bindings +# +#bindkey '^[[A' up-line-or-search +#bindkey '^[[B' down-line-or-search +#bindkey '^[^[[C' emacs-forward-word +#bindkey '^[^[[D' emacs-backward-word +# +#bindkey -s '^X^Z' '%-^M' +#bindkey '^[e' expand-cmd-path +#bindkey '^[^I' reverse-menu-complete +#bindkey '^X^N' accept-and-infer-next-history +#bindkey '^W' kill-region +#bindkey '^I' complete-word +## Fix weird sequence that rxvt produces +#bindkey -s '^[[Z' '\t' +# + +bindkey '^o' '__fzf-open-widget' +bindkey '^p' '__fzf-preview-widget' +bindkey '^j' '__fzf-jump-widget' + +# TODO: Run these after zsh-edit +# Overwrite zsh-edit bindings +#bindkey '^W' backward-kill-subword +#bindkey '^H' backward-kill-shell-word diff --git a/dot_local/share/zsh/brew/brew.plugin.zsh b/dot_local/share/zsh/brew/brew.plugin.zsh new file mode 100644 index 0000000..e929174 --- /dev/null +++ b/dot_local/share/zsh/brew/brew.plugin.zsh @@ -0,0 +1,29 @@ +# Set up brew +if [[ -f /opt/homebrew/bin/brew ]]; then + export HOMEBREW_NO_ENV_HINTS=1 + export HOMEBREW_NO_ANALYTICS=1 + eval "$(/opt/homebrew/bin/brew shellenv)" + fpath=("/opt/homebrew/share/zsh/site-functions" $fpath) + + # Prefer GNU versions of certain tools + local tool_bin + for tool_bin in /opt/homebrew/opt/*/libexec/gnubin(N); do + if [[ "${tool_bin}" == */gsed/* ]]; then + continue # Alias to gnu-sed + fi + export PATH="${tool_bin}${PATH+:$PATH}" + export MANPATH="$(dirname ${tool_bin})/gnuman${MANPATH+:$MANPATH}" + done + + # Brew leaves and deps + brews() { + local formulae="$(brew leaves | xargs brew deps --installed --for-each)" + local casks="$(brew list --cask)" + local blue="$(tput setaf 4)" + local bold="$(tput bold)" + local off="$(tput sgr0)" + echo "${blue}==>${off} ${bold}Formulae${off}" + echo "${formulae}" | sed "s/^\(.*\):\(.*\)$/\1${blue}\2${off}/" + echo "\n${blue}==>${off} ${bold}Casks${off}\n${casks}" + } +fi diff --git a/dot_local/share/zsh/clipboard/clipboard.plugins.zsh b/dot_local/share/zsh/clipboard/clipboard.plugins.zsh new file mode 100644 index 0000000..9287f30 --- /dev/null +++ b/dot_local/share/zsh/clipboard/clipboard.plugins.zsh @@ -0,0 +1,67 @@ +# +# See: https://github.com/neovim/neovim/blob/e682d799fa3cf2e80a02d00c6ea874599d58f0e7/runtime/autoload/provider/clipboard.vim#L55-L121 +# +# - pbcopy, pbpaste (macOS) +# - cygwin (Windows running Cygwin) +# - wl-copy, wl-paste (if $WAYLAND_DISPLAY is set) +# - xsel (if $DISPLAY is set) +# - xclip (if $DISPLAY is set) +# - lemonade (for SSH) https://github.com/pocke/lemonade +# - doitclient (for SSH) http://www.chiark.greenend.org.uk/~sgtatham/doit/ +# - win32yank (Windows) +# - tmux (if $TMUX is set) +# + +function detect-clipboard() { + emulate -L zsh + + if [[ "${OSTYPE}" == darwin* ]] && (( ${+commands[pbcopy]} )) && (( ${+commands[pbpaste]} )); then + function clipcopy() { cat "${1:-/dev/stdin}" | pbcopy; } + function clippaste() { pbpaste; } + elif [[ "${OSTYPE}" == (cygwin|msys)* ]]; then + function clipcopy() { cat "${1:-/dev/stdin}" > /dev/clipboard; } + function clippaste() { cat /dev/clipboard; } + elif [ -n "${WAYLAND_DISPLAY:-}" ] && (( ${+commands[wl-copy]} )) && (( ${+commands[wl-paste]} )); then + function clipcopy() { cat "${1:-/dev/stdin}" | wl-copy &>/dev/null &|; } + function clippaste() { wl-paste; } + elif [ -n "${DISPLAY:-}" ] && (( ${+commands[xsel]} )); then + function clipcopy() { cat "${1:-/dev/stdin}" | xsel --clipboard --input; } + function clippaste() { xsel --clipboard --output; } + elif [ -n "${DISPLAY:-}" ] && (( ${+commands[xclip]} )); then + function clipcopy() { cat "${1:-/dev/stdin}" | xclip -selection clipboard -in &>/dev/null &|; } + function clippaste() { xclip -out -selection clipboard; } + elif (( ${+commands[lemonade]} )); then + function clipcopy() { cat "${1:-/dev/stdin}" | lemonade copy; } + function clippaste() { lemonade paste; } + elif (( ${+commands[doitclient]} )); then + function clipcopy() { cat "${1:-/dev/stdin}" | doitclient wclip; } + function clippaste() { doitclient wclip -r; } + elif (( ${+commands[win32yank]} )); then + function clipcopy() { cat "${1:-/dev/stdin}" | win32yank -i; } + function clippaste() { win32yank -o; } + elif [[ $OSTYPE == linux-android* ]] && (( $+commands[termux-clipboard-set] )); then + function clipcopy() { cat "${1:-/dev/stdin}" | termux-clipboard-set; } + function clippaste() { termux-clipboard-get; } + elif [ -n "${TMUX:-}" ] && (( ${+commands[tmux]} )); then + function clipcopy() { tmux load-buffer "${1:--}"; } + function clippaste() { tmux save-buffer -; } + elif [[ $(uname -r) = *icrosoft* ]]; then + function clipcopy() { cat "${1:-/dev/stdin}" | clip.exe; } + function clippaste() { powershell.exe -noprofile -command Get-Clipboard; } + else + function _retry_clipboard_detection_or_fail() { + local clipcmd="${1}"; shift + if detect-clipboard; then + "${clipcmd}" "$@" + else + print "${clipcmd}: Platform $OSTYPE not supported or xclip/xsel not installed" >&2 + return 1 + fi + } + function clipcopy() { _retry_clipboard_detection_or_fail clipcopy "$@"; } + function clippaste() { _retry_clipboard_detection_or_fail clippaste "$@"; } + return 1 + fi +} + +detect-clipboard && unset -f detect-clipboard || : diff --git a/dot_local/share/zsh/coloured-man/coloured-man.plugin.zsh b/dot_local/share/zsh/coloured-man/coloured-man.plugin.zsh new file mode 100644 index 0000000..ddaa38b --- /dev/null +++ b/dot_local/share/zsh/coloured-man/coloured-man.plugin.zsh @@ -0,0 +1,13 @@ +function man() { + # mb/md - bold+blinking + # so - standout + # us - underliined + LESS_TERMCAP_mb="${fg_bold[red]}" \ + LESS_TERMCAP_md="${fg_bold[red]}" \ + LESS_TERMCAP_me="${reset_color}" \ + LESS_TERMCAP_so="${fg_bold[yellow]}${bg[blue]}" \ + LESS_TERMCAP_se="${reset_color}" \ + LESS_TERMCAP_us="${fg_bold[green]}" \ + LESS_TERMCAP_ue="${reset_color}" \ + command env man "$@" +} \ No newline at end of file diff --git a/dot_local/share/zsh/completion/completion.plugin.zsh b/dot_local/share/zsh/completion/completion.plugin.zsh new file mode 100644 index 0000000..97ada23 --- /dev/null +++ b/dot_local/share/zsh/completion/completion.plugin.zsh @@ -0,0 +1,64 @@ +# Completions +zmodload -i zsh/complist + +unsetopt menu_complete # do not autoselect the first completion entry +setopt always_to_end # Always place the cursor to the end of the word completed +setopt list_packed # The completion menu takes less space +setopt auto_menu # Display the completion menu after two use of the TAB key +setopt complete_in_word # By default, the cursor goes at the end of the word when completion start. Setting this will not move the cursor and the completion will happen on both end of the word completed. + +# TODO: show paginated list on tab without prompt, but do not select first entry +zstyle ':completion:*' menu yes select +zstyle ':completion:*:default' select-prompt '%F{black}%K{cyan}line %l %p%f%k' +zstyle ':completion:*:default' select-scroll 1 + +bindkey -M menuselect '^f' vi-insert +zstyle ':completion:*' special-dirs true +zstyle ':completion:*' matcher-list 'm:{a-zA-Z}={A-Za-z}' 'r:|=*' 'l:|=* r:|=*' +zstyle ':completion:*' use-cache yes +zstyle ':completion:*' cache-path ${XDG_CACHE_HOME:-${HOME}/.cache}/zsh/completions +zstyle ':completion:*' single-ignored show +zstyle ':completion:*:*:*:*:processes' command "ps -u $USERNAME -o pid,user,comm -w -w" + +# Group by descriptions and show description nme +zstyle ':completion:*' group-name '' +zstyle ':completion:*:*:*:*:descriptions' format '%F{cyan}%d%f' + +zstyle ':completion:*:*:*:*:corrections' format '%F{yellow}%d (errors: %e):%f' +zstyle ':completion:*:messages' format ' %F{purple}-- %d --%f' +zstyle ':completion:*:warnings' format ' %F{red}-- No matches found! --%f' + +zstyle ":completion:*" list-colors ${(s.:.)LS_COLORS} +zstyle ':completion:*:*:kill:*:processes' list-colors '=(#b) #([0-9]#)*( *[a-z])*=34=31=33' + +# Don't auto-complete uncommon/fake commands (WSL) +zstyle ':completion:*:*:*:commands' ignored-patterns '*.dll' '*.DLL' '*.nls' '*.NLS' '*.mof' '*.MOF' + +# Don't autocomplete non-login users by default +if [[ -f /etc/passwd ]]; then + # shellcheck disable=SC2046 + zstyle ':completion:*:*:*:users' ignored-patterns $(grep -E '/(nologin|false)$' /etc/passwd | cut -d: -f1 | sort) +else + zstyle ':completion:*:*:*:users' ignored-patterns '_*' +fi + +# Ignore "private" functions +zstyle ':completion:*:functions' ignored-patterns '_*' '.*' +zstyle ':completion:*:widgets' ignored-patterns '_*' '.*' + +# TODO: check/review +zstyle ':completion:*:paths' ignore-parents 'parent pwd directory' +zstyle ':completion:*:paths' expand suffix +zstyle ':completion:*:paths' list-suffixes yes +zstyle ':completion:*:paths' path-completion no + +# TODO: complete hosts from history, .ssh/config, .ssh/known_hosts, /etc/hosts and .local/share/zsh/comphosts +# zstyle -e ':completion:*' hosts ${KNOWN_HOSTS} + +# man completion +zstyle ':completion:*' insert-sections yes +zstyle ':completion:*' separate-sections yes + +# Needed for _gnu_generic to prevent descriptions from getting cropped. +# TODO: Might be fixed in a future version of zsh. +zstyle ':completion:*' command '- COLUMNS=999' diff --git a/dot_local/share/zsh/fzf/fzf.plugin.zsh b/dot_local/share/zsh/fzf/fzf.plugin.zsh new file mode 100644 index 0000000..70f73b9 --- /dev/null +++ b/dot_local/share/zsh/fzf/fzf.plugin.zsh @@ -0,0 +1,90 @@ +ftop() { + FZF_DEFAULT_COMMAND='ps -ef' \ + fzf --bind 'ctrl-r:reload(ps -ef)' \ + --header 'Press CTRL-R to reload' \ + --header-lines=1 \ + --height=50% --layout=reverse +} + +__fzf-jump-widget() { + LBUFFER="${LBUFFER}$(fasd -ld | tac | fzf)" + local ret=$? + zle redisplay + if [[ $ret == 0 ]]; then + zle accept-line + fi + return $ret +} + +zle -N __fzf-jump-widget + +__fzf-open-widget() { + FILE=$(fasd -lf | tac | fzf) + local ret=$? + if [[ $ret != 0 ]]; then + return $ret + fi + if [[ "${LBUFFER}" != "" ]]; then + LBUFFER="${LBUFFER}${FILE}" + elif [[ $(file --mime ${FILE}) =~ "binary" ]]; then + LBUFFER="xdg-open ${FILE}" + else + LBUFFER="${EDITOR} ${FILE}" + fi + zle redisplay + if [[ $ret == 0 ]]; then + zle accept-line + fi + return $ret +} + +zle -N __fzf-open-widget + +# Search files with preview +__fzf-preview-widget() { + LBUFFER="${LBUFFER}$(ls | fzf -e --preview=${FZF_BAT_PREVIEW})" +} +zle -N __fzf-preview-widget + +# rg on Asteroids +rf() { + RG_PREFIX="rga --files-with-matches" + local file + file="$( + FZF_DEFAULT_COMMAND="$RG_PREFIX '$1'" \ + fzf --sort --preview="[[ ! -z {} ]] && echo {} && rga --pretty --context 5 {q} {}" \ + --phony -q "$1" \ + --bind "change:reload:$RG_PREFIX {q}" \ + --preview-window="70%:wrap" + )" && + echo $file + # echo "opening $file" && + # xdg-open "$file" +} + +# Fancy git diff using fzf +if which git &>/dev/null; then + alias gdf=' + git status -s \ + | fzf --no-sort --reverse \ + --preview "git diff --color=always {+2} | delta" \ + --bind=ctrl-j:preview-down --bind=ctrl-k:preview-up \ + --preview-window=right:70%:wrap' +fi + +# figure out some useful things to do... +# https://junegunn.kr/2016/07/fzf-git/ +_FZF_BAT_PREVIEW='[[ $(file --mime {}) =~ "binary" ]] && echo "<folder/binary file>" || bat --style=numbers --color=always {} --line-range :500' +alias fzfp="fzf --preview='${_FZF_BAT_PREVIEW}'" +alias fzfd="fzf --preview='${_FZF_BAT_PREVIEW}' --bind='enter:execute(bat --style=numbers --color=always --paging=always {}),ctrl-e:execute(micro {}),tab:toggle-preview'" + +export FZF_DEFAULT_OPTS="-1 --height 50% --layout=reverse --border --multi --info=inline" + +# Use fd/rg/ag if possible to follow any ignores / sensible configs +if which fd &>/dev/null; then + export FZF_DEFAULT_COMMAND='fd --type f' +elif which rg &>/dev/null; then + export FZF_DEFAULT_COMMAND='rg --files' +elif which ag &>/dev/null; then + export FZF_DEFAULT_COMMAND='ag --files-with-matches' +fi diff --git a/dot_local/share/zsh/git/git.plugin.zsh b/dot_local/share/zsh/git/git.plugin.zsh new file mode 100644 index 0000000..8c7b362 --- /dev/null +++ b/dot_local/share/zsh/git/git.plugin.zsh @@ -0,0 +1,16 @@ +alias g='git' + +__git_aliases() { + local IFS=$'\n' + for _git_config_line in $(git config --list | grep -E '^alias\.' | cut -d. -f2-); do + if ! which "g${_git_config_line%%=*}" &>/dev/null; then + if [[ ${_git_config_line} = *'=!'* ]]; then + alias "g${_git_config_line:s/=\!/=}" + else + alias "g${_git_config_line:s/=/=git }" + fi + fi + done +} +__git_aliases +unset __git_aliases |