From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 20363 invoked by alias); 25 Jul 2018 22:40:31 -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: 43207 Received: (qmail 3425 invoked by uid 1010); 25 Jul 2018 22:40:31 -0000 X-Qmail-Scanner-Diagnostics: from mail-it0-f41.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.214.41):SA:0(-1.9/5.0):. Processed in 2.048138 secs); 25 Jul 2018 22:40:31 -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_H3,RCVD_IN_MSPIKE_WL,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=9FQxLUBurAl8NbKGgEnASQ3TZvEwAdhyOPuAP5Ivirw=; b=1YlVdF1QFvnb/cmeClSn+12df4D77oHGtaG27Uxw7tiuNKbQ/v3ncU2hXxfIR3Y3tw H3I3AYwxpgmzSdL++k2Sf78zYaBqyRQuk4yMU2SqyUv7Gko8RJI0KG6wMH+F/b9ynWrk TOl6YOo7K+7wGjduURSKkOOzknOFtZ6XW+aOuuz4Rc0CcZ253ELcCaWSIZ5FvuqUgFXA 87DwWXkRmk+7ArpabT2uOkeiY8vi+yDflxYivVFacQHEtimHbJPWAnjqVuGBZokV+CBb JSVxgQnS9D4q193pHtPsjX/8pZj0JFvjiFFqW7sylO9i1rrkVDCeZtksI38HXuXvKmxl uKMg== 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=9FQxLUBurAl8NbKGgEnASQ3TZvEwAdhyOPuAP5Ivirw=; b=jJLvnZw0yuVlhrR6y5CeNp04kEZ1lPXuPErQooGn25i9GmrAqBJgpdzlaoDp2DF1lc X7i1WeGz/lQEicbJx2xDlKu9ghkaiOSXSK6+ZlgCoBf9FimnLwIBEsUgVlPfgg4ymihv HAMiXFBpUlIsGp2sxJZKYPjzBL+1K+bwLrYJ4TmwazbgMfnx5Vvm/Gn6a5RZK4gpdWDP znjxy8vQyVZC1DwwXoxlw/NHoE/KxvP38QcWFLugzWPcAoOW2XLU2W6SaMiuk1cam2K3 GHvbBsww8z9CjYX6+wRz1u15msd5Ins+vLe6Zp1IRrkQuOORZv654utSWNCkuscOwzJf YAYw== X-Gm-Message-State: AOUpUlFGtWK9yMdH+hK2t5ak5ZeUZYAgmYTWw7ZfWFXd5Zgxz3iU3GP3 xgDuNgB/T8E3EPod8pd1RDRDgW27idFjTA== X-Google-Smtp-Source: AAOMgpfYnoxXhh9wUUEN+j4Q/qJZGm+M7wxpMsDO6ZLATGT/OkDQdXRzoDwV8YwWPdFsXcYI64RJuQ== X-Received: by 2002:a02:90cf:: with SMTP id c15-v6mr22522633jag.130.1532558426261; Wed, 25 Jul 2018 15:40:26 -0700 (PDT) From: dana Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: quoted-printable Mime-Version: 1.0 (Mac OS X Mail 11.3 \(3445.6.18\)) Subject: [PATCH] Completion: Improve _bind_addresses, _php Message-Id: <33A64FE9-7144-4FAC-BD75-3950245B53B7@dana.is> Date: Wed, 25 Jul 2018 17:40:24 -0500 To: Zsh hackers list X-Mailer: Apple Mail (2.3445.6.18) The PHP function hasn't been updated in many years, so i tore it up a = little: * Removed checks dealing with PHP 4 (long dead now) * Added several missing options, particularly ones related to reflection = and the built-in Web server * Added helper functions to complete some of the above * Fixed missing */+/=3D on several option specs * Removed the functionality that tried to use ld.so.conf to get = extension paths. This could work, if it was updated to account for the fact that = ld.so.conf itself often contains only an include statement, but, as far as i've = seen, nobody puts their PHP extension path in ld.so.conf* anyway, so * Drastically improved option-exclusivity accuracy. (Making this as = accurate as possible is functionally pleasing to me, but let me know if i'm = abusing groups and/or readability too much by doing so...) It's common when using `php -S` to specify either 0.0.0.0 or localhost = as the listen address, which was something that _bind_addresses couldn't = accommodate. Someone on IRC suggested that i add that functionality directly to the = function, and i'd thought about doing that in the past anyway, so that suited me I am a bit anxious about giving utility functions short options because = compadd has already used up so many of them. I picked ones that don't conflict, = so it's not a big deal i guess, but i'm curious whether there are any = conventions or expectations when it comes to that kind of thing dana diff --git a/Completion/Unix/Type/_bind_addresses = b/Completion/Unix/Type/_bind_addresses index 6042eaf1e..d12727800 100644 --- a/Completion/Unix/Type/_bind_addresses +++ b/Completion/Unix/Type/_bind_addresses @@ -1,9 +1,21 @@ #autoload =20 -# @todo In the future it might be useful to have this function take a = glob or -# similar to filter out loop-back addresses, only return IPv4/6, etc. +# Complete locally bound IP addresses +# +# Options: +# -0 Return also `0.0.0.0` and `::` +# -4 Return only IPv4 addresses +# -6 Return only IPv6 addresses +# -b Return IPv6 addresses in brackets (for use with port numbers) +# -h Return also `localhost` +# -L Exclude loop-back addresses (`127.0.0.0/8` and `::1`) +# -K Exclude link-local addresses (`169.254.0.0/16` and `fe80::/10`) =20 +local MATCH MBEGIN MEND local -a expl tmp cmd=3D( ifconfig -a ) +local -A opts + +zparseopts -A opts -D -E -- 0 4 6 b h L K =20 # A lot of Linux systems have ifconfig, but this is probably safer (and = it's # parsed the same way) @@ -14,4 +26,25 @@ tmp=3D( = ${(@M)tmp##(|[[:space:]]##)inet(|6)(|:)[[:space:]]*} ) tmp=3D( ${(@)tmp#*inet(|6)(|:)[[:space:]]##} ) tmp=3D( ${(@)tmp%%[^0-9A-Fa-f:.]*} ) =20 +# The order of operations here is significant +(( $+opts[-0] )) && tmp+=3D( 0.0.0.0 :: ) + +if (( $+opts[-6] )); then + tmp=3D( ${(@M)tmp:#*:*} ) +elif (( $+opts[-4] )); then + tmp=3D( ${(@)tmp:#*:*} ) +fi + +(( $+opts[-L] )) && { + tmp=3D( ${(@)tmp:#127.*} ) + tmp=3D( ${(@)tmp:#[0:]##:1} ) +} +(( $+opts[-K] )) && { + tmp=3D( ${(@)tmp:#169.254.*} ) + tmp=3D( ${(@)tmp:#(#i)fe[89ab]?:*} ) +} + +(( $+opts[-b] )) && tmp=3D( ${(@)tmp/(#m)*:*/\[$MATCH\]} ) +(( $+opts[-h] )) && tmp+=3D( localhost ) + _wanted bind-addresses expl 'bind address' compadd -a "$@" - tmp diff --git a/Completion/Unix/Command/_php b/Completion/Unix/Command/_php index d03f3395e..2302216c1 100644 --- a/Completion/Unix/Command/_php +++ b/Completion/Unix/Command/_php @@ -1,71 +1,177 @@ -#compdef php +#compdef php -P php[0-9.-] =20 -# PHP 5.0.4 (cli) -# PHP 4.3.11 (cli) +# Notes: +# - We make no distinction between internal and user functions +# - We don't complete CGI options, which are rarely used interactively +# - Exclusivity on some of the miscellaneous options isn't very = accurate +# - @todo Arguments to an -f script aren't completed accurately -- we = need to +# massage words/CURRENT so that the -f arg becomes words[1], but if = we just +# leave it at that the output will break if the script has any = options of its +# own. We would want to complete script options only following `--`, = as in +# `php -f /bin/foo -- -` =20 -local curcontext=3D"$curcontext" line state expl -typeset -A opt_args +# Complete PHP class names +(( $+functions[_php_classes] )) || +_php_classes() { + local cmd + local -a tmp =20 -local -a args -local exclusions php_suffix + cmd=3D'foreach ( get_declared_classes() as $c ) { echo "$c\n"; }' + tmp=3D( ${(f)"$( _call_program classes $words[1] -r ${(q)cmd} )"} ) =20 -zstyle -s ":completion:${curcontext}:" suffixes php_suffix '|' || = php_suffix=3D'php|phar' -local php_files=3D":PHP file:_files -g '*.($php_suffix)(-.)'" + _wanted -x classes expl 'PHP class' compadd -a "$@" - tmp +} + +# Complete PHP extensions/module names; use --zend for Zend extensions = only +(( $+functions[_php_extensions] )) || +_php_extensions() { + local idx + local -a expl zend tmp + + zparseopts -a zend -D -E -- -zend + + # `php -m` lists all extensions under two sections called '[PHP = Modules]' and + # '[Zend Modules]'. An extension can (but won't necessarily) exist = under both + # of these at the same time + tmp=3D( ${(f)"$( _call_program extensions $words[1] -m )"} ) + idx=3D${tmp[(i)\[Zend Modules\]]} + + # Get only Zend extensions (for --rz) + if (( $#zend )); then + tmp=3D( ${(@)tmp[(idx+1),-1]} ) + # Get PHP extensions (for everything else) + else + tmp=3D( ${(@)tmp[2,(idx-1)]} ) + fi + + _wanted -x extensions expl 'PHP extension' compadd -a "$@" - tmp +} + +# Complete PHP function names +(( $+functions[_php_functions] )) || +_php_functions() { + local cmd + local -a expl tmp + + cmd=3D' + foreach ( get_defined_functions() as $a ) { + foreach ( $a as $f ) { + echo "$f\n"; + } + } + ' + tmp=3D( ${(f)"$( _call_program functions $words[1] -r ${(q)cmd} )"} ) + + _wanted -x functions expl 'PHP function' compadd -a "$@" - tmp +} + +_php() { + local curcontext=3D$curcontext php_suffix php_files ret=3D1 + local -a context expl line state state_descr args + local -A opt_args + + zstyle -s ":completion:${curcontext}:" suffixes php_suffix '|' || + php_suffix=3D'php|php5|phar' + + php_files=3D":PHP file:_files -g '*.($php_suffix)(#q-.)'" =20 -if _pick_variant php5=3DPHP\ 5 php4 --version; then - exclusions=3D"-B --process-begin -R --process-code -F --process-file = -E --process-end" args=3D( - '(-B --process-begin -f --file -r --run = 1)'{-B,--process-begin}'[run specified PHP code before processing input = lines]:PHP code:' - '(-R --process-code -F --process-file -f --file -r --run = 1)'{-R,--process-code}'[run specified PHP code for every input line]:PHP = code:' - '(-F --process-file -R --process-code -f --file -r --run = 1)'{-F,--process-file}'[parse and execute specified file for every input = line]'$php_files - '(-E --process-end -f --file -r --run 1)'{-E,--process-end}'[run = specified PHP code after processing all input lines]:PHP code:' - '(-H --hide-args)'{-H,--hide-args}'[hide any passed arguments from = external tools]' + + mc # Misc. options + '(-a --interactive)'{-a,--interactive}'[run interactively]' + '*'{-d+,--define=3D}'[define INI directive]: :->directive' + '(-e --profile-info)'{-e,--profile-info}'[generate extended = information for debugger/profiler]' + '(-H --hide-args)'{-H,--hide-args}'[hide script name and arguments = from external tools]' + '(fi im pb pf rf rn sc sv *)--ini[display configured INI paths]' + # Note: PHP does not automatically prepend extension_dir to = extension file + # names (the way it does when parsing the INI file) at the command = line + '*'{-z+,--zend-extension=3D}'[load specified Zend extension]:Zend = extension:_files -g "*.so(|.*)(#q-.)"' + + + '(fi)' # File arguments + "(im pb pf rf sv)"{-f+,--file=3D}'[parse and/or execute specified = file]'$php_files + '(-)1'$php_files + + + '(hv)' # Help/version options; kept separate by convention + '(- 1 *)'{-h,--help}'[display help information]' + '(- 1 *)'{-v,--version}'[display version information]' + '!(- 1 *)'{-\?,-\\\?,--usage} + + + '(im)' # Info/module options (exclusive with everything but = -c/-n) + '(fi mc pb pf rf rn sc sv *)'{-i,--info}'[display configuration = information (phpinfo())]' + '(fi mc pb pf rf rn sc sv *)'{-m,--modules}'[display installed = extensions]' + + + '(in)' # php.ini set/disable options (unrelated to --ini!) + {-c+,--php-ini=3D}'[specify php.ini or containing directory]:INI = file or directory:_files -g "*.ini(-.)"' + {-n,--no-php-ini}'[ignore php.ini]' + + + '(pb)' # Input-processing begin/end options + '(-B --process-begin fi im rf rn sc sv)'{-B+,--process-begin=3D}'[run= specified PHP code before processing input lines]:PHP code:' + '(-E --process-end fi im rf rn sc sv)'{-E+,--process-end=3D}'[run = specified PHP code after processing input lines]:PHP code:' + + + '(pf)' # Input-processing options + '(fi im rf rn sc sv)'{-R+,--process-code=3D}'[run specified PHP = code for every input line]:PHP code:' + '(fi im rf rn sc sv)'{-F+,--process-file=3D}'[parse and execute = specified file for every input line]'$php_files + + + '(rf)' # Reflection options + '(fi im rn pb pf sc sv *)'{--rc=3D,--rclass=3D}'[display = information about specified class]: :_php_classes' + '(fi im rn pb pf sc sv *)'{--re=3D,--rextension=3D}'[display = information about specified extension]: :_php_extensions' + '(fi im rn pb pf sc sv *)'{--rf=3D,--rfunction=3D}'[display = information about specified function]: :_php_functions' + '(fi im rn pb pf sc sv *)'{--ri=3D,--rextinfo=3D}'[display = configuration information about specified extension]: :_php_extensions' + '(fi im rn pb pf sc sv *)'{--rz=3D,--rzendextension=3D}'[display = information about specified Zend extension]: :_php_extensions --zend' + + + '(rn)' # Run-script options + "(fi im pb pf rf sc sv)"{-r+,--run=3D}'[run specified PHP code]:PHP = code:' + + + '(sc)' # Source-checking/formatting options + '(im pb pf rf rn sv *)'{-l,--syntax-check}'[check syntax only = (lint)]' + '(im pb pf rf rn sv *)'{-s,--syntax-highlight}'[display HTML = syntax-highlighted source]' + '!(im pb pf rf rn sv *)--syntax-highlighting' + '(im pb pf rf rn sv *)'{-w,--strip}'[display source stripped of = comments and whitespace]' + + + sv # Built-in Web server options + '(-S --server fi im pb pf rf rn sc *)'{-S+,--server=3D}'[start Web = server on specified address/port]: :->server' + '(-t --docroot fi im pb pf rf rn sc *)'{-t+,--docroot=3D}'[specify = Web-server document root]:document root:_directories' + + + ar # Script-argument operands + '(-)*:: :->argument' ) -fi - -args+=3D( - '(-a --interactive)'{-a,--interactive}'[run interactively]' - '(-c --php-ini -n --no-php-ini)'{-c,--php-ini}'[look for php.ini file = in the specified directory]:INI file or directory:_files -g "*.ini(-.)"' - '(-c --php-ini -n --no-php-ini)'{-n,--no-php-ini}'[no php.ini file = will be used]' - '(-d --define)'{-d,--define}'[define INI entry]:configuration = directive:->directive' - '(-e --profile-info)'{-e,--profile-info}'[generate extended = information for debugger/profiler]' - "(-f --file -r --run $exclusions 1)"{-f,--file}'[parse specified = file]'$php_files - '(- 1 *)'{-h,--help}'[display help information]' - '(- 1 *)'{-i,--info}'[PHP information]' - '(- *)'{-l,--syntax-check}'[syntax check only (lint)]' - '(- 1 *)'{-m,--modules}'[show compiled in modules]' - "(-r --run -f --file $exclusions -l --syntax-check -s = --syntax-highlight -w --strip 1)"{-r,--run}'[run the specified PHP code = without using script tags ]:PHP code:' - '(- 1 *)'{-s,--syntax-highlight}'[display colour syntax highlighted = source]' - '(- 1 *)'{-v,--version}'[display version information]' - '(- *)'{-w,--strip}'[display source with stripped comments and = whitespace]' - '(-z --zend-extension)'{-z,--zend-extension}'[load specified Zend = extension]:extension file:->extension' - '(-)1'$php_files - '(-)*::script argument: _normal' -) - -_arguments -C -s -S "$args[@]" && return 0 - -case $state in - directive) - local -a directives suf - local code=3D'foreach (ini_get_all() as $k =3D> $v) { echo "$k\n"; = }' - directives=3D( $(_call_program directives $words[1] -r ${(q)code} = 2>/dev/null) ) - if compset -P 1 '*=3D'; then - _default && return 0 - else - compset -S '=3D*' || suf=3D( -qS '=3D' ) - _wanted directives expl 'configuration directive' compadd = "$suf[@]" -a directives && return 0 - fi - ;; - extension) - local -a paths - if [[ -r /etc/ld.so.conf ]]; then - paths=3D( ${(f)"$( $v) { echo = "$k\n"; }' + directives=3D( ${(f)"$( + _call_program directives $words[1] -r ${(q)code} + )"} ) + if compset -P 1 '*=3D'; then + _default && ret=3D0 + else + compset -S '=3D*' || suf=3D( -qS '=3D' ) + _wanted directives expl 'INI directive' \ + compadd "$suf[@]" -a directives && ret=3D0 + fi + ;; + server) + if compset -P '*:'; then + _wanted -2V port-numbers expl 'port number' \ + compadd 80 81 443 591 8000 8001 8008 8080 8443 && ret=3D0 + ret=3D0 + else + _wanted hosts expl 'local address' _bind_addresses -0bh -qS: && = ret=3D0 + fi + ;; + esac + + return ret +} + +_php "$@"