Advertisement
Guest User

Kingbash

a guest
Jan 24th, 2013
45
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Bash 9.56 KB | None | 0 0
  1. #! /bin/bash
  2. # usage:
  3. # bind -x '"\t": out=$(kingbash.script "$PS1"); READLINE_LINE=$(echo "$out" | head -n -1); READLINE_POINT=$(echo "$out" | tail -n 1)'
  4.  
  5. function kb_ls() { /usr/bin/ls -1dsqh "$@"; }
  6.  
  7. function kb_highlight() {
  8.     case $cmdname in
  9. #Video
  10. mplayer|mwrap|vlc|gmplayer|smplayer|mencoder|kmplayer|Parole|whaawmp|dragonplayer|ffmpeg)
  11. extlist='mkv|m4v|mp.|avi|wmv|rmvb|as?|divx|vob|ogm|rm|flv|part|iso|ogg|wav|flac|m4a' ;;
  12. #Audio
  13. mpg123|mpg123s|mpg321|mp3blaster|cmus|cplay|moc|xmms|xmms2|sonata|deadbeef|ogg123|mnama)
  14. extlist='mp.|aac|wav|ogg|gsm|dct|flac|au|aiff|vox|wma|aac|ra|m4a' ;;
  15. #PDF
  16. llpp|xpdf|epdfview|evince|foxit|mupdf|okular|apvlv|zathura)
  17. extlist='pdf' ;;
  18. #Images
  19. feh|geeqie|gqview|eog|gpicview|gthumb|mirage|qiv|ristretto|xnview|xv|viewnior)
  20. extlist='jpg|jpeg|png|gif|bmp|icon?|tiff?' ;;
  21. #Games
  22. sdlmame|openmsx|msxplay|zsnes|desmume|VirtualBoy)
  23. extlist='rom|dsk' ;;
  24. #Wine
  25. wine|winewrap|wineconsole)
  26. extlist='exe|com|bat' ;;
  27. #Archives
  28. atool|x|xi|gunzip|extract|unzip|unrar|zip|rar|7z|mcomix|v)
  29. extlist='tgz|zip|rar|bz2|gz|tar|exe|pk3|lha|Z|lzma' ;;
  30. #Text
  31. vim|nano|acme|beaver|geany|leafpad|medit|mousepad|pyroom|sam|vi|gvim|emacs|tea|scite)
  32. extlist='txt|rc|sh|c|bash|py|ini' ;;
  33. #Default has to not match
  34. *) extlist='-Unmatch-';;
  35. esac
  36. }
  37.  
  38. function kb_listcheck() {
  39.     for tempfile in $1; do
  40.         if [[ "$reset" == "$tempfile" ]]; then
  41.             sel=$resetcounter
  42.             reset=
  43.         else
  44.             ((resetcounter++))
  45.         fi
  46.         if [[ "$cmdname" =~ ^(c|cd|popd|rmdir)$ ]]; then
  47.             if [[ -d "$tempfile" ]]; then
  48.             goodlist+=( "$tempfile" )
  49.             ((colorsw++))
  50.             else
  51.             badlist+=( "$tempfile" )
  52.             fi
  53.         elif [[ "$tempfile" =~ \.($extlist)$ ]]; then
  54.             goodlist+=( "$tempfile" )
  55.             ((colorsw++))
  56.         else
  57.             badlist+=( "$tempfile" )
  58.         fi
  59.     done
  60. }
  61.  
  62. function kb_menu() {
  63.     local end=0 h goodlist badlist total colorsw page pages sel=0 count key newk change=1 lim=12 displayres tempfile
  64.     local -A lslist
  65.     tput rmam >&2 #don't wrap long lines
  66.     IFS=$'\n'
  67.     prompt="$2"
  68.  
  69.     while ((end==0)); do
  70.  
  71.     # the [a-z] or [abcd] structure messes up globbing
  72.     prompt=${prompt//]/\\]}
  73.     prompt=${prompt//\\\\]/\\]}
  74.  
  75.     # build a new list
  76.     if ((change != 0)); then
  77.         sel=0
  78.         resetcounter=0
  79.         change=0
  80.         if [[ "$1" == command ]]; then
  81.             displayres=( $(compgen -A command -A alias -A builtin -A function $prompt | sort -u) )
  82.         elif [[ "$1" == file ]]; then
  83.             colorsw=0
  84.             goodlist=()
  85.             badlist=()
  86.             displayres=()
  87.             kb_listcheck "$prompt*"
  88.         fi
  89.         [[ "$1" == file ]] && colorsw=${#goodlist[@]} && displayres=( "${goodlist[@]}" "${badlist[@]}" )
  90.         total=${#displayres[@]}
  91.  
  92.         # on zero results retry without front match
  93.         if [[ "$1" == file ]] && ((total==0)); then
  94.             colorsw=0
  95.             if [[ "${prompt//[^\/]}" ]]; then
  96.                 kb_listcheck "${prompt%/*}/*${prompt##*/}*"
  97.             else
  98.                 kb_listcheck "*$prompt*"
  99.             fi
  100.             colorsw=${#goodlist[@]}
  101.             displayres=( "${goodlist[@]}" "${badlist[@]}" )
  102.             total=${#displayres[@]}
  103.         fi
  104.         ((total==1)) && prompt=${displayres[0]} && break
  105.         (( total < lim )) && h=$total || h=$lim
  106.         pages=$(( total /lim))
  107.     fi
  108.     ((sel < 0)) && sel=0
  109.     ((sel >= total)) && sel=$((total -1))
  110.  
  111.     page=$((sel /lim))
  112.     ((page==pages))&&lastpage=$'\e[7m'||lastpage=
  113.     echo -n  $'\e[0m'"${lastpage}p$page/$pages"$'\e[m'": $before$prompt"$'\e[47m \e[0m ' >&2
  114.     [[ "$key" != "ESC[C" ]] && rightonce=0
  115.     [[ $rightonce == 1 ]] && echo -n "$helptext" >&2
  116.  
  117.     for ((count = lim *(sel /lim); count < lim +lim *(sel /lim); count++)); do
  118.         echo -ne '\e[0m' >&2
  119.         [[ $count == $total && $page == 0 ]] && break || echo >&2
  120. #       (($sel == $count)) && echo -n "X "$'\e[7m' >&2 || echo -n "  " >&2
  121.         (($sel == $count)) && echo -n $'\e[7m' >&2
  122.         ((count < colorsw)) && echo -ne '\e[1;34m' >&2
  123.         if [[ "$1" == file ]]; then
  124.             tempfile=${displayres[$count]//\'}
  125.             tempfile=${tempfile//[}
  126.             tempfile=${tempfile//]}
  127.             if [[ "$tempfile" ]]; then
  128.                 if ! [[ "${lslist["$tempfile"]}" ]]; then
  129.                     ls_reform=$(kb_ls "${displayres[$count]}")
  130. [[ -d "${displayres[$count]}" ]] && ls_reform=$'\e[4m'"----"
  131. printf -v "lslist[$tempfile]" '%4s|%s' "${ls_reform%% *}" "${displayres[$count]}"
  132.                 fi
  133.                 echo -n "${lslist["$tempfile"]}" >&2
  134.             fi
  135.         else
  136.             echo -n "${displayres[$count]}" >&2
  137.         fi
  138.         (($sel == $count)) && for ((colcount=0;colcount<cols;colcount++)); do echo -n '          '; done  >&2
  139.     done
  140.  
  141.     tput civis >&2 #turn cursor invisible
  142.     read -n1 -s key
  143.     [[ $key ]] || key=ENTER
  144.     #[[ "$key" == ' ' ]] && key=Space
  145.     if [[ "$key" == $'\e' ]]; then
  146.         key=ESC
  147.         while true; do
  148.             read -n 1 -t 0.01 -s newk
  149.             [[ "$newk" == $'\e' ]] && newk=ESC
  150.             key=${key}${newk}
  151.             [[ -z "$newk" || "$newk" =~ [~A-Da-d] ]] && break
  152.         done
  153.     fi
  154.     case "$key" in
  155. 'ESC[A')    ((sel--));; #UP
  156. 'ESC[B')    ((sel++));; #DOWN
  157. 'ESC[6~')   ((sel+=lim));; #PGDN
  158. 'ESC[5~')   ((sel-=lim));; #PGUP
  159. 'ESC[D')    change=1; #LEFT
  160.     if [[ ${prompt: -3} == ../ ]]; then
  161.         prompt+=../
  162.     elif [[ "${prompt//[^\/]}" == / ]]; then
  163.         prompt=
  164.     elif [[ "${prompt//[^\/]}" ]]; then
  165.         ! [[ ${prompt: -1} == / ]] && prompt=${prompt%/*}/
  166.         prompt=${prompt%/*/*}/
  167.     else prompt=../
  168.     fi;;
  169. 'ESC[C') if [[ "$rightonce" == 0 ]]; then #RIGHT
  170.     helptext=$'\e[31m'"$(file -b "${displayres[$sel]}")"
  171. if [[ -d "${displayres[$sel]}" ]]; then
  172.     helptext+=" with $(/usr/bin/ls "${displayres[$sel]}" | wc -l) files: $(/usr/bin/ls "${displayres[$sel]}" | tr '\n' ' ')"
  173. fi
  174.     rightonce=1
  175.     else
  176.     rightonce=0
  177.     change=1;
  178.     prompt=${displayres[$sel]}
  179.     [[ -d "$prompt" ]] && prompt+=/ || end=1
  180.     fi;;
  181. 'ESC[4~'|'ESC[F'|'ESC[8~'|'ESCOF')  ((sel=$total));; #END
  182. 'ESC[1~'|'ESC[H'|'ESC[7~'|'ESCOH')  ((sel=0));; #HOME
  183. 'ESC[12~'|'ESCOQ') oldprompt="$prompt" #F2
  184.     oldbefore=$before
  185.     reset=${displayres[$sel]}
  186.     before="Enter new command: "
  187.     for (( count=0; count < $h; count++)); do
  188.         echo -ne "\e[2K\e[A\r" >&2
  189.     done
  190.     echo -ne '\e[2K\r' >&2
  191.     kb_menu command ""
  192.     doubleclear=1
  193.     change=1
  194.     cmdname=$prompt
  195.     kb_highlight
  196.     before=$cmdname\ ${oldbefore#* }
  197.     prompt=$oldprompt
  198.     ;;
  199. 'ESC[13~'|'ESCOR') prompt=$(echo "$prompt" | sed 's/[^/]*$//') #F3
  200.     [[ "$prompt" ]] || prompt=.
  201.     sel=0
  202.     displayres=( $(/usr/bin/ls -d1qt $prompt/*) )
  203.     ;;
  204. 'ENTER')    [[ "${displayres[$sel]}" ]] && prompt="${displayres[$sel]}"; end=1;; #ENTER
  205. 'ESC[2~')   appendprompt=\ $prompt; prompt="${displayres[$sel]}"; end=1;; #INSERT
  206. 'ESC')      nospace=0; end=1;; #ESC
  207. $'\x7f'|$'\x08')    change=1; [[ $prompt ]] && prompt=${prompt::-1};; #BACKSPACE
  208. 'ESC'*) :;; #UNUSED KEY
  209. *) change=1; prompt+=$key;;
  210.     esac
  211.    
  212.     if [[ $doubleclear ]]; then
  213.         doubleclear=
  214.     else
  215.         for (( count=0; count < $h; count++)); do
  216.             echo -ne "\e[2K\e[A\r" >&2
  217.         done
  218.         echo -ne '\e[2K\r' >&2
  219.     fi
  220.     done
  221. }
  222. function kb_replace_var() {
  223.     local var fill
  224.     OIFS=$IFS
  225.     IFS=$'\n'
  226.     last="${last/\~/$HOME}"
  227.     [[ "${last//[^$]}" ]] && \
  228.     for var in $(echo "$last" | /usr/bin/grep -o '\$[a-zA-Z_][a-zA-Z0-9_]*' | tr -d '$'); do
  229.         fill=${!var}
  230.         last="${last/\$$var/$fill}"
  231.     done
  232.     IFS=$OIFS
  233. }
  234. function kb_write_prompt() {
  235.     local out escquote lang
  236.     IFS=$' \t\n'
  237.     [[ -d "$1" ]] && dir=/ || dir=' '
  238.     (( nospace == 1 )) && { dir= && nospace=; } || nospace=\'
  239.     escquote=${1//\'/\'\\\'\'}
  240.     out="$before$nospace$escquote$nospace$dir$appendprompt"
  241.     lang=$LC_ALL
  242.     LC_ALL=C
  243.     ((READLINE_POINT+=${#out} - ${#READFIRST}))
  244.     LC_ALL=$LC_ALL
  245.     READLINE_LINE=$out$READLAST
  246. }
  247. function kb_output() {
  248.     echo "$READLINE_LINE"
  249.     echo "$READLINE_POINT"
  250. }
  251.  
  252. trap 'tput smam >&2; tput cnorm >&2; kb_output; exit' EXIT
  253. trap 'tput smam >&2; tput cnorm >&2; exit' INT QUIT TERM HUP
  254.  
  255. #local cmdname extlist appendprompt recursive quotes last before psheight nospace=0 extglob nocaseglob nullglob globstar READFIRST READLAST
  256. nospace=0
  257.     READFIRST="${READLINE_LINE::$READLINE_POINT}"
  258.     READLAST="${READLINE_LINE:$READLINE_POINT}"
  259.     psheight=$( echo -ne "$1" | wc -l)
  260. #   ((psheight--))
  261.     cols=$(( $(tput cols) / 10))
  262.     IFS=$' \t\n'
  263.  
  264.     # is the line has no words, add a tab.
  265.     if [[ "$READFIRST" =~ ^[[:blank:]]*$ ]]; then
  266.         READLINE_LINE="$READFIRST"$'\t'"$READLAST"
  267.         ((READLINE_POINT++))
  268.         exit
  269.     fi
  270.  
  271.     # count non-escaped quotes
  272.     quotes=${READFIRST//\\\'}
  273.     quotes=${quotes//[^\']}
  274.     quotes=${#quotes}
  275.  
  276.     # the last word is empty, start completing from scratch
  277.     if [[ "${READFIRST: -1}" == ' ' && "${READFIRST: -2:1}" != '\' ]] && (( quotes % 2 == 0)); then
  278.         before=$READFIRST
  279.         last=
  280.     # complete a command (TODO:add sudo and such)
  281.     elif [[ $READFIRST =~ ^\ *[^\ ]+$ ]]; then
  282.         kb_menu command "$READFIRST"
  283.         prompt+=" "
  284.         ((READLINE_POINT+=${#prompt} - ${#READFIRST}))
  285.         READLINE_LINE=$prompt$READLAST
  286.         IFS=$' \t\n'
  287.         echo -ne "\e[${psheight}A\r\e[2K" >&2
  288.         exit
  289.  
  290.     # complete part of a word
  291.     else
  292.         last="${READFIRST##* }"
  293.         recursive="${READFIRST% *}"
  294.     fi
  295.  
  296.     shopt -s nocaseglob
  297.     shopt -s nullglob
  298. #   shopt -u globstar
  299.     cmdname=$(echo $READFIRST)
  300.     cmdname=${cmdname%% *}
  301.     kb_highlight "$cmdname"
  302.  
  303.     # add words that end in \ to the $last word
  304.     while [[ -z "$before" ]] ; do
  305.         if [[ "${recursive: -1}" == '\' ]]; then
  306.             last="${recursive##* } $last"
  307.             recursive=${recursive% *}
  308.         else
  309.             before=$recursive\
  310.         fi
  311.     done
  312.  
  313.     # for structures like cat 'word1 word2<TAB>
  314.     if (( quotes % 2 == 1 )) && ! [[ "$last" =~ \' ]]; then
  315.         # $last will be part of a quote instead.
  316.         # assume last quote is not escape.
  317.         before="${READFIRST%\'*}"
  318.         last="${READFIRST##*\'}"
  319.     fi
  320.  
  321.     # for structures like cat 'word1 word2'/<TAB>
  322.     lastquote="${READFIRST##* }"
  323.     beforequote="${READFIRST% *}"
  324.     if [[ "${lastquote//[^\']}" == \' && "${beforequote}" =~ \ \' ]]; then
  325.         last=${beforequote##* \'}\ $lastquote
  326.         before=${beforequote% \'*}\
  327.     fi
  328.  
  329.     kb_replace_var
  330.  
  331.     last=${last//\'}
  332.  
  333.     kb_menu 'file' "$last"
  334.     kb_write_prompt "$prompt"
  335.  
  336.     echo -ne "\r\e[2K\e[${psheight}A\r\e[2K" >&2
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement