summaryrefslogtreecommitdiff
path: root/dotfiles/system/.zsh/fzf-tab.zsh
diff options
context:
space:
mode:
Diffstat (limited to 'dotfiles/system/.zsh/fzf-tab.zsh')
-rw-r--r--dotfiles/system/.zsh/fzf-tab.zsh389
1 files changed, 389 insertions, 0 deletions
diff --git a/dotfiles/system/.zsh/fzf-tab.zsh b/dotfiles/system/.zsh/fzf-tab.zsh
new file mode 100644
index 0000000..ed2767d
--- /dev/null
+++ b/dotfiles/system/.zsh/fzf-tab.zsh
@@ -0,0 +1,389 @@
+# temporarily change options
+'builtin' 'local' '-a' '_ftb_opts'
+[[ ! -o 'aliases' ]] || _ftb_opts+=('aliases')
+[[ ! -o 'sh_glob' ]] || _ftb_opts+=('sh_glob')
+[[ ! -o 'no_brace_expand' ]] || _ftb_opts+=('no_brace_expand')
+'builtin' 'setopt' 'no_aliases' 'no_sh_glob' 'brace_expand'
+
+# thanks Valodim/zsh-capture-completion
+-ftb-compadd() {
+ # parse all options
+ local -A apre hpre dscrs _oad
+ local -a isfile _opts __ expl
+ zparseopts -E -a _opts P:=apre p:=hpre d:=dscrs X+:=expl O:=_oad A:=_oad D:=_oad f=isfile \
+ i: S: s: I: x: r: R: W: F: M+: E: q e Q n U C \
+ J:=__ V:=__ a=__ l=__ k=__ o=__ 1=__ 2=__
+
+ # just delegate and leave if any of -O, -A or -D are given or fzf-tab is not enabled
+ if (( $#_oad != 0 || ! IN_FZF_TAB )); then
+ builtin compadd "$@"
+ return
+ fi
+
+ # store matches in $__hits and descriptions in $__dscr
+ local -a __hits __dscr
+ if (( $#dscrs == 1 )); then
+ __dscr=( "${(@P)${(v)dscrs}}" )
+ fi
+ builtin compadd -A __hits -D __dscr "$@"
+ local ret=$?
+ if (( $#__hits == 0 )); then
+ return $ret
+ fi
+
+ # store $curcontext for furthur usage
+ _ftb_curcontext=${curcontext#:}
+
+ # only store the fist `-X`
+ expl=$expl[2]
+
+ # keep order of group description
+ [[ -n $expl ]] && _ftb_groups+=$expl
+
+ # store these values in _ftb_compcap
+ local -a keys=(apre hpre PREFIX SUFFIX IPREFIX ISUFFIX)
+ local key expanded __tmp_value=$'<\0>' # placeholder
+ for key in $keys; do
+ expanded=${(P)key}
+ if [[ -n $expanded ]]; then
+ __tmp_value+=$'\0'$key$'\0'$expanded
+ fi
+ done
+ if [[ -n $expl ]]; then
+ # store group index
+ __tmp_value+=$'\0group\0'$_ftb_groups[(ie)$expl]
+ fi
+ if [[ -n $isfile ]]; then
+ # NOTE: need a extra ${} here or ~ expansion won't work
+ __tmp_value+=$'\0realdir\0'${${(Qe)~${:-$IPREFIX$hpre}}}
+ fi
+ _opts+=("${(@kv)apre}" "${(@kv)hpre}" $isfile)
+ __tmp_value+=$'\0args\0'${(pj:\1:)_opts}
+
+ if (( $+builtins[fzf-tab-compcap-generate] )); then
+ fzf-tab-compcap-generate __hits __dscr __tmp_value
+ else
+ # dscr - the string to show to users
+ # word - the string to be inserted
+ local dscr word i
+ for i in {1..$#__hits}; do
+ word=$__hits[i] dscr=$__dscr[i]
+ if [[ -n $dscr ]]; then
+ dscr=${dscr//$'\n'}
+ elif [[ -n $word ]]; then
+ dscr=$word
+ fi
+ _ftb_compcap+=$dscr$'\2'$__tmp_value$'\0word\0'$word
+ done
+ fi
+
+ # tell zsh that the match is successful
+ builtin compadd -U -qS '' -R -ftb-remove-space ''
+}
+
+# when insert multi results, a whitespace will be added to each result
+# remove left space of our fake result because I can't remove right space
+# FIXME: what if the left char is not whitespace: `echo $widgets[\t`
+-ftb-remove-space() {
+ [[ $LBUFFER[-1] == ' ' ]] && LBUFFER[-1]=''
+}
+
+-ftb-zstyle() {
+ zstyle $1 ":fzf-tab:$_ftb_curcontext" ${@:2}
+}
+
+-ftb-complete() {
+ local -a _ftb_compcap
+ local -Ua _ftb_groups
+ local choice choices _ftb_curcontext continuous_trigger print_query accept_line bs=$'\2' nul=$'\0'
+ local ret=0
+
+ # must run with user options; don't move `emulate -L zsh` above this line
+ (( $+builtins[fzf-tab-compcap-generate] )) && fzf-tab-compcap-generate -i
+ COLUMNS=500 _ftb__main_complete "$@" || ret=$?
+ (( $+builtins[fzf-tab-compcap-generate] )) && fzf-tab-compcap-generate -o
+
+ emulate -L zsh -o extended_glob
+
+ local _ftb_query _ftb_complist=() _ftb_headers=() command opts
+ -ftb-generate-complist # sets `_ftb_complist`
+
+ case $#_ftb_complist in
+ 0) return 1;;
+ # NOTE: won't trigger continuous completion
+ 1) choices=("EXPECT_KEY" "${_ftb_compcap[1]%$bs*}");;
+ *)
+ -ftb-generate-query # sets `_ftb_query`
+ -ftb-generate-header # sets `_ftb_headers`
+ -ftb-zstyle -s continuous-trigger continuous_trigger || continuous_trigger=/
+ -ftb-zstyle -s print-query print_query || print_query=alt-enter
+ -ftb-zstyle -s accept-line accept_line
+
+ choices=("${(@f)"$(builtin print -rl -- $_ftb_headers $_ftb_complist | -ftb-fzf)"}")
+ ret=$?
+ # choices=(query_string expect_key returned_word)
+
+ # insert query string directly
+ if [[ $choices[2] == $print_query ]] || [[ -n $choices[1] && $#choices == 1 ]] ; then
+ local -A v=("${(@0)${_ftb_compcap[1]}}")
+ local -a args=("${(@ps:\1:)v[args]}")
+ [[ -z $args[1] ]] && args=() # don't pass an empty string
+ IPREFIX=$v[IPREFIX] PREFIX=$v[PREFIX] SUFFIX=$v[SUFFIX] ISUFFIX=$v[ISUFFIX]
+ # NOTE: should I use `-U` here?, ../f\tabcd -> ../abcd
+ builtin compadd "${args[@]:--Q}" -Q -- $choices[1]
+
+ compstate[list]=
+ compstate[insert]=
+ if (( $#choices[1] > 0 )); then
+ compstate[insert]='2'
+ [[ $RBUFFER == ' '* ]] || compstate[insert]+=' '
+ fi
+ return $ret
+ fi
+ choices[1]=()
+
+ choices=("${(@)${(@)choices%$nul*}#*$nul}")
+
+ unset CTXT
+ ;;
+ esac
+
+ if [[ -n $choices[1] && $choices[1] == $continuous_trigger ]]; then
+ typeset -gi _ftb_continue=1
+ fi
+
+ if [[ -n $choices[1] && $choices[1] == $accept_line ]]; then
+ typeset -gi _ftb_accept=1
+ fi
+ choices[1]=()
+
+ for choice in "$choices[@]"; do
+ local -A v=("${(@0)${_ftb_compcap[(r)${(b)choice}$bs*]#*$bs}}")
+ local -a args=("${(@ps:\1:)v[args]}")
+ [[ -z $args[1] ]] && args=() # don't pass an empty string
+ IPREFIX=$v[IPREFIX] PREFIX=$v[PREFIX] SUFFIX=$v[SUFFIX] ISUFFIX=$v[ISUFFIX]
+ builtin compadd "${args[@]:--Q}" -Q -- "$v[word]"
+ done
+
+ compstate[list]=
+ compstate[insert]=
+ if (( $#choices == 1 )); then
+ compstate[insert]='2'
+ [[ $RBUFFER == ' '* ]] || compstate[insert]+=' '
+ elif (( $#choices > 1 )); then
+ compstate[insert]='all'
+ fi
+ return $ret
+}
+
+fzf-tab-debug() {
+ (( $+_ftb_debug_cnt )) || typeset -gi _ftb_debug_cnt
+ local tmp=${TMPPREFIX:-/tmp/zsh}-$$-fzf-tab-$(( ++_ftb_debug_cnt )).log
+ local -i debug_fd=-1 IN_FZF_TAB=1
+ {
+ exec {debug_fd}>&2 2>| $tmp
+ local -a debug_indent; debug_indent=( '%'{3..20}'(e. .)' )
+ local PROMPT4 PS4="${(j::)debug_indent}+%N:%i> "
+ setopt xtrace
+ : $ZSH_NAME $ZSH_VERSION
+ zle .fzf-tab-orig-$_ftb_orig_widget
+ unsetopt xtrace
+ if (( debug_fd != -1 )); then
+ zle -M "fzf-tab-debug: Trace output left in $tmp"
+ fi
+ } always {
+ (( debug_fd != -1 )) && exec 2>&$debug_fd {debug_fd}>&-
+ }
+}
+
+fzf-tab-complete() {
+ # this name must be ugly to avoid clashes
+ local -i _ftb_continue=1 _ftb_accept=0 ret=0
+ # hide the cursor until finishing completion, so that users won't see cursor up and down
+ # NOTE: MacOS Terminal doesn't support civis & cnorm
+ echoti civis >/dev/tty 2>/dev/null
+ while (( _ftb_continue )); do
+ _ftb_continue=0
+ local IN_FZF_TAB=1
+ {
+ zle .fzf-tab-orig-$_ftb_orig_widget
+ ret=$?
+ } always {
+ IN_FZF_TAB=0
+ }
+ if (( _ftb_continue )); then
+ zle .split-undo
+ zle .reset-prompt
+ zle -R
+ zle fzf-tab-dummy
+ fi
+ done
+ echoti cnorm >/dev/tty 2>/dev/null
+ zle .redisplay
+ (( _ftb_accept )) && zle .accept-line
+ return $ret
+}
+
+# this function does nothing, it is used to be wrapped by other plugins like f-sy-h.
+# this make it possible to call the wrapper function without causing any other side effects.
+fzf-tab-dummy() { }
+
+zle -N fzf-tab-debug
+zle -N fzf-tab-complete
+zle -N fzf-tab-dummy
+
+disable-fzf-tab() {
+ emulate -L zsh -o extended_glob
+ (( $+_ftb_orig_widget )) || return 0
+
+ bindkey '^I' $_ftb_orig_widget
+ case $_ftb_orig_list_grouped in
+ 0) zstyle ':completion:*' list-grouped false ;;
+ 1) zstyle ':completion:*' list-grouped true ;;
+ 2) zstyle -d ':completion:*' list-grouped ;;
+ esac
+ unset _ftb_orig_widget _ftb_orig_list_groupded
+
+ # unhook compadd so that _approximate can work properply
+ unfunction compadd 2>/dev/null
+
+ functions[_main_complete]=$functions[_ftb__main_complete]
+ functions[_approximate]=$functions[_ftb__approximate]
+
+ # Don't remove .fzf-tab-orig-$_ftb_orig_widget as we won't be able to reliably
+ # create it if enable-fzf-tab is called again.
+}
+
+enable-fzf-tab() {
+ emulate -L zsh -o extended_glob
+ (( ! $+_ftb_orig_widget )) || disable-fzf-tab
+
+ typeset -g _ftb_orig_widget="${${$(builtin bindkey '^I')##* }:-expand-or-complete}"
+ if (( ! $+widgets[.fzf-tab-orig-$_ftb_orig_widget] )); then
+ # Widgets that get replaced by compinit.
+ local compinit_widgets=(
+ complete-word
+ delete-char-or-list
+ expand-or-complete
+ expand-or-complete-prefix
+ list-choices
+ menu-complete
+ menu-expand-or-complete
+ reverse-menu-complete
+ )
+ # Note: We prefix the name of the widget with '.' so that it doesn't get wrapped.
+ if [[ $widgets[$_ftb_orig_widget] == builtin &&
+ $compinit_widgets[(Ie)$_ftb_orig_widget] != 0 ]]; then
+ # We are initializing before compinit and being asked to fall back to a completion
+ # widget that isn't defined yet. Create our own copy of the widget ahead of time.
+ zle -C .fzf-tab-orig-$_ftb_orig_widget .$_ftb_orig_widget _main_complete
+ else
+ # Copy the widget before it's wrapped by zsh-autosuggestions and zsh-syntax-highlighting.
+ zle -A $_ftb_orig_widget .fzf-tab-orig-$_ftb_orig_widget
+ fi
+ fi
+
+ zstyle -t ':completion:*' list-grouped false
+ typeset -g _ftb_orig_list_grouped=$?
+
+ zstyle ':completion:*' list-grouped false
+ bindkey '^I' fzf-tab-complete
+ bindkey '^X.' fzf-tab-debug
+
+ # make sure we can copy them
+ autoload +X -Uz _main_complete _approximate
+
+ # hook compadd
+ functions[compadd]=$functions[-ftb-compadd]
+
+ # hook _main_complete to trigger fzf-tab
+ functions[_ftb__main_complete]=$functions[_main_complete]
+ function _main_complete() { -ftb-complete "$@" }
+
+ # TODO: This is not a full support, see #47
+ # _approximate will also hook compadd
+ # let it call -ftb-compadd instead of builtin compadd so that fzf-tab can capture result
+ # make sure _approximate has been loaded.
+ functions[_ftb__approximate]=$functions[_approximate]
+ function _approximate() {
+ # if not called by fzf-tab, don't do anything with compadd
+ (( ! IN_FZF_TAB )) || unfunction compadd
+ _ftb__approximate
+ (( ! IN_FZF_TAB )) || functions[compadd]=$functions[-ftb-compadd]
+ }
+}
+
+toggle-fzf-tab() {
+ emulate -L zsh -o extended_glob
+ if (( $+_ftb_orig_widget )); then
+ disable-fzf-tab
+ else
+ enable-fzf-tab
+ fi
+}
+
+build-fzf-tab-module() {
+ local MACOS
+ if [[ ${OSTYPE} == darwin* ]]; then
+ MACOS=true
+ fi
+ pushd $FZF_TAB_HOME/modules
+ CPPFLAGS=-I/usr/local/include CFLAGS="-g -Wall -O2" LDFLAGS=-L/usr/local/lib ./configure --disable-gdbm --without-tcsetpgrp ${MACOS:+DL_EXT=bundle}
+ make -j
+ popd
+}
+
+zmodload zsh/zutil
+zmodload zsh/mapfile
+zmodload -F zsh/stat b:zstat
+
+0="${${ZERO:-${0:#$ZSH_ARGZERO}}:-${(%):-%N}}"
+0="${${(M)0:#/*}:-$PWD/$0}"
+FZF_TAB_HOME="${0:A:h}"
+
+source "$FZF_TAB_HOME"/lib/zsh-ls-colors/ls-colors.zsh fzf-tab-lscolors
+
+typeset -ga _ftb_group_colors=(
+ $'\x1b[94m' $'\x1b[32m' $'\x1b[33m' $'\x1b[35m' $'\x1b[31m' $'\x1b[38;5;27m' $'\x1b[36m'
+ $'\x1b[38;5;100m' $'\x1b[38;5;98m' $'\x1b[91m' $'\x1b[38;5;80m' $'\x1b[92m'
+ $'\x1b[38;5;214m' $'\x1b[38;5;165m' $'\x1b[38;5;124m' $'\x1b[38;5;120m'
+)
+
+# init
+() {
+ emulate -L zsh -o extended_glob
+
+ fpath+=($FZF_TAB_HOME/lib)
+
+ autoload -Uz -- $FZF_TAB_HOME/lib/-#ftb*(:t)
+
+ if (( $+FZF_TAB_COMMAND || $+FZF_TAB_OPTS || $+FZF_TAB_QUERY || $+FZF_TAB_SINGLE_GROUP || $+fzf_tab_preview_init )) \
+ || zstyle -m ":fzf-tab:*" command '*' \
+ || zstyle -m ":fzf-tab:*" extra-opts '*'; then
+ print -P "%F{red}%B[fzf-tab] Sorry, your configuration is not supported anymore\n" \
+ "See https://github.com/Aloxaf/fzf-tab/pull/132 for more information%f%b"
+ fi
+
+ if [[ -n $FZF_TAB_HOME/modules/Src/aloxaf/fzftab.(so|bundle)(#qN) ]]; then
+ module_path+=("$FZF_TAB_HOME/modules/Src")
+ zmodload aloxaf/fzftab
+
+ if [[ $FZF_TAB_MODULE_VERSION != "0.2.2" ]]; then
+ zmodload -u aloxaf/fzftab
+ local rebuild
+ print -Pn "%F{yellow}fzftab module needs to be rebuild, rebuild now?[Y/n]:%f"
+ read -q rebuild
+ if [[ $rebuild == y ]]; then
+ build-fzf-tab-module
+ zmodload aloxaf/fzftab
+ fi
+ fi
+ fi
+}
+
+enable-fzf-tab
+zle -N toggle-fzf-tab
+
+# restore options
+(( ${#_ftb_opts} )) && setopt ${_ftb_opts[@]}
+'builtin' 'unset' '_ftb_opts'