summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@tavianator.com>2021-01-24 11:16:12 -0500
committerTavian Barnes <tavianator@tavianator.com>2021-01-24 11:16:12 -0500
commited59c036124c231c3d8514367d54d3f5901c0aca (patch)
treed91d26fee70492311ce72d4850d05d13d6a3452c
parentb2e7cae06154fd4130a1e98a28d898cc84244073 (diff)
downloadbfs-ed59c036124c231c3d8514367d54d3f5901c0aca.tar.xz
completions/bash: Some improvements
-rw-r--r--completions/bfs.bash533
1 files changed, 342 insertions, 191 deletions
diff --git a/completions/bfs.bash b/completions/bfs.bash
index a890c5f..0896bef 100644
--- a/completions/bfs.bash
+++ b/completions/bfs.bash
@@ -1,194 +1,345 @@
-# bash completion script
-
-_bfs ()
-{
- local cword=$COMP_CWORD
- local cur="${COMP_WORDS[$cword]}"
- local prev prev1
- if (($cword > 0)); then
- prev="${COMP_WORDS[$(($cword-1))]}"
- fi
- if (($cword > 1)); then
- prev1="${COMP_WORDS[$(($cword-2))]}"
- fi
-
- # arguments with a special completion procedure
- local options_special='-exec -execdir -ok -okdir -fprintf -D -S -regextype -fstype -gid -uid -group -user -perm -type -xtype'
-
- # arguments whose values should not be completed
- # (e.g. because they are numeric, glob, regexp, time, etc.)
- local options_nocomp='-maxdepth -mindepth -amin -Bmin -cmin -mmin -asince -Bsince -csince -msince -atime -Btime -ctime -mtime -ilname -iname -ipath -iregex -iwholename -inum -links -lname -name -path -wholename -regex -since -size -used -printf -newerat -newerBt -newerct -newermt -xattrname'
-
- # arguments whose value is a filename
- local options_filecomp='-anewer -Bnewer -cnewer -mnewer -newer -samefile -fls -fprint -fprint0 -neweraa -neweraB -newerac -neweram -newerBa -newerBB -newerBc -newerBm -newerca -newercB -newercc -newercm -newerma -newermB -newermc -newermm -f'
-
- # arguments whose value is a dirname
- local options_dircomp=''
-
- # options with no value
- local flags='-H -L -P -E -X -d -s -x -O1 -O2 -O3 -not -and -or -exclude -color -nocolor -daystart -depth -follow -ignore_readdir_race -noignore_readdir_race -mount -nohidden -status -unique -warn -nowarn -xdev -acl -capable -empty -executable -readable -writable -false -true -hidden -nogroup -nouser -sparse -xattr -delete -rm -exit -ls -print -print0 -printx -prune -quit -version -help'
-
- local all_options="${flags} ${options_special} ${options_nocomp} ${options_filecomp} ${options_dircomp}"
-
- # completions which require parsing the whole command string
- case "${COMP_WORDS[*]}" in
- (*\ -exec\ *|*\ -execdir\ *|*\ -ok\ *|*\ -okdir\ *)
- case "$prev" in
- (-exec|-execdir|-ok|-okdir)
- # complete commands for first word after exec-type option
- COMPREPLY=($(compgen -c -- "$cur"))
- return
- ;;
- esac
- # default completion only after exec-type option
- #TODO: complete whatever command was provided after -exec
- #TODO: detect end of -exec string and continue completing as normal
- COMPREPLY=($(compgen -o default -o bashdefault -- "$cur"))
- return
- ;;
- esac
-
- # completions with 2-word lookbehind
- case "$prev1" in
- (-fprintf)
- # -fprintf FORMAT FILE
- # Like -ls/-print/-print0/-printf, but write to FILE instead of standard
- # output
- # when -fprintf is prev1, current word is FILE; perform file completion
- COMPREPLY=($(compgen -f -- "$cur"))
- return
- ;;
- esac
-
- # completions with 1-word lookbehind
- case "$prev" in
- (-maxdepth|-mindepth|-[aBcm]min|-[aBcm]since|-[aBcm]time|-ilname|-iname|-ipath|-iregex|-iwholename|-inum|-links|-lname|-name|-path|-wholename|-regex|-since|-size|-used|-printf|-newer[aBcm]t|-xattrname)
- # arguments whose values should not be completed
- # (e.g. because they are numeric, glob, regexp, time, etc.)
- COMPREPLY=()
- return
- ;;
- (-[aBcm]newer|-newer|-samefile|-fls|-fprint|-fprint0|-newer[aBcm][aBcm]|-f)
- # arguments whose value is a filename
- #FIXME: -o filenames should suppress spaces and add trailing / to dirnames
- COMPREPLY=($(compgen -o filenames -f -- "$cur"))
- return
- ;;
- # (-f)
- # # arguments whose value is a dirname
- # COMPREPLY=($(compgen -d -- "$cur"))
- # return
- # ;;
- (-type|-xtype)
- # -type [bcdlpfswD]
- # Find files of the given type
- # -xtype [bcdlpfswD]
- # Find files of the given type, following links when -type would not, and
- # vice versa
- if [[ -n $cur ]] && ! [[ $cur =~ ,$ ]]; then
- cur+=,
- fi
- COMPREPLY=("${cur}"{b,c,d,l,p,f,s,w,D})
- return
- ;;
- (-gid|-uid)
- # -gid [-+]N
- # -uid [-+]N
- # Find files owned by group/user ID N
- #TODO: list numeric uids/gids
- COMPREPLY=()
- return
- ;;
- (-group)
- # -group NAME
- # Find files owned by the group NAME
- COMPREPLY=($(compgen -g -- "$cur"))
- return
- ;;
- (-user)
- # -user NAME
- # Find files owned by the user NAME
- COMPREPLY=($(compgen -u -- "$cur"))
- return
- ;;
- (-S)
- # -S bfs|dfs|ids|eds
- # Use breadth-first/depth-first/iterative/exponential deepening search
- # (default: -S bfs)
- COMPREPLY=($(compgen -W 'bfs dfs ids eds' -- "$cur"))
- return
- ;;
- (-D)
- # -D FLAG
- # Turn on a debugging flag (see -D help)
- COMPREPLY=($(compgen -W 'help cost exec opt rates search stat tree all' -- "$cur"))
- return
- ;;
- (-regextype)
- # -regextype TYPE
- # Use TYPE-flavored regexes (default: posix-basic; see -regextype help)
- COMPREPLY=($(compgen -W 'help posix-basic posix-extended' -- "$cur"))
- return
- ;;
- (-fstype)
- # -fstype TYPE
- # Find files on file systems with the given TYPE
- #TODO: parse the mount table for a list of mounted filesystem types
- COMPREPLY=()
- return
- ;;
- (-perm)
- # -perm [-]MODE
- # Find files with a matching mode
- # sample syntax:
- # -perm 777
- # -perm 507
- # -perm u+rw
- # -perm og-rx
- if [[ -z "$cur" ]]; then
- # initial completion
- COMPREPLY=(0 1 2 3 4 5 6 7 u g o)
- return
- elif [[ "$cur" =~ [rwx][rwx][rwx]$ ]] || [[ "$cur" =~ [0-7][0-7][0-7]$ ]]; then
- # final completion (filled in all possible mode bits)
- COMPREPLY=("$cur")
+#!/bin/bash
+
+############################################################################
+# bfs #
+# Copyright (C) 2020 Benjamin Mundt <benMundt@ibm.com> #
+# Copyright (C) 2020 Tavian Barnes <tavianator@tavianator.com> #
+# #
+# Permission to use, copy, modify, and/or distribute this software for any #
+# purpose with or without fee is hereby granted. #
+# #
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES #
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF #
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR #
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES #
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN #
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF #
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #
+############################################################################
+
+# bash completion script for bfs
+
+_bfs() {
+ local cword="$COMP_CWORD"
+ local cur="${COMP_WORDS[cword]}"
+ local prev prev2
+ if ((cword > 0)); then
+ prev="${COMP_WORDS[cword-1]}"
+ fi
+ if ((cword > 1)); then
+ prev2="${COMP_WORDS[cword-2]}"
+ fi
+
+ # Options with a special completion procedure
+ local special=(
+ -D
+ -S
+ -exec
+ -execdir
+ -fprintf
+ -fstype
+ -gid
+ -group
+ -ok
+ -okdir
+ -perm
+ -regextype
+ -type
+ -uid
+ -user
+ -xtype
+ )
+
+ # Options whose values should not be completed
+ # (e.g. because they are numeric, glob, regexp, time, etc.)
+ local nocomp=(
+ -{a,B,c,m}{min,since,time}
+ -ilname
+ -iname
+ -inum
+ -ipath
+ -iregex
+ -iwholename
+ -links
+ -lname
+ -maxdepth
+ -mindepth
+ -name
+ -newer{a,B,c,m}t
+ -path
+ -printf
+ -regex
+ -since
+ -size
+ -used
+ -wholename
+ -xattrname
+ )
+
+ # Options whose value is a filename
+ local filecomp=(
+ -{a,B,c,m}newer
+ -f
+ -fls
+ -fprint
+ -fprint0
+ -newer
+ -newer{a,B,c,m}{a,B,c,m}
+ -samefile
+ )
+
+ local operators=(
+ -a
+ -and
+ -exclude
+ -not
+ -o
+ -or
+ )
+
+ # Flags that take no arguments
+ local nullary_flags=(
+ -E
+ -H
+ -L
+ -O{0,1,2,3,4,fast}
+ -P
+ -X
+ -d
+ -x
+ )
+
+ # Options that take no arguments
+ local nullary_options=(
+ -color
+ -daystart
+ -depth
+ -follow
+ -ignore_readdir_race
+ -maxdepth
+ -mindepth
+ -mount
+ -nocolor
+ -noignore_readdir_race
+ -noleaf
+ -nowarn
+ -status
+ -unique
+ -warn
+ -xdev
+ )
+
+ # Tests that take no arguments
+ local nullary_tests=(
+ -capable
+ -empty
+ -executable
+ -false
+ -hidden
+ -nogroup
+ -nohidden
+ -nouser
+ -readable
+ -sparse
+ -true
+ -writable
+ -xattr
+ -xattrname
+ )
+
+ # Actions that take no arguments
+ local nullary_actions=(
+ --help
+ --version
+ -delete
+ -exit
+ -help
+ -ls
+ -print
+ -print0
+ -printx
+ -prune
+ -quit
+ -rm
+ -version
+ )
+
+ local everything=(
+ "${special[@]}"
+ "${nocomp[@]}"
+ "${filecomp[@]}"
+ "${operators[@]}"
+ "${nullary_flags[@]}"
+ "${nullary_options[@]}"
+ "${nullary_tests[@]}"
+ "${nullary_actions[@]}"
+ )
+
+ # Completing -exec requires matching the whole command line
+ local iscmd isarg word
+ for word in "${COMP_WORDS[@]::cword}"; do
+ case "$word" in
+ -exec|-execdir|-ok|-okdir)
+ iscmd=y
+ ;;
+ \\\;|+)
+ if [[ -n "$iscmd" ]] || [[ -n "$isarg" ]]; then
+ iscmd=
+ isarg=
+ fi
+ ;;
+ *)
+ if [[ -n "$iscmd" ]]; then
+ iscmd=
+ isarg=y
+ fi
+ ;;
+ esac
+ done
+
+ if [[ -n "$iscmd" ]]; then
+ COMPREPLY=($(compgen -c -- "$cur"))
return
- elif [[ "$cur" =~ [0-7]$ ]]; then
- # intermediate completion, octal mode specifier
- COMPREPLY=("$cur"{0,1,2,3,4,5,6,7})
+ elif [[ -n "$isarg" ]]; then
+ COMPREPLY=($(compgen -o default -o bashdefault -W "{} + \\\\;" -- "$cur"))
return
- elif [[ "$cur" =~ ^[ugo]*[+-][rwx]*$ ]]; then
- # intermediate completion, symbolic mode specifier
+ fi
+
+ # Completions with 2-word lookbehind
+ case "$prev2" in
+ -fprintf)
+ # -fprintf FORMAT FILE
+ # Like -ls/-print/-print0/-printf, but write to FILE instead of standard
+ # output
+ # when -fprintf is prev2, current word is FILE; perform file completion
+ COMPREPLY=($(compgen -f -- "$cur"))
+ return
+ ;;
+ esac
+
+ # No completion for numbers, globs, regexes, times, etc.
+ if [[ " ${nocomp[@]} " =~ " $prev " ]]; then
COMPREPLY=()
- [[ "$cur" =~ [rwx]$ ]] && COMPREPLY+=("${cur}")
- [[ "$cur" =~ [+-][wx]*r ]] || COMPREPLY+=("${cur}r")
- [[ "$cur" =~ [+-][rx]*w ]] || COMPREPLY+=("${cur}w")
- [[ "$cur" =~ [+-][rw]*x ]] || COMPREPLY+=("${cur}x")
- return 0
- elif [[ "$cur" =~ ^[ugo] ]]; then
- # intermediate completion, symbolic group specifier
- COMPREPLY=(+ -)
- [[ "$cur" =~ ^[go]*u ]] || COMPREPLY+=("${cur}u")
- [[ "$cur" =~ ^[uo]*g ]] || COMPREPLY+=("${cur}g")
- [[ "$cur" =~ ^[ug]*o ]] || COMPREPLY+=("${cur}o")
- return 0
- fi
- COMPREPLY=()
- return
- ;;
- esac
-
- # completions with no lookbehind
- case "$cur" in
- (-*)
- # complete all options
- COMPREPLY=($(compgen -o default -o bashdefault -W "${all_options}" -- "$cur"))
- return
- ;;
- esac
-
- # default completion
- COMPREPLY=($(compgen -o default -o bashdefault -- "$cur"))
- return
-} &&
- complete -F _bfs bfs
+ return
+ fi
+
+ # Complete filenames
+ if [[ " ${filecomp[@]} " =~ " $prev " ]]; then
+ COMPREPLY=($(compgen -o filenames -f -- "$cur"))
+ return
+ fi
+
+ # Other completions with 1-word lookbehind
+ case "$prev" in
+ -type|-xtype)
+ # -type [bcdlpfswD]
+ # Find files of the given type
+ # -xtype [bcdlpfswD]
+ # Find files of the given type, following links when -type would not, and
+ # vice versa
+ COMPREPLY=()
+ if [[ -n $cur ]] && ! [[ $cur =~ ,$ ]]; then
+ COMPREPLY+=("$cur")
+ cur+=,
+ fi
+ COMPREPLY+=("$cur"{b,c,d,l,p,f,s,w,D})
+ return
+ ;;
+ -gid|-uid)
+ # -gid [-+]N
+ # -uid [-+]N
+ # Find files owned by group/user ID N
+ # TODO: list numeric uids/gids
+ COMPREPLY=()
+ return
+ ;;
+ -group)
+ # -group NAME
+ # Find files owned by the group NAME
+ COMPREPLY=($(compgen -g -- "$cur"))
+ return
+ ;;
+ -user)
+ # -user NAME
+ # Find files owned by the user NAME
+ COMPREPLY=($(compgen -u -- "$cur"))
+ return
+ ;;
+ -S)
+ # -S bfs|dfs|ids|eds
+ # Use breadth-first/depth-first/iterative/exponential deepening search
+ # (default: -S bfs)
+ COMPREPLY=($(compgen -W 'bfs dfs ids eds' -- "$cur"))
+ return
+ ;;
+ -D)
+ # -D FLAG
+ # Turn on a debugging flag (see -D help)
+ COMPREPLY=($(compgen -W 'help cost exec opt rates search stat tree all' -- "$cur"))
+ return
+ ;;
+ -regextype)
+ # -regextype TYPE
+ # Use TYPE-flavored regexes (default: posix-basic; see -regextype help)
+ COMPREPLY=($(compgen -W 'help posix-basic posix-extended' -- "$cur"))
+ return
+ ;;
+ -fstype)
+ # -fstype TYPE
+ # Find files on file systems with the given TYPE
+ #TODO: parse the mount table for a list of mounted filesystem types
+ COMPREPLY=()
+ return
+ ;;
+ (-perm)
+ # -perm [-]MODE
+ # Find files with a matching mode
+ # sample syntax:
+ # -perm 777
+ # -perm 507
+ # -perm u+rw
+ # -perm og-rx
+ if [[ -z "$cur" ]]; then
+ # initial completion
+ COMPREPLY=(0 1 2 3 4 5 6 7 u g o)
+ return
+ elif [[ "$cur" =~ [rwx][rwx][rwx]$ ]] || [[ "$cur" =~ [0-7][0-7][0-7]$ ]]; then
+ # final completion (filled in all possible mode bits)
+ COMPREPLY=("$cur")
+ return
+ elif [[ "$cur" =~ [0-7]$ ]]; then
+ # intermediate completion, octal mode specifier
+ COMPREPLY=("$cur"{0,1,2,3,4,5,6,7})
+ return
+ elif [[ "$cur" =~ ^[ugo]*[+-][rwx]*$ ]]; then
+ # intermediate completion, symbolic mode specifier
+ COMPREPLY=()
+ [[ "$cur" =~ [rwx]$ ]] && COMPREPLY+=("${cur}")
+ [[ "$cur" =~ [+-][wx]*r ]] || COMPREPLY+=("${cur}r")
+ [[ "$cur" =~ [+-][rx]*w ]] || COMPREPLY+=("${cur}w")
+ [[ "$cur" =~ [+-][rw]*x ]] || COMPREPLY+=("${cur}x")
+ return 0
+ elif [[ "$cur" =~ ^[ugo] ]]; then
+ # intermediate completion, symbolic group specifier
+ COMPREPLY=(+ -)
+ [[ "$cur" =~ ^[go]*u ]] || COMPREPLY+=("${cur}u")
+ [[ "$cur" =~ ^[uo]*g ]] || COMPREPLY+=("${cur}g")
+ [[ "$cur" =~ ^[ug]*o ]] || COMPREPLY+=("${cur}o")
+ return 0
+ fi
+ COMPREPLY=()
+ return
+ ;;
+ esac
+
+ # Completions with no lookbehind
+ if [[ "$cur" == -* ]]; then
+ # complete all options
+ COMPREPLY=($(compgen -o default -o bashdefault -W "${everything[*]}" -- "$cur"))
+ return
+ fi
+
+ # default completion
+ COMPREPLY=($(compgen -o default -o bashdefault -f -W "${everything[*]} ! ," -- "$cur"))
+ return
+} && complete -F _bfs bfs