SHARE
TWEET

Expand dots to dot-dot component.

bac0n Jul 17th, 2018 (edited) 147 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #
  2. # Expand dots to dot-dot component (~/.bash_aliases).
  3. #
  4. # https://github.com/bac0n/bash_completion
  5. #
  6. if [ -n "$PS1" ]; then
  7. cd(){
  8.     local d=${@:(-1)}
  9.     local x='' y='' z=3
  10.     while [[ ! -d $d ]] && [[ ${d:${#x}} =~ (^|/)([.]{3,})(/.*)?$ ]]; do
  11.         x=${d:0:(${#d} - ${#BASH_REMATCH[3]})}
  12.         if [[ ! -d $x ]]; then
  13.             y='..'
  14.             for ((z=3; z <= ${#BASH_REMATCH[2]}; z++)); do
  15.                 y+='/..'
  16.             done
  17.             d=${d:0:(${#d} - ${#BASH_REMATCH[0]})}${BASH_REMATCH[1]}${y}${BASH_REMATCH[3]}
  18.         fi
  19.     done
  20.     builtin pushd "$d" > /dev/null && /bin/ls --almost-all --color=auto
  21. }
  22.  
  23. cd_undo(){
  24.     if [[ ${READLINE_LINE%% *} != cd ]]; then
  25.         return
  26.     fi
  27.     local d='' x='' y='' z=0
  28.     READLINE_LINE=${READLINE_LINE%/}
  29.     d=$(rev <<< ${READLINE_LINE#* })
  30.     if [[ $d =~ (^|/)([.]{2}(/[.]{2})+)(/.*)?$ ]]; then
  31.         y=.
  32.         x=${BASH_REMATCH[2]//\/}
  33.         for ((z=0; z < (${#x} / 2); z++ )); do
  34.             y+=.
  35.         done
  36.         x=${d:0:(${#d} - ${#BASH_REMATCH[0]})}
  37.         READLINE_LINE="cd $(rev <<< ${x}${BASH_REMATCH[1]}${y}${BASH_REMATCH[4]})"
  38.         READLINE_POINT=$((${#READLINE_LINE} - ${#x} - ${#BASH_REMATCH[1]}))
  39.     else
  40.         i=0
  41.         x=$((${#READLINE_LINE} - $READLINE_POINT))
  42.         while [[ ${d:$x} =~ (^|/)([.]{3,})(/.*)?$ ]]; do
  43.             x=$((${#d} - ${#BASH_REMATCH[3]}))
  44.             if (( (${#BASH_REMATCH[2]} + ${#BASH_REMATCH[3]}) == ($READLINE_POINT - 3) )); then
  45.                 continue
  46.             fi
  47.             READLINE_POINT=$((${#BASH_REMATCH[0]} - ${#BASH_REMATCH[1]} + 3))
  48.             break
  49.         done
  50.     fi
  51. }
  52. fi
  53.  
  54. # bind cd undo to readline keyseq ESC ESC.
  55. if [[ $(declare -F cd_undo) = cd_undo ]]; then
  56.     bind -r '"\e\e"'
  57.     bind -x '"\e\e"  :cd_undo'
  58.     bind -x '"\e\e\e":cd_undo'
  59. fi
  60.  
  61. ##
  62.  
  63. # (/etc/bash_completion.d/cd)
  64. #
  65. # This meta-cd function observes the CDPATH variable, so that cd additionally
  66. # completes on directories under those specified in CDPATH.
  67. #
  68. _cd()
  69. {
  70.     local cur prev words cword
  71.     _init_completion || return
  72.  
  73.     local IFS=$'\n' i j k
  74.  
  75.     compopt -o filenames
  76.  
  77.     # Expand dots to dot-dot component.
  78.     local x='' y='' z=3
  79.     while [[ ! -d $cur ]] && [[ ${cur:${#x}} =~ (^|/)([.]{3,})(/.*)?$ ]]; do
  80.         if [[ -n $(compgen -d -- $cur) ]]; then
  81.             if [[ $cur == ..+(.) ]] || [[ $cur == */..+(.) ]]; then
  82.                 COMPREPLY+=("$cur/")
  83.             fi
  84.             break
  85.         fi
  86.         x="${cur:0:(${#cur}-${#BASH_REMATCH[3]})}"
  87.         if [[ ! -d $x ]]; then
  88.             y='..'
  89.             for ((z=3; z <= ${#BASH_REMATCH[2]}; z++)); do
  90.                 y+='/..'
  91.             done
  92.             cur="${cur:0:(${#cur}-${#BASH_REMATCH[0]})}${BASH_REMATCH[1]}${y}${BASH_REMATCH[3]}"
  93.         fi
  94.     done
  95.  
  96.     # Use standard dir completion if no CDPATH or parameter starts with /,
  97.     # ./ or ../
  98.     if [[ -z "${CDPATH:-}" || "$cur" == ?(.)?(.)/* ]]; then
  99.         _filedir -d
  100.         return
  101.     fi
  102.  
  103.     local -r mark_dirs=$(_rl_enabled mark-directories && echo y)
  104.     local -r mark_symdirs=$(_rl_enabled mark-symlinked-directories && echo y)
  105.  
  106.     # we have a CDPATH, so loop on its contents
  107.     for i in ${CDPATH//:/$'\n'}; do
  108.         # create an array of matched subdirs
  109.         k="${#COMPREPLY[@]}"
  110.         for j in $( compgen -d -- $i/$cur ); do
  111.             if [[ ( $mark_symdirs && -h $j || $mark_dirs && ! -h $j ) && ! -d ${j#$i/} ]]; then
  112.                 j+="/"
  113.             fi
  114.             COMPREPLY[k++]=${j#$i/}
  115.         done
  116.     done
  117.  
  118.     _filedir -d
  119.  
  120.     if [[ ${#COMPREPLY[@]} -eq 1 ]]; then
  121.         i=${COMPREPLY[0]}
  122.         if [[ "$i" == "$cur" && $i != "*/" ]]; then
  123.             COMPREPLY[0]="${i}/"
  124.         fi
  125.     fi
  126.     return
  127. }
  128.  
  129. if shopt -q cdable_vars; then
  130.     complete -v -F _cd -o nospace cd pushd
  131. else
  132.     complete -F _cd -o nospace cd pushd
  133. fi
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
Not a member of Pastebin yet?
Sign Up, it unlocks many cool features!
 
Top