summaryrefslogtreecommitdiff
path: root/bash_completion
diff options
context:
space:
mode:
authorGabriel F. T. Gomes <gabriel@inconstante.eti.br>2017-09-25 23:46:54 -0300
committerGabriel F. T. Gomes <gabriel@inconstante.eti.br>2017-09-25 23:46:54 -0300
commit6d88f1055806932d9291f96847d2b691cccda2cd (patch)
tree0ff79eedaa8a239331256048981deedbd0721965 /bash_completion
parent059a87a5936cfebfd2d71ab8057002cafb2ea051 (diff)
downloadbash-completion-6d88f1055806932d9291f96847d2b691cccda2cd.tar.gz
New upstream version 2.7upstream/2.7
Diffstat (limited to 'bash_completion')
-rw-r--r--bash_completion421
1 files changed, 268 insertions, 153 deletions
diff --git a/bash_completion b/bash_completion
index 6d3ba762..d16b10a5 100644
--- a/bash_completion
+++ b/bash_completion
@@ -3,8 +3,7 @@
# bash_completion - programmable completion functions for bash 4.1+
#
# Copyright © 2006-2008, Ian Macdonald <ian@caliban.org>
-# © 2009-2013, Bash Completion Maintainers
-# <bash-completion-devel@lists.alioth.debian.org>
+# © 2009-2017, Bash Completion Maintainers
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -22,9 +21,9 @@
#
# The latest version of this software can be obtained here:
#
-# http://bash-completion.alioth.debian.org/
-#
-# RELEASE: 2.1
+# https://github.com/scop/bash-completion
+
+BASH_COMPLETION_VERSINFO=(2 7)
if [[ $- == *v* ]]; then
BASH_COMPLETION_ORIGINAL_V_VALUE="-v"
@@ -38,11 +37,6 @@ else
set +v
fi
-# Set the following to the location of the backwards compat completion dir.
-#
-: ${BASH_COMPLETION_COMPAT_DIR:=/etc/bash_completion.d}
-readonly BASH_COMPLETION_COMPAT_DIR
-
# Blacklisted completions, causing problems with our code.
#
_blacklist_glob='@(acroread.sh)'
@@ -53,13 +47,10 @@ shopt -s extglob progcomp
# A lot of the following one-liners were taken directly from the
# completion examples provided with the bash 2.04 source distribution
-# Make directory commands see only directories
-complete -d pushd
-
# start of section containing compspecs that can be handled within bash
# user commands see only users
-complete -u write chfn groups slay w sux runuser
+complete -u groups slay w sux
# bg completes with stopped jobs
complete -A stopped -P '"%' -S '"' bg
@@ -82,9 +73,6 @@ complete -A helptopic help
# unalias completes with aliases
complete -a unalias
-# bind completes with readline bindings (make this more intelligent)
-complete -A binding bind
-
# type and which complete on commands
complete -c command type which
@@ -136,7 +124,7 @@ have()
#
_rl_enabled()
{
- [[ "$( bind -v )" = *$1+([[:space:]])on* ]]
+ [[ "$( bind -v )" == *$1+([[:space:]])on* ]]
}
# This function shell-quotes the argument
@@ -246,7 +234,7 @@ __reassemble_comp_words_by_ref()
fi
# Default to cword unchanged
- eval $3=$COMP_CWORD
+ printf -v "$3" %s "$COMP_CWORD"
# Are characters excluded which were former included?
if [[ $exclude ]]; then
# Yes, list of word completion separators has shrunk;
@@ -261,33 +249,35 @@ __reassemble_comp_words_by_ref()
# Is word separator not preceded by whitespace in original line
# and are we not going to append to word 0 (the command
# itself), then append to current word.
- [[ $line != [$' \t']* ]] && (( j >= 2 )) && ((j--))
+ [[ $line != [[:blank:]]* ]] && (( j >= 2 )) && ((j--))
# Append word separator to current or new word
ref="$2[$j]"
- eval $2[$j]=\${!ref}\${COMP_WORDS[i]}
+ printf -v "$ref" %s "${!ref}${COMP_WORDS[i]}"
# Indicate new cword
- [[ $i == $COMP_CWORD ]] && eval $3=$j
+ [[ $i == $COMP_CWORD ]] && printf -v "$3" %s "$j"
# Remove optional whitespace + word separator from line copy
line=${line#*"${COMP_WORDS[$i]}"}
# Start new word if word separator in original line is
# followed by whitespace.
- [[ $line == [$' \t']* ]] && ((j++))
+ [[ $line == [[:blank:]]* ]] && ((j++))
# Indicate next word if available, else end *both* while and
# for loop
(( $i < ${#COMP_WORDS[@]} - 1)) && ((i++)) || break 2
done
# Append word to current word
ref="$2[$j]"
- eval $2[$j]=\${!ref}\${COMP_WORDS[i]}
+ printf -v "$ref" %s "${!ref}${COMP_WORDS[i]}"
# Remove optional whitespace + word from line copy
line=${line#*"${COMP_WORDS[i]}"}
# Indicate new cword
- [[ $i == $COMP_CWORD ]] && eval $3=$j
+ [[ $i == $COMP_CWORD ]] && printf -v "$3" %s "$j"
done
- [[ $i == $COMP_CWORD ]] && eval $3=$j
+ [[ $i == $COMP_CWORD ]] && printf -v "$3" %s "$j"
else
# No, list of word completions separators hasn't changed;
- eval $2=\( \"\${COMP_WORDS[@]}\" \)
+ for i in ${!COMP_WORDS[@]}; do
+ printf -v "$2[i]" %s "${COMP_WORDS[i]}"
+ done
fi
} # __reassemble_comp_words_by_ref()
@@ -318,8 +308,8 @@ __get_cword_at_cursor_by_ref()
]]; do
# Strip first character
cur="${cur:1}"
- # Decrease cursor position
- ((index--))
+ # Decrease cursor position, staying >= 0
+ [[ $index -gt 0 ]] && ((index--))
done
# Does found word match cword?
@@ -448,8 +438,8 @@ _get_cword()
]]; do
# Strip first character
cur="${cur:1}"
- # Decrease cursor position
- ((index--))
+ # Decrease cursor position, staying >= 0
+ [[ $index -gt 0 ]] && ((index--))
done
# Does found word matches cword?
@@ -558,37 +548,37 @@ _quote_readline_by_ref()
#
_filedir()
{
- local i IFS=$'\n' xspec
+ local IFS=$'\n'
- _tilde "$cur" || return 0
+ _tilde "$cur" || return
local -a toks
- local quoted x tmp
+ local x tmp
- _quote_readline_by_ref "$cur" quoted
- x=$( compgen -d -- "$quoted" ) &&
+ x=$( compgen -d -- "$cur" ) &&
while read -r tmp; do
toks+=( "$tmp" )
done <<< "$x"
if [[ "$1" != -d ]]; then
+ local quoted
+ _quote_readline_by_ref "$cur" quoted
+
# Munge xspec to contain uppercase version too
# http://thread.gmane.org/gmane.comp.shells.bash.bugs/15294/focus=15306
- xspec=${1:+"!*.@($1|${1^^})"}
+ local xspec=${1:+"!*.@($1|${1^^})"}
x=$( compgen -f -X "$xspec" -- $quoted ) &&
while read -r tmp; do
toks+=( "$tmp" )
done <<< "$x"
- fi
-
- # If the filter failed to produce anything, try without it if configured to
- [[ -n ${COMP_FILEDIR_FALLBACK:-} && \
- -n "$1" && "$1" != -d && ${#toks[@]} -lt 1 ]] && \
- x=$( compgen -f -- $quoted ) &&
- while read -r tmp; do
- toks+=( "$tmp" )
- done <<< "$x"
+ # Try without filter if it failed to produce anything and configured to
+ [[ -n ${COMP_FILEDIR_FALLBACK:-} && -n "$1" && ${#toks[@]} -lt 1 ]] && \
+ x=$( compgen -f -- $quoted ) &&
+ while read -r tmp; do
+ toks+=( "$tmp" )
+ done <<< "$x"
+ fi
if [[ ${#toks[@]} -ne 0 ]]; then
# 2>/dev/null for direct invocation, e.g. in the _filedir unit test
@@ -622,11 +612,59 @@ _split_longopt()
# False (> 0) if not.
_variables()
{
- if [[ $cur =~ ^(\$\{?)([A-Za-z0-9_]*)$ ]]; then
- [[ $cur == *{* ]] && local suffix=} || local suffix=
- COMPREPLY+=( $( compgen -P ${BASH_REMATCH[1]} -S "$suffix" -v -- \
- "${BASH_REMATCH[2]}" ) )
+ if [[ $cur =~ ^(\$(\{[!#]?)?)([A-Za-z0-9_]*)$ ]]; then
+ # Completing $var / ${var / ${!var / ${#var
+ if [[ $cur == \${* ]]; then
+ local arrs vars
+ vars=( $( compgen -A variable -P ${BASH_REMATCH[1]} -S '}' -- ${BASH_REMATCH[3]} ) ) && \
+ arrs=( $( compgen -A arrayvar -P ${BASH_REMATCH[1]} -S '[' -- ${BASH_REMATCH[3]} ) )
+ if [[ ${#vars[@]} -eq 1 && $arrs ]]; then
+ # Complete ${arr with ${array[ if there is only one match, and that match is an array variable
+ compopt -o nospace
+ COMPREPLY+=( ${arrs[*]} )
+ else
+ # Complete ${var with ${variable}
+ COMPREPLY+=( ${vars[*]} )
+ fi
+ else
+ # Complete $var with $variable
+ COMPREPLY+=( $( compgen -A variable -P '$' -- "${BASH_REMATCH[3]}" ) )
+ fi
+ return 0
+ elif [[ $cur =~ ^(\$\{[#!]?)([A-Za-z0-9_]*)\[([^]]*)$ ]]; then
+ # Complete ${array[i with ${array[idx]}
+ local IFS=$'\n'
+ COMPREPLY+=( $( compgen -W '$(printf %s\\n "${!'${BASH_REMATCH[2]}'[@]}")' \
+ -P "${BASH_REMATCH[1]}${BASH_REMATCH[2]}[" -S ']}' -- "${BASH_REMATCH[3]}" ) )
+ # Complete ${arr[@ and ${arr[*
+ if [[ ${BASH_REMATCH[3]} == [@*] ]]; then
+ COMPREPLY+=( "${BASH_REMATCH[1]}${BASH_REMATCH[2]}[${BASH_REMATCH[3]}]}" )
+ fi
+ __ltrim_colon_completions "$cur" # array indexes may have colons
return 0
+ elif [[ $cur =~ ^\$\{[#!]?[A-Za-z0-9_]*\[.*\]$ ]]; then
+ # Complete ${array[idx] with ${array[idx]}
+ COMPREPLY+=( "$cur}" )
+ __ltrim_colon_completions "$cur"
+ return 0
+ else
+ case $prev in
+ TZ)
+ cur=/usr/share/zoneinfo/$cur
+ _filedir
+ for i in ${!COMPREPLY[@]}; do
+ if [[ ${COMPREPLY[i]} == *.tab ]]; then
+ unset 'COMPREPLY[i]'
+ continue
+ elif [[ -d ${COMPREPLY[i]} ]]; then
+ COMPREPLY[i]+=/
+ compopt -o nospace
+ fi
+ COMPREPLY[i]=${COMPREPLY[i]#/usr/share/zoneinfo/}
+ done
+ return 0
+ ;;
+ esac
fi
return 1
}
@@ -707,7 +745,7 @@ _init_completion()
fi
done
- [[ $cword -eq 0 ]] && return 1
+ [[ $cword -le 0 ]] && return 1
prev=${words[cword-1]}
[[ ${split-} ]] && _split_longopt && split=true
@@ -722,15 +760,17 @@ __parse_options()
# Take first found long option, or first one (short) if not found.
option=
- for i in $1; do
- case $i in
+ local -a array
+ read -a array <<<"$1"
+ for i in "${array[@]}"; do
+ case "$i" in
---*) break ;;
--?*) option=$i ; break ;;
-?*) [[ $option ]] || option=$i ;;
*) break ;;
esac
done
- [[ $option ]] || return 0
+ [[ $option ]] || return
IFS=$' \t\n' # affects parsing of the regexps below...
@@ -760,7 +800,7 @@ _parse_help()
esac } \
| while read -r line; do
- [[ $line == *([ $'\t'])-* ]] || continue
+ [[ $line == *([[:blank:]])-* ]] || continue
# transform "-f FOO, --foo=FOO" to "-f , --foo=FOO" etc
while [[ $line =~ \
((^|[^-])-[A-Za-z0-9?][[:space:]]+)\[?[A-Z0-9]+\]? ]]; do
@@ -825,7 +865,8 @@ _mac_addresses()
# - ifconfig on Linux: HWaddr or ether
# - ifconfig on FreeBSD: ether
# - ip link: link/ether
- COMPREPLY+=( $( { ifconfig -a || ip link show; } 2>/dev/null | sed -ne \
+ COMPREPLY+=( $( \
+ { LC_ALL=C ifconfig -a || ip link show; } 2>/dev/null | command sed -ne \
"s/.*[[:space:]]HWaddr[[:space:]]\{1,\}\($re\)[[:space:]].*/\1/p" -ne \
"s/.*[[:space:]]HWaddr[[:space:]]\{1,\}\($re\)[[:space:]]*$/\1/p" -ne \
"s|.*[[:space:]]\(link/\)\{0,1\}ether[[:space:]]\{1,\}\($re\)[[:space:]].*|\2|p" -ne \
@@ -833,12 +874,12 @@ _mac_addresses()
) )
# ARP cache
- COMPREPLY+=( $( { arp -an || ip neigh show; } 2>/dev/null | sed -ne \
+ COMPREPLY+=( $( { arp -an || ip neigh show; } 2>/dev/null | command sed -ne \
"s/.*[[:space:]]\($re\)[[:space:]].*/\1/p" -ne \
"s/.*[[:space:]]\($re\)[[:space:]]*$/\1/p" ) )
# /etc/ethers
- COMPREPLY+=( $( sed -ne \
+ COMPREPLY+=( $( command sed -ne \
"s/^[[:space:]]*\($re\)[[:space:]].*/\1/p" /etc/ethers 2>/dev/null ) )
COMPREPLY=( $( compgen -W '${COMPREPLY[@]}' -- "$cur" ) )
@@ -851,23 +892,24 @@ _configured_interfaces()
{
if [[ -f /etc/debian_version ]]; then
# Debian system
- COMPREPLY=( $( compgen -W "$( sed -ne 's|^iface \([^ ]\{1,\}\).*$|\1|p'\
- /etc/network/interfaces )" -- "$cur" ) )
+ COMPREPLY=( $( compgen -W "$( command sed -ne 's|^iface \([^ ]\{1,\}\).*$|\1|p'\
+ /etc/network/interfaces /etc/network/interfaces.d/* 2>/dev/null )" \
+ -- "$cur" ) )
elif [[ -f /etc/SuSE-release ]]; then
# SuSE system
COMPREPLY=( $( compgen -W "$( printf '%s\n' \
/etc/sysconfig/network/ifcfg-* | \
- sed -ne 's|.*ifcfg-\(.*\)|\1|p' )" -- "$cur" ) )
+ command sed -ne 's|.*ifcfg-\([^*].*\)$|\1|p' )" -- "$cur" ) )
elif [[ -f /etc/pld-release ]]; then
# PLD Linux
COMPREPLY=( $( compgen -W "$( command ls -B \
/etc/sysconfig/interfaces | \
- sed -ne 's|.*ifcfg-\(.*\)|\1|p' )" -- "$cur" ) )
+ command sed -ne 's|.*ifcfg-\([^*].*\)$|\1|p' )" -- "$cur" ) )
else
# Assume Red Hat
COMPREPLY=( $( compgen -W "$( printf '%s\n' \
/etc/sysconfig/network-scripts/ifcfg-* | \
- sed -ne 's|.*ifcfg-\(.*\)|\1|p' )" -- "$cur" ) )
+ command sed -ne 's|.*ifcfg-\([^*].*\)$|\1|p' )" -- "$cur" ) )
fi
}
@@ -877,9 +919,9 @@ _ip_addresses()
{
local PATH=$PATH:/sbin
COMPREPLY+=( $( compgen -W \
- "$( { LC_ALL=C ifconfig -a || ip addr show; } 2>/dev/null |
- sed -ne 's/.*addr:\([^[:space:]]*\).*/\1/p' \
- -ne 's|.*inet[[:space:]]\{1,\}\([^[:space:]/]*\).*|\1|p' )" \
+ "$( { LC_ALL=C ifconfig -a || ip addr show; } 2>/dev/null | command sed -ne \
+ 's/.*addr:\([^[:space:]]*\).*/\1/p' -ne \
+ 's|.*inet[[:space:]]\{1,\}\([^[:space:]/]*\).*|\1|p' )" \
-- "$cur" ) )
}
@@ -929,7 +971,7 @@ _tilde()
local result=0
if [[ $1 == \~* && $1 != */* ]]; then
# Try generate ~username completions
- COMPREPLY=( $( compgen -P '~' -u "${1#\~}" ) )
+ COMPREPLY=( $( compgen -P '~' -u -- "${1#\~}" ) )
result=${#COMPREPLY[@]}
# 2>/dev/null for direct invocation, e.g. in the _tilde unit test
[[ $result -gt 0 ]] && compopt -o filenames 2>/dev/null
@@ -996,7 +1038,7 @@ _expand()
eval cur=$cur 2>/dev/null
elif [[ "$cur" == \~* ]]; then
cur=${cur#\~}
- COMPREPLY=( $( compgen -P '~' -u "$cur" ) )
+ COMPREPLY=( $( compgen -P '~' -u -- "$cur" ) )
[[ ${#COMPREPLY[@]} -eq 1 ]] && eval COMPREPLY[0]=${COMPREPLY[0]}
return ${#COMPREPLY[@]}
fi
@@ -1007,7 +1049,7 @@ _expand()
[[ $OSTYPE == *@(solaris|aix)* ]] &&
_pids()
{
- COMPREPLY=( $( compgen -W '$( command ps -efo pid | sed 1d )' -- "$cur" ))
+ COMPREPLY=( $( compgen -W '$( command ps -efo pid | command sed 1d )' -- "$cur" ))
} ||
_pids()
{
@@ -1019,7 +1061,7 @@ _pids()
[[ $OSTYPE == *@(solaris|aix)* ]] &&
_pgids()
{
- COMPREPLY=( $( compgen -W '$( command ps -efo pgid | sed 1d )' -- "$cur" ))
+ COMPREPLY=( $( compgen -W '$( command ps -efo pgid | command sed 1d )' -- "$cur" ))
} ||
_pgids()
{
@@ -1028,25 +1070,32 @@ _pgids()
# This function completes on process names.
# AIX and SunOS prefer X/Open, all else should be BSD.
+# @param $1 if -s, don't try to avoid truncated command names
[[ $OSTYPE == *@(solaris|aix)* ]] &&
_pnames()
{
COMPREPLY=( $( compgen -X '<defunct>' -W '$( command ps -efo comm | \
- sed -e 1d -e "s:.*/::" -e "s/^-//" | sort -u )' -- "$cur" ) )
+ command sed -e 1d -e "s:.*/::" -e "s/^-//" | sort -u )' -- "$cur" ) )
} ||
_pnames()
{
- # FIXME: completes "[kblockd/0]" to "0". Previously it was completed
- # to "kblockd" which isn't correct either. "kblockd/0" would be
- # arguably most correct, but killall from psmisc 22 treats arguments
- # containing "/" specially unless -r is given so that wouldn't quite
- # work either. Perhaps it'd be best to not complete these to anything
- # for now.
- # Not using "ps axo comm" because under some Linux kernels, it
- # truncates command names (see e.g. http://bugs.debian.org/497540#19)
- COMPREPLY=( $( compgen -X '<defunct>' -W '$( command ps axo command= | \
- sed -e "s/ .*//" -e "s:.*/::" -e "s/:$//" -e "s/^[[(-]//" \
- -e "s/[])]$//" | sort -u )' -- "$cur" ) )
+ if [[ "$1" == -s ]]; then
+ COMPREPLY=( $( compgen -X '<defunct>' \
+ -W '$( command ps axo comm | command sed -e 1d )' -- "$cur" ) )
+ else
+ # FIXME: completes "[kblockd/0]" to "0". Previously it was completed
+ # to "kblockd" which isn't correct either. "kblockd/0" would be
+ # arguably most correct, but killall from psmisc 22 treats arguments
+ # containing "/" specially unless -r is given so that wouldn't quite
+ # work either. Perhaps it'd be best to not complete these to anything
+ # for now.
+ COMPREPLY=( $( compgen -X '<defunct>' -W '$( command ps axo command= | command sed -e \
+ "s/ .*//" -e \
+ "s:.*/::" -e \
+ "s/:$//" -e \
+ "s/^[[(-]//" -e \
+ "s/[])]$//" | sort -u )' -- "$cur" ) )
+ fi
}
# This function completes on user IDs
@@ -1103,12 +1152,17 @@ _services()
_sysvdirs
local restore_nullglob=$(shopt -p nullglob); shopt -s nullglob
- COMPREPLY=( $( printf '%s\n' ${sysvdirs[0]}/!($_backup_glob|functions) ) )
+ COMPREPLY=( \
+ $( printf '%s\n' ${sysvdirs[0]}/!($_backup_glob|functions|README) ) )
$restore_nullglob
COMPREPLY+=( $( systemctl list-units --full --all 2>/dev/null | \
awk '$1 ~ /\.service$/ { sub("\\.service$", "", $1); print $1 }' ) )
+ if [[ -x /sbin/upstart-udev-bridge ]]; then
+ COMPREPLY+=( $( initctl list 2>/dev/null | cut -d' ' -f1 ) )
+ fi
+
COMPREPLY=( $( compgen -W '${COMPREPLY[@]#${sysvdirs[0]}/}' -- "$cur" ) )
}
@@ -1122,7 +1176,7 @@ _service()
_init_completion || return
# don't complete past 2nd token
- [[ $cword -gt 2 ]] && return 0
+ [[ $cword -gt 2 ]] && return
if [[ $cword -eq 1 && $prev == ?(*/)service ]]; then
_services
@@ -1130,7 +1184,7 @@ _service()
else
local sysvdirs
_sysvdirs
- COMPREPLY=( $( compgen -W '`sed -e "y/|/ /" \
+ COMPREPLY=( $( compgen -W '`command sed -e "y/|/ /" \
-ne "s/^.*\(U\|msg_u\)sage.*{\(.*\)}.*$/\2/p" \
${sysvdirs[0]}/${prev##*/} 2>/dev/null` start stop' -- "$cur" ) )
fi
@@ -1151,7 +1205,7 @@ _modules()
local modpath
modpath=/lib/modules/$1
COMPREPLY=( $( compgen -W "$( command ls -RL $modpath 2>/dev/null | \
- sed -ne 's/^\(.*\)\.k\{0,1\}o\(\.[gx]z\)\{0,1\}$/\1/p' )" -- "$cur" ) )
+ command sed -ne 's/^\(.*\)\.k\{0,1\}o\(\.[gx]z\)\{0,1\}$/\1/p' )" -- "$cur" ) )
}
# This function completes on installed modules
@@ -1171,10 +1225,10 @@ _installed_modules()
# context of current completion.
_usergroup()
{
- if [[ $cur = *\\\\* || $cur = *:*:* ]]; then
+ if [[ $cur == *\\\\* || $cur == *:*:* ]]; then
# Give up early on if something seems horribly wrong.
return
- elif [[ $cur = *\\:* ]]; then
+ elif [[ $cur == *\\:* ]]; then
# Completing group after 'user\:gr<TAB>'.
# Reply with a list of groups prefixed with 'user:', readline will
# escape to the colon.
@@ -1189,7 +1243,7 @@ _usergroup()
COMPREPLY=( $( compgen -g -- "$mycur" ) )
fi
COMPREPLY=( $( compgen -P "$prefix" -W "${COMPREPLY[@]}" ) )
- elif [[ $cur = *:* ]]; then
+ elif [[ $cur == *:* ]]; then
# Completing group after 'user:gr<TAB>'.
# Reply with a list of unprefixed groups since readline with split on :
# and only replace the 'gr' part
@@ -1258,14 +1312,14 @@ _fstypes()
if [[ -e /proc/filesystems ]]; then
# Linux
fss="$( cut -d$'\t' -f2 /proc/filesystems )
- $( awk '! /\*/ { print $NF }' /etc/filesystems 2>/dev/null )"
+ $( awk '! /\*/ { print $NF }' /etc/filesystems 2>/dev/null )"
else
# Generic
fss="$( awk '/^[ \t]*[^#]/ { print $3 }' /etc/fstab 2>/dev/null )
- $( awk '/^[ \t]*[^#]/ { print $3 }' /etc/mnttab 2>/dev/null )
- $( awk '/^[ \t]*[^#]/ { print $4 }' /etc/vfstab 2>/dev/null )
- $( awk '{ print $1 }' /etc/dfs/fstypes 2>/dev/null )
- $( [[ -d /etc/fs ]] && command ls /etc/fs )"
+ $( awk '/^[ \t]*[^#]/ { print $3 }' /etc/mnttab 2>/dev/null )
+ $( awk '/^[ \t]*[^#]/ { print $4 }' /etc/vfstab 2>/dev/null )
+ $( awk '{ print $1 }' /etc/dfs/fstypes 2>/dev/null )
+ $( [[ -d /etc/fs ]] && command ls /etc/fs )"
fi
[[ -n $fss ]] && COMPREPLY+=( $( compgen -W "$fss" -- "$cur" ) )
@@ -1354,7 +1408,7 @@ _dvd_devices()
_terms()
{
COMPREPLY+=( $( compgen -W \
- "$( sed -ne 's/^\([^[:space:]#|]\{2,\}\)|.*/\1/p' /etc/termcap \
+ "$( command sed -ne 's/^\([^[:space:]#|]\{2,\}\)|.*/\1/p' /etc/termcap \
2>/dev/null )" -- "$cur" ) )
COMPREPLY+=( $( compgen -W "$( { toe -a 2>/dev/null || toe 2>/dev/null; } \
| awk '{ print $1 }' | sort -u )" -- "$cur" ) )
@@ -1375,12 +1429,11 @@ _user_at_host()
if [[ $cur == *@* ]]; then
_known_hosts_real "$cur"
else
- COMPREPLY=( $( compgen -u -- "$cur" ) )
+ COMPREPLY=( $( compgen -u -S @ -- "$cur" ) )
+ compopt -o nospace
fi
-
- return 0
}
-shopt -u hostcomplete && complete -F _user_at_host -o nospace talk ytalk finger
+shopt -u hostcomplete && complete -F _user_at_host talk ytalk finger
# NOTE: Using this function as a helper function is deprecated. Use
# `_known_hosts_real' instead.
@@ -1397,6 +1450,39 @@ _known_hosts()
_known_hosts_real $options -- "$cur"
} # _known_hosts()
+# Helper function to locate ssh included files in configs
+# This function look for the "Include" keyword in ssh config files and include
+# them recursively adding each result to the config variable
+_included_ssh_config_files()
+{
+ [[ $# -lt 1 ]] && echo "error: $FUNCNAME: missing mandatory argument CONFIG"
+ local configfile i f
+ configfile=$1
+ local included=$( command sed -ne 's/^[[:blank:]]*[Ii][Nn][Cc][Ll][Uu][Dd][Ee][[:blank:]]\{1,\}\([^#%]*\)\(#.*\)\{0,1\}$/\1/p' "${configfile}" )
+ for i in ${included[@]}; do
+ # Check the origin of $configfile to complete relative included paths on included
+ # files according to ssh_config(5):
+ # "[...] Files without absolute paths are assumed to be in ~/.ssh if included in a user
+ # configuration file or /etc/ssh if included from the system configuration file.[...]"
+ if ! [[ "$i" =~ ^\~.*|^\/.* ]]; then
+ if [[ "$configfile" =~ ^\/etc\/ssh.* ]]; then
+ i="/etc/ssh/$i"
+ else
+ i="$HOME/.ssh/$i"
+ fi
+ fi
+ __expand_tilde_by_ref i
+ # In case the expanded variable contains multiple paths
+ for f in ${i}; do
+ if [ -r $f ]; then
+ config+=( "$f" )
+ # The Included file is processed to look for Included files in itself
+ _included_ssh_config_files $f
+ fi
+ done
+ done
+} # _included_ssh_config_files()
+
# Helper function for completing _known_hosts.
# This function performs host completion based on ssh's config and known_hosts
# files, as well as hostnames reported by avahi-browse if
@@ -1441,6 +1527,11 @@ _known_hosts_real()
done
fi
+ # "Include" keyword in ssh config files
+ for i in "${config[@]}"; do
+ _included_ssh_config_files "$i"
+ done
+
# Known hosts files from configs
if [[ ${#config[@]} -gt 0 ]]; then
local OIFS=$IFS IFS=$'\n' j
@@ -1533,7 +1624,7 @@ _known_hosts_real()
# append any available aliases from config files
if [[ ${#config[@]} -gt 0 && -n "$aliases" ]]; then
- local hosts=$( sed -ne 's/^[ \t]*[Hh][Oo][Ss][Tt]\([Nn][Aa][Mm][Ee]\)\{0,1\}['"$'\t '"']\{1,\}\([^#*?]*\)\(#.*\)\{0,1\}$/\2/p' "${config[@]}" )
+ local hosts=$( command sed -ne 's/^[[:blank:]]*[Hh][Oo][Ss][Tt][[:blank:]]\{1,\}\([^#*?%]*\)\(#.*\)\{0,1\}$/\1/p' "${config[@]}" )
COMPREPLY+=( $( compgen -P "$prefix$user" \
-S "$suffix" -W "$hosts" -- "$cur" ) )
fi
@@ -1548,7 +1639,7 @@ _known_hosts_real()
# time ago, so...
COMPREPLY+=( $( compgen -P "$prefix$user" -S "$suffix" -W \
"$( avahi-browse -cpr _workstation._tcp 2>/dev/null | \
- awk -F';' '/^=/ { print $7 }' | sort -u )" -- "$cur" ) )
+ awk -F';' '/^=/ { print $7 }' | sort -u )" -- "$cur" ) )
fi
# Add hosts reported by ruptime.
@@ -1565,7 +1656,6 @@ _known_hosts_real()
__ltrim_colon_completions "$prefix$user$cur"
- return 0
} # _known_hosts_real()
complete -F _known_hosts traceroute traceroute6 tracepath tracepath6 \
fping fping6 telnet rsh rlogin ftp dig mtr ssh-installkeys showmount
@@ -1586,7 +1676,7 @@ _cd()
# ./ or ../
if [[ -z "${CDPATH:-}" || "$cur" == ?(.)?(.)/* ]]; then
_filedir -d
- return 0
+ return
fi
local -r mark_dirs=$(_rl_enabled mark-directories && echo y)
@@ -1596,7 +1686,7 @@ _cd()
for i in ${CDPATH//:/$'\n'}; do
# create an array of matched subdirs
k="${#COMPREPLY[@]}"
- for j in $( compgen -d $i/$cur ); do
+ for j in $( compgen -d -- $i/$cur ); do
if [[ ( $mark_symdirs && -h $j || $mark_dirs && ! -h $j ) && ! -d ${j#$i/} ]]; then
j+="/"
fi
@@ -1613,12 +1703,12 @@ _cd()
fi
fi
- return 0
+ return
}
if shopt -q cdable_vars; then
- complete -v -F _cd -o nospace cd
+ complete -v -F _cd -o nospace cd pushd
else
- complete -F _cd -o nospace cd
+ complete -F _cd -o nospace cd pushd
fi
# a wrapper method for the next one, when the offset is unknown
@@ -1664,7 +1754,7 @@ _command_offset()
COMP_WORDS[i]=${COMP_WORDS[i+$word_offset]}
done
for (( i; i <= COMP_CWORD; i++ )); do
- unset COMP_WORDS[i]
+ unset 'COMP_WORDS[i]'
done
((COMP_CWORD -= $word_offset))
@@ -1751,49 +1841,49 @@ _longopt()
case "${prev,,}" in
--help|--usage|--version)
- return 0
+ return
;;
--*dir*)
_filedir -d
- return 0
+ return
;;
--*file*|--*path*)
_filedir
- return 0
+ return
;;
--+([-a-z0-9_]))
- local argtype=$( $1 --help 2>&1 | sed -ne \
+ local argtype=$( LC_ALL=C $1 --help 2>&1 | command sed -ne \
"s|.*$prev\[\{0,1\}=[<[]\{0,1\}\([-A-Za-z0-9_]\{1,\}\).*|\1|p" )
case ${argtype,,} in
*dir*)
_filedir -d
- return 0
+ return
;;
*file*|*path*)
_filedir
- return 0
+ return
;;
esac
;;
esac
- $split && return 0
+ $split && return
if [[ "$cur" == -* ]]; then
- COMPREPLY=( $( compgen -W "$( $1 --help 2>&1 | \
- sed -ne 's/.*\(--[-A-Za-z0-9]\{1,\}=\{0,1\}\).*/\1/p' | sort -u )" \
+ COMPREPLY=( $( compgen -W "$( LC_ALL=C $1 --help 2>&1 | \
+ command sed -ne 's/.*\(--[-A-Za-z0-9]\{1,\}=\{0,1\}\).*/\1/p' | sort -u )" \
-- "$cur" ) )
[[ $COMPREPLY == *= ]] && compopt -o nospace
- elif [[ "$1" == @(mk|rm)dir ]]; then
+ elif [[ "$1" == @(@(mk|rm)dir|chroot) ]]; then
_filedir -d
else
_filedir
fi
}
# makeinfo and texi2dvi are defined elsewhere.
-complete -F _longopt a2ps awk base64 bash bc bison cat colordiff cp csplit \
- cut date df diff dir du enscript env expand fmt fold gperf \
- grep grub head indent irb ld ldd less ln ls m4 md5sum mkdir mkfifo mknod \
+complete -F _longopt a2ps awk base64 bash bc bison cat chroot colordiff cp \
+ csplit cut date df diff dir du enscript env expand fmt fold gperf \
+ grep grub head irb ld ldd less ln ls m4 md5sum mkdir mkfifo mknod \
mv netstat nl nm objcopy objdump od paste pr ptx readelf rm rmdir \
sed seq sha{,1,224,256,384,512}sum shar sort split strip sum tac tail tee \
texindex touch tr uname unexpand uniq units vdir wc who
@@ -1804,7 +1894,7 @@ _filedir_xspec()
local cur prev words cword
_init_completion || return
- _tilde "$cur" || return 0
+ _tilde "$cur" || return
local IFS=$'\n' xspec=${_xspecs[${1##*/}]} tmp
local -a toks
@@ -1828,7 +1918,7 @@ _filedir_xspec()
xspec="$matchop($xspec|${xspec^^})"
toks+=( $(
- eval compgen -f -X "!$xspec" -- "\$(quote_readline "\$cur")" | {
+ eval compgen -f -X "'!$xspec'" -- "\$(quote_readline "\$cur")" | {
while read -r tmp; do
[[ -n $tmp ]] && printf '%s\n' $tmp
done
@@ -1852,10 +1942,11 @@ _install_xspec()
}
# bzcmp, bzdiff, bz*grep, bzless, bzmore intentionally not here, see Debian: #455510
_install_xspec '!*.?(t)bz?(2)' bunzip2 bzcat pbunzip2 pbzcat lbunzip2 lbzcat
-_install_xspec '!*.@(zip|[ejsw]ar|exe|pk3|wsz|zargo|xpi|s[tx][cdiw]|sx[gm]|o[dt][tspgfc]|od[bm]|oxt|epub|apk|do[ct][xm]|p[op]t[mx]|xl[st][xm])' unzip zipinfo
+_install_xspec '!*.@(zip|[ejsw]ar|exe|pk3|wsz|zargo|xpi|s[tx][cdiw]|sx[gm]|o[dt][tspgfc]|od[bm]|oxt|epub|apk|ipa|do[ct][xm]|p[op]t[mx]|xl[st][xm]|pyz)' unzip zipinfo
_install_xspec '*.Z' compress znew
# zcmp, zdiff, z*grep, zless, zmore intentionally not here, see Debian: #455510
-_install_xspec '!*.@(Z|[gGd]z|t[ag]z)' gunzip zcat unpigz
+_install_xspec '!*.@(Z|[gGd]z|t[ag]z)' gunzip zcat
+_install_xspec '!*.@(Z|[gGdz]z|t[ag]z)' unpigz
_install_xspec '!*.Z' uncompress
# lzcmp, lzdiff intentionally not here, see Debian: #455510
_install_xspec '!*.@(tlz|lzma)' lzcat lzegrep lzfgrep lzgrep lzless lzmore unlzma
@@ -1863,21 +1954,21 @@ _install_xspec '!*.@(?(t)xz|tlz|lzma)' unxz xzcat
_install_xspec '!*.lrz' lrunzip
_install_xspec '!*.@(gif|jp?(e)g|miff|tif?(f)|pn[gm]|p[bgp]m|bmp|xpm|ico|xwd|tga|pcx)' ee
_install_xspec '!*.@(gif|jp?(e)g|tif?(f)|png|p[bgp]m|bmp|x[bp]m|rle|rgb|pcx|fits|pm|svg)' qiv
-_install_xspec '!*.@(gif|jp?(e)g|tif?(f)|png|p[bgp]m|bmp|x[bp]m|rle|rgb|pcx|fits|pm|?(e)ps)' xv
+_install_xspec '!*.@(gif|jp?(e)g?(2)|j2[ck]|jp[2f]|tif?(f)|png|p[bgp]m|bmp|x[bp]m|rle|rgb|pcx|fits|pm|?(e)ps)' xv
_install_xspec '!*.@(@(?(e)ps|?(E)PS|pdf|PDF)?(.gz|.GZ|.bz2|.BZ2|.Z))' gv ggv kghostview
_install_xspec '!*.@(dvi|DVI)?(.@(gz|Z|bz2))' xdvi kdvi
_install_xspec '!*.dvi' dvips dviselect dvitype dvipdf advi dvipdfm dvipdfmx
_install_xspec '!*.[pf]df' acroread gpdf xpdf
_install_xspec '!*.@(?(e)ps|pdf)' kpdf
_install_xspec '!*.@(okular|@(?(e|x)ps|?(E|X)PS|[pf]df|[PF]DF|dvi|DVI|cb[rz]|CB[RZ]|djv?(u)|DJV?(U)|dvi|DVI|gif|jp?(e)g|miff|tif?(f)|pn[gm]|p[bgp]m|bmp|xpm|ico|xwd|tga|pcx|GIF|JP?(E)G|MIFF|TIF?(F)|PN[GM]|P[BGP]M|BMP|XPM|ICO|XWD|TGA|PCX|epub|EPUB|odt|ODT|fb?(2)|FB?(2)|mobi|MOBI|g3|G3|chm|CHM)?(.?(gz|GZ|bz2|BZ2)))' okular
-_install_xspec '!*.pdf' epdfview
+_install_xspec '!*.pdf' epdfview pdfunite
_install_xspec '!*.@(cb[rz7t]|djv?(u)|?(e)ps|pdf)' zathura
_install_xspec '!*.@(?(e)ps|pdf)' ps2pdf ps2pdf12 ps2pdf13 ps2pdf14 ps2pdfwr
_install_xspec '!*.texi*' makeinfo texi2html
-_install_xspec '!*.@(?(la)tex|texi|dtx|ins|ltx|dbj)' tex latex slitex jadetex pdfjadetex pdftex pdflatex texi2dvi
+_install_xspec '!*.@(?(la)tex|texi|dtx|ins|ltx|dbj)' tex latex slitex jadetex pdfjadetex pdftex pdflatex texi2dvi xetex xelatex luatex lualatex
_install_xspec '!*.mp3' mpg123 mpg321 madplay
-_install_xspec '!*@(.@(mp?(e)g|MP?(E)G|wma|avi|AVI|asf|vob|VOB|bin|dat|divx|DIVX|vcd|ps|pes|fli|flv|FLV|fxm|FXM|viv|rm|ram|yuv|mov|MOV|qt|QT|wmv|mp[234]|MP[234]|m4[pv]|M4[PV]|mkv|MKV|og[gmv]|OG[GMV]|t[ps]|T[PS]|m2t?(s)|M2T?(S)|wav|WAV|flac|FLAC|asx|ASX|mng|MNG|srt|m[eo]d|M[EO]D|s[3t]m|S[3T]M|it|IT|xm|XM)|+([0-9]).@(vdr|VDR))?(.part)' xine aaxine fbxine
-_install_xspec '!*@(.@(mp?(e)g|MP?(E)G|wma|avi|AVI|asf|vob|VOB|bin|dat|divx|DIVX|vcd|ps|pes|fli|flv|FLV|fxm|FXM|viv|rm|ram|yuv|mov|MOV|qt|QT|wmv|mp[234]|MP[234]|m4[pv]|M4[PV]|mkv|MKV|og[gmv]|OG[GMV]|t[ps]|T[PS]|m2t?(s)|M2T?(S)|wav|WAV|flac|FLAC|asx|ASX|mng|MNG|srt|m[eo]d|M[EO]D|s[3t]m|S[3T]M|it|IT|xm|XM|iso|ISO)|+([0-9]).@(vdr|VDR))?(.part)' kaffeine dragon
+_install_xspec '!*@(.@(mp?(e)g|MP?(E)G|wm[av]|WM[AV]|avi|AVI|asf|vob|VOB|bin|dat|divx|DIVX|vcd|ps|pes|fli|flv|FLV|fxm|FXM|viv|rm|ram|yuv|mov|MOV|qt|QT|web[am]|WEB[AM]|mp[234]|MP[234]|m?(p)4[av]|M?(P)4[AV]|mkv|MKV|og[gmv]|OG[GMV]|t[ps]|T[PS]|m2t?(s)|M2T?(S)|mts|MTS|wav|WAV|flac|FLAC|asx|ASX|mng|MNG|srt|m[eo]d|M[EO]D|s[3t]m|S[3T]M|it|IT|xm|XM)|+([0-9]).@(vdr|VDR))?(.part)' xine aaxine fbxine
+_install_xspec '!*@(.@(mp?(e)g|MP?(E)G|wm[av]|WM[AV]|avi|AVI|asf|vob|VOB|bin|dat|divx|DIVX|vcd|ps|pes|fli|flv|FLV|fxm|FXM|viv|rm|ram|yuv|mov|MOV|qt|QT|web[am]|WEB[AM]|mp[234]|MP[234]|m?(p)4[av]|M?(P)4[AV]|mkv|MKV|og[gmv]|OG[GMV]|t[ps]|T[PS]|m2t?(s)|M2T?(S)|mts|MTS|wav|WAV|flac|FLAC|asx|ASX|mng|MNG|srt|m[eo]d|M[EO]D|s[3t]m|S[3T]M|it|IT|xm|XM|iso|ISO)|+([0-9]).@(vdr|VDR))?(.part)' kaffeine dragon
_install_xspec '!*.@(avi|asf|wmv)' aviplay
_install_xspec '!*.@(rm?(j)|ra?(m)|smi?(l))' realplay
_install_xspec '!*.@(mpg|mpeg|avi|mov|qt)' xanim
@@ -1886,12 +1977,13 @@ _install_xspec '!*.@(mp3|ogg|pls|m3u)' gqmpeg freeamp
_install_xspec '!*.fig' xfig
_install_xspec '!*.@(mid?(i)|cmf)' playmidi
_install_xspec '!*.@(mid?(i)|rmi|rcp|[gr]36|g18|mod|xm|it|x3m|s[3t]m|kar)' timidity
-_install_xspec '!*.@(669|abc|am[fs]|d[bs]m|dmf|far|it|mdl|m[eo]d|mid?(i)|mt[2m]|okta|p[st]m|s[3t]m|ult|umx|wav|xm)' modplugplay modplug123
-_install_xspec '*.@(o|so|so.!(conf|*/*)|a|[rs]pm|gif|jp?(e)g|mp3|mp?(e)g|avi|asf|ogg|class)' vi vim gvim rvim view rview rgvim rgview gview emacs xemacs sxemacs kate kwrite
+_install_xspec '!*.@(669|abc|am[fs]|d[bs]m|dmf|far|it|mdl|m[eo]d|mid?(i)|mt[2m]|oct|okt?(a)|p[st]m|s[3t]m|ult|umx|wav|xm)' modplugplay modplug123
+_install_xspec '*.@([ao]|so|so.!(conf|*/*)|[rs]pm|gif|jp?(e)g|mp3|mp?(e)g|avi|asf|ogg|class)' vi vim gvim rvim view rview rgvim rgview gview emacs xemacs sxemacs kate kwrite
_install_xspec '!*.@(zip|z|gz|tgz)' bzme
# konqueror not here on purpose, it's more than a web/html browser
-_install_xspec '!*.@(?([xX]|[sS])[hH][tT][mM]?([lL]))' netscape mozilla lynx galeon dillo elinks amaya firefox mozilla-firefox iceweasel google-chrome chromium-browser epiphany
-_install_xspec '!*.@(sxw|stw|sxg|sgl|doc?([mx])|dot?([mx])|rtf|txt|htm|html|?(f)odt|ott|odm)' oowriter
+_install_xspec '!*.@(?([xX]|[sS])[hH][tT][mM]?([lL]))' netscape mozilla lynx galeon dillo elinks amaya epiphany
+_install_xspec '!*.@(?([xX]|[sS])[hH][tT][mM]?([lL])|[pP][dD][fF])' firefox mozilla-firefox iceweasel google-chrome chromium-browser
+_install_xspec '!*.@(sxw|stw|sxg|sgl|doc?([mx])|dot?([mx])|rtf|txt|htm|html|?(f)odt|ott|odm|pdf)' oowriter
_install_xspec '!*.@(sxi|sti|pps?(x)|ppt?([mx])|pot?([mx])|?(f)odp|otp)' ooimpress
_install_xspec '!*.@(sxc|stc|xls?([bmx])|xlw|xlt?([mx])|[ct]sv|?(f)ods|ots)' oocalc
_install_xspec '!*.@(sxd|std|sda|sdd|?(f)odg|otg)' oodraw
@@ -1906,7 +1998,6 @@ _install_xspec '!*.ly' lilypond ly2dvi
_install_xspec '!*.@(dif?(f)|?(d)patch)?(.@([gx]z|bz2|lzma))' cdiff
_install_xspec '!@(*.@(ks|jks|jceks|p12|pfx|bks|ubr|gkr|cer|crt|cert|p7b|pkipath|pem|p10|csr|crl)|cacerts)' portecle
_install_xspec '!*.@(mp[234c]|og[ag]|@(fl|a)ac|m4[abp]|spx|tta|w?(a)v|wma|aif?(f)|asf|ape)' kid3 kid3-qt
-_install_xspec '!*.py' pyflakes
unset -f _install_xspec
# Minimal completion to use as fallback in _completion_loader.
@@ -1917,23 +2008,47 @@ _minimal()
$split && return
_filedir
}
-# Complete the empty string to allow completion of '>', '>>', and '<'
+# Complete the empty string to allow completion of '>', '>>', and '<' on < 4.3
# http://lists.gnu.org/archive/html/bug-bash/2012-01/msg00045.html
complete -F _minimal ''
+__load_completion()
+{
+ local -a dirs=( ${BASH_COMPLETION_USER_DIR:-${XDG_DATA_HOME:-$HOME/.local/share}/bash-completion}/completions )
+ local OIFS=$IFS IFS=: dir cmd="$1" compfile
+ for dir in ${XDG_DATA_DIRS:-/usr/local/share:/usr/share}; do
+ dirs+=( $dir/bash-completion/completions )
+ done
+ IFS=$OIFS
+
+ if [[ $BASH_SOURCE == */* ]]; then
+ dirs+=( "${BASH_SOURCE%/*}/completions" )
+ else
+ dirs+=( ./completions )
+ fi
+
+ for dir in "${dirs[@]}"; do
+ for compfile in "${cmd##*/}" "${cmd##*/}".bash _"${cmd##*/}"; do
+ compfile="$dir/$compfile"
+ # Avoid trying to source dirs; https://bugzilla.redhat.com/903540
+ [[ -f "$compfile" ]] && . "$compfile" &>/dev/null && return 0
+ done
+ done
+
+ return 1
+}
+
# set up dynamic completion loading
_completion_loader()
{
- local compfile=./completions
- [[ $BASH_SOURCE == */* ]] && compfile="${BASH_SOURCE%/*}/completions"
- compfile+="/${1##*/}"
+ # $1=_EmptycmD_ already for empty cmds in bash 4.3, set to it for earlier
+ local cmd="${1:-_EmptycmD_}"
- # Avoid trying to source dirs; https://bugzilla.redhat.com/903540
- [[ -f "$compfile" ]] && . "$compfile" &>/dev/null && return 124
+ __load_completion "$cmd" && return 124
# Need to define *something*, otherwise there will be no completion at all.
- complete -F _minimal "$1" && return 124
+ complete -F _minimal -- "$cmd" && return 124
} &&
complete -D -F _completion_loader
@@ -1947,31 +2062,31 @@ _xfunc()
local srcfile=$1
shift
declare -F $1 &>/dev/null || {
- local compdir=./completions
- [[ $BASH_SOURCE == */* ]] && compdir="${BASH_SOURCE%/*}/completions"
- . "$compdir/$srcfile"
+ __load_completion "$srcfile"
}
"$@"
}
# source compat completion directory definitions
-if [[ -d $BASH_COMPLETION_COMPAT_DIR && -r $BASH_COMPLETION_COMPAT_DIR && \
- -x $BASH_COMPLETION_COMPAT_DIR ]]; then
- for i in $(LC_ALL=C command ls "$BASH_COMPLETION_COMPAT_DIR"); do
- i=$BASH_COMPLETION_COMPAT_DIR/$i
+compat_dir=${BASH_COMPLETION_COMPAT_DIR:-/etc/bash_completion.d}
+if [[ -d $compat_dir && -r $compat_dir && -x $compat_dir ]]; then
+ for i in "$compat_dir"/*; do
[[ ${i##*/} != @($_backup_glob|Makefile*|$_blacklist_glob) \
&& -f $i && -r $i ]] && . "$i"
done
fi
-unset i _blacklist_glob
+unset compat_dir i _blacklist_glob
# source user completion file
-[[ ${BASH_SOURCE[0]} != ~/.bash_completion && -r ~/.bash_completion ]] \
- && . ~/.bash_completion
+user_completion=${BASH_COMPLETION_USER_FILE:-~/.bash_completion}
+[[ ${BASH_SOURCE[0]} != $user_completion && -r $user_completion ]] \
+ && . $user_completion
+unset user_completion
+
unset -f have
unset have
set $BASH_COMPLETION_ORIGINAL_V_VALUE
unset BASH_COMPLETION_ORIGINAL_V_VALUE
-# ex: ts=4 sw=4 et filetype=sh
+# ex: filetype=sh