From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 3098 invoked by alias); 28 Jun 2018 04:59:48 -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: 43106 Received: (qmail 11404 invoked by uid 1010); 28 Jun 2018 04:59:47 -0000 X-Qmail-Scanner-Diagnostics: from mail-ot0-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(74.125.82.195):SA:0(-1.7/5.0):. Processed in 1.28906 secs); 28 Jun 2018 04:59:47 -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.7 required=5.0 tests=BAYES_00, FREEMAIL_ENVFROM_END_DIGIT,FREEMAIL_FROM,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL,SPF_PASS,T_DKIM_INVALID,UNPARSEABLE_RELAY autolearn=no autolearn_force=no version=3.4.1 X-Envelope-From: phy1729@gmail.com X-Qmail-Scanner-Mime-Attachments: | X-Qmail-Scanner-Zip-Files: | DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=date:from:to:subject:message-id:mail-followup-to:references :mime-version:content-disposition:in-reply-to:user-agent; bh=XbX8HCmTgtKFRpNxksXYQ0+Vkd+zKsNrNdDNQci6T/U=; b=DWSnyz/blBjxRvzsZMkob8E3UlHt67bvd79tWGWAnFiy5gkxU8uGOUHg/wMQK/AybB 33wLWnCBnNs/EjvRyPWDWc6eBkOSGkF4oROwqKtAQaGIzf9R5Dp2vwDJqQi40EsUMLyh CSw1K0U7hKrUgeWBuqLSRdqXUHae5y/fPXeWsWCY+aMcSof6uigLrO3UX/P8/OggiX7b eDZlTUdSkoA6SISp+mqsxn2bp9HHmxYVk71oGgIkE3qV6RNG4MLmdfjLINUykuzKxU0S 9IphmtliYh3mdhveWA8pvDF7yAtD3rLZ/ljZW8SRyIg4IxYJp+6LPwj7oIhOxrmJtEBm pIrQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:subject:message-id:mail-followup-to :references:mime-version:content-disposition:in-reply-to:user-agent; bh=XbX8HCmTgtKFRpNxksXYQ0+Vkd+zKsNrNdDNQci6T/U=; b=BQOMisjE3NJtdD5DDKsxxOU4aZI7xWRHS7ScjusQbRx1XhY27NuLy0flltzeKMV0rJ 0shD++Go6oQj6wYHGHaMzSH9pSU/yADzfWNm5L/DPHITvcf5ee2wE0k+7M8RrCdvwDuJ XQpVx+azmbv+cOuO7Dfp+oC6qLqjB/ekZYJkn6r/C7+UQ49QpW9BHSzr1+gS/3Hj36zm kk+ETjT8F4s8iZarSNSwCratUeNlEtlGcOQQzv8kG5eablZPkf/a5LGUXZA8qDyr1mRz ZWocEufqOhLXhkQ9DBQje6T9PQfNMNSak0+GnyWO4yTDcjGa7EMuR2bcK5OtnFELBcOC 6a4g== X-Gm-Message-State: APt69E1KdO0qA+yIpf6Lmzgne1gPXZeLenXdp1JTxzPc+OWORbpIrA5B vd8bguobObkPDpodMwPyO9sY9UJs X-Google-Smtp-Source: AAOMgpdiNIYmksPTSRUB5FlsIcYKbquuPQHmQw2Q6fGTkQP4U0NArXxvo3wyT0odUU4h3bgm9XG5Kw== X-Received: by 2002:a9d:b54:: with SMTP id p20-v6mr4852313otd.143.1530161983304; Wed, 27 Jun 2018 21:59:43 -0700 (PDT) Date: Wed, 27 Jun 2018 23:59:40 -0500 From: Matthew Martin To: zsh-workers@zsh.org Subject: Re: [patch] Add ldap completer Message-ID: <20180628045936.GA76779@CptOrmolo.darkstar> Mail-Followup-To: zsh-workers@zsh.org References: <20180619125722.GA33230@CptOrmolo.darkstar> <17077.1529439708@thecus> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <17077.1529439708@thecus> User-Agent: Mutt/1.10.0 (2018-05-17) On Tue, Jun 19, 2018 at 10:21:48PM +0200, Oliver Kiddle wrote: > Matthew Martin wrote: > > For the protocol _describe, is -I correct? I don't grok the differences > > between the prefixes and suffixes. For host is -S '' correct for not > > adding a space after and should the completer avoid adding the space? > > You should use -S. > The normal way would actually be to have: > compset -S ':*' || suf=( -S :// ) > Then append $suf to _describe. > > -S/-P are what you normally use for separators like : / , etc. > These work together with the suffix auto-removal. The completion > matching is aware of them and considers them for some purposes. > > -s/-p suffixes/prefixes are included in matching control. So if you use, e.g: > compadd -M 'r:|/=* r:|=*' -p "head/" - tail > then h/t will complete to head/tail > This is behind things like _multi_parts. They are also quoted > automatically whereas for -P/-S you might need compquote so these are > sometimes used to take advantage of that. > > -i/-I is akin to directly modifying IPREFIX and ISUFFIX. They tend > to be used when bypassing matching but can have other uses. Aside > from quoting, they don't behave exactly like a direct modification of > IPREFIX/ISUFFIX but that goes beyond my understanding. Thanks, that helped. It seems that most times using -S sould check the SUFFIX first, so I've added that to scope as well. > > The ldapi protocol is not completed correctly because I don't know how > > to make _files replace / with %2f. > > I don't think you can currently without redoing much of _files. You > could probably still get _path_files (with -S %2f) to do much of the > work. > The completion system does track layers of quoting following compset -q > but you can't give it custom forms as %2f would be. (Note in case this ever happens: ed needs something similar since ed 'foo\\bar' edits the file foo\bar.) > > + # [protocol://]host[:port][/basedn[?[attribute,...][?[scope][?[filter]]]]] > > + if ! compset -P '*://'; then > > + tags=(protocol) > > + fi > > + > > + if ! compset -P '*/'; then > > + if compset -P '*:'; then > > In general, where you have compset -P. compset -S is also applicable > when completing whatever falls to the left of the separator. > > > + _tags $tags > > + while _tags; do > > + _requested protocol && _describe -t protocol protocol protocols -I :// > > + _requested host && _hosts -S '' > > + _requested port && _guard '|<1-65535>' port > > _guard was created to solve a particular problem. A quick demonstration > of which is the following: _arguments '--long' ':number:' > --l now does not complete to --long because number is being > offered. > I tend to limit it's use to these situations. Even if I've typed some > letters, getting the "port" description can still be useful. Noted and fixed. > > + _requested basedn expl 'base DN' > > + _requested attribute expl attribute > > + _requested scope && _describe -t scope scope scopes > > If the scope is followed by '?' and a filter, you might want a ? suffix > on this. Perhaps in auto-removable form. Or the default suffix could be > auto-removable. Added with -suffix check. > > + _requested filter expl filter > > + done > > The tags loop is not correct. You need to break out of the loop if > matches were added. _alternative would work here. $tags never contains > more than one value, however, so the easiest would just be to directly > generate matches in each place where you assign to $tags. > > If you don't like adding && ret=0 everywhere, compare > compstate[nmatches] from the start and end of the function. It's possible for the tags array to have both protocol and host. _tags makes much more sense now knowing it's looping over groups. Two questions Why does _tags not do the compstate[nmatches] check? It would ensure that the promises made to the user in the tag-order api are kept and prevents mistaks. Would it be worthwile to write a function that takes a word specifier (e.g. [protocol://]host[:port][/basedn[?[attribute,...][?[scope][?[filter]]]]] ) to make cases like this easier? Next up I was going to submit _smtp which has a uri argument for -s. Not sure how many other commands take completable uris. > > + ':: :_guard "*=*" "filter"' \ > > Is this really doing what you want: offering filter only if there is an > equals sign in the current word? Indeed not and removed. Thanks for the review! - Matthew Martin diff --git a/Completion/BSD/Command/_ldap b/Completion/BSD/Command/_ldap new file mode 100644 index 000000000..8fa17e2f8 --- /dev/null +++ b/Completion/BSD/Command/_ldap @@ -0,0 +1,87 @@ +#compdef ldap + +local -a commands scopes +commands=( + search:'search a directory' +) +scopes=( + base:'base object only' + one:'one level' + sub:subtree +) + +_ldap_url() { + local nm=$compstate[nmatches] + local -a expl protocols suf_proto suf_scope tags + protocols=( + ldap:'TCP in plaintext' + ldaps:'TLS' + ldap+tls:'TCP and use StartTLS' + ldapi:'connect to a socket' + ) + + # [protocol://]host[:port][/basedn[?[attribute,...][?[scope][?[filter]]]]] + if ! compset -P '*://'; then + tags=(protocol) + compset -S ':*' || suf_proto=( -S :// ) + fi + + if ! compset -P '*/'; then + if compset -P '*:'; then + tags=(port) + compset -S '/*' + else + if ! compset -S '://*'; then + tags+=(host) + compset -S '[:/]*' + fi + fi + else + case $PREFIX in + *\?*\?*\?*) tags=(filter);; + *\?*\?*) tags=(scope); [[ -suffix \?* ]] || suf_scope=( -qS \? );; + *\?*) tags=(attribute);; + *) tags=(basedn);; + esac + compset -P '*\?' + compset -S '\?*' + fi + + _tags $tags + while _tags; do + _requested protocol && _describe -t protocol protocol protocols $suf_proto + _requested host && _hosts -S '' + _requested port expl port + _requested basedn expl 'base DN' + _requested attribute expl attribute + _requested scope && _describe -t scope scope scopes $suf_scope + _requested filter expl filter + [[ nm -ne compstate[nmatches] ]] && return 0 + done +} + +if (( CURRENT == 2 )); then + _describe command commands +else + shift words; (( CURRENT-- )) + case $words[1] in + search) + _arguments -s -S -A '-*' \ + '-b+[specify base DN]:base DN:' \ + '-c+[specify CA file]:CA file:' \ + '-D+[specify bind DN]:bind DN:' \ + '-H+[specify URL]: :_ldap_url' \ + '-L[output in LDIF]' \ + '-l+[specify time limit or 0 for no limit]:time limit [0]:' \ + '-s+[specify scope]:scope [sub]:(($scopes))' \ + '-v[be verbose]' \ + '-W[prompt for bind secret]' \ + '-w+[specify bind secret]:bind secret:' \ + '-x[use simple authentication]' \ + '-Z[use StartTLS]' \ + '-z+[specify maximum number of results or 0 for no limit]:size limit [0]:' \ + '::filter:' \ + '*:attribute:' + ;; + esac +fi