From 7b1f95cbe4ed79d086163fb1c10aa442371d79eb Mon Sep 17 00:00:00 2001 From: Wuffers Lightwolf Date: Sat, 10 Dec 2011 18:10:54 -0600 Subject: [PATCH 1/8] Two-lines now --- themes/wuffers.zsh-theme | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/themes/wuffers.zsh-theme b/themes/wuffers.zsh-theme index 182d8a34f..02a94c7d7 100644 --- a/themes/wuffers.zsh-theme +++ b/themes/wuffers.zsh-theme @@ -2,4 +2,5 @@ ZSH_THEME_GIT_PROMPT_PREFIX="%{$fg_bold[blue]%}[" ZSH_THEME_GIT_PROMPT_SUFFIX="]%{$reset_color%} " ZSH_THEME_GIT_PROMPT_DIRTY="%{$fg_bold[red]%} x%{$fg_bold[blue]%}" -PROMPT='%{$(git_prompt_info)%}%{$fg_bold[green]%}{%{$(rvm current)%}}%{$reset_color%} %{$fg[cyan]%}%c%{$reset_color%} ' +PROMPT='%{$(git_prompt_info)%}%{$fg_bold[green]%}{%{$(rvm current)%}}%{$reset_color%} %{$fg[cyan]%}%c%{$reset_color%} +$ ' From c41efbd438c990d94702d66c9356c46a4e4d55f9 Mon Sep 17 00:00:00 2001 From: Wuffers Lightwolf Date: Tue, 20 Dec 2011 12:08:40 -0600 Subject: [PATCH 2/8] Add f plugin --- plugins/f/f.plugin.zsh | 3 + plugins/f/f.sh | 306 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 309 insertions(+) create mode 100644 plugins/f/f.plugin.zsh create mode 100644 plugins/f/f.sh diff --git a/plugins/f/f.plugin.zsh b/plugins/f/f.plugin.zsh new file mode 100644 index 000000000..18a8d34e9 --- /dev/null +++ b/plugins/f/f.plugin.zsh @@ -0,0 +1,3 @@ +# See https://github.com/clvv/f for more info + +source f.sh diff --git a/plugins/f/f.sh b/plugins/f/f.sh new file mode 100644 index 000000000..60e60d4be --- /dev/null +++ b/plugins/f/f.sh @@ -0,0 +1,306 @@ +# This tool gives you quick access to your frequent/recent files +# +# INSTALL: +# Source this file somewhere in your shell rc (.bashrc or .zshrc). +# +# SYNOPSIS: +# _f [options] [query ...] +# options: +# -s show list of files with their ranks +# -l list paths only +# -e set command to execute on the result file +# -a match files and directories +# -d match directories only +# -f match files only +# -r match by rank only +# -h show a brief help message +# +# EXAMPLES: +# f foo # list recent files mathcing foo +# f foo bar # list recent files mathcing foo and bar +# f -e vim foo # run vim on the most frecent file matching foo +# +# TIPS: +# alias z="f -d -e cd" +# alias v="f -e vim" +# alias m="f -e mplayer" +# alias o="f -e xdg-open" + +_f() { + + if [ "$1" = "--add" ]; then # add entries + shift + + # bail out if we don't own ~/.f (we're another user but our ENV is still set) + [ -f "$_F_DATA" -a ! -O "$_F_DATA" ] && return + + # blacklists + local each + for each in "${_F_BLACKLIST[@]}"; do + [[ "$*" =~ "$each" ]] && return + done + + # shifts + for each in "${_F_SHIFT[@]}"; do + while [ "$1" = "$each" ]; do shift; done + done + + # ignores + [[ "${_F_IGNORE[@]}" =~ "$1" ]] && return + shift + + local FILES + while [ "$1" ]; do + # add the adsolute path of the file to FILES, and a delimiter "|" + FILES+="$($_F_READLINK -e -- "$1" 2>> "$_F_SINK")|" + shift + done + + # add current pwd if the option set + [ "$_F_TRACK_PWD" = "1" -a "$(pwd -P)" != "$HOME" ] && FILES+="$(pwd -P)" + + [ -z "${FILES//|/}" ] && return # stop if we have nothing to add + + # maintain the file + local tempfile + tempfile="$(mktemp $_F_DATA.XXXXXX)" || return + $_F_AWK -v list="$FILES" -v now="$(date +%s)" -v max="$_F_MAX" -F"|" ' + BEGIN { + split(list, files, "|") + for(i in files) { + path = files[i] + if ( path == "" ) continue + paths[path] = path # array for checking + rank[path] = 1 + time[path] = now + } + } + $2 >= 1 { + if( $1 in paths ) { + rank[$1] = $2 + 1 + time[$1] = now + } else { + rank[$1] = $2 + time[$1] = $3 + } + count += $2 + } + END { + if( count > max ) + for( i in rank ) print i "|" 0.9*rank[i] "|" time[i] # aging + else + for( i in rank ) print i "|" rank[i] "|" time[i] + }' "$_F_DATA" 2>> "$_F_SINK" >| "$tempfile" + if [ $? -ne 0 -a -f "$_F_DATA" ]; then + env rm -f "$tempfile" + else + env mv -f "$tempfile" "$_F_DATA" + fi + + elif [ "$1" = "--query" ]; then + # query the database, this need some local variables to be set + while read line; do + [ -${typ} "${line%%|*}" ] && echo "$line" + done < "$_F_DATA" | \ + $_F_AWK -v t="$(date +%s)" -v mode="$mode" -v q="$fnd" -F"|" ' + function frecent(rank, time) { + dx = t-time + if( dx < 3600 ) return rank*4 + if( dx < 86400 ) return rank*2 + if( dx < 604800 ) return rank/2 + return rank/4 + } + function likelihood(pattern, path) { + m = gsub( "/+", "/", path ) + r = 1 + for( i in pattern ) { + tmp = path + gsub( ".*" pattern[i], "", tmp) + n = gsub( "/+", "/", tmp ) + if( n == m ) + return 0 + else if( n == 0 ) + r *= 20 # F + else + r *= 1 - ( n / m ) + } + return r + } + function getRank() { + if( mode == "rank" ) + f = $2 + else + f = frecent($2, $3) + wcase[$1] = f * likelihood( pattern, $1 ) + nocase[$1] = f * likelihood( pattern2, tolower($1) ) + } + BEGIN { + split(q, pattern, " ") + for( i in pattern ) pattern2[i] = tolower(pattern[i]) # nocase + } + { + getRank() + cx = cx || wcase[$1] + ncx = ncx || nocase[$1] + } + END { + if( cx ) { + for( i in wcase ) + if( wcase[i] ) printf "%-10s %s\n", wcase[i], i + } else if( ncx ) { + for( i in nocase ) + if( nocase[i] ) printf "%-10s %s\n", nocase[i], i + } + }' - 2>> "$_F_SINK" + + else + # parsing logic and processing + [ -f "$_F_DATA" ] || return # no db yet + local fnd last + while [ "$1" ]; do case "$1" in + --complete) [ "$2" = "--" ] && shift; set -- $(echo $2); local list=1;; + --) while [ "$2" ]; do shift; fnd+="$1 "; last="$1"; done;; + -*) local opt=${1:1}; while [ "$opt" ]; do case ${opt:0:1} in + s) local show=1;; + l) local list=1;; + r) local mode=rank;; + t) local mode=recent;; + e) if [ "${opt:1}" ]; then # there are characters after "-e" + local exec=${opt:1} # anything after "-e" + else # use the next argument + local exec=${2:?"Argument needed after -e"} + shift + fi; break;; + a) local typ=e;; + d) local typ=d;; + f) local typ=f;; + h) echo "_f [options] [query ...] + options: + -s show list of files with their ranks + -l list paths only + -e set command to execute on the result file + -a match files and directories + -d match directories only + -f match files only + -r match by rank only + -h show a brief help message" >&2; return;; + #*) fnd+="$1 "; last="$1"; break;; # unknown option detected + esac; opt="${opt:1}"; done;; + *) fnd+="$1 "; last="$1";; + esac; shift; done + + [ "$typ" ] || local typ=e # default to match file and directory + + # if we hit enter on a completion just execute + case "$last" in + # completions will always start with / + /*) [ -z "$show$list" -a -${typ} "$last" -a "$exec" ] \ + && $exec "$last" && return;; + esac + + local result + result="$(_f --query 2>> "$_F_SINK")" # query the database + [ $? -gt 0 ] && return + if [ "$list" ]; then + echo "$result" | sort -n | sed 's/^[0-9.]*[ ]*//' + elif [ "$show" ]; then + echo "$result" | sort -n + elif [ "$fnd" -a "$exec" ]; then # exec + $exec "$(echo "$result" | sort -n | sed 's/^[0-9.]*[ ]*//' | tail -n1)" + elif [ "$fnd" ] && [ "$ZSH_SUBSHELL$BASH_SUBSHELL" != "0" ]; then # echo + echo "$(echo "$result" | sort -n | sed 's/^[0-9.]*[ ]*//' | tail -n1)" + else # no args, show + echo "$result" | sort -n + fi + + fi +} + +# set default options +alias ${_F_CMD_A:=a}='_f -a' +alias ${_F_CMD_S:=s}='_f -s' +alias ${_F_CMD_D:=d}='_f -d' +alias ${_F_CMD_F:=f}='_f -f' + +[ -z "$_F_DATA" ] && _F_DATA="$HOME/.f" +[ -z "$_F_BLACKLIST" ] && _F_BLACKLIST=(--help) +[ -z "$_F_SHIFT" ] && _F_SHIFT=(sudo busybox) +[ -z "$_F_IGNORE" ] && _F_IGNORE=(_f cd ls echo) +[ -z "$_F_SINK" ] && _F_SINK=/dev/null +[ -z "$_F_TRACK_PWD" ] && _F_TRACK_PWD=1 +[ -z "$_F_MAX" ] && _F_MAX=2000 + +if [ -z "$_F_AWK" ]; then + # awk preferences + for awk in gawk original-awk nawk mawk awk; do + $awk "" >> "$_F_SINK" 2>&1 && _F_AWK=$awk && break + done +fi + +if readlink -e / >> "$_F_SINK" 2>&1; then + _F_READLINK=readlink +elif greadlink -e / >> "$_F_SINK" 2>&1; then + _F_READLINK=greadlink +else # fall back on emulated readlink + _f_readlink() { + # function that mimics readlink from GNU coreutils + [ "$1" = "-e" ] && shift && local e=1 # existence option + [ "$1" = "--" ] && shift + [ "$1" = "/" ] && echo / && return + [ "$1" = "." ] && echo "$(pwd -P)" && return + local path + if [ "${1##*/}" = ".." ]; then + path="$(cd "$1" >> "$_F_SINK" 2>&1 && pwd -P)" + [ -z "$path" ] && return 1 # if cd fails + elif [[ "${1#/}" =~ "/" ]]; then + # if target contains "/" (not counting top level) or target is ".." + local base="$(cd "${1%/*}" >> "$_F_SINK" 2>&1 && pwd -P)" + [ -z "$base" ] && return 1 # if cd fails + path="${base%/}/${1##*/}" + elif [ -z "${1##/*}" ]; then # straight top level + path="$1" + else # anything within where we are + path="$(pwd -P)"'/'"$1" + fi + [ "$path" = "/" ] && echo / && return + path=${path%/} # strip off trailing "/" + [ "$e" = "1" -a ! -e "$path" ] && return + echo "$path" + } + _F_READLINK=_f_readlink +fi + +if compctl >> "$_F_SINK" 2>&1; then # zsh + _f_zsh_tab_completion() { + local compl + read -c compl + reply=(${(f)"$(_f --complete "$compl")"}) + } + compctl -U -K _f_zsh_tab_completion -x 'C[-1,-*e],s[-]n[1,e]' -c -- _f + # add zsh hook + autoload -U add-zsh-hook + function _f_preexec () { eval "_f --add $3" >> "$_F_SINK" 2>&1; } + add-zsh-hook preexec _f_preexec +elif complete >> "$_F_SINK" 2>&1; then # bash + _f_bash_completion() { + # complete command after "-e" + local cur=${COMP_WORDS[COMP_CWORD]} + [[ ${COMP_WORDS[COMP_CWORD-1]} == -*e ]] && \ + COMPREPLY=( $(compgen -A command $cur) ) && return + # get completion results using expanded aliases + local RESULT=$( _f --complete "$(alias -p ${COMP_WORDS} | \ + sed -n "\$s/^.*'\(.*\)'/\1/p") ${COMP_LINE#* }" ) + local IFS=$'\n' + COMPREPLY=( $RESULT ) + } + _f_bash_hook_completion() { + for cmd in $*; do + complete -F _f_bash_completion $cmd + done + } + _f_bash_hook_completion $_F_CMD_A $_F_CMD_S $_F_CMD_D $_F_CMD_F + # add bash hook + echo $PROMPT_COMMAND | grep -v -q "_f --add" && \ + PROMPT_COMMAND='eval "_f --add $(history 1 | \ + sed -e "s/^[ ]*[0-9]*[ ]*//")" >> "$_F_SINK" 2>&1;'"$PROMPT_COMMAND" +fi From 0af17c00c4cc244632b03e5430639030b00c4800 Mon Sep 17 00:00:00 2001 From: Wuffers Lightwolf Date: Tue, 20 Dec 2011 12:11:57 -0600 Subject: [PATCH 3/8] Fix no such file or directory error on loading plugin --- plugins/f/f.plugin.zsh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/f/f.plugin.zsh b/plugins/f/f.plugin.zsh index 18a8d34e9..98efdfd08 100644 --- a/plugins/f/f.plugin.zsh +++ b/plugins/f/f.plugin.zsh @@ -1,3 +1,3 @@ # See https://github.com/clvv/f for more info -source f.sh +source ./f.sh From d72dc2dabb547629cd1cafc1f470c361f83cb8c5 Mon Sep 17 00:00:00 2001 From: Wuffers Lightwolf Date: Tue, 20 Dec 2011 12:13:18 -0600 Subject: [PATCH 4/8] Really fix that issue this time... --- plugins/f/f.plugin.zsh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/f/f.plugin.zsh b/plugins/f/f.plugin.zsh index 98efdfd08..19a74afd3 100644 --- a/plugins/f/f.plugin.zsh +++ b/plugins/f/f.plugin.zsh @@ -1,3 +1,3 @@ # See https://github.com/clvv/f for more info -source ./f.sh +source $ZSH_HOME/plugins/f/f.sh From 862c7e1c8eab85cd3621cad21ace1ab817c2ac42 Mon Sep 17 00:00:00 2001 From: Wuffers Lightwolf Date: Tue, 20 Dec 2011 12:13:47 -0600 Subject: [PATCH 5/8] Fix incorrect variable name --- plugins/f/f.plugin.zsh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/f/f.plugin.zsh b/plugins/f/f.plugin.zsh index 19a74afd3..0a148fb0d 100644 --- a/plugins/f/f.plugin.zsh +++ b/plugins/f/f.plugin.zsh @@ -1,3 +1,3 @@ # See https://github.com/clvv/f for more info -source $ZSH_HOME/plugins/f/f.sh +source $ZSH/plugins/f/f.sh From 9d11c2672980239c36e131dfde768812ca712a98 Mon Sep 17 00:00:00 2001 From: Wuffers Lightwolf Date: Tue, 20 Dec 2011 17:46:10 -0600 Subject: [PATCH 6/8] Update to latest version of f --- plugins/f/f.sh | 60 +++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 54 insertions(+), 6 deletions(-) diff --git a/plugins/f/f.sh b/plugins/f/f.sh index 60e60d4be..4ee588340 100644 --- a/plugins/f/f.sh +++ b/plugins/f/f.sh @@ -229,6 +229,7 @@ alias ${_F_CMD_F:=f}='_f -f' [ -z "$_F_SINK" ] && _F_SINK=/dev/null [ -z "$_F_TRACK_PWD" ] && _F_TRACK_PWD=1 [ -z "$_F_MAX" ] && _F_MAX=2000 +[ -z "$_F_QUERY_SEPARATOR" ] && _F_QUERY_SEPARATOR=, if [ -z "$_F_AWK" ]; then # awk preferences @@ -271,18 +272,38 @@ else # fall back on emulated readlink fi if compctl >> "$_F_SINK" 2>&1; then # zsh - _f_zsh_tab_completion() { + _f_zsh_cmd_complete() { local compl read -c compl + compstate[insert]=menu # no expand reply=(${(f)"$(_f --complete "$compl")"}) } - compctl -U -K _f_zsh_tab_completion -x 'C[-1,-*e],s[-]n[1,e]' -c -- _f + compctl -U -K _f_zsh_cmd_complete -x 'C[-1,-*e],s[-]n[1,e]' -c -- _f + _f_zsh_word_complete() { + local fnd="$(echo "${words[CURRENT]}" | sed 's/'"$_F_QUERY_SEPARATOR"'/ /g')" + local typ=${1:-e} + _f --query 2>> "$_F_SINK" | sed 's/^[0-9.]*[ ]*//' | while read line; do + compadd -U "$line" + done + compstate[insert]=menu # no expand + } + _f_zsh_word_complete_trigger() { + [[ ${words[CURRENT]} == "$_F_QUERY_SEPARATOR"* ]] && _f_zsh_word_complete + } + _f_zsh_word_complete_f() { _f_zsh_word_complete f ; } + _f_zsh_word_complete_d() { _f_zsh_word_complete d ; } + { zstyle ':completion:*' completer _complete _ignored \ + _f_zsh_word_complete_trigger + zle -C f-complete menu-select _f_zsh_word_complete + zle -C f-complete-f menu-select _f_zsh_word_complete_f + zle -C f-complete-d menu-select _f_zsh_word_complete_d + } >> "$_F_SINK" 2>&1 # add zsh hook autoload -U add-zsh-hook function _f_preexec () { eval "_f --add $3" >> "$_F_SINK" 2>&1; } add-zsh-hook preexec _f_preexec elif complete >> "$_F_SINK" 2>&1; then # bash - _f_bash_completion() { + _f_bash_cmd_complete() { # complete command after "-e" local cur=${COMP_WORDS[COMP_CWORD]} [[ ${COMP_WORDS[COMP_CWORD-1]} == -*e ]] && \ @@ -293,12 +314,39 @@ elif complete >> "$_F_SINK" 2>&1; then # bash local IFS=$'\n' COMPREPLY=( $RESULT ) } - _f_bash_hook_completion() { + _f_bash_hook_cmd_complete() { for cmd in $*; do - complete -F _f_bash_completion $cmd + complete -F _f_bash_cmd_complete $cmd done } - _f_bash_hook_completion $_F_CMD_A $_F_CMD_S $_F_CMD_D $_F_CMD_F + _f_bash_hook_cmd_complete $_F_CMD_A $_F_CMD_S $_F_CMD_D $_F_CMD_F + _f_bash_word_complete() { + local cur=${COMP_WORDS[COMP_CWORD]} + if [[ $cur == "$_F_QUERY_SEPARATOR"* ]]; then + local fnd="$(echo "$cur" | sed 's/'"$_F_QUERY_SEPARATOR"'/ /g')" + local typ=e + local RESULT=$(_f --query 2>> "$_F_SINK" | sed 's/^[0-9.]*[ ]*//') + local IFS=$'\n' + COMPREPLY=( $RESULT ) + fi + } + _f_bash_word_complete_wrap() { + _f_bash_word_complete + # try original comp func + [ "$COMPREPLY" ] || eval "$( echo "$_F_BASH_COMPLETE_P" | \ + grep -e "${COMP_WORDS[0]}$" | sed -n 's/.*-F \(.*\) .*/\1/p' )" + # fall back on original complete options + [ "$COMPREPLY" ] || COMPREPLY=( $(eval "$(echo "$_F_BASH_COMPLETE_P" | \ + grep -e "${COMP_WORDS[0]}$" | sed 's/complete/compgen/') \ + ${COMP_WORDS[COMP_CWORD]}" 2>> "$_F_SINK") ) + } + _f_bash_hook_word_complete_wrap_all() { + export _F_BASH_COMPLETE_P="$(complete -p)" + for cmd in $(complete -p | awk '{print $NF}' | tr '\n' ' '); do + complete -F _f_bash_word_complete_wrap $cmd + done + } + complete -D -F _f_bash_word_complete >> "$_F_SINK" 2>&1 # add bash hook echo $PROMPT_COMMAND | grep -v -q "_f --add" && \ PROMPT_COMMAND='eval "_f --add $(history 1 | \ From a04b63b56358f7dc7007adcf477dfe6074dbab91 Mon Sep 17 00:00:00 2001 From: Wuffers Lightwolf Date: Wed, 21 Dec 2011 17:12:39 -0600 Subject: [PATCH 7/8] Update f plugin --- plugins/f/f.sh | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/plugins/f/f.sh b/plugins/f/f.sh index 4ee588340..d2d3a51f0 100644 --- a/plugins/f/f.sh +++ b/plugins/f/f.sh @@ -160,21 +160,22 @@ _f() { while [ "$1" ]; do case "$1" in --complete) [ "$2" = "--" ] && shift; set -- $(echo $2); local list=1;; --) while [ "$2" ]; do shift; fnd+="$1 "; last="$1"; done;; - -*) local opt=${1:1}; while [ "$opt" ]; do case ${opt:0:1} in - s) local show=1;; - l) local list=1;; - r) local mode=rank;; - t) local mode=recent;; - e) if [ "${opt:1}" ]; then # there are characters after "-e" - local exec=${opt:1} # anything after "-e" - else # use the next argument - local exec=${2:?"Argument needed after -e"} - shift - fi; break;; - a) local typ=e;; - d) local typ=d;; - f) local typ=f;; - h) echo "_f [options] [query ...] + -*) [ "$ZSH_VERSION" ] && local x='o=${o[2,#o]}' || local x='o=${o:1}' + local o=${1#-}; while [ "$o" ]; do case $o in + s*) local show=1;; + l*) local list=1;; + r*) local mode=rank;; + t*) local mode=recent;; + e*) eval $x; if [ "$o" ]; then # there are characters after "-e" + local exec=$o # anything after "-e" + else # use the next argument + local exec=${2:?"Argument needed after -e"} + shift + fi; break;; + a*) local typ=e;; + d*) local typ=d;; + f*) local typ=f;; + h*) echo "_f [options] [query ...] options: -s show list of files with their ranks -l list paths only @@ -185,7 +186,7 @@ _f() { -r match by rank only -h show a brief help message" >&2; return;; #*) fnd+="$1 "; last="$1"; break;; # unknown option detected - esac; opt="${opt:1}"; done;; + esac; eval $x; done;; *) fnd+="$1 "; last="$1";; esac; shift; done From 19f7520c6a9f8a77d91fca312a4cec2ca110c36e Mon Sep 17 00:00:00 2001 From: Wuffers Lightwolf Date: Wed, 21 Dec 2011 18:23:33 -0600 Subject: [PATCH 8/8] Update f.sh --- plugins/f/f.sh | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/plugins/f/f.sh b/plugins/f/f.sh index d2d3a51f0..ead1b7b1e 100644 --- a/plugins/f/f.sh +++ b/plugins/f/f.sh @@ -100,7 +100,7 @@ _f() { elif [ "$1" = "--query" ]; then # query the database, this need some local variables to be set while read line; do - [ -${typ} "${line%%|*}" ] && echo "$line" + [ -${typ:-e} "${line%%|*}" ] && echo "$line" done < "$_F_DATA" | \ $_F_AWK -v t="$(date +%s)" -v mode="$mode" -v q="$fnd" -F"|" ' function frecent(rank, time) { @@ -158,7 +158,7 @@ _f() { [ -f "$_F_DATA" ] || return # no db yet local fnd last while [ "$1" ]; do case "$1" in - --complete) [ "$2" = "--" ] && shift; set -- $(echo $2); local list=1;; + --complete) [ "$2" = "--" ] && shift; set -- $(echo $2); local list=1 r=r;; --) while [ "$2" ]; do shift; fnd+="$1 "; last="$1"; done;; -*) [ "$ZSH_VERSION" ] && local x='o=${o[2,#o]}' || local x='o=${o:1}' local o=${1#-}; while [ "$o" ]; do case $o in @@ -190,12 +190,10 @@ _f() { *) fnd+="$1 "; last="$1";; esac; shift; done - [ "$typ" ] || local typ=e # default to match file and directory - # if we hit enter on a completion just execute case "$last" in # completions will always start with / - /*) [ -z "$show$list" -a -${typ} "$last" -a "$exec" ] \ + /*) [ -z "$show$list" -a -${typ:-e} "$last" -a "$exec" ] \ && $exec "$last" && return;; esac @@ -203,15 +201,15 @@ _f() { result="$(_f --query 2>> "$_F_SINK")" # query the database [ $? -gt 0 ] && return if [ "$list" ]; then - echo "$result" | sort -n | sed 's/^[0-9.]*[ ]*//' + echo "$result" | sort -n${r} | sed 's/^[0-9.]*[ ]*//' elif [ "$show" ]; then - echo "$result" | sort -n + echo "$result" | sort -n${r} elif [ "$fnd" -a "$exec" ]; then # exec - $exec "$(echo "$result" | sort -n | sed 's/^[0-9.]*[ ]*//' | tail -n1)" + $exec "$(echo "$result" | sort -n | sed -n '$s/^[0-9.]*[ ]*//p')" elif [ "$fnd" ] && [ "$ZSH_SUBSHELL$BASH_SUBSHELL" != "0" ]; then # echo - echo "$(echo "$result" | sort -n | sed 's/^[0-9.]*[ ]*//' | tail -n1)" + echo "$(echo "$result" | sort -n | sed -n '$s/^[0-9.]*[ ]*//p')" else # no args, show - echo "$result" | sort -n + echo "$result" | sort -n${r} fi fi @@ -279,12 +277,12 @@ if compctl >> "$_F_SINK" 2>&1; then # zsh compstate[insert]=menu # no expand reply=(${(f)"$(_f --complete "$compl")"}) } - compctl -U -K _f_zsh_cmd_complete -x 'C[-1,-*e],s[-]n[1,e]' -c -- _f + compctl -U -K _f_zsh_cmd_complete -V f -x 'C[-1,-*e],s[-]n[1,e]' -c -- _f _f_zsh_word_complete() { local fnd="$(echo "${words[CURRENT]}" | sed 's/'"$_F_QUERY_SEPARATOR"'/ /g')" local typ=${1:-e} - _f --query 2>> "$_F_SINK" | sed 's/^[0-9.]*[ ]*//' | while read line; do - compadd -U "$line" + _f --query 2>> "$_F_SINK" | sort -nr | sed 's/^[0-9.]*[ ]*//' | while read line; do + compadd -U -V f "$line" done compstate[insert]=menu # no expand }