summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog6
-rw-r--r--Completion/BSD/Command/_chflags66
-rw-r--r--Completion/BSD/Type/_flags70
-rw-r--r--Completion/Unix/Command/_chmod25
-rw-r--r--Completion/Unix/Command/_find2
-rw-r--r--Completion/Unix/Command/_mkdir2
-rw-r--r--Completion/Unix/Type/_modes37
7 files changed, 119 insertions, 89 deletions
diff --git a/ChangeLog b/ChangeLog
index e5ee40b30..911218299 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
2018-01-03 Oliver Kiddle <okiddle@yahoo.co.uk>
+ * dana: 42210: Completion/BSD/Command/_chflags,
+ Completion/BSD/Type/_flags, Completion/Unix/Command/_chmod,
+ Completion/Unix/Command/_find, Completion/Unix/Command/_mkdir,
+ Completion/Unix/Type/_modes: factor out completion of file
+ modes and flags and handle _comp_priv_prefix for chflags
+
* dana: 42209: Completion/Unix/Command/_unexpand: take account
of numeric options such as -4 instead of -t4
diff --git a/Completion/BSD/Command/_chflags b/Completion/BSD/Command/_chflags
index ddf61b25e..f97d1cdd1 100644
--- a/Completion/BSD/Command/_chflags
+++ b/Completion/BSD/Command/_chflags
@@ -1,68 +1,8 @@
#compdef chflags
-local args flag_descs flags own='-g *(-u$EUID)'
+local args own='-g *(-u$EUID)'
-flag_descs=(
- uappnd 'user append-only'
- uchg 'user immutable'
-)
-
-if (( ! EUID )); then
- flag_descs+=(
- arch archived
- nodump nodump
- sappnd 'system append-only'
- schg 'system immutable'
- )
- unset own
-fi
-
-if [[ $OSTYPE = (darwin|dragonfly|freebsd|netbsd)* ]]; then
- flag_descs+=(opaque opaque)
-
- if [[ $OSTYPE = darwin* ]]; then
- flag_descs+=(hidden hidden)
- fi
-
- if [[ $OSTYPE = (dragonfly|freebsd)* ]]; then
- flag_descs+=(uunlnk 'user undeletable')
- (( EUID )) || flag_descs+=(sunlnk 'system undeletable')
- fi
-
- [[ $OSTYPE = dragonflybsd* ]] && {
- flag_descs+=(
- cache XXX
- nouhistory 'user nohistory'
- )
-
- (( EUID )) || flag_descs+=(
- noscache XXX
- noshistory 'system nohistory'
- )
- }
-
- [[ $OSTYPE = freebsd* ]] && flag_descs+=(
- uarch archive
- uhidden hidden
- uoffline offline
- urdonly 'DOS, Windows and CIFS readonly'
- ureparse 'Windows reparse point'
- usparse 'sparse file'
- usystem 'DOS, Windows and CIFS system'
- )
-fi
-
-() {
- for 1 2; do
- if [[ $1 = no* ]]; then
- flags+=("(${1#no})$1[set the $2 flag]"
- "($1)${1#no}[unset the $2 flag]")
- else
- flags+=("(no$1)$1[set the $2 flag]"
- "($1)no$1[unset the $2 flag]")
- fi
- done
-} $flag_descs
+(( ! EUID || $+_comp_priv_prefix )) && own=
if [[ $OSTYPE = (darwin|dragonfly|freebsd)* ]]; then
args=(
@@ -72,7 +12,7 @@ if [[ $OSTYPE = (darwin|dragonfly|freebsd)* ]]; then
fi
_arguments -s -A "-*" : $args \
- ':file flag:_values -s , "file flags" $flags[@]' \
+ ': :_flags' \
'*:file:_files "$own"' \
- opth \
'-h[act on symlinks]' \
diff --git a/Completion/BSD/Type/_flags b/Completion/BSD/Type/_flags
new file mode 100644
index 000000000..95044121c
--- /dev/null
+++ b/Completion/BSD/Type/_flags
@@ -0,0 +1,70 @@
+#autoload
+
+# Provides completion for file flags (formerly part of _chflags)
+
+local curcontext=$curcontext su=$(( ! EUID || $+_comp_priv_prefix ))
+local -a context line state state_descr copts=( "${@}" ) flags flag_descs
+local -A val_args
+
+flag_descs+=(
+ uappnd 'user append-only'
+ uchg 'user immutable'
+)
+
+if (( su )); then
+ flag_descs+=(
+ arch archived
+ nodump nodump
+ sappnd 'system append-only'
+ schg 'system immutable'
+ )
+fi
+
+if [[ $OSTYPE = (darwin|dragonfly|freebsd|netbsd)* ]]; then
+ flag_descs+=(opaque opaque)
+
+ if [[ $OSTYPE = darwin* ]]; then
+ flag_descs+=(hidden hidden)
+ fi
+
+ if [[ $OSTYPE = (dragonfly|freebsd)* ]]; then
+ flag_descs+=(uunlnk 'user undeletable')
+
+ (( su )) &&
+ flag_descs+=(sunlnk 'system undeletable')
+ fi
+
+ if [[ $OSTYPE = dragonfly* ]]; then
+ flag_descs+=(
+ cache XXX
+ nouhistory 'user nohistory'
+ )
+
+ (( su )) && flag_descs+=(
+ noscache XXX
+ noshistory 'system nohistory'
+ )
+ fi
+
+ [[ $OSTYPE = freebsd* ]] && flag_descs+=(
+ uarch archive
+ uhidden hidden
+ uoffline offline
+ urdonly 'DOS, Windows and CIFS readonly'
+ ureparse 'Windows reparse point'
+ usparse 'sparse file'
+ usystem 'DOS, Windows and CIFS system'
+ )
+fi
+
+for 1 2 in $flag_descs; do
+ if [[ $1 = no* ]]; then
+ flags+=("(${1#no})$1[set the $2 flag]"
+ "($1)${1#no}[unset the $2 flag]")
+ else
+ flags+=("(no$1)$1[set the $2 flag]"
+ "($1)no$1[unset the $2 flag]")
+ fi
+done
+
+_values -O copts -s , 'file flags' $flags
diff --git a/Completion/Unix/Command/_chmod b/Completion/Unix/Command/_chmod
index 85e6df1ae..80c6f33ca 100644
--- a/Completion/Unix/Command/_chmod
+++ b/Completion/Unix/Command/_chmod
@@ -3,7 +3,7 @@
local curcontext="$curcontext" state line expl ret=1
local -a args privs
-args=( '*:file:->files' '1:mode:->mode' )
+args=( '*: :->files' '1: :_modes' )
if _pick_variant gnu=Free\ Soft unix --version; then
args+=(
@@ -45,35 +45,12 @@ else
'(1)-I[removes all inherited entries from named files ACLs]'
)
;;
- solaris*) privs=( 'l[mandatory locking]' ) ;;
esac
fi
_arguments -C -s "$args[@]" && ret=0
case "$state" in
- mode)
- compset -P \*,
- compset -S ,\*
- if [[ -prefix [0-7] ]]; then
- _message -e number 'numeric mode'
- elif compset -P '[a-z]#[+-=]'; then
- _values -S '' privilege \
- 'r[read]' 'w[write]' 'x[execute]' \
- 's[set uid/gid]' 't[sticky]' \
- 'X[execute only if directory or executable to another]' \
- "u[owner's current permissions]" \
- "g[group's current permissions]" \
- "o[other's current permissions]" \
- "$privs[@]" && ret=0
- else
- suf=( -S '' )
- compset -P '*'
- _alternative -O suf \
- 'who:who:((u\:user g\:group a\:all o\:others))' \
- 'operators:operator:(+ - =)' && ret=0
- fi
- ;;
files)
if [[ -n $opt_args[--reference] ]]; then
zmodload -F zsh/stat b:zstat 2>/dev/null
diff --git a/Completion/Unix/Command/_find b/Completion/Unix/Command/_find
index 3854d6cce..2bfb89825 100644
--- a/Completion/Unix/Command/_find
+++ b/Completion/Unix/Command/_find
@@ -139,7 +139,7 @@ _arguments -C $args \
'*-nogroup' \
'*-nouser' \
'*-ok:program: _command_names -e:*\;::program arguments: _normal' \
- '*-perm:file permission bits' \
+ '*-perm: :_modes' \
'*-print' \
'*-prune' \
'*-size:file size (blocks)' \
diff --git a/Completion/Unix/Command/_mkdir b/Completion/Unix/Command/_mkdir
index 2850b405d..830a96162 100644
--- a/Completion/Unix/Command/_mkdir
+++ b/Completion/Unix/Command/_mkdir
@@ -4,7 +4,7 @@ local curcontext="$curcontext" state line expl args variant ret=1
typeset -A opt_args
args=(
- '(-m --mode)'{-m,--mode=}'[set permission mode]:numeric mode'
+ '(-m --mode)'{-m,--mode=}'[set permission mode]: :_modes'
'(-p --parents)'{-p,--parents}'[make parent directories as needed]'
'(-)*: :->directories'
)
diff --git a/Completion/Unix/Type/_modes b/Completion/Unix/Type/_modes
new file mode 100644
index 000000000..fbe4c9363
--- /dev/null
+++ b/Completion/Unix/Type/_modes
@@ -0,0 +1,37 @@
+#autoload
+
+# Provides completion for file modes (formerly part of _chmod)
+
+local curcontext=$curcontext
+local -a context line state state_descr copts=( "${@}" ) privs
+local -A val_args
+
+privs=(
+ 'r[read]' 'w[write]' 'x[execute]'
+ 's[set uid/gid]' 't[sticky]'
+ 'X[execute only if directory or executable to another]'
+ "u[owner's current permissions]"
+ "g[group's current permissions]"
+ "o[others' current permissions]"
+)
+
+[[ $OSTYPE == solaris* ]] &&
+privs+=( 'l[mandatory locking]' )
+
+compset -P '*,'
+compset -S ',*'
+
+if [[ -prefix [0-7] ]]; then
+ _message -e number 'numeric mode'
+elif compset -P '[a-z]#[+-=]'; then
+ _values -O copts -S '' privilege $privs && return 0
+else
+ compset -P '*'
+ copts=( -S '' )
+ _alternative -O copts \
+ 'who:who:((a\:all u\:owner g\:group o\:others))' \
+ 'operators:operator:(+ - =)' \
+ && return 0
+fi
+
+return 1