aboutsummaryrefslogtreecommitdiff
path: root/bash/bash_completion.d/man.bash
diff options
context:
space:
mode:
Diffstat (limited to 'bash/bash_completion.d/man.bash')
-rw-r--r--bash/bash_completion.d/man.bash101
1 files changed, 55 insertions, 46 deletions
diff --git a/bash/bash_completion.d/man.bash b/bash/bash_completion.d/man.bash
index ffef48ec..274f663a 100644
--- a/bash/bash_completion.d/man.bash
+++ b/bash/bash_completion.d/man.bash
@@ -1,43 +1,32 @@
# Autocompletion for man(1)
_man() {
- # Don't even bother if we don't have manpath(1)
- hash manpath 2>/dev/null || return
-
- # Snarf the word
- local word
- word=${COMP_WORDS[COMP_CWORD]}
-
- # Don't bother if the word has slashes in it, the user is probably trying
- # to complete an actual path
- case $word in
+ # Don't interfere with a user typing a path
+ case $2 in
*/*) return 1 ;;
esac
- # If this is the second word, and the previous word started with a number,
- # we'll assume that's the section to search
- local section subdir
- if ((COMP_CWORD > 1)) ; then
- case ${COMP_WORDS[COMP_CWORD-1]} in
- [0-9]*)
- section=${COMP_WORDS[COMP_CWORD-1]}
- subdir=man${section%%[^0-9]*}
- ;;
- esac
- fi
+ # If previous word started with a number, we'll assume that's a section to
+ # search
+ case $3 in
+ [0-9]*) sec=$3 ;;
+ esac
+
+ # Cut completion short if we have neither section nor word; there will
+ # probably be too many results
+ [[ -n $sec ]] || [[ -n $2 ]] || return
# Read completion results from a subshell and add them to the COMPREPLY
# array individually
- local page
- while IFS= read -rd '' page ; do
- [[ -n $page ]] || continue
- COMPREPLY[${#COMPREPLY[@]}]=$page
+ local ci comp
+ while IFS= read -d '' -r comp ; do
+ COMPREPLY[ci++]=$comp
done < <(
# Do not return dotfiles, give us extended globbing, and expand empty
# globs to just nothing
shopt -u dotglob
- shopt -s extglob nullglob
+ shopt -s nullglob
# Make globbing case-insensitive if appropriate
while read -r _ setting ; do
@@ -49,34 +38,54 @@ _man() {
esac
done < <(bind -v)
- # Break manpath(1) output into an array of paths
- declare -a manpaths
- IFS=: read -a manpaths -r < <(manpath 2>/dev/null)
-
- # Iterate through the manual page paths and add every manual page we find
- declare -a pages
- for manpath in "${manpaths[@]}" ; do
- [[ -n $manpath ]] || continue
- if [[ -n $section ]] ; then
- for page in \
- "$manpath"/"$subdir"/"$word"*."$section"?(.[glx]z|.bz2|.lzma|.Z)
- do
- pages[${#pages[@]}]=$page
+ # Figure out the manual paths to search
+ if hash amanpath 2>/dev/null ; then
+
+ # manpath(1) exists, run it to find what to search
+ IFS=: read -a manpaths -r \
+ < <(manpath 2>/dev/null)
+ else
+
+ # Fall back on some typical paths
+ manpaths=( \
+ "$HOME"/.local/man \
+ "$HOME"/.local/share/man \
+ /usr/man \
+ /usr/share/man \
+ /usr/local/man \
+ /usr/local/share/man \
+ )
+ fi
+
+ # Add pages from each manual directory
+ local pages pi
+ for mp in "${manpaths[@]}" ; do
+ [[ -n $mp ]] || continue
+
+ # Which pattern? Depends on section specification
+ if [[ -n $sec ]] ; then
+
+ # Section requested; quoted value in glob
+ for page in "$mp"/man"${sec%%[!0-9]*}"/"$2"*."$sec"* ; do
+ pages[pi++]=${page##*/}
done
else
- for page in "$manpath"/man[0-9]*/"$word"*.* ; do
- pages[${#pages[@]}]=$page
+
+ # No section;
+ for page in "$mp"/man[0-9]*/"$2"*.[0-9]* ; do
+ pages[pi++]=${page##*/}
done
fi
done
- # Strip paths, .gz suffixes, and finally .<section> suffixes
- pages=("${pages[@]##*/}")
- pages=("${pages[@]%.@([glx]z|bz2|lzma|Z)}")
+ # Bail if there are no pages
+ ((pi)) || exit
+
+ # Strip section suffixes
pages=("${pages[@]%.[0-9]*}")
- # Print quoted entries, null-delimited
- printf '%q\0' "${pages[@]}"
+ # Print entries, null-delimited
+ printf '%s\0' "${pages[@]}"
)
}
complete -F _man -o bashdefault -o default man