diff options
author | Vikas Kushwaha <dev@vikas.rocks> | 2025-01-24 10:35:59 +0530 |
---|---|---|
committer | Vikas Kushwaha <dev@vikas.rocks> | 2025-01-24 10:35:59 +0530 |
commit | 18507fd21b7a7709133d8f3049c683e1abffcda2 (patch) | |
tree | d43bc141b2e588300e639bdb4f004ad6945e6081 /.config/zsh/plugins | |
parent | e02304f014645a01ef6cdd40276997dea58504d9 (diff) |
jupyter update
Diffstat (limited to '.config/zsh/plugins')
-rw-r--r-- | .config/zsh/plugins/fzf-completion.zsh | 329 | ||||
m--------- | .config/zsh/plugins/zsh-autosuggestions | 0 | ||||
-rw-r--r-- | .config/zsh/plugins/zsh-autosuggestions.zsh | 864 | ||||
m--------- | .config/zsh/plugins/zsh-history-substring-search | 0 | ||||
-rw-r--r-- | .config/zsh/plugins/zsh-history-substring-search.zsh | 759 |
5 files changed, 0 insertions, 1952 deletions
diff --git a/.config/zsh/plugins/fzf-completion.zsh b/.config/zsh/plugins/fzf-completion.zsh deleted file mode 100644 index f12afca..0000000 --- a/.config/zsh/plugins/fzf-completion.zsh +++ /dev/null @@ -1,329 +0,0 @@ -# ____ ____ -# / __/___ / __/ -# / /_/_ / / /_ -# / __/ / /_/ __/ -# /_/ /___/_/ completion.zsh -# -# - $FZF_TMUX (default: 0) -# - $FZF_TMUX_OPTS (default: '-d 40%') -# - $FZF_COMPLETION_TRIGGER (default: '**') -# - $FZF_COMPLETION_OPTS (default: empty) - -# Both branches of the following `if` do the same thing -- define -# __fzf_completion_options such that `eval $__fzf_completion_options` sets -# all options to the same values they currently have. We'll do just that at -# the bottom of the file after changing options to what we prefer. -# -# IMPORTANT: Until we get to the `emulate` line, all words that *can* be quoted -# *must* be quoted in order to prevent alias expansion. In addition, code must -# be written in a way works with any set of zsh options. This is very tricky, so -# careful when you change it. -# -# Start by loading the builtin zsh/parameter module. It provides `options` -# associative array that stores current shell options. -if 'zmodload' 'zsh/parameter' 2>'/dev/null' && (( ${+options} )); then - # This is the fast branch and it gets taken on virtually all Zsh installations. - # - # ${(kv)options[@]} expands to array of keys (option names) and values ("on" - # or "off"). The subsequent expansion# with (j: :) flag joins all elements - # together separated by spaces. __fzf_completion_options ends up with a value - # like this: "options=(shwordsplit off aliases on ...)". - __fzf_completion_options="options=(${(j: :)${(kv)options[@]}})" -else - # This branch is much slower because it forks to get the names of all - # zsh options. It's possible to eliminate this fork but it's not worth the - # trouble because this branch gets taken only on very ancient or broken - # zsh installations. - () { - # That `()` above defines an anonymous function. This is essentially a scope - # for local parameters. We use it to avoid polluting global scope. - 'local' '__fzf_opt' - __fzf_completion_options="setopt" - # `set -o` prints one line for every zsh option. Each line contains option - # name, some spaces, and then either "on" or "off". We just want option names. - # Expansion with (@f) flag splits a string into lines. The outer expansion - # removes spaces and everything that follow them on every line. __fzf_opt - # ends up iterating over option names: shwordsplit, aliases, etc. - for __fzf_opt in "${(@)${(@f)$(set -o)}%% *}"; do - if [[ -o "$__fzf_opt" ]]; then - # Option $__fzf_opt is currently on, so remember to set it back on. - __fzf_completion_options+=" -o $__fzf_opt" - else - # Option $__fzf_opt is currently off, so remember to set it back off. - __fzf_completion_options+=" +o $__fzf_opt" - fi - done - # The value of __fzf_completion_options here looks like this: - # "setopt +o shwordsplit -o aliases ..." - } -fi - -# Enable the default zsh options (those marked with <Z> in `man zshoptions`) -# but without `aliases`. Aliases in functions are expanded when functions are -# defined, so if we disable aliases here, we'll be sure to have no pesky -# aliases in any of our functions. This way we won't need prefix every -# command with `command` or to quote every word to defend against global -# aliases. Note that `aliases` is not the only option that's important to -# control. There are several others that could wreck havoc if they are set -# to values we don't expect. With the following `emulate` command we -# sidestep this issue entirely. -'emulate' 'zsh' '-o' 'no_aliases' - -# This brace is the start of try-always block. The `always` part is like -# `finally` in lesser languages. We use it to *always* restore user options. -{ - -# Bail out if not interactive shell. -[[ -o interactive ]] || return 0 - -# To use custom commands instead of find, override _fzf_compgen_{path,dir} -if ! declare -f _fzf_compgen_path > /dev/null; then - _fzf_compgen_path() { - echo "$1" - command find -L "$1" \ - -name .git -prune -o -name .hg -prune -o -name .svn -prune -o \( -type d -o -type f -o -type l \) \ - -a -not -path "$1" -print 2> /dev/null | sed 's@^\./@@' - } -fi - -if ! declare -f _fzf_compgen_dir > /dev/null; then - _fzf_compgen_dir() { - command find -L "$1" \ - -name .git -prune -o -name .hg -prune -o -name .svn -prune -o -type d \ - -a -not -path "$1" -print 2> /dev/null | sed 's@^\./@@' - } -fi - -########################################################### - -__fzf_comprun() { - if [[ "$(type _fzf_comprun 2>&1)" =~ function ]]; then - _fzf_comprun "$@" - elif [ -n "$TMUX_PANE" ] && { [ "${FZF_TMUX:-0}" != 0 ] || [ -n "$FZF_TMUX_OPTS" ]; }; then - shift - if [ -n "$FZF_TMUX_OPTS" ]; then - fzf-tmux ${(Q)${(Z+n+)FZF_TMUX_OPTS}} -- "$@" - else - fzf-tmux -d ${FZF_TMUX_HEIGHT:-40%} -- "$@" - fi - else - shift - fzf "$@" - fi -} - -# Extract the name of the command. e.g. foo=1 bar baz**<tab> -__fzf_extract_command() { - local token tokens - tokens=(${(z)1}) - for token in $tokens; do - token=${(Q)token} - if [[ "$token" =~ [[:alnum:]] && ! "$token" =~ "=" ]]; then - echo "$token" - return - fi - done - echo "${tokens[1]}" -} - -__fzf_generic_path_completion() { - local base lbuf cmd compgen fzf_opts suffix tail dir leftover matches - base=$1 - lbuf=$2 - cmd=$(__fzf_extract_command "$lbuf") - compgen=$3 - fzf_opts=$4 - suffix=$5 - tail=$6 - - setopt localoptions nonomatch - eval "base=$base" - [[ $base = *"/"* ]] && dir="$base" - while [ 1 ]; do - if [[ -z "$dir" || -d ${dir} ]]; then - leftover=${base/#"$dir"} - leftover=${leftover/#\/} - [ -z "$dir" ] && dir='.' - [ "$dir" != "/" ] && dir="${dir/%\//}" - matches=$(eval "$compgen $(printf %q "$dir")" | FZF_DEFAULT_OPTS="--height ${FZF_TMUX_HEIGHT:-40%} --reverse --bind=ctrl-z:ignore $FZF_DEFAULT_OPTS $FZF_COMPLETION_OPTS" __fzf_comprun "$cmd" ${(Q)${(Z+n+)fzf_opts}} -q "$leftover" | while read item; do - echo -n "${(q)item}$suffix " - done) - matches=${matches% } - if [ -n "$matches" ]; then - LBUFFER="$lbuf$matches$tail" - fi - zle reset-prompt - break - fi - dir=$(dirname "$dir") - dir=${dir%/}/ - done -} - -_fzf_path_completion() { - __fzf_generic_path_completion "$1" "$2" _fzf_compgen_path \ - "-m" "" " " -} - -_fzf_dir_completion() { - __fzf_generic_path_completion "$1" "$2" _fzf_compgen_dir \ - "" "/" "" -} - -_fzf_feed_fifo() ( - command rm -f "$1" - mkfifo "$1" - cat <&0 > "$1" & -) - -_fzf_complete() { - setopt localoptions ksh_arrays - # Split arguments around -- - local args rest str_arg i sep - args=("$@") - sep= - for i in {0..${#args[@]}}; do - if [[ "${args[$i]}" = -- ]]; then - sep=$i - break - fi - done - if [[ -n "$sep" ]]; then - str_arg= - rest=("${args[@]:$((sep + 1)):${#args[@]}}") - args=("${args[@]:0:$sep}") - else - str_arg=$1 - args=() - shift - rest=("$@") - fi - - local fifo lbuf cmd matches post - fifo="${TMPDIR:-/tmp}/fzf-complete-fifo-$$" - lbuf=${rest[0]} - cmd=$(__fzf_extract_command "$lbuf") - post="${funcstack[1]}_post" - type $post > /dev/null 2>&1 || post=cat - - _fzf_feed_fifo "$fifo" - matches=$(FZF_DEFAULT_OPTS="--height ${FZF_TMUX_HEIGHT:-40%} --reverse --bind=ctrl-z:ignore $FZF_DEFAULT_OPTS $FZF_COMPLETION_OPTS $str_arg" __fzf_comprun "$cmd" "${args[@]}" -q "${(Q)prefix}" < "$fifo" | $post | tr '\n' ' ') - if [ -n "$matches" ]; then - LBUFFER="$lbuf$matches" - fi - command rm -f "$fifo" -} - -_fzf_complete_telnet() { - _fzf_complete +m -- "$@" < <( - command grep -v '^\s*\(#\|$\)' /etc/hosts | command grep -Fv '0.0.0.0' | - awk '{if (length($2) > 0) {print $2}}' | sort -u - ) -} - -_fzf_complete_ssh() { - _fzf_complete +m -- "$@" < <( - setopt localoptions nonomatch - command cat <(command tail -n +1 ~/.ssh/config ~/.ssh/config.d/* /etc/ssh/ssh_config 2> /dev/null | command grep -i '^\s*host\(name\)\? ' | awk '{for (i = 2; i <= NF; i++) print $1 " " $i}' | command grep -v '[*?]') \ - <(command grep -oE '^[[a-z0-9.,:-]+' ~/.ssh/known_hosts | tr ',' '\n' | tr -d '[' | awk '{ print $1 " " $1 }') \ - <(command grep -v '^\s*\(#\|$\)' /etc/hosts | command grep -Fv '0.0.0.0') | - awk '{if (length($2) > 0) {print $2}}' | sort -u - ) -} - -_fzf_complete_export() { - _fzf_complete -m -- "$@" < <( - declare -xp | sed 's/=.*//' | sed 's/.* //' - ) -} - -_fzf_complete_unset() { - _fzf_complete -m -- "$@" < <( - declare -xp | sed 's/=.*//' | sed 's/.* //' - ) -} - -_fzf_complete_unalias() { - _fzf_complete +m -- "$@" < <( - alias | sed 's/=.*//' - ) -} - -_fzf_complete_kill() { - _fzf_complete -m --preview 'echo {}' --preview-window down:3:wrap --min-height 15 -- "$@" < <( - command ps -ef | sed 1d - ) -} - -_fzf_complete_kill_post() { - awk '{print $2}' -} - -fzf-completion() { - local tokens cmd prefix trigger tail matches lbuf d_cmds - setopt localoptions noshwordsplit noksh_arrays noposixbuiltins - - # http://zsh.sourceforge.net/FAQ/zshfaq03.html - # http://zsh.sourceforge.net/Doc/Release/Expansion.html#Parameter-Expansion-Flags - tokens=(${(z)LBUFFER}) - if [ ${#tokens} -lt 1 ]; then - zle ${fzf_default_completion:-expand-or-complete} - return - fi - - cmd=$(__fzf_extract_command "$LBUFFER") - - # Explicitly allow for empty trigger. - trigger=${FZF_COMPLETION_TRIGGER-'**'} - [ -z "$trigger" -a ${LBUFFER[-1]} = ' ' ] && tokens+=("") - - # When the trigger starts with ';', it becomes a separate token - if [[ ${LBUFFER} = *"${tokens[-2]}${tokens[-1]}" ]]; then - tokens[-2]="${tokens[-2]}${tokens[-1]}" - tokens=(${tokens[0,-2]}) - fi - - lbuf=$LBUFFER - tail=${LBUFFER:$(( ${#LBUFFER} - ${#trigger} ))} - # Kill completion (do not require trigger sequence) - if [ "$cmd" = kill -a ${LBUFFER[-1]} = ' ' ]; then - tail=$trigger - tokens+=$trigger - lbuf="$lbuf$trigger" - fi - - # Trigger sequence given - if [ ${#tokens} -gt 1 -a "$tail" = "$trigger" ]; then - d_cmds=(${=FZF_COMPLETION_DIR_COMMANDS:-cd pushd rmdir}) - - [ -z "$trigger" ] && prefix=${tokens[-1]} || prefix=${tokens[-1]:0:-${#trigger}} - [ -n "${tokens[-1]}" ] && lbuf=${lbuf:0:-${#tokens[-1]}} - - if eval "type _fzf_complete_${cmd} > /dev/null"; then - prefix="$prefix" eval _fzf_complete_${cmd} ${(q)lbuf} - zle reset-prompt - elif [ ${d_cmds[(i)$cmd]} -le ${#d_cmds} ]; then - _fzf_dir_completion "$prefix" "$lbuf" - else - _fzf_path_completion "$prefix" "$lbuf" - fi - # Fall back to default completion - else - zle ${fzf_default_completion:-expand-or-complete} - fi -} - -[ -z "$fzf_default_completion" ] && { - binding=$(bindkey '^I') - [[ $binding =~ 'undefined-key' ]] || fzf_default_completion=$binding[(s: :w)2] - unset binding -} - -zle -N fzf-completion -bindkey '^I' fzf-completion - -} always { - # Restore the original options. - eval $__fzf_completion_options - 'unset' '__fzf_completion_options' -} diff --git a/.config/zsh/plugins/zsh-autosuggestions b/.config/zsh/plugins/zsh-autosuggestions new file mode 160000 +Subproject 0e810e5afa27acbd074398eefbe28d13005dbc1 diff --git a/.config/zsh/plugins/zsh-autosuggestions.zsh b/.config/zsh/plugins/zsh-autosuggestions.zsh deleted file mode 100644 index b19cac7..0000000 --- a/.config/zsh/plugins/zsh-autosuggestions.zsh +++ /dev/null @@ -1,864 +0,0 @@ -# Fish-like fast/unobtrusive autosuggestions for zsh. -# https://github.com/zsh-users/zsh-autosuggestions -# v0.7.0 -# Copyright (c) 2013 Thiago de Arruda -# Copyright (c) 2016-2021 Eric Freese -# -# Permission is hereby granted, free of charge, to any person -# obtaining a copy of this software and associated documentation -# files (the "Software"), to deal in the Software without -# restriction, including without limitation the rights to use, -# copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the -# Software is furnished to do so, subject to the following -# conditions: -# -# The above copyright notice and this permission notice shall be -# included in all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -# OTHER DEALINGS IN THE SOFTWARE. - -#--------------------------------------------------------------------# -# Global Configuration Variables # -#--------------------------------------------------------------------# - -# Color to use when highlighting suggestion -# Uses format of `region_highlight` -# More info: http://zsh.sourceforge.net/Doc/Release/Zsh-Line-Editor.html#Zle-Widgets -(( ! ${+ZSH_AUTOSUGGEST_HIGHLIGHT_STYLE} )) && -typeset -g ZSH_AUTOSUGGEST_HIGHLIGHT_STYLE='fg=8' - -# Prefix to use when saving original versions of bound widgets -(( ! ${+ZSH_AUTOSUGGEST_ORIGINAL_WIDGET_PREFIX} )) && -typeset -g ZSH_AUTOSUGGEST_ORIGINAL_WIDGET_PREFIX=autosuggest-orig- - -# Strategies to use to fetch a suggestion -# Will try each strategy in order until a suggestion is returned -(( ! ${+ZSH_AUTOSUGGEST_STRATEGY} )) && { - typeset -ga ZSH_AUTOSUGGEST_STRATEGY - ZSH_AUTOSUGGEST_STRATEGY=(history) -} - -# Widgets that clear the suggestion -(( ! ${+ZSH_AUTOSUGGEST_CLEAR_WIDGETS} )) && { - typeset -ga ZSH_AUTOSUGGEST_CLEAR_WIDGETS - ZSH_AUTOSUGGEST_CLEAR_WIDGETS=( - history-search-forward - history-search-backward - history-beginning-search-forward - history-beginning-search-backward - history-substring-search-up - history-substring-search-down - up-line-or-beginning-search - down-line-or-beginning-search - up-line-or-history - down-line-or-history - accept-line - copy-earlier-word - ) -} - -# Widgets that accept the entire suggestion -(( ! ${+ZSH_AUTOSUGGEST_ACCEPT_WIDGETS} )) && { - typeset -ga ZSH_AUTOSUGGEST_ACCEPT_WIDGETS - ZSH_AUTOSUGGEST_ACCEPT_WIDGETS=( - forward-char - end-of-line - vi-forward-char - vi-end-of-line - vi-add-eol - ) -} - -# Widgets that accept the entire suggestion and execute it -(( ! ${+ZSH_AUTOSUGGEST_EXECUTE_WIDGETS} )) && { - typeset -ga ZSH_AUTOSUGGEST_EXECUTE_WIDGETS - ZSH_AUTOSUGGEST_EXECUTE_WIDGETS=( - ) -} - -# Widgets that accept the suggestion as far as the cursor moves -(( ! ${+ZSH_AUTOSUGGEST_PARTIAL_ACCEPT_WIDGETS} )) && { - typeset -ga ZSH_AUTOSUGGEST_PARTIAL_ACCEPT_WIDGETS - ZSH_AUTOSUGGEST_PARTIAL_ACCEPT_WIDGETS=( - forward-word - emacs-forward-word - vi-forward-word - vi-forward-word-end - vi-forward-blank-word - vi-forward-blank-word-end - vi-find-next-char - vi-find-next-char-skip - ) -} - -# Widgets that should be ignored (globbing supported but must be escaped) -(( ! ${+ZSH_AUTOSUGGEST_IGNORE_WIDGETS} )) && { - typeset -ga ZSH_AUTOSUGGEST_IGNORE_WIDGETS - ZSH_AUTOSUGGEST_IGNORE_WIDGETS=( - orig-\* - beep - run-help - set-local-history - which-command - yank - yank-pop - zle-\* - ) -} - -# Pty name for capturing completions for completion suggestion strategy -(( ! ${+ZSH_AUTOSUGGEST_COMPLETIONS_PTY_NAME} )) && -typeset -g ZSH_AUTOSUGGEST_COMPLETIONS_PTY_NAME=zsh_autosuggest_completion_pty - -#--------------------------------------------------------------------# -# Utility Functions # -#--------------------------------------------------------------------# - -_zsh_autosuggest_escape_command() { - setopt localoptions EXTENDED_GLOB - - # Escape special chars in the string (requires EXTENDED_GLOB) - echo -E "${1//(#m)[\"\'\\()\[\]|*?~]/\\$MATCH}" -} - -#--------------------------------------------------------------------# -# Widget Helpers # -#--------------------------------------------------------------------# - -_zsh_autosuggest_incr_bind_count() { - typeset -gi bind_count=$((_ZSH_AUTOSUGGEST_BIND_COUNTS[$1]+1)) - _ZSH_AUTOSUGGEST_BIND_COUNTS[$1]=$bind_count -} - -# Bind a single widget to an autosuggest widget, saving a reference to the original widget -_zsh_autosuggest_bind_widget() { - typeset -gA _ZSH_AUTOSUGGEST_BIND_COUNTS - - local widget=$1 - local autosuggest_action=$2 - local prefix=$ZSH_AUTOSUGGEST_ORIGINAL_WIDGET_PREFIX - - local -i bind_count - - # Save a reference to the original widget - case $widgets[$widget] in - # Already bound - user:_zsh_autosuggest_(bound|orig)_*) - bind_count=$((_ZSH_AUTOSUGGEST_BIND_COUNTS[$widget])) - ;; - - # User-defined widget - user:*) - _zsh_autosuggest_incr_bind_count $widget - zle -N $prefix$bind_count-$widget ${widgets[$widget]#*:} - ;; - - # Built-in widget - builtin) - _zsh_autosuggest_incr_bind_count $widget - eval "_zsh_autosuggest_orig_${(q)widget}() { zle .${(q)widget} }" - zle -N $prefix$bind_count-$widget _zsh_autosuggest_orig_$widget - ;; - - # Completion widget - completion:*) - _zsh_autosuggest_incr_bind_count $widget - eval "zle -C $prefix$bind_count-${(q)widget} ${${(s.:.)widgets[$widget]}[2,3]}" - ;; - esac - - # Pass the original widget's name explicitly into the autosuggest - # function. Use this passed in widget name to call the original - # widget instead of relying on the $WIDGET variable being set - # correctly. $WIDGET cannot be trusted because other plugins call - # zle without the `-w` flag (e.g. `zle self-insert` instead of - # `zle self-insert -w`). - eval "_zsh_autosuggest_bound_${bind_count}_${(q)widget}() { - _zsh_autosuggest_widget_$autosuggest_action $prefix$bind_count-${(q)widget} \$@ - }" - - # Create the bound widget - zle -N -- $widget _zsh_autosuggest_bound_${bind_count}_$widget -} - -# Map all configured widgets to the right autosuggest widgets -_zsh_autosuggest_bind_widgets() { - emulate -L zsh - - local widget - local ignore_widgets - - ignore_widgets=( - .\* - _\* - ${_ZSH_AUTOSUGGEST_BUILTIN_ACTIONS/#/autosuggest-} - $ZSH_AUTOSUGGEST_ORIGINAL_WIDGET_PREFIX\* - $ZSH_AUTOSUGGEST_IGNORE_WIDGETS - ) - - # Find every widget we might want to bind and bind it appropriately - for widget in ${${(f)"$(builtin zle -la)"}:#${(j:|:)~ignore_widgets}}; do - if [[ -n ${ZSH_AUTOSUGGEST_CLEAR_WIDGETS[(r)$widget]} ]]; then - _zsh_autosuggest_bind_widget $widget clear - elif [[ -n ${ZSH_AUTOSUGGEST_ACCEPT_WIDGETS[(r)$widget]} ]]; then - _zsh_autosuggest_bind_widget $widget accept - elif [[ -n ${ZSH_AUTOSUGGEST_EXECUTE_WIDGETS[(r)$widget]} ]]; then - _zsh_autosuggest_bind_widget $widget execute - elif [[ -n ${ZSH_AUTOSUGGEST_PARTIAL_ACCEPT_WIDGETS[(r)$widget]} ]]; then - _zsh_autosuggest_bind_widget $widget partial_accept - else - # Assume any unspecified widget might modify the buffer - _zsh_autosuggest_bind_widget $widget modify - fi - done -} - -# Given the name of an original widget and args, invoke it, if it exists -_zsh_autosuggest_invoke_original_widget() { - # Do nothing unless called with at least one arg - (( $# )) || return 0 - - local original_widget_name="$1" - - shift - - if (( ${+widgets[$original_widget_name]} )); then - zle $original_widget_name -- $@ - fi -} - -#--------------------------------------------------------------------# -# Highlighting # -#--------------------------------------------------------------------# - -# If there was a highlight, remove it -_zsh_autosuggest_highlight_reset() { - typeset -g _ZSH_AUTOSUGGEST_LAST_HIGHLIGHT - - if [[ -n "$_ZSH_AUTOSUGGEST_LAST_HIGHLIGHT" ]]; then - region_highlight=("${(@)region_highlight:#$_ZSH_AUTOSUGGEST_LAST_HIGHLIGHT}") - unset _ZSH_AUTOSUGGEST_LAST_HIGHLIGHT - fi -} - -# If there's a suggestion, highlight it -_zsh_autosuggest_highlight_apply() { - typeset -g _ZSH_AUTOSUGGEST_LAST_HIGHLIGHT - - if (( $#POSTDISPLAY )); then - typeset -g _ZSH_AUTOSUGGEST_LAST_HIGHLIGHT="$#BUFFER $(($#BUFFER + $#POSTDISPLAY)) $ZSH_AUTOSUGGEST_HIGHLIGHT_STYLE" - region_highlight+=("$_ZSH_AUTOSUGGEST_LAST_HIGHLIGHT") - else - unset _ZSH_AUTOSUGGEST_LAST_HIGHLIGHT - fi -} - -#--------------------------------------------------------------------# -# Autosuggest Widget Implementations # -#--------------------------------------------------------------------# - -# Disable suggestions -_zsh_autosuggest_disable() { - typeset -g _ZSH_AUTOSUGGEST_DISABLED - _zsh_autosuggest_clear -} - -# Enable suggestions -_zsh_autosuggest_enable() { - unset _ZSH_AUTOSUGGEST_DISABLED - - if (( $#BUFFER )); then - _zsh_autosuggest_fetch - fi -} - -# Toggle suggestions (enable/disable) -_zsh_autosuggest_toggle() { - if (( ${+_ZSH_AUTOSUGGEST_DISABLED} )); then - _zsh_autosuggest_enable - else - _zsh_autosuggest_disable - fi -} - -# Clear the suggestion -_zsh_autosuggest_clear() { - # Remove the suggestion - unset POSTDISPLAY - - _zsh_autosuggest_invoke_original_widget $@ -} - -# Modify the buffer and get a new suggestion -_zsh_autosuggest_modify() { - local -i retval - - # Only available in zsh >= 5.4 - local -i KEYS_QUEUED_COUNT - - # Save the contents of the buffer/postdisplay - local orig_buffer="$BUFFER" - local orig_postdisplay="$POSTDISPLAY" - - # Clear suggestion while waiting for next one - unset POSTDISPLAY - - # Original widget may modify the buffer - _zsh_autosuggest_invoke_original_widget $@ - retval=$? - - emulate -L zsh - - # Don't fetch a new suggestion if there's more input to be read immediately - if (( $PENDING > 0 || $KEYS_QUEUED_COUNT > 0 )); then - POSTDISPLAY="$orig_postdisplay" - return $retval - fi - - # Optimize if manually typing in the suggestion or if buffer hasn't changed - if [[ "$BUFFER" = "$orig_buffer"* && "$orig_postdisplay" = "${BUFFER:$#orig_buffer}"* ]]; then - POSTDISPLAY="${orig_postdisplay:$(($#BUFFER - $#orig_buffer))}" - return $retval - fi - - # Bail out if suggestions are disabled - if (( ${+_ZSH_AUTOSUGGEST_DISABLED} )); then - return $? - fi - - # Get a new suggestion if the buffer is not empty after modification - if (( $#BUFFER > 0 )); then - if [[ -z "$ZSH_AUTOSUGGEST_BUFFER_MAX_SIZE" ]] || (( $#BUFFER <= $ZSH_AUTOSUGGEST_BUFFER_MAX_SIZE )); then - _zsh_autosuggest_fetch - fi - fi - - return $retval -} - -# Fetch a new suggestion based on what's currently in the buffer -_zsh_autosuggest_fetch() { - if (( ${+ZSH_AUTOSUGGEST_USE_ASYNC} )); then - _zsh_autosuggest_async_request "$BUFFER" - else - local suggestion - _zsh_autosuggest_fetch_suggestion "$BUFFER" - _zsh_autosuggest_suggest "$suggestion" - fi -} - -# Offer a suggestion -_zsh_autosuggest_suggest() { - emulate -L zsh - - local suggestion="$1" - - if [[ -n "$suggestion" ]] && (( $#BUFFER )); then - POSTDISPLAY="${suggestion#$BUFFER}" - else - unset POSTDISPLAY - fi -} - -# Accept the entire suggestion -_zsh_autosuggest_accept() { - local -i retval max_cursor_pos=$#BUFFER - - # When vicmd keymap is active, the cursor can't move all the way - # to the end of the buffer - if [[ "$KEYMAP" = "vicmd" ]]; then - max_cursor_pos=$((max_cursor_pos - 1)) - fi - - # If we're not in a valid state to accept a suggestion, just run the - # original widget and bail out - if (( $CURSOR != $max_cursor_pos || !$#POSTDISPLAY )); then - _zsh_autosuggest_invoke_original_widget $@ - return - fi - - # Only accept if the cursor is at the end of the buffer - # Add the suggestion to the buffer - BUFFER="$BUFFER$POSTDISPLAY" - - # Remove the suggestion - unset POSTDISPLAY - - # Run the original widget before manually moving the cursor so that the - # cursor movement doesn't make the widget do something unexpected - _zsh_autosuggest_invoke_original_widget $@ - retval=$? - - # Move the cursor to the end of the buffer - if [[ "$KEYMAP" = "vicmd" ]]; then - CURSOR=$(($#BUFFER - 1)) - else - CURSOR=$#BUFFER - fi - - return $retval -} - -# Accept the entire suggestion and execute it -_zsh_autosuggest_execute() { - # Add the suggestion to the buffer - BUFFER="$BUFFER$POSTDISPLAY" - - # Remove the suggestion - unset POSTDISPLAY - - # Call the original `accept-line` to handle syntax highlighting or - # other potential custom behavior - _zsh_autosuggest_invoke_original_widget "accept-line" -} - -# Partially accept the suggestion -_zsh_autosuggest_partial_accept() { - local -i retval cursor_loc - - # Save the contents of the buffer so we can restore later if needed - local original_buffer="$BUFFER" - - # Temporarily accept the suggestion. - BUFFER="$BUFFER$POSTDISPLAY" - - # Original widget moves the cursor - _zsh_autosuggest_invoke_original_widget $@ - retval=$? - - # Normalize cursor location across vi/emacs modes - cursor_loc=$CURSOR - if [[ "$KEYMAP" = "vicmd" ]]; then - cursor_loc=$((cursor_loc + 1)) - fi - - # If we've moved past the end of the original buffer - if (( $cursor_loc > $#original_buffer )); then - # Set POSTDISPLAY to text right of the cursor - POSTDISPLAY="${BUFFER[$(($cursor_loc + 1)),$#BUFFER]}" - - # Clip the buffer at the cursor - BUFFER="${BUFFER[1,$cursor_loc]}" - else - # Restore the original buffer - BUFFER="$original_buffer" - fi - - return $retval -} - -() { - typeset -ga _ZSH_AUTOSUGGEST_BUILTIN_ACTIONS - - _ZSH_AUTOSUGGEST_BUILTIN_ACTIONS=( - clear - fetch - suggest - accept - execute - enable - disable - toggle - ) - - local action - for action in $_ZSH_AUTOSUGGEST_BUILTIN_ACTIONS modify partial_accept; do - eval "_zsh_autosuggest_widget_$action() { - local -i retval - - _zsh_autosuggest_highlight_reset - - _zsh_autosuggest_$action \$@ - retval=\$? - - _zsh_autosuggest_highlight_apply - - zle -R - - return \$retval - }" - done - - for action in $_ZSH_AUTOSUGGEST_BUILTIN_ACTIONS; do - zle -N autosuggest-$action _zsh_autosuggest_widget_$action - done -} - -#--------------------------------------------------------------------# -# Completion Suggestion Strategy # -#--------------------------------------------------------------------# -# Fetches a suggestion from the completion engine -# - -_zsh_autosuggest_capture_postcompletion() { - # Always insert the first completion into the buffer - compstate[insert]=1 - - # Don't list completions - unset 'compstate[list]' -} - -_zsh_autosuggest_capture_completion_widget() { - # Add a post-completion hook to be called after all completions have been - # gathered. The hook can modify compstate to affect what is done with the - # gathered completions. - local -a +h comppostfuncs - comppostfuncs=(_zsh_autosuggest_capture_postcompletion) - - # Only capture completions at the end of the buffer - CURSOR=$#BUFFER - - # Run the original widget wrapping `.complete-word` so we don't - # recursively try to fetch suggestions, since our pty is forked - # after autosuggestions is initialized. - zle -- ${(k)widgets[(r)completion:.complete-word:_main_complete]} - - if is-at-least 5.0.3; then - # Don't do any cr/lf transformations. We need to do this immediately before - # output because if we do it in setup, onlcr will be re-enabled when we enter - # vared in the async code path. There is a bug in zpty module in older versions - # where the tty is not properly attached to the pty slave, resulting in stty - # getting stopped with a SIGTTOU. See zsh-workers thread 31660 and upstream - # commit f75904a38 - stty -onlcr -ocrnl -F /dev/tty - fi - - # The completion has been added, print the buffer as the suggestion - echo -nE - $'\0'$BUFFER$'\0' -} - -zle -N autosuggest-capture-completion _zsh_autosuggest_capture_completion_widget - -_zsh_autosuggest_capture_setup() { - # There is a bug in zpty module in older zsh versions by which a - # zpty that exits will kill all zpty processes that were forked - # before it. Here we set up a zsh exit hook to SIGKILL the zpty - # process immediately, before it has a chance to kill any other - # zpty processes. - if ! is-at-least 5.4; then - zshexit() { - # The zsh builtin `kill` fails sometimes in older versions - # https://unix.stackexchange.com/a/477647/156673 - kill -KILL $$ 2>&- || command kill -KILL $$ - - # Block for long enough for the signal to come through - sleep 1 - } - fi - - # Try to avoid any suggestions that wouldn't match the prefix - zstyle ':completion:*' matcher-list '' - zstyle ':completion:*' path-completion false - zstyle ':completion:*' max-errors 0 not-numeric - - bindkey '^I' autosuggest-capture-completion -} - -_zsh_autosuggest_capture_completion_sync() { - _zsh_autosuggest_capture_setup - - zle autosuggest-capture-completion -} - -_zsh_autosuggest_capture_completion_async() { - _zsh_autosuggest_capture_setup - - zmodload zsh/parameter 2>/dev/null || return # For `$functions` - - # Make vared completion work as if for a normal command line - # https://stackoverflow.com/a/7057118/154703 - autoload +X _complete - functions[_original_complete]=$functions[_complete] - function _complete() { - unset 'compstate[vared]' - _original_complete "$@" - } - - # Open zle with buffer set so we can capture completions for it - vared 1 -} - -_zsh_autosuggest_strategy_completion() { - # Reset options to defaults and enable LOCAL_OPTIONS - emulate -L zsh - - # Enable extended glob for completion ignore pattern - setopt EXTENDED_GLOB - - typeset -g suggestion - local line REPLY - - # Exit if we don't have completions - whence compdef >/dev/null || return - - # Exit if we don't have zpty - zmodload zsh/zpty 2>/dev/null || return - - # Exit if our search string matches the ignore pattern - [[ -n "$ZSH_AUTOSUGGEST_COMPLETION_IGNORE" ]] && [[ "$1" == $~ZSH_AUTOSUGGEST_COMPLETION_IGNORE ]] && return - - # Zle will be inactive if we are in async mode - if zle; then - zpty $ZSH_AUTOSUGGEST_COMPLETIONS_PTY_NAME _zsh_autosuggest_capture_completion_sync - else - zpty $ZSH_AUTOSUGGEST_COMPLETIONS_PTY_NAME _zsh_autosuggest_capture_completion_async "\$1" - zpty -w $ZSH_AUTOSUGGEST_COMPLETIONS_PTY_NAME $'\t' - fi - - { - # The completion result is surrounded by null bytes, so read the - # content between the first two null bytes. - zpty -r $ZSH_AUTOSUGGEST_COMPLETIONS_PTY_NAME line '*'$'\0''*'$'\0' - - # Extract the suggestion from between the null bytes. On older - # versions of zsh (older than 5.3), we sometimes get extra bytes after - # the second null byte, so trim those off the end. - # See http://www.zsh.org/mla/workers/2015/msg03290.html - suggestion="${${(@0)line}[2]}" - } always { - # Destroy the pty - zpty -d $ZSH_AUTOSUGGEST_COMPLETIONS_PTY_NAME - } -} - -#--------------------------------------------------------------------# -# History Suggestion Strategy # -#--------------------------------------------------------------------# -# Suggests the most recent history item that matches the given -# prefix. -# - -_zsh_autosuggest_strategy_history() { - # Reset options to defaults and enable LOCAL_OPTIONS - emulate -L zsh - - # Enable globbing flags so that we can use (#m) and (x~y) glob operator - setopt EXTENDED_GLOB - - # Escape backslashes and all of the glob operators so we can use - # this string as a pattern to search the $history associative array. - # - (#m) globbing flag enables setting references for match data - # TODO: Use (b) flag when we can drop support for zsh older than v5.0.8 - local prefix="${1//(#m)[\\*?[\]<>()|^~#]/\\$MATCH}" - - # Get the history items that match the prefix, excluding those that match - # the ignore pattern - local pattern="$prefix*" - if [[ -n $ZSH_AUTOSUGGEST_HISTORY_IGNORE ]]; then - pattern="($pattern)~($ZSH_AUTOSUGGEST_HISTORY_IGNORE)" - fi - - # Give the first history item matching the pattern as the suggestion - # - (r) subscript flag makes the pattern match on values - typeset -g suggestion="${history[(r)$pattern]}" -} - -#--------------------------------------------------------------------# -# Match Previous Command Suggestion Strategy # -#--------------------------------------------------------------------# -# Suggests the most recent history item that matches the given -# prefix and whose preceding history item also matches the most -# recently executed command. -# -# For example, suppose your history has the following entries: -# - pwd -# - ls foo -# - ls bar -# - pwd -# -# Given the history list above, when you type 'ls', the suggestion -# will be 'ls foo' rather than 'ls bar' because your most recently -# executed command (pwd) was previously followed by 'ls foo'. -# -# Note that this strategy won't work as expected with ZSH options that don't -# preserve the history order such as `HIST_IGNORE_ALL_DUPS` or -# `HIST_EXPIRE_DUPS_FIRST`. - -_zsh_autosuggest_strategy_match_prev_cmd() { - # Reset options to defaults and enable LOCAL_OPTIONS - emulate -L zsh - - # Enable globbing flags so that we can use (#m) and (x~y) glob operator - setopt EXTENDED_GLOB - - # TODO: Use (b) flag when we can drop support for zsh older than v5.0.8 - local prefix="${1//(#m)[\\*?[\]<>()|^~#]/\\$MATCH}" - - # Get the history items that match the prefix, excluding those that match - # the ignore pattern - local pattern="$prefix*" - if [[ -n $ZSH_AUTOSUGGEST_HISTORY_IGNORE ]]; then - pattern="($pattern)~($ZSH_AUTOSUGGEST_HISTORY_IGNORE)" - fi - - # Get all history event numbers that correspond to history - # entries that match the pattern - local history_match_keys - history_match_keys=(${(k)history[(R)$~pattern]}) - - # By default we use the first history number (most recent history entry) - local histkey="${history_match_keys[1]}" - - # Get the previously executed command - local prev_cmd="$(_zsh_autosuggest_escape_command "${history[$((HISTCMD-1))]}")" - - # Iterate up to the first 200 history event numbers that match $prefix - for key in "${(@)history_match_keys[1,200]}"; do - # Stop if we ran out of history - [[ $key -gt 1 ]] || break - - # See if the history entry preceding the suggestion matches the - # previous command, and use it if it does - if [[ "${history[$((key - 1))]}" == "$prev_cmd" ]]; then - histkey="$key" - break - fi - done - - # Give back the matched history entry - typeset -g suggestion="$history[$histkey]" -} - -#--------------------------------------------------------------------# -# Fetch Suggestion # -#--------------------------------------------------------------------# -# Loops through all specified strategies and returns a suggestion -# from the first strategy to provide one. -# - -_zsh_autosuggest_fetch_suggestion() { - typeset -g suggestion - local -a strategies - local strategy - - # Ensure we are working with an array - strategies=(${=ZSH_AUTOSUGGEST_STRATEGY}) - - for strategy in $strategies; do - # Try to get a suggestion from this strategy - _zsh_autosuggest_strategy_$strategy "$1" - - # Ensure the suggestion matches the prefix - [[ "$suggestion" != "$1"* ]] && unset suggestion - - # Break once we've found a valid suggestion - [[ -n "$suggestion" ]] && break - done -} - -#--------------------------------------------------------------------# -# Async # -#--------------------------------------------------------------------# - -_zsh_autosuggest_async_request() { - zmodload zsh/system 2>/dev/null # For `$sysparams` - - typeset -g _ZSH_AUTOSUGGEST_ASYNC_FD _ZSH_AUTOSUGGEST_CHILD_PID - - # If we've got a pending request, cancel it - if [[ -n "$_ZSH_AUTOSUGGEST_ASYNC_FD" ]] && { true <&$_ZSH_AUTOSUGGEST_ASYNC_FD } 2>/dev/null; then - # Close the file descriptor and remove the handler - exec {_ZSH_AUTOSUGGEST_ASYNC_FD}<&- - zle -F $_ZSH_AUTOSUGGEST_ASYNC_FD - - # We won't know the pid unless the user has zsh/system module installed - if [[ -n "$_ZSH_AUTOSUGGEST_CHILD_PID" ]]; then - # Zsh will make a new process group for the child process only if job - # control is enabled (MONITOR option) - if [[ -o MONITOR ]]; then - # Send the signal to the process group to kill any processes that may - # have been forked by the suggestion strategy - kill -TERM -$_ZSH_AUTOSUGGEST_CHILD_PID 2>/dev/null - else - # Kill just the child process since it wasn't placed in a new process - # group. If the suggestion strategy forked any child processes they may - # be orphaned and left behind. - kill -TERM $_ZSH_AUTOSUGGEST_CHILD_PID 2>/dev/null - fi - fi - fi - - # Fork a process to fetch a suggestion and open a pipe to read from it - exec {_ZSH_AUTOSUGGEST_ASYNC_FD}< <( - # Tell parent process our pid - echo $sysparams[pid] - - # Fetch and print the suggestion - local suggestion - _zsh_autosuggest_fetch_suggestion "$1" - echo -nE "$suggestion" - ) - - # There's a weird bug here where ^C stops working unless we force a fork - # See https://github.com/zsh-users/zsh-autosuggestions/issues/364 - autoload -Uz is-at-least - is-at-least 5.8 || command true - - # Read the pid from the child process - read _ZSH_AUTOSUGGEST_CHILD_PID <&$_ZSH_AUTOSUGGEST_ASYNC_FD - - # When the fd is readable, call the response handler - zle -F "$_ZSH_AUTOSUGGEST_ASYNC_FD" _zsh_autosuggest_async_response -} - -# Called when new data is ready to be read from the pipe -# First arg will be fd ready for reading -# Second arg will be passed in case of error -_zsh_autosuggest_async_response() { - emulate -L zsh - - local suggestion - - if [[ -z "$2" || "$2" == "hup" ]]; then - # Read everything from the fd and give it as a suggestion - IFS='' read -rd '' -u $1 suggestion - zle autosuggest-suggest -- "$suggestion" - - # Close the fd - exec {1}<&- - fi - - # Always remove the handler - zle -F "$1" -} - -#--------------------------------------------------------------------# -# Start # -#--------------------------------------------------------------------# - -# Start the autosuggestion widgets -_zsh_autosuggest_start() { - # By default we re-bind widgets on every precmd to ensure we wrap other - # wrappers. Specifically, highlighting breaks if our widgets are wrapped by - # zsh-syntax-highlighting widgets. This also allows modifications to the - # widget list variables to take effect on the next precmd. However this has - # a decent performance hit, so users can set ZSH_AUTOSUGGEST_MANUAL_REBIND - # to disable the automatic re-binding. - if (( ${+ZSH_AUTOSUGGEST_MANUAL_REBIND} )); then - add-zsh-hook -d precmd _zsh_autosuggest_start - fi - - _zsh_autosuggest_bind_widgets -} - -# Mark for auto-loading the functions that we use -autoload -Uz add-zsh-hook is-at-least - -# Automatically enable asynchronous mode in newer versions of zsh. Disable for -# older versions because there is a bug when using async mode where ^C does not -# work immediately after fetching a suggestion. -# See https://github.com/zsh-users/zsh-autosuggestions/issues/364 -if is-at-least 5.0.8; then - typeset -g ZSH_AUTOSUGGEST_USE_ASYNC= -fi - -# Start the autosuggestion widgets on the next precmd -add-zsh-hook precmd _zsh_autosuggest_start diff --git a/.config/zsh/plugins/zsh-history-substring-search b/.config/zsh/plugins/zsh-history-substring-search new file mode 160000 +Subproject 87ce96b1862928d84b1afe7c173316614b30e30 diff --git a/.config/zsh/plugins/zsh-history-substring-search.zsh b/.config/zsh/plugins/zsh-history-substring-search.zsh deleted file mode 100644 index a791cc4..0000000 --- a/.config/zsh/plugins/zsh-history-substring-search.zsh +++ /dev/null @@ -1,759 +0,0 @@ -#!/usr/bin/env zsh -############################################################################## -# -# Copyright (c) 2009 Peter Stephenson -# Copyright (c) 2011 Guido van Steen -# Copyright (c) 2011 Suraj N. Kurapati -# Copyright (c) 2011 Sorin Ionescu -# Copyright (c) 2011 Vincent Guerci -# Copyright (c) 2016 Geza Lore -# Copyright (c) 2017 Bengt Brodersen -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following -# disclaimer in the documentation and/or other materials provided -# with the distribution. -# -# * Neither the name of the FIZSH nor the names of its contributors -# may be used to endorse or promote products derived from this -# software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. -# -############################################################################## - -#----------------------------------------------------------------------------- -# declare global configuration variables -#----------------------------------------------------------------------------- - -typeset -g HISTORY_SUBSTRING_SEARCH_HIGHLIGHT_FOUND='bg=magenta,fg=white,bold' -typeset -g HISTORY_SUBSTRING_SEARCH_HIGHLIGHT_NOT_FOUND='bg=red,fg=white,bold' -typeset -g HISTORY_SUBSTRING_SEARCH_GLOBBING_FLAGS='i' -typeset -g HISTORY_SUBSTRING_SEARCH_ENSURE_UNIQUE='' -typeset -g HISTORY_SUBSTRING_SEARCH_FUZZY='' - -#----------------------------------------------------------------------------- -# declare internal global variables -#----------------------------------------------------------------------------- - -typeset -g BUFFER MATCH MBEGIN MEND CURSOR -typeset -g _history_substring_search_refresh_display -typeset -g _history_substring_search_query_highlight -typeset -g _history_substring_search_result -typeset -g _history_substring_search_query -typeset -g -a _history_substring_search_query_parts -typeset -g -a _history_substring_search_raw_matches -typeset -g -i _history_substring_search_raw_match_index -typeset -g -a _history_substring_search_matches -typeset -g -i _history_substring_search_match_index -typeset -g -A _history_substring_search_unique_filter - -#----------------------------------------------------------------------------- -# the main ZLE widgets -#----------------------------------------------------------------------------- - -history-substring-search-up() { - _history-substring-search-begin - - _history-substring-search-up-history || - _history-substring-search-up-buffer || - _history-substring-search-up-search - - _history-substring-search-end -} - -history-substring-search-down() { - _history-substring-search-begin - - _history-substring-search-down-history || - _history-substring-search-down-buffer || - _history-substring-search-down-search - - _history-substring-search-end -} - -zle -N history-substring-search-up -zle -N history-substring-search-down - -#----------------------------------------------------------------------------- -# implementation details -#----------------------------------------------------------------------------- - -zmodload -F zsh/parameter - -# -# We have to "override" some keys and widgets if the -# zsh-syntax-highlighting plugin has not been loaded: -# -# https://github.com/nicoulaj/zsh-syntax-highlighting -# -if [[ $+functions[_zsh_highlight] -eq 0 ]]; then - # - # Dummy implementation of _zsh_highlight() that - # simply removes any existing highlights when the - # user inserts printable characters into $BUFFER. - # - _zsh_highlight() { - if [[ $KEYS == [[:print:]] ]]; then - region_highlight=() - fi - } - - # - # The following snippet was taken from the zsh-syntax-highlighting project: - # - # https://github.com/zsh-users/zsh-syntax-highlighting/blob/56b134f5d62ae3d4e66c7f52bd0cc2595f9b305b/zsh-syntax-highlighting.zsh#L126-161 - # - # Copyright (c) 2010-2011 zsh-syntax-highlighting contributors - # All rights reserved. - # - # Redistribution and use in source and binary forms, with or without - # modification, are permitted provided that the following conditions are - # met: - # - # * Redistributions of source code must retain the above copyright - # notice, this list of conditions and the following disclaimer. - # - # * Redistributions in binary form must reproduce the above copyright - # notice, this list of conditions and the following disclaimer in the - # documentation and/or other materials provided with the distribution. - # - # * Neither the name of the zsh-syntax-highlighting contributors nor the - # names of its contributors may be used to endorse or promote products - # derived from this software without specific prior written permission. - # - # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - # IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR - # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - # - #--------------8<-------------------8<-------------------8<----------------- - # Rebind all ZLE widgets to make them invoke _zsh_highlights. - _zsh_highlight_bind_widgets() - { - # Load ZSH module zsh/zleparameter, needed to override user defined widgets. - zmodload zsh/zleparameter 2>/dev/null || { - echo 'zsh-syntax-highlighting: failed loading zsh/zleparameter.' >&2 - return 1 - } - - # Override ZLE widgets to make them invoke _zsh_highlight. - local cur_widget - for cur_widget in ${${(f)"$(builtin zle -la)"}:#(.*|_*|orig-*|run-help|which-command|beep|yank*)}; do - case $widgets[$cur_widget] in - - # Already rebound event: do nothing. - user:$cur_widget|user:_zsh_highlight_widget_*);; - - # User defined widget: override and rebind old one with prefix "orig-". - user:*) eval "zle -N orig-$cur_widget ${widgets[$cur_widget]#*:}; \ - _zsh_highlight_widget_$cur_widget() { builtin zle orig-$cur_widget -- \"\$@\" && _zsh_highlight }; \ - zle -N $cur_widget _zsh_highlight_widget_$cur_widget";; - - # Completion widget: override and rebind old one with prefix "orig-". - completion:*) eval "zle -C orig-$cur_widget ${${widgets[$cur_widget]#*:}/:/ }; \ - _zsh_highlight_widget_$cur_widget() { builtin zle orig-$cur_widget -- \"\$@\" && _zsh_highlight }; \ - zle -N $cur_widget _zsh_highlight_widget_$cur_widget";; - - # Builtin widget: override and make it call the builtin ".widget". - builtin) eval "_zsh_highlight_widget_$cur_widget() { builtin zle .$cur_widget -- \"\$@\" && _zsh_highlight }; \ - zle -N $cur_widget _zsh_highlight_widget_$cur_widget";; - - # Default: unhandled case. - *) echo "zsh-syntax-highlighting: unhandled ZLE widget '$cur_widget'" >&2 ;; - esac - done - } - #-------------->8------------------->8------------------->8----------------- - - _zsh_highlight_bind_widgets -fi - -_history-substring-search-begin() { - setopt localoptions extendedglob - - _history_substring_search_refresh_display= - _history_substring_search_query_highlight= - - # - # If the buffer is the same as the previously displayed history substring - # search result, then just keep stepping through the match list. Otherwise - # start a new search. - # - if [[ -n $BUFFER && $BUFFER == ${_history_substring_search_result:-} ]]; then - return; - fi - - # - # Clear the previous result. - # - _history_substring_search_result='' - - if [[ -z $BUFFER ]]; then - # - # If the buffer is empty, we will just act like up-history/down-history - # in ZSH, so we do not need to actually search the history. This should - # speed things up a little. - # - _history_substring_search_query= - _history_substring_search_query_parts=() - _history_substring_search_raw_matches=() - - else - # - # For the purpose of highlighting we keep a copy of the original - # query string. - # - _history_substring_search_query=$BUFFER - - # - # compose search pattern - # - if [[ -n $HISTORY_SUBSTRING_SEARCH_FUZZY ]]; then - # - # `=` split string in arguments - # - _history_substring_search_query_parts=(${=_history_substring_search_query}) - else - _history_substring_search_query_parts=(${==_history_substring_search_query}) - fi - - # - # Escape and join query parts with wildcard character '*' as seperator - # `(j:CHAR:)` join array to string with CHAR as seperator - # - local search_pattern="*${(j:*:)_history_substring_search_query_parts[@]//(#m)[\][()|\\*?#<>~^]/\\$MATCH}*" - - # - # Find all occurrences of the search pattern in the history file. - # - # (k) returns the "keys" (history index numbers) instead of the values - # (R) returns values in reverse older, so the index of the youngest - # matching history entry is at the head of the list. - # - _history_substring_search_raw_matches=(${(k)history[(R)(#$HISTORY_SUBSTRING_SEARCH_GLOBBING_FLAGS)${search_pattern}]}) - fi - - # - # In order to stay as responsive as possible, we will process the raw - # matches lazily (when the user requests the next match) to choose items - # that need to be displayed to the user. - # _history_substring_search_raw_match_index holds the index of the last - # unprocessed entry in _history_substring_search_raw_matches. Any items - # that need to be displayed will be added to - # _history_substring_search_matches. - # - # We use an associative array (_history_substring_search_unique_filter) as - # a 'set' data structure to ensure uniqueness of the results if desired. - # If an entry (key) is in the set (non-empty value), then we have already - # added that entry to _history_substring_search_matches. - # - _history_substring_search_raw_match_index=0 - _history_substring_search_matches=() - _history_substring_search_unique_filter=() - - # - # If $_history_substring_search_match_index is equal to - # $#_history_substring_search_matches + 1, this indicates that we - # are beyond the end of $_history_substring_search_matches and that we - # have also processed all entries in - # _history_substring_search_raw_matches. - # - # If $#_history_substring_search_match_index is equal to 0, this indicates - # that we are beyond the beginning of $_history_substring_search_matches. - # - # If we have initially pressed "up" we have to initialize - # $_history_substring_search_match_index to 0 so that it will be - # incremented to 1. - # - # If we have initially pressed "down" we have to initialize - # $_history_substring_search_match_index to 1 so that it will be - # decremented to 0. - # - if [[ $WIDGET == history-substring-search-down ]]; then - _history_substring_search_match_index=1 - else - _history_substring_search_match_index=0 - fi -} - -_history-substring-search-end() { - setopt localoptions extendedglob - - _history_substring_search_result=$BUFFER - - # the search was successful so display the result properly by clearing away - # existing highlights and moving the cursor to the end of the result buffer - if [[ $_history_substring_search_refresh_display -eq 1 ]]; then - region_highlight=() - CURSOR=${#BUFFER} - fi - - # highlight command line using zsh-syntax-highlighting - _zsh_highlight - - # highlight the search query inside the command line - if [[ -n $_history_substring_search_query_highlight ]]; then - # highlight first matching query parts - local highlight_start_index=0 - local highlight_end_index=0 - local query_part - for query_part in $_history_substring_search_query_parts; do - local escaped_query_part=${query_part//(#m)[\][()|\\*?#<>~^]/\\$MATCH} - # (i) get index of pattern - local query_part_match_index="${${BUFFER:$highlight_start_index}[(i)(#$HISTORY_SUBSTRING_SEARCH_GLOBBING_FLAGS)${escaped_query_part}]}" - if [[ $query_part_match_index -le ${#BUFFER:$highlight_start_index} ]]; then - highlight_start_index=$(( $highlight_start_index + $query_part_match_index )) - highlight_end_index=$(( $highlight_start_index + ${#query_part} )) - region_highlight+=("$(($highlight_start_index - 1)) $(($highlight_end_index - 1)) $_history_substring_search_query_highlight") - fi - done - fi - - # For debugging purposes: - # zle -R "mn: "$_history_substring_search_match_index" m#: "${#_history_substring_search_matches} - # read -k -t 200 && zle -U $REPLY - - # Exit successfully from the history-substring-search-* widgets. - return 0 -} - -_history-substring-search-up-buffer() { - # - # Check if the UP arrow was pressed to move the cursor within a multi-line - # buffer. This amounts to three tests: - # - # 1. $#buflines -gt 1. - # - # 2. $CURSOR -ne $#BUFFER. - # - # 3. Check if we are on the first line of the current multi-line buffer. - # If so, pressing UP would amount to leaving the multi-line buffer. - # - # We check this by adding an extra "x" to $LBUFFER, which makes - # sure that xlbuflines is always equal to the number of lines - # until $CURSOR (including the line with the cursor on it). - # - local buflines XLBUFFER xlbuflines - buflines=(${(f)BUFFER}) - XLBUFFER=$LBUFFER"x" - xlbuflines=(${(f)XLBUFFER}) - - if [[ $#buflines -gt 1 && $CURSOR -ne $#BUFFER && $#xlbuflines -ne 1 ]]; then - zle up-line-or-history - return 0 - fi - - return 1 -} - -_history-substring-search-down-buffer() { - # - # Check if the DOWN arrow was pressed to move the cursor within a multi-line - # buffer. This amounts to three tests: - # - # 1. $#buflines -gt 1. - # - # 2. $CURSOR -ne $#BUFFER. - # - # 3. Check if we are on the last line of the current multi-line buffer. - # If so, pressing DOWN would amount to leaving the multi-line buffer. - # - # We check this by adding an extra "x" to $RBUFFER, which makes - # sure that xrbuflines is always equal to the number of lines - # from $CURSOR (including the line with the cursor on it). - # - local buflines XRBUFFER xrbuflines - buflines=(${(f)BUFFER}) - XRBUFFER="x"$RBUFFER - xrbuflines=(${(f)XRBUFFER}) - - if [[ $#buflines -gt 1 && $CURSOR -ne $#BUFFER && $#xrbuflines -ne 1 ]]; then - zle down-line-or-history - return 0 - fi - - return 1 -} - -_history-substring-search-up-history() { - # - # Behave like up in ZSH, except clear the $BUFFER - # when beginning of history is reached like in Fish. - # - if [[ -z $_history_substring_search_query ]]; then - - # we have reached the absolute top of history - if [[ $HISTNO -eq 1 ]]; then - BUFFER= - - # going up from somewhere below the top of history - else - zle up-line-or-history - fi - - return 0 - fi - - return 1 -} - -_history-substring-search-down-history() { - # - # Behave like down-history in ZSH, except clear the - # $BUFFER when end of history is reached like in Fish. - # - if [[ -z $_history_substring_search_query ]]; then - - # going down from the absolute top of history - if [[ $HISTNO -eq 1 && -z $BUFFER ]]; then - BUFFER=${history[1]} - _history_substring_search_refresh_display=1 - - # going down from somewhere above the bottom of history - else - zle down-line-or-history - fi - - return 0 - fi - - return 1 -} - -_history_substring_search_process_raw_matches() { - # - # Process more outstanding raw matches and append any matches that need to - # be displayed to the user to _history_substring_search_matches. - # Return whether there were any more results appended. - # - - # - # While we have more raw matches. Process them to see if there are any more - # matches that need to be displayed to the user. - # - while [[ $_history_substring_search_raw_match_index -lt $#_history_substring_search_raw_matches ]]; do - # - # Move on to the next raw entry and get its history index. - # - _history_substring_search_raw_match_index+=1 - local index=${_history_substring_search_raw_matches[$_history_substring_search_raw_match_index]} - - # - # If HISTORY_SUBSTRING_SEARCH_ENSURE_UNIQUE is set to a non-empty value, - # then ensure that only unique matches are presented to the user. - # When HIST_IGNORE_ALL_DUPS is set, ZSH already ensures a unique history, - # so in this case we do not need to do anything. - # - if [[ ! -o HIST_IGNORE_ALL_DUPS && -n $HISTORY_SUBSTRING_SEARCH_ENSURE_UNIQUE ]]; then - # - # Get the actual history entry at the new index, and check if we have - # already added it to _history_substring_search_matches. - # - local entry=${history[$index]} - - if [[ -z ${_history_substring_search_unique_filter[$entry]} ]]; then - # - # This is a new unique entry. Add it to the filter and append the - # index to _history_substring_search_matches. - # - _history_substring_search_unique_filter[$entry]=1 - _history_substring_search_matches+=($index) - - # - # Indicate that we did find a match. - # - return 0 - fi - - else - # - # Just append the new history index to the processed matches. - # - _history_substring_search_matches+=($index) - - # - # Indicate that we did find a match. - # - return 0 - fi - - done - - # - # We are beyond the end of the list of raw matches. Indicate that no - # more matches are available. - # - return 1 -} - -_history-substring-search-has-next() { - # - # Predicate function that returns whether any more older matches are - # available. - # - - if [[ $_history_substring_search_match_index -lt $#_history_substring_search_matches ]]; then - # - # We did not reach the end of the processed list, so we do have further - # matches. - # - return 0 - - else - # - # We are at the end of the processed list. Try to process further - # unprocessed matches. _history_substring_search_process_raw_matches - # returns whether any more matches were available, so just return - # that result. - # - _history_substring_search_process_raw_matches - return $? - fi -} - -_history-substring-search-has-prev() { - # - # Predicate function that returns whether any more younger matches are - # available. - # - - if [[ $_history_substring_search_match_index -gt 1 ]]; then - # - # We did not reach the beginning of the processed list, so we do have - # further matches. - # - return 0 - - else - # - # We are at the beginning of the processed list. We do not have any more - # matches. - # - return 1 - fi -} - -_history-substring-search-found() { - # - # A match is available. The index of the match is held in - # $_history_substring_search_match_index - # - # 1. Make $BUFFER equal to the matching history entry. - # - # 2. Use $HISTORY_SUBSTRING_SEARCH_HIGHLIGHT_FOUND - # to highlight the current buffer. - # - BUFFER=$history[$_history_substring_search_matches[$_history_substring_search_match_index]] - _history_substring_search_query_highlight=$HISTORY_SUBSTRING_SEARCH_HIGHLIGHT_FOUND -} - -_history-substring-search-not-found() { - # - # No more matches are available. - # - # 1. Make $BUFFER equal to $_history_substring_search_query so the user can - # revise it and search again. - # - # 2. Use $HISTORY_SUBSTRING_SEARCH_HIGHLIGHT_NOT_FOUND - # to highlight the current buffer. - # - BUFFER=$_history_substring_search_query - _history_substring_search_query_highlight=$HISTORY_SUBSTRING_SEARCH_HIGHLIGHT_NOT_FOUND -} - -_history-substring-search-up-search() { - _history_substring_search_refresh_display=1 - - # - # Select history entry during history-substring-down-search: - # - # The following variables have been initialized in - # _history-substring-search-up/down-search(): - # - # $_history_substring_search_matches is the current list of matches that - # need to be displayed to the user. - # $_history_substring_search_match_index is the index of the current match - # that is being displayed to the user. - # - # The range of values that $_history_substring_search_match_index can take - # is: [0, $#_history_substring_search_matches + 1]. A value of 0 - # indicates that we are beyond the beginning of - # $_history_substring_search_matches. A value of - # $#_history_substring_search_matches + 1 indicates that we are beyond - # the end of $_history_substring_search_matches and that we have also - # processed all entries in _history_substring_search_raw_matches. - # - # If $_history_substring_search_match_index equals - # $#_history_substring_search_matches and - # $_history_substring_search_raw_match_index is not greater than - # $#_history_substring_search_raw_matches, then we need to further process - # $_history_substring_search_raw_matches to see if there are any more - # entries that need to be displayed to the user. - # - # In _history-substring-search-up-search() the initial value of - # $_history_substring_search_match_index is 0. This value is set in - # _history-substring-search-begin(). _history-substring-search-up-search() - # will initially increment it to 1. - # - - if [[ $_history_substring_search_match_index -gt $#_history_substring_search_matches ]]; then - # - # We are beyond the end of $_history_substring_search_matches. This - # can only happen if we have also exhausted the unprocessed matches in - # _history_substring_search_raw_matches. - # - # 1. Update display to indicate search not found. - # - _history-substring-search-not-found - return - fi - - if _history-substring-search-has-next; then - # - # We do have older matches. - # - # 1. Move index to point to the next match. - # 2. Update display to indicate search found. - # - _history_substring_search_match_index+=1 - _history-substring-search-found - - else - # - # We do not have older matches. - # - # 1. Move the index beyond the end of - # _history_substring_search_matches. - # 2. Update display to indicate search not found. - # - _history_substring_search_match_index+=1 - _history-substring-search-not-found - fi - - # - # When HIST_FIND_NO_DUPS is set, meaning that only unique command lines from - # history should be matched, make sure the new and old results are different. - # - # However, if the HIST_IGNORE_ALL_DUPS shell option, or - # HISTORY_SUBSTRING_SEARCH_ENSURE_UNIQUE is set, then we already have a - # unique history, so in this case we do not need to do anything. - # - if [[ -o HIST_IGNORE_ALL_DUPS || -n $HISTORY_SUBSTRING_SEARCH_ENSURE_UNIQUE ]]; then - return - fi - - if [[ -o HIST_FIND_NO_DUPS && $BUFFER == $_history_substring_search_result ]]; then - # - # Repeat the current search so that a different (unique) match is found. - # - _history-substring-search-up-search - fi -} - -_history-substring-search-down-search() { - _history_substring_search_refresh_display=1 - - # - # Select history entry during history-substring-down-search: - # - # The following variables have been initialized in - # _history-substring-search-up/down-search(): - # - # $_history_substring_search_matches is the current list of matches that - # need to be displayed to the user. - # $_history_substring_search_match_index is the index of the current match - # that is being displayed to the user. - # - # The range of values that $_history_substring_search_match_index can take - # is: [0, $#_history_substring_search_matches + 1]. A value of 0 - # indicates that we are beyond the beginning of - # $_history_substring_search_matches. A value of - # $#_history_substring_search_matches + 1 indicates that we are beyond - # the end of $_history_substring_search_matches and that we have also - # processed all entries in _history_substring_search_raw_matches. - # - # In _history-substring-search-down-search() the initial value of - # $_history_substring_search_match_index is 1. This value is set in - # _history-substring-search-begin(). _history-substring-search-down-search() - # will initially decrement it to 0. - # - - if [[ $_history_substring_search_match_index -lt 1 ]]; then - # - # We are beyond the beginning of $_history_substring_search_matches. - # - # 1. Update display to indicate search not found. - # - _history-substring-search-not-found - return - fi - - if _history-substring-search-has-prev; then - # - # We do have younger matches. - # - # 1. Move index to point to the previous match. - # 2. Update display to indicate search found. - # - _history_substring_search_match_index+=-1 - _history-substring-search-found - - else - # - # We do not have younger matches. - # - # 1. Move the index beyond the beginning of - # _history_substring_search_matches. - # 2. Update display to indicate search not found. - # - _history_substring_search_match_index+=-1 - _history-substring-search-not-found - fi - - # - # When HIST_FIND_NO_DUPS is set, meaning that only unique command lines from - # history should be matched, make sure the new and old results are different. - # - # However, if the HIST_IGNORE_ALL_DUPS shell option, or - # HISTORY_SUBSTRING_SEARCH_ENSURE_UNIQUE is set, then we already have a - # unique history, so in this case we do not need to do anything. - # - if [[ -o HIST_IGNORE_ALL_DUPS || -n $HISTORY_SUBSTRING_SEARCH_ENSURE_UNIQUE ]]; then - return - fi - - if [[ -o HIST_FIND_NO_DUPS && $BUFFER == $_history_substring_search_result ]]; then - # - # Repeat the current search so that a different (unique) match is found. - # - _history-substring-search-down-search - fi -} - -# -*- mode: zsh; sh-indentation: 2; indent-tabs-mode: nil; sh-basic-offset: 2; -*- -# vim: ft=zsh sw=2 ts=2 et |