From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 29457 invoked by alias); 28 Jun 2018 01:39:11 -0000 Mailing-List: contact zsh-workers-help@zsh.org; run by ezmlm Precedence: bulk X-No-Archive: yes List-Id: Zsh Workers List List-Post: List-Help: List-Unsubscribe: X-Seq: 43104 Received: (qmail 11505 invoked by uid 1010); 28 Jun 2018 01:39:11 -0000 X-Qmail-Scanner-Diagnostics: from mail-io0-f195.google.com by f.primenet.com.au (envelope-from , uid 7791) with qmail-scanner-2.11 (clamdscan: 0.99.2/21882. spamassassin: 3.4.1. Clear:RC:0(209.85.223.195):SA:0(-1.9/5.0):. Processed in 2.036578 secs); 28 Jun 2018 01:39:11 -0000 X-Spam-Checker-Version: SpamAssassin 3.4.1 (2015-04-28) on f.primenet.com.au X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2,SPF_PASS,T_DKIMWL_WL_MED,T_DKIM_INVALID autolearn=ham autolearn_force=no version=3.4.1 X-Envelope-From: dana@dana.is X-Qmail-Scanner-Mime-Attachments: | X-Qmail-Scanner-Zip-Files: | DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=dana-is.20150623.gappssmtp.com; s=20150623; h=from:content-transfer-encoding:mime-version:subject:message-id:date :to; bh=rft7poca5T2JsWtgFEWX5FtwprwNWtZ0n4O5a2jyXw8=; b=Ygvmcfd/33Jqf1p/3vQl8w3k1x6dcnf8atifVabFo1G/2XtheL8wX4vNgtu0wbxMjN TBk059kPCa+AHazlOSzjuAgpxEBbMHyXsVjMJxGbwA8qOP8KuOEMX24n7XLkfBHWRTH3 mDV0AbNU6Z8V3k8pVLeq6FxGH7lY/OYGmv2I4pENvM2N52epNR8LoWxj6a+NR1khB4Yq YEBabsfGvcTfIHtEOkQRpsmYspUidx1RJGsdV/q0izjg0JBMd/8Vk+aLHnR34GNpHTiE 7ybcQTaz+ZB7WT4TJPzWButIn9DItstYS0fyIYGtB7v2EtxhVIarPZSpM9Q5NXU3Mw6g OJzQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:content-transfer-encoding:mime-version :subject:message-id:date:to; bh=rft7poca5T2JsWtgFEWX5FtwprwNWtZ0n4O5a2jyXw8=; b=DeewSrdifwdcp2HweGDuy/M+ec9KQ8hPsELoiZEvUdcGhnlAT2f9qo71r1VTDOwo7a gRxDsCdm/gU8DmEeYVG6UjX8NlQjtXcoeveajiWFPAix7aB5GZkr+DHHY2XGhsCaWOJr hC1RQ2inhAL7p/dxkYXVLg49gLOptajiq4BLMMHS9yOcak7MR/6wcN+7T9YOmYmeo9gP aPtsORyp8tMNgR46sjFTyAiz/H9IM+SSt/8ElMjx0PyjGt7q/wHrq5fzS9AT0StkaFD5 1hAZDPg6tfl7bpgc+fjWcXWLf+zziMAWEqErchsUrKCjwkQ9a7iOIgB8h4GfcZkNThaX cl9Q== X-Gm-Message-State: APt69E0Bsy4+rUf3DaqDyFUw7A8MBjxoHYtiQJd+vXVS292GM4XZWCmk nbtGIUvKr19XcMA7JhtN+Cjs6tNh0UA= X-Google-Smtp-Source: AAOMgpfjgvkoo65v5xN+NDvJ/j8PbdoDc3Wlq1Tt3NwBNcDzz13AZ9Srnjg+LpYsswQrxyhxTfqlIg== X-Received: by 2002:a6b:2353:: with SMTP id j80-v6mr6321780ioj.99.1530149946310; Wed, 27 Jun 2018 18:39:06 -0700 (PDT) From: dana Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Mime-Version: 1.0 (Mac OS X Mail 11.3 \(3445.6.18\)) Subject: [PATCH] Completion: Improve _pgrep Message-Id: Date: Wed, 27 Jun 2018 20:39:04 -0500 To: Zsh workers X-Mailer: Apple Mail (2.3445.6.18) Some pgrep/pkill improvements i'd had sitting for a while: * Add full support for procps/-ng (Linux) * Support Dragonfly as with FreeBSD * Add one or two options missing from other variants (like -l) * Use -o+ form for options accepting arguments * Improve option exclusivity in a few places * Improve descriptions in several places * Don't complete shell-specific signals (hopefully there aren't any = systems out there that actually have a SIGEXIT or SIGDEBUG) * Account for numeric signals and symbolic ones prefixed by 'SIG', so = that e.g. `kill -9 -` doesn't still offer -KILL * On non-Linux systems, only complete signals as the first argument (let = me know if there's a better way than how i did this) I also alphabetised the option specs. Sorry if that makes an extra mess = of the diff, but i had a really hard time keeping track of which ones were = accounted for when they were all randomly ordered. :/ dana diff --git a/Completion/Unix/Command/_pgrep = b/Completion/Unix/Command/_pgrep index ec3f8bfd0..c4db2b73f 100644 --- a/Completion/Unix/Command/_pgrep +++ b/Completion/Unix/Command/_pgrep @@ -1,75 +1,138 @@ #compdef pgrep pkill =20 -local curcontext=3D"$curcontext" state line ret=3D1 expl +# Notes: +# - We assume that Linux systems use procps-ng =E2=80=94 specifically, = procps-ng >=3D3.3.4 +# (which changed the behaviour of -f and added -a) +# - The (s) exclusion group is used here to account for the fact that a = signal +# given to pkill must be the first argument on non-Linux platforms. = The (ss) +# exclusion group is used on Linux to keep the other signal options = exclusive +# with --signal +# - We don't really need to keep pgopts and pkopts separate, but it = seems like +# it should make things a bit easier to follow +# - @todo We could complete log-in classes given to -c +# - @todo We could complete routing tables given to -T + +local curcontext=3D"$curcontext" state line ret=3D1 expl pgopts pkopts = i typeset -A opt_args -typeset -a arguments - -arguments=3D('-P[parent process id]:parent process id:->ppid' - '-F[match only in process in pidfile]:files:_files' - '-g[match only in process group ids]:group:->pgid' - '-G[match only real group id]:group:_groups' - '-j[match only in processes inside jails]:jail id:_sequence _jails = -0 -o jid' - '-J[match only in project ids]:project id:->projid' - '-M[extract the name list from the specified core]:files:_files' - '-N[extract the name list from the specified system]:files:_files' - '-s[match only session id]:session id:->sid' - '-t[match only controlled by terminal]:terminal device:_sequence = _ttys -d' - '-T[match only in processes specified routing table in rtable]' - '-u[match only effective user id]:user:_users' - '-U[match only real user id]:user:_users' - '(-n)-o[oldest process]' - '(-o)-n[newest process]' - '-a[include process ancestors in the match list]' - '-c[print a count of matching processes]' - '-f[match against full command line]' - '-i[ignore case distinctions]' - '-I[confirmation before attempting to single each process]' - '-L[given pidfile must be locked]' - '-q[do not write anything to standard output]' - '-S[search also in system processes]' - '-v[negate matching]' - '-w[show thread ids instead of pids]' - '-x[match exactly]' - '-z[match only in zones]:zone:_zones') - -if [[ $service =3D=3D 'pgrep' ]]; then - arguments+=3D('-d[output delimiter]:delimiter:compadd ${(s\:\:)IFS}' - '-l[list name in addition to id]') -fi - -local optchars -case "$OSTYPE" in +typeset -a arguments sig_arguments aopts + +# These arguments (a) are common to all variants (like -x), (b) are the = most +# common amongst all variants (like -a), or (c) have a single = unambiguous +# meaning amongst all variants (like --help). Many of them are filtered = out or +# overridden below +arguments=3D( + '(s)-a[include process ancestors in match list]' + '(s)-c+[match only on specified login class]:login class' + '(s -F --pidfile)'{-F+,--pidfile=3D}'[match only processes in = specified PID file]:PID file:_files' + '(s -f --full)'{-f,--full}'[match against full command line]' + '(s -G --group)'{-G+,--group=3D}'[match only on specified real group = IDs]: :_sequence _groups' + '(s -g --pgroup)'{-g+,--pgroup=3D}'[match only on specified process = group IDs]: :->pgid' + '(s : * -)'{-h,--help}'[display help information]' + '(s)-I[request confirmation before signalling each process]' + '(s)-i[ignore case distinctions]' + '(s)-J+[match only on specified project IDs]: :->projid' + '(s)-j+[match only on specified jail IDs]:jail:_sequence _jails -0 -o = jid' + '(s -L --logpidfile)'{-L,--logpidfile}'[fail if PID file not locked = (with -F)]' + '(s)-M+[extract name list from specified core]:core file:_files' + '(s)-N+[extract name list from specified system]:system file:_files' + '(s -o -n --oldest --newest)'{-n,--newest}'[match newest process]' + '(s -o -n --oldest --newest)'{-o,--oldest}'[match oldest process]' + '(s -P --parent)'{-P+,--parent=3D}'[match only on specified parent = process IDs]: :->ppid' + '(s -l)-q[suppress normal output]' + '(s)-S[search also in system processes (kernel threads)]' + '(s -s --session)'{-s+,--session=3D}'[match only on specified process = session IDs]: :->sid' + '(ss)--signal=3D[specify signal to send to = process]:signal:(${signals\:#(EXIT|ZERR|DEBUG)})' + '(s)-T+[match only on specified routing table]:routing table' + '(s -t --terminal)'{-t+,--terminal=3D}'[match only on specified = controlling terminals]:terminal device:_sequence _ttys -d' + '(s -U --uid)'{-U+,--uid=3D}'[match only on specified real user IDs]: = :_sequence _users' + '(s -u --euid)'{-u+,--euid=3D}'[match only on specified effective = user IDs]: :_sequence _users' + '(s -v --inverse)'{-v,--inverse}'[negate matching]' + '(s -x --exact)'{-x,--exact}'[match process name or command line = (with -f) exactly]' + '(s)--ns=3D[match only on same namespaces as specified PID]: :_pids' + '(s)--nslist=3D[match only on specified namespaces (with = --ns)]:namespace:(ipc mnt net pid user uts)' + '(s : * -)'{-V,--version}'[display version information]' + '(s)-z+[match only on specified zone IDs]:zone:_sequence _zones' +) +[[ $service =3D=3D pgrep ]] && arguments+=3D( + '(s -d --delimiter)'{-d+,--delimiter=3D}'[specify output = delimiter]:delimiter:compadd ${(s<>)IFS}' + '(s -q)-l[display process name (and arguments with -f)]' + '(s -w --lightweight)'{-w,--lightweight}'[show all thread IDs instead = of PID]' +) +[[ $service =3D=3D pkill ]] && arguments+=3D( + '(s -e --echo)'{-e,--echo}'[display signalled process]' + '(s)-l[display kill command]' +) + +case $OSTYPE in linux*) - optchars=3D"cflvxdnoPgsuUGtw" + # Note: We deliberately exclude -v but not --inverse from pkill + pgopts=3DacdFfGghLlnoPstUuVvwx- + pkopts=3DceFfGghLnoPstUuVx- + arguments=3D( + ${arguments:#((#s)|*\))(\*|)-[acl]*} + '(-c --count)'{-c,--count}'[display count of matching processes]' + ) + [[ $service =3D=3D pgrep ]] && arguments+=3D( + '(-a -l --list-full --list-name)'{-a,--list-full}'[display full = command line]' + '(-a -l --list-full --list-name)'{-l,--list-name}'[display = process name]' + ) ;; - freebsd*) - optchars=3D"LSafilnoqvxFGMNPUdgjstu" + dragonfly*|freebsd*) + pgopts=3DacdFfGgijLlMNnoPqSstUuvx + pkopts=3DacFfGgIijLlMNnoPstUuvx ;; openbsd*) - optchars=3D"flnoqvxdGgPsTtUu" + pgopts=3DdfGglnoPqsTtUuvx + pkopts=3DfGgIlnoPqsTtUuvx ;; darwin*) - optchars=3D"LafilnoqvxFGPUdgtu" + pgopts=3DadFfGgiLlnoPqtUuvx + pkopts=3DaFfGgIiLlnoPtUuvx ;; solaris*) - optchars=3D"flvxdnoPgsuUGJtTcz" - arguments=3D( ${arguments##-T*} ) - arguments=3D( ${arguments##-c*} ) - arguments+=3D( '-T[match only processes in task ids]:taskid:->task' = ) - arguments+=3D( '-c[match only processes in contract = ids]:taskid:->contract' ) + pgopts=3DcdfGgJlnoPsTtUuvxz + pkopts=3DcfGgJnoPsTtUuvxz + arguments=3D( + ${arguments:#((#s)|*\))(\*|)-[cT]*} + '-c+[match only on specified contract IDs]: :->contract' + '-T+[match only on specified task IDs]: :->task' + ) ;; *) - optchars=3D"flvxdnoPgsuUGt" + pgopts=3DdfGgilnPstUuvx + pkopts=3DfGgilnPstUuvx ;; esac -# Only keep relevant arguments according to $optchars. -arguments=3D( ${(M)arguments:#(|\*)(|\(*\))-[$optchars]*} - '*:process name:->pname') -if [[ $service =3D=3D 'pkill' ]]; then - arguments+=3D('-'${^signals}'[signal]') + +if [[ $service =3D=3D pgrep ]]; then + arguments=3D( ${(M)arguments:#((#s)|*\))(\*|)-[$pgopts]*} ) +else + arguments=3D( ${(M)arguments:#((#s)|*\))(\*|)-[$pkopts]*} ) + + if [[ $OSTYPE =3D=3D linux* ]]; then + sig_arguments=3D( + '(ss)' ) + else + sig_arguments=3D( + '(s)' ) + fi + + # Make sure to exclude zsh-specific signals from our signal list. = This + # presumes that EXIT is always listed first and ZERR/DEBUG last =E2=80=94= see + # signames.c + for (( i =3D 1; i <=3D $#signals; i++ )); do + [[ $signals[i] =3D=3D (EXIT|ZERR|DEBUG) ]] && continue + sig_arguments+=3D( '(--signal)-'$signals[i] ) + # Sometimes zsh will only have the number for a signal + [[ $signals[i] =3D=3D <-> ]] || sig_arguments+=3D( + '!(--signal)-SIG'$signals[i] + '!(--signal)-'$(( i - 1 )) + ) + done fi =20 -_arguments -C -s -w $arguments && ret=3D0 +arguments+=3D( $sig_arguments + o '(s)*: :->pname' ) + +[[ $OSTYPE =3D=3D linux* ]] || aopts+=3D( -A '*-' ) +_arguments -C -s -S $aopts : $arguments && ret=3D0 =20 case $state in (sid) @@ -87,7 +150,7 @@ case $state in sid=3D(${(uon)$(ps -A -o sid=3D)}) fi =20 - _wanted sid expl 'session id' compadd -S ',' -q -F used $sid + _wanted sid expl 'session ID' compadd -S ',' -q -F used $sid ;; =20 (ppid) @@ -101,7 +164,7 @@ case $state in ppid=3D(${(uon)$(ps -A -o ppid=3D)}) fi =20 - _wanted ppid expl 'parent process id' compadd -S ',' -q -F used = $ppid + _wanted ppid expl 'parent process ID' compadd -S ',' -q -F used = $ppid ;; =20 (pgid) @@ -115,7 +178,7 @@ case $state in pgid=3D(${(uon)$(ps -A -o pgid=3D)}) fi =20 - _wanted pgid expl 'process group id' compadd -S ',' -q -F used = $pgid + _wanted pgid expl 'process group ID' compadd -S ',' -q -F used = $pgid ;; =20 (projid) @@ -125,7 +188,7 @@ case $state in used=3D(${(s:,:)IPREFIX}) projid=3D(${(uon)$(ps -A -o project=3D)}) =20 - _wanted projid expl 'project id' compadd -S ',' -q -F used $projid + _wanted projid expl 'project ID' compadd -S ',' -q -F used $projid ;; =20 (contract) @@ -135,7 +198,7 @@ case $state in used=3D(${(s:,:)IPREFIX}) ctid=3D(${(uon)$(ps -A -o ctid=3D)}) =20 - _wanted ctid expl 'contract id' compadd -S ',' -q -F used $ctid + _wanted ctid expl 'contract ID' compadd -S ',' -q -F used $ctid ;; =20 (task) @@ -145,7 +208,7 @@ case $state in used=3D(${(s:,:)IPREFIX}) taskid=3D(${(uon)$(ps -A -o project=3D)}) =20 - _wanted taskid expl 'task id' compadd -S ',' -q -F used $taskid + _wanted taskid expl 'task ID' compadd -S ',' -q -F used $taskid ;; =20 (pname)