Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #! /bin/echo This file must be sourced: .
- function kb_highlight() {
- case $cmdname in
- #Video
- mplayer|mwrap|vlc|gmplayer|smplayer|mencoder|kmplayer|Parole|whaawmp|dragonplayer|ffmpeg)
- extlist='mkv|m4v|mp.|avi|wmv|rmvb|as?|divx|vob|ogm|rm|flv|part|iso|ogg|wav|flac|m4a'
- ;;
- #Audio
- mpg123|mpg123s|mpg321|mp3blaster|cmus|cplay|moc|xmms|xmms2|sonata|deadbeef|ogg123|mnama)
- extlist='mp?|aac|wav|ogg|gsm|dct|flac|au|aiff|vox|wma|aac|ra|m4a'
- ;;
- #PDF
- llpp|xpdf|epdfview|evince|foxit|mupdf|okular|apvlv|zathura)
- extlist='pdf'
- ;;
- #Images
- feh|geeqie|gqview|eog|gpicview|gthumb|mirage|qiv|ristretto|xnview|xv|viewnior)
- extlist='jpg|jpeg|png|gif|bmp|icon?|tiff?'
- ;;
- #Games
- sdlmame|openmsx|msxplay|zsnes|desmume|VirtualBoy)
- extlist='rom|dsk'
- ;;
- #Wine
- wine|winewrap|wineconsole)
- extlist='exe|com|bat'
- ;;
- #Archives
- atool|x|xi|gunzip|extract|unzip|unrar|zip|rar|7z|mcomix|v)
- extlist='tgz|zip|rar|bz2|gz|tar|exe|pk3|lha|Z|lzma'
- ;;
- #Text
- vim|nano|acme|beaver|geany|leafpad|medit|mousepad|pyroom|sam|vi|gvim|emacs|tea|scite)
- extlist='txt|rc|sh|c|bash|py|ini'
- ;;
- *) extlist='-Unmatch-';;
- esac
- }
- function kb_menu() {
- local end=0 h goodlist badlist total colorsw page pages sel=0 count key newk change=1 lim=7 displayres tempfile
- tput rmam #don't wrap long lines
- IFS=$'\n'
- prompt="$2"
- while ((end==0)); do
- # build a new list
- if ((change == 1)); then
- change=0
- sel=0
- if [[ "$1" == command ]]; then
- displayres=( $(compgen -A command -A alias -A builtin -A function $prompt | sort -u) )
- elif [[ "$1" == file ]]; then
- colorsw=0
- goodlist=()
- badlist=()
- displayres=()
- for tempfile in $prompt*; do
- if [[ -d "$tempfile" ]]; then
- tempfile+=/
- fi
- if [[ "$cmdname" =~ ^(c|cd|popd|rmdir)$ ]]; then
- if [[ -d "$tempfile" ]]; then
- goodlist+=( "$tempfile" )
- ((colorsw++))
- else
- badlist+=( "$tempfile" )
- fi
- elif [[ "$tempfile" =~ \.($extlist)$ ]]; then
- goodlist+=( "$tempfile" )
- ((colorsw++))
- else
- badlist+=( "$tempfile" )
- fi
- done
- fi
- [[ "$1" == file ]] && colorsw=${#goodlist[@]} && displayres=( "${goodlist[@]}" "${badlist[@]}" )
- total=${#displayres[@]}
- # on zero results retry without front match
- if [[ "$1" == file ]] && ((total==0)); then
- colorsw=0
- if [[ "${prompt//[^\/]}" ]]; then
- for tempfile in ${prompt%/*}/*${prompt##*/}*; do
- if [[ -d "$tempfile" ]]; then
- tempfile+=/
- fi
- if [[ "$cmdname" =~ ^(c|cd|popd|rmdir)$ ]]; then
- if [[ -d "$tempfile" ]]; then
- goodlist+=( "$tempfile" )
- ((colorsw++))
- else
- badlist+=( "$tempfile" )
- fi
- elif [[ "$tempfile" =~ \.($extlist)$ ]]; then
- goodlist+=( "$tempfile" )
- ((colorsw++))
- else
- badlist+=( "$tempfile" )
- fi
- done
- else
- for tempfile in *$prompt*; do
- if [[ -d "$tempfile" ]]; then
- tempfile+=/
- fi
- if [[ "$cmdname" =~ ^(c|cd|popd|rmdir)$ ]]; then
- if [[ -d "$tempfile" ]]; then
- goodlist+=( "$tempfile" )
- ((colorsw++))
- else
- badlist+=( "$tempfile" )
- fi
- elif [[ "$tempfile" =~ \.($extlist)$ ]]; then
- goodlist+=( "$tempfile" )
- ((colorsw++))
- else
- badlist+=( "$tempfile" )
- fi
- done
- fi
- colorsw=${#goodlist[@]}
- displayres=( "${goodlist[@]}" "${badlist[@]}" )
- total=${#displayres[@]}
- fi
- ((total==1)) && prompt=${displayres[0]} && break
- (( total < lim )) && h=$total || h=$lim
- pages=$(( total /lim))
- fi
- ((sel < 0)) && sel=0
- ((sel >= total)) && sel=$((total -1))
- page=$((sel /lim))
- echo "p$page/$pages: $before$prompt"$'\e[47m \e[0m '
- echo -ne '\e[A'
- for ((count = lim *(sel /lim); count < lim +lim *(sel /lim); count++)); do
- echo -ne '\e[0m'
- [[ $count == $total && $page == 0 ]] && break || echo
- (($sel == $count)) && echo -n "X " || echo -n " "
- ((count < colorsw)) && echo -ne '\e[31m'
- echo -n "${displayres[$count]}"
- done
- tput civis >&2 #turn cursor invisible
- read -n1 key
- [[ $key ]] || key=ENTER
- #[[ "$key" == ' ' ]] && key=Space
- if [[ "$key" == $'\e' ]]; then
- key=ESC
- while true; do
- read -n 1 -t 0.0001 -s newk
- [[ "$newk" == $'\e' ]] && newk=ESC
- key=${key}${newk}
- [[ -z "$newk" || "$newk" =~ [~A-Da-d] ]] && break
- done
- fi
- case "$key" in
- 'ESC[A') ((sel--));; #UP
- 'ESC[B') ((sel++));; #DOWN
- 'ESC[6~') ((sel+=7));; #PGDN
- 'ESC[5~') ((sel-=7));; #PGUP
- 'ESC[4~'|'ESC[F'|'ESC[8~'|'ESCOF') ((sel=$total));; #END
- 'ESC[1~'|'ESC[H'|'ESC[7~'|'ESCOH') ((sel=0));; #HOME
- 'ENTER') [[ "${displayres[$sel]}" ]] && prompt="${displayres[$sel]}"; end=1;; #ENTER
- 'ESC[2~') appendprompt=\ $prompt; prompt="${displayres[$sel]}"; end=1;; #INSERT
- 'ESC') nospace=1; end=1;; #ESC
- $'\x7f'|$'\x08') change=1; [[ $prompt ]] && prompt=${prompt::-1};; #BACKSPACE
- 'ESC'*) :;; #UNUSED KEY
- *) change=1; prompt+=$key;;
- esac
- for (( count=0; count < $h; count++)); do
- echo -ne "\e[2K\e[A\r"
- done
- tput cnorm >&2 #restore cursor visibility
- echo -ne '\e[2K\r'
- done
- }
- function kb_replace_var() {
- local var fill
- OIFS=$IFS
- IFS=$'\n'
- last="${last/\~/$HOME}"
- [[ "${last//[^$]}" ]] && \
- for var in $(echo "$last" | /usr/bin/grep -o '\$[a-zA-Z_][a-zA-Z0-9_]*' | tr -d '$'); do
- fill=${!var}
- last="${last/\$$var/$fill}"
- done
- IFS=$OIFS
- }
- function kb_write_prompt() {
- local out escquote lang
- IFS=$' \t\n'
- dir=${1: -1}
- [[ "$dir" == / ]] && dir= || dir=' '
- (( nospace == 1 )) && { dir= && nospace=; } || nospace=\'
- escquote=${1//\'/\'\\\'\'}
- out="$before$nospace$escquote$nospace$dir$appendprompt"
- lang=$LC_ALL
- LC_ALL=C
- ((READLINE_POINT+=${#out} - ${#READFIRST}))
- LC_ALL=$LC_ALL
- READLINE_LINE=$out$READLAST
- }
- function kb_main() {
- local cmdname extlist appendprompt recursive quotes last before psheight nospace=0 extglob nocaseglob nullglob globstar READFIRST READLAST
- READFIRST="${READLINE_LINE::$READLINE_POINT}"
- READLAST="${READLINE_LINE:$READLINE_POINT}"
- psheight=$( echo -e "$PS1" | wc -l)
- ((psheight--))
- IFS=$' \t\n'
- # is the line has no words, add a tab.
- if [[ "$READFIRST" =~ ^[[:blank:]]*$ ]]; then
- READLINE_LINE="$READFIRST"$'\t'"$READLAST"
- ((READLINE_POINT++))
- return
- fi
- # count non-escaped quotes
- quotes=${READFIRST//\\\'}
- quotes=${quotes//[^\']}
- quotes=${#quotes}
- # the last word is empty, start completing from scratch
- if [[ "${READFIRST: -1}" == ' ' && "${READFIRST: -2:1}" != '\' ]] && (( quotes % 2 == 0)); then
- before=$READFIRST
- last=
- # complete a command (TODO:add sudo and such)
- elif [[ $READFIRST =~ ^\ *[^\ ]+$ ]]; then
- kb_menu command "$READFIRST"
- prompt+=" "
- ((READLINE_POINT+=${#prompt} - ${#READFIRST}))
- READLINE_LINE=$prompt$READLAST
- IFS=$' \t\n'
- echo -ne "\e[${psheight}A\r\e[2K"
- return
- # complete part of a word
- else
- last="${READFIRST##* }"
- recursive="${READFIRST% *}"
- # last="${a[$((words -1))]}"
- fi
- nocaseglob=$(shopt nocaseglob | /usr/bin/grep -F on)
- [[ $nocaseglob ]] || shopt -s nocaseglob
- nullglob=$(shopt nullglob | /usr/bin/grep -F on)
- [[ $nullglob ]] || shopt -s nullglob
- extglob=$(shopt extglob | /usr/bin/grep -F on)
- [[ $extglob ]] || shopt -s extglob
- globstar=$(shopt globstar | /usr/bin/grep -F off)
- [[ $globstar ]] || shopt -u globstar
- cmdname=$(echo $READFIRST)
- cmdname=${cmdname%% *}
- kb_highlight "$cmdname"
- # add words that end in \ to the $last word
- while [[ -z "$before" ]] ; do
- if [[ "${recursive: -1}" == '\' ]]; then
- last="${recursive##* } $last"
- recursive=${recursive% *}
- else
- before=$recursive\
- fi
- done
- if (( quotes % 2 == 1 )) && ! [[ "$last" =~ \' ]]; then
- # $last will be part of a quote instead.
- # assume last quote is not escape.
- before="${READFIRST%\'*}"
- last="${READFIRST##*\'}"
- fi
- kb_replace_var
- last=${last//\'}
- kb_menu 'file' "$last"
- kb_write_prompt "$prompt"
- IFS=$' \t\n'
- echo -ne "\r\e[2K\e[${psheight}A\r\e[2K"
- [[ $nocaseglob ]] || shopt -u nocaseglob
- [[ $nullglob ]] || shopt -u nullglob
- [[ $extglob ]] || shopt -u extglob
- [[ $globstar ]] || shopt -s globstar
- tput smam >&2 #restore line wrap
- }
- bind -x '"\t":kb_main'
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement