Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
[PATCH] completion: add _uids, _gids
- X-seq: zsh-workers 54935
- From: dana <dana@xxxxxxx>
- To: zsh-workers@xxxxxxx
- Subject: [PATCH] completion: add _uids, _gids
- Date: Thu, 09 Jul 2026 21:40:20 -0500
- Archived-at: <https://zsh.org/workers/54935>
- Feedback-id: i9be146f9:Fastmail
- List-id: <zsh-workers.zsh.org>
most tools take either a name or an id for users/groups, but some specifically
need an id. here are functions for that + updates to use them. and a few
related/near-by changes
dana
diff --git a/Completion/Unix/Type/_gids b/Completion/Unix/Type/_gids
new file mode 100644
index 000000000..579fb36a2
--- /dev/null
+++ b/Completion/Unix/Type/_gids
@@ -0,0 +1,21 @@
+#autoload
+
+# see _uids
+
+local -a match mbegin mend gids disp inst cmd=( getent group )
+
+(( $+commands[getent] )) || cmd=( cat /etc/group )
+
+[[ $OSTYPE == darwin* ]] && gids=( ${${(f)"$(
+ _call_program dscl-list dscl . -list /Groups PrimaryGroupID
+)"}/#(#b)([^ ]##)[ ]##(-#<->)*/$match[2]:$match[1]} )
+
+(( $#gids )) || {
+ gids=( ${${(f)"$( _call_program group $cmd )"}:#[[:space:]]#\#*} )
+ gids=( ${gids/#(#b)([^:]##):[^:]##:([^:]##):*/$match[2]:$match[1]} )
+}
+
+disp=( ${gids#*:} )
+inst=( ${gids%%:*} )
+
+_describe -t group-ids 'group ID' disp inst "$@"
diff --git a/Completion/Unix/Type/_uids b/Completion/Unix/Type/_uids
new file mode 100644
index 000000000..b2fdefe68
--- /dev/null
+++ b/Completion/Unix/Type/_uids
@@ -0,0 +1,21 @@
+#autoload
+
+local -a match mbegin mend uids disp inst cmd=( getent passwd )
+
+(( $+commands[getent] )) || cmd=( cat /etc/passwd )
+
+# open directory is the primary source on macos
+[[ $OSTYPE == darwin* ]] && uids=( ${${(f)"$(
+ _call_program dscl-list dscl . -list /Users UniqueID
+)"}/#(#b)([^ ]##)[ ]##(-#<->)*/$match[2]:$match[1]} )
+
+(( $#uids )) || {
+ # most systems allow comments in this file
+ uids=( ${${(f)"$( _call_program passwd $cmd )"}:#[[:space:]]#\#*} )
+ uids=( ${uids/#(#b)([^:]##):[^:]##:([^:]##):*/$match[2]:$match[1]} )
+}
+
+disp=( ${uids#*:} )
+inst=( ${uids%%:*} )
+
+_describe -t user-ids 'user ID' disp inst "$@"
diff --git a/Completion/Darwin/Command/_hdiutil b/Completion/Darwin/Command/_hdiutil
index 20e69cbc5..2f2133d03 100644
--- a/Completion/Darwin/Command/_hdiutil
+++ b/Completion/Darwin/Command/_hdiutil
@@ -247,8 +247,8 @@ _hdiutil(){
Case-sensitive\ APFS\:'APFS (case-sensitive)'
))" \
"-volname[volume name]:name" \
- "-uid[uid of root directory]:uid in number" \
- "-gid[gid of root directory]:gid in number" \
+ "-uid[uid of root directory]: :_uids" \
+ "-gid[gid of root directory]: :_gids" \
"-mode[mode of root directory]:mode" \
"-nouuid[suppress adding a UUID]" \
"(-noautostretch)-autostretch" \
diff --git a/Completion/Linux/Command/_ionice b/Completion/Linux/Command/_ionice
index 9989cd6a9..0b21ce14d 100644
--- a/Completion/Linux/Command/_ionice
+++ b/Completion/Linux/Command/_ionice
@@ -16,9 +16,9 @@ _arguments -C -s -S \
'(- *)'{-V,--version}'[display version information]' \
'(- *)'{-h,--help}'[display help information]' \
+ '(args)' \
- '(H)'{-p-,--pid=-}'[interpret args as process ID]::process id:_pids' \
- '(H)'{-P-,--pgid=-}'[specify process group IDs]::process group:_pgids' \
- '(H)'{-u-,--uid=-}'[act on running process owned by specified users]::user id' && ret=0
+ '(H)'{-p-,--pid=-}'[interpret args as process ID]:: :_pids' \
+ '(H)'{-P-,--pgid=-}'[specify process group IDs]:: :_pgids' \
+ '(H)'{-u-,--uid=-}'[act on running process owned by specified users]:: :_uids' && ret=0
if [[ -n $state ]]; then
if (( $+opt_args[args--p] || $+opt_args[args---pid] )); then
@@ -26,7 +26,7 @@ if [[ -n $state ]]; then
elif (( $+opt_args[args--P] || $+opt_args[args---pgid] )); then
_pgids && ret=0
elif (( $+opt_args[args--u] || $+opt_args[args---uid] )); then
- _message -e uids 'user id'
+ _uids && ret=0
else
_normal -p $service && ret=0
fi
diff --git a/Completion/Linux/Command/_iptables b/Completion/Linux/Command/_iptables
index 2ac13b481..a9bdfc4e0 100644
--- a/Completion/Linux/Command/_iptables
+++ b/Completion/Linux/Command/_iptables
@@ -240,10 +240,10 @@ while
osf) args+=( --genre:string --{ttl,log}:level ) ;;
owner)
args+=(
- '--uid-owner[match packet by user id of creating process]:user id'
- '--gid-owner[match packet by ggroup id of creating process]:group id'
- '--pid-owner[match packet by process id of creating process]:process id:_pids'
- '--sid-owner[match packet by session id of creating process]:session id'
+ '--uid-owner[match packet by user id of creating process]: :_uids'
+ '--gid-owner[match packet by group id of creating process]: :_gids'
+ '--pid-owner[match packet by process id of creating process]: :_pids'
+ '--sid-owner[match packet by session id of creating process]:session id'
--suppl-groups --socket-exists
)
;;
diff --git a/Completion/Linux/Command/_nsenter b/Completion/Linux/Command/_nsenter
index 8e7c6bc42..9299efa7c 100644
--- a/Completion/Linux/Command/_nsenter
+++ b/Completion/Linux/Command/_nsenter
@@ -14,8 +14,8 @@ _arguments -S -s \
'(-C --cgroup)'{-C-,--cgroup=-}'[enter cgroup namespace]::file:_files' \
'(-U --user)'{-U-,--user=-}'[enter user namespace]::file:_files' \
'(-T --time)'{-T-,--time=-}'[enter time namespace]::file:_files' \
- '(-S --setuid)'{-S+,--setuid=}'[set uid in entered namespace]:uid [0]' \
- '(-G --setgid)'{-G+,--setgid=}'[set gid in entered namespace]:gid [0]' \
+ '(-S --setuid)'{-S+,--setuid=}'[set uid in entered namespace]:user ID [0]:_uids' \
+ '(-G --setgid)'{-G+,--setgid=}'[set gid in entered namespace]:group ID [0]:_gids' \
"--preserve-credentials[don't touch uids or gids]" \
'(-r --root)'{-r+,--root=}'[set the root directory]:directory:_directories' \
'(-w --wd)'{-w+,--wd=}'[set the working directory]:directory:_directories' \
@@ -25,4 +25,3 @@ _arguments -S -s \
"${ign}(- 1 *)"{-V,--version}'[display version information]' \
'1: : _command_names -e' \
'*::args :_normal'
-
diff --git a/Completion/Linux/Command/_unshare b/Completion/Linux/Command/_unshare
index ff6f7042f..b0be378b5 100644
--- a/Completion/Linux/Command/_unshare
+++ b/Completion/Linux/Command/_unshare
@@ -30,8 +30,8 @@ _arguments -S -s \
'--keep-caps[retain capabilities granted in user namespaces]' \
'(-R --root)'{-R+,--root=}'[set the root directory]:directory:_directories' \
'(-w --wd)'{-w+,--wd=}'[set the working directory]:directory:_directories' \
- '(-S --setuid)'{-S+,--setuid=}'[set uid in entered namespace]:uid [0]' \
- '(-G --setgid)'{-G+,--setgid=}'[set gid in entered namespace]:gid [0]' \
+ '(-S --setuid)'{-S+,--setuid=}'[set uid in entered namespace]:user ID [0]:_uids' \
+ '(-G --setgid)'{-G+,--setgid=}'[set gid in entered namespace]:group ID [0]:_gids' \
'--monotonic=[set clock monotonic offset in time namespaces]:offset (seconds)' \
'--boottime=[set clock boottime offset in time namespaces]:offset (seconds)' \
"${ign}(- 1 *)"{-h,--help}'[display usage information]' \
diff --git a/Completion/Linux/Type/_fuse_values b/Completion/Linux/Type/_fuse_values
index 211eb5b35..f772b85f0 100644
--- a/Completion/Linux/Type/_fuse_values
+++ b/Completion/Linux/Type/_fuse_values
@@ -37,11 +37,12 @@ fvals=(
'direct_io[use direct I/O]'
'kernel_cache[cache files in kernel]'
'umask[set file permissions]:permission mask (octal)'
- 'uid[set file owner]:user id:'
- 'gid[set file group]:group id:'
- 'entry_timeout[cache timeout for names]:timeout (s)'
- 'negative_timeout[cache timeout for deleted names]:timeout (s)'
- 'attr_timeout[cache timeout for attributes]:timeout (s)'
+ 'uid[set file owner]: :_uids'
+ 'gid[set file group]: :_gids'
+ 'entry_timeout[cache timeout for names]: :_numbers -fu seconds -l0 -d1 timeout'
+ 'negative_timeout[cache timeout for deleted names]: :_numbers -fu seconds -l0 -d0 timeout'
+ 'attr_timeout[cache timeout for attributes]: :_numbers -fu seconds -l0 -d1 timeout'
+ 'ac_attr_timeout[auto_cache timeout for attributes]: :_numbers -fu seconds -l0 timeout'
)
[[ -n $cvalsvar ]] && set -- "$@" ${(P)cvalsvar}
diff --git a/Completion/Solaris/Command/_prstat b/Completion/Solaris/Command/_prstat
index a95919127..a52250ec3 100644
--- a/Completion/Solaris/Command/_prstat
+++ b/Completion/Solaris/Command/_prstat
@@ -27,15 +27,15 @@ _arguments -A "-*" \
'-L[statistics for each light-weight process (LWP)]' \
'-m[microstate process accounting information]' \
'-n[restrict number of output lines]:ntop,[nbottom]' \
- '-p[only processes whose process ID is in the list]:PID list' \
+ '-p[only processes whose process ID is in the list]: :_sequence _pids' \
'-P[only processes or lwps which have most recently executed on a CPU in the list]:CPU list' \
'-R[put prstat in the real time scheduling class]' \
'-s[sort key (descending)]:sort key [cpu]:(($sort_key))' \
'-S[sort key (ascending)]:sort key [cpu]:(($sort_key))' \
'-t[total usage summary for each user]' \
'-T[information about processes and tasks]' \
- '-u[only processes whose effective user ID is in the list]:UID:_users' \
- '-U[only processes whose real user ID is in the list]:UID:_users' \
+ '-u[only processes whose effective user ID is in the list]: :_sequence _users' \
+ '-U[only processes whose real user ID is in the list]: :_sequence _users' \
'-v[verbose process usage]' \
'-z[only processes or LWPs whose zone ID is in the list]:zone ID' \
'-Z[information about processes and zones]'
diff --git a/Completion/Unix/Command/_find b/Completion/Unix/Command/_find
index 2afb46e34..44d684c63 100644
--- a/Completion/Unix/Command/_find
+++ b/Completion/Unix/Command/_find
@@ -64,8 +64,8 @@ case $variant in
freebsd*|dragonfly*|darwin*|gnu)
args+=(
'*-delete'
- '*-gid:numeric group ID'
- '*-uid:numeric user ID'
+ '*-gid: :_gids'
+ '*-uid: :_uids'
'*-noleaf'
'*-lname:link pattern to search'
'*-ilname:link pattern to search (case insensitive)'
diff --git a/Completion/Unix/Command/_genisoimage b/Completion/Unix/Command/_genisoimage
index e0a5f2ab8..5de30235d 100644
--- a/Completion/Unix/Command/_genisoimage
+++ b/Completion/Unix/Command/_genisoimage
@@ -26,7 +26,8 @@ _arguments \
'(-D -disable-deep-relocation)'{-D,-disable-deep-relocation}'[disable deep directory relocation]' \
'-file-mode:mode:' \
'(-f -follow-links)'{-f,-follow-links}'[follow symbolic links]' \
- '-gid:gid:' \
+ '-gid[override GID from source files to specified GID]: :_gids' \
+ '-uid[override UID from source files to specified UID]: :_uids' \
'-graft-points[allow to use graft points for filenames]' \
'-root:dir:_files -/' \
'-old-root:dir:_files -/' \
diff --git a/Completion/Unix/Command/_links b/Completion/Unix/Command/_links
index 495937709..0dddff7f6 100644
--- a/Completion/Unix/Command/_links
+++ b/Completion/Unix/Command/_links
@@ -129,12 +129,12 @@ case $state in
;;
sproxies)
if ! compset -P '*@'; then
- _message -e users 'user id'
+ _users -r@ -S@
return
fi
;&
proxies)
- local suf=-S:
+ local -a suf=( -r: -S: )
if compset -P '*:'; then
_message -e ports 'port number'
else
diff --git a/Completion/Unix/Command/_mount b/Completion/Unix/Command/_mount
index bdabd3791..61c65037f 100644
--- a/Completion/Unix/Command/_mount
+++ b/Completion/Unix/Command/_mount
@@ -339,16 +339,16 @@ if (( ! $+_fs_any )); then
'rootcontext:context:_selinux_contexts -a file_type'
)
_fs_adfs=(
- 'uid[set owner of root]:user ID'
- 'gid[set group of root]:group ID'
+ 'uid[set owner of root]: :_uids'
+ 'gid[set group of root]: :_gids'
'ownmask[permission mask for ADFS "owner" permissions]:mask (octal)'
'othmask[permission mask for ADFS "other" permissions]:mask (octal)'
)
_fs_affs=(
- 'uid[set owner of root]:user ID'
- 'gid[set group of root]:group ID'
- 'setuid[set owner of all files]:user ID'
- 'setgid[set group of all files]:group ID'
+ 'uid[set owner of root]: :_uids'
+ 'gid[set group of root]: :_gids'
+ 'setuid[set owner of all files]: :_uids'
+ 'setgid[set group of all files]: :_gids'
'mode[set file permissions]:file permission bits'
"protect[don't allow changes to permissions]"
'usemp[set owner of root to owner of mount point]'
@@ -360,8 +360,8 @@ if (( ! $+_fs_any )); then
'bs[specify block size]:block size:(512 1024 2048 4192)'
)
_fs_devpts=(
- "uid[set owner of newly created pty's]:user ID"
- "gid[set group of newly created pty's]:group ID"
+ "uid[set owner of newly created pty's]: :_uids"
+ "gid[set group of newly created pty's]: :_gids"
"mode[set mode of newly created pty's]:file permission bits"
)
_fs_ext2=(
@@ -380,16 +380,16 @@ if (( ! $+_fs_any )); then
'nouid32[disable 32-bit UIDs and GIDs]'
'(orlov)oldalloc[use old allocator for new inodes]'
'(oldalloc)orlov[use orlov allocator for new inodes]'
- 'resgid[specify access to reserved space (group ID)]:group ID'
- 'resuid[specify access to reserved space (user ID)]:user ID'
+ 'resgid[specify access to reserved space (group ID)]: :_gids'
+ 'resuid[specify access to reserved space (user ID)]: :_uids'
'sb[specify super block number]:super block number'
'(nouser_xattr)user_xattr[support user extended attributes]'
'(user_xattr)nouser_xattr[do not support user extended attributes]'
)
_fs_fat=(
'blocksize[specify block size]:block size:(512 1024 2048)'
- 'uid[specify user ID of all files]:user ID'
- 'gid[specify group ID of all files]:group ID'
+ 'uid[specify user ID of all files]: :_uids'
+ 'gid[specify group ID of all files]: :_gids'
'umask[specify umask]:umask value (octal)'
'dmask[specify umask for directories only]:umask value (octal)'
'fmask[specify umask for files only]:umask value (octal)'
@@ -443,8 +443,8 @@ if (( ! $+_fs_any )); then
'quiet[do not complain about invalid mount options]'
)
_fs_hpfs=(
- 'uid[specify user ID of all files]:user ID'
- 'gid[specify group ID of all files]:group ID'
+ 'uid[specify user ID of all files]: :_uids'
+ 'gid[specify group ID of all files]: :_gids'
'umask[specify umask]:umask value (octal)'
'case[specify file name conversion]:file name conversion:((lower\:convert\ to\ lower\ case asis\:no\ conversion))'
'conv[specify CR elimination]:CR elimination:((binary\:no\ elimination test\:delete\ CRs\ \(e.g.\ before\ NL\) auto\:sometimes\ yes,\ sometimes\ not))'
@@ -478,8 +478,8 @@ if (( ! $+_fs_any )); then
'(uni_xlate)utf8[use UTF-8 for converting file names]'
'(utf8)uni_xlate[translate unicode to escaped sequences]:type:(0 1 2)'
'posix[distinguish upper and lower case]:state:((0\:off 1\:on))'
- 'uid[specify user ID of all files]:user ID'
- 'gid[specify group ID of all files]:group ID'
+ 'uid[specify user ID of all files]: :_uids'
+ 'gid[specify group ID of all files]: :_gids'
'umask[specify umask]:umask value (octal)'
)
_fs_reiserfs=(
@@ -501,8 +501,8 @@ if (( ! $+_fs_any )); then
'nr_inodes[set number of inodes]:inodes'
)
_fs_udf=(
- 'uid[specify user ID of all files]:user ID'
- 'gid[specify group ID of all files]:group ID'
+ 'uid[specify user ID of all files]: :_uids'
+ 'gid[specify group ID of all files]: :_gids'
'umask[specify umask]:umask value (octal)'
'unhide[show hidden and associated files]'
'undelete[show deleted files]'
@@ -518,14 +518,14 @@ if (( ! $+_fs_any )); then
'onerror[set behaviour on error]:behaviour on error:(panic lock umount repair)'
)
_fs_usbfs=(
- 'devuid[set owner of device files]:user ID'
- 'devgid[set group of device files]:group ID'
+ 'devuid[set owner of device files]: :_uids'
+ 'devgid[set group of device files]: :_gids'
'devmode[set mode of device files]:file permission bits'
- 'busuid[set owner of bus directories]:user ID'
- 'busgid[set group of bus directories]:group ID'
+ 'busuid[set owner of bus directories]: :_uids'
+ 'busgid[set group of bus directories]: :_gids'
'busmode[set mode of bus directories]:file permission bits'
- 'listuid[set owner of file devices]:user ID'
- 'listgid[set group of file devices]:group ID'
+ 'listuid[set owner of file devices]: :_uids'
+ 'listgid[set group of file devices]: :_gids'
'listmode[set mode of file devices]:file permission bits'
)
_fs_xfs=(
diff --git a/Completion/Unix/Command/_user_admin b/Completion/Unix/Command/_user_admin
index d5a53af7c..f5a205168 100644
--- a/Completion/Unix/Command/_user_admin
+++ b/Completion/Unix/Command/_user_admin
@@ -19,7 +19,7 @@ case ${service%???}:${(M)service%???}:$OSTYPE in
'(-D -g --gid)'{-g+,--gid=}'[specify primary group]:initial group:_groups'
'(-D -G --groups)'{-G+,--groups=}'[specify supplementary groups]:supplementary group:_sequence _groups'
'(-D -s --shell)'{-s+,--shell=}"[shell]:shell:( $shells /bin/false )"
- '(-D -u --uid)'{-u+,--uid=}'[specify uid]:uid'
+ '(-D -u --uid)'{-u+,--uid=}'[specify uid]:user ID (must be unique without -o):_uids'
'(-D -o --non-unique)'{-o,--non-unique}'[allow non unique uid]'
)
;|
@@ -135,7 +135,7 @@ case ${service%???}:${(M)service%???}:$OSTYPE in
;|
group:*)
args+=(
- '(-g --gid)'{-g+,--gid=}'[specify gid]:gid'
+ '(-g --gid)'{-g+,--gid=}'[specify gid]:group ID (must be unique without -o):_gids'
'(-o --non-unique)'{-o,--non-unique}'[allow non unique gid]'
)
;|
Messages sorted by:
Reverse Date,
Date,
Thread,
Author