zsh-users
 help / color / mirror / code / Atom feed
* More-verbose tab-completion idiom?
@ 2022-03-17  0:26 Phil Pennock
  2022-03-17  0:50 ` Daniel Shahaf
  2022-03-17  1:20 ` Bart Schaefer
  0 siblings, 2 replies; 11+ messages in thread
From: Phil Pennock @ 2022-03-17  0:26 UTC (permalink / raw)
  To: zsh-users

Folks,

I have a command (`nats`) which takes a "context", and where that can be
set as an environment variable.  I have tab-completion of these working,
based upon knowing where the contexts are stored.  Each context is a
JSON file in a specific directory, but I mostly only need the name.

But, I could provide a more detailed description, by parsing the
.description field from the JSON file.  AFAIK this is going to be
external shell-outs to jq right now (unless anyone has a solid reliable
pattern for JSON extraction from a simple KV object in zsh?).

This is relatively expensive and I don't want to do it by default.  I
mean, if most people have at most 3 contexts then it might be sane for
them, but I have 35 and while I might be an outlier, I can believe there
would be people with more.

Is there a standard idiom and keybinding for "go ahead and get the
expensive data, to provide me with more details to choose between the
options", or would I be creating this from scratch?

My completion for this command also gets pointed at by the installer,
so I really want to make sure that what I end up with is not a baroque
Phil Special but instead something which fits better with whatever the
plugin ecosystems are doing, etc.

I know about use-cache etc and have that in other completions of mine,
so if there's no existing idiom for "trigger expensive completion" then
I will use a zstyle to let people request "descriptions" for this
completion, and use-cache if that's set.  I'm asking in case there's a
better way I'm not familiar with.

Thanks,
-Phil


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: More-verbose tab-completion idiom?
  2022-03-17  0:26 More-verbose tab-completion idiom? Phil Pennock
@ 2022-03-17  0:50 ` Daniel Shahaf
  2022-03-17  1:26   ` Phil Pennock
  2022-03-17  1:20 ` Bart Schaefer
  1 sibling, 1 reply; 11+ messages in thread
From: Daniel Shahaf @ 2022-03-17  0:50 UTC (permalink / raw)
  To: Phil Pennock; +Cc: zsh-users

Phil Pennock wrote on Wed, Mar 16, 2022 at 20:26:52 -0400:
> Is there a standard idiom and keybinding for "go ahead and get the
> expensive data, to provide me with more details to choose between the
> options", or would I be creating this from scratch?

There's the verbose and extra-verbose styles (the former is default on,
the latter is default off).  To set that style only for one keybinding,
see _generic in the manual.  I don't have a recommendation for what
key to bind.

Cheers,

Daniel

> My completion for this command also gets pointed at by the installer,
> so I really want to make sure that what I end up with is not a baroque
> Phil Special but instead something which fits better with whatever the
> plugin ecosystems are doing, etc.
> 
> I know about use-cache etc and have that in other completions of mine,
> so if there's no existing idiom for "trigger expensive completion" then
> I will use a zstyle to let people request "descriptions" for this
> completion, and use-cache if that's set.  I'm asking in case there's a
> better way I'm not familiar with.
> 
> Thanks,
> -Phil
> 


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: More-verbose tab-completion idiom?
  2022-03-17  0:26 More-verbose tab-completion idiom? Phil Pennock
  2022-03-17  0:50 ` Daniel Shahaf
@ 2022-03-17  1:20 ` Bart Schaefer
  2022-03-17  1:24   ` Bart Schaefer
  2022-03-17  2:21   ` Phil Pennock
  1 sibling, 2 replies; 11+ messages in thread
From: Bart Schaefer @ 2022-03-17  1:20 UTC (permalink / raw)
  To: Phil Pennock; +Cc: Zsh Users

On Wed, Mar 16, 2022 at 5:27 PM Phil Pennock
<zsh-workers+phil.pennock@spodhuis.org> wrote:
>
> But, I could provide a more detailed description, by parsing the
> .description field from the JSON file.  AFAIK this is going to be
> external shell-outs to jq right now (unless anyone has a solid reliable
> pattern for JSON extraction from a simple KV object in zsh?).

If it's REALLY simple and both keys and values are properly quoted,
you might be able to get away with

() {
  local IFS='{},:'
  typeset -gA context=( ${(Q)=1} )
} "$(<json_context_file)"

but that assumes you don't have colons or commas or braces in the keys
or descriptions.


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: More-verbose tab-completion idiom?
  2022-03-17  1:20 ` Bart Schaefer
@ 2022-03-17  1:24   ` Bart Schaefer
  2022-03-17  2:21   ` Phil Pennock
  1 sibling, 0 replies; 11+ messages in thread
From: Bart Schaefer @ 2022-03-17  1:24 UTC (permalink / raw)
  To: Phil Pennock; +Cc: Zsh Users

On Wed, Mar 16, 2022 at 6:20 PM Bart Schaefer <schaefer@brasslantern.com> wrote:
>
>   typeset -gA context=( ${(Q)=1} )

Even better:
typeset -gA context=( ${(Q)${(z)=1}} )


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: More-verbose tab-completion idiom?
  2022-03-17  0:50 ` Daniel Shahaf
@ 2022-03-17  1:26   ` Phil Pennock
  0 siblings, 0 replies; 11+ messages in thread
From: Phil Pennock @ 2022-03-17  1:26 UTC (permalink / raw)
  To: Daniel Shahaf; +Cc: zsh-users

On 2022-03-17 at 00:50 +0000, Daniel Shahaf wrote:
> There's the verbose and extra-verbose styles (the former is default on,
> the latter is default off).  To set that style only for one keybinding,
> see _generic in the manual.  I don't have a recommendation for what
> key to bind.

Perfect, extra-verbose is exactly what I was looking for, thank you.

Then folks can set the style on a per-command/value basis, or bind to
set it as they see fit.

Thanks,
-Phil


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: More-verbose tab-completion idiom?
  2022-03-17  1:20 ` Bart Schaefer
  2022-03-17  1:24   ` Bart Schaefer
@ 2022-03-17  2:21   ` Phil Pennock
  2022-03-17 16:30     ` Daniel Shahaf
  2022-03-17 20:44     ` Bart Schaefer
  1 sibling, 2 replies; 11+ messages in thread
From: Phil Pennock @ 2022-03-17  2:21 UTC (permalink / raw)
  To: Bart Schaefer; +Cc: Zsh Users

On 2022-03-16 at 18:20 -0700, Bart Schaefer wrote:
> but that assumes you don't have colons or commas or braces in the keys
> or descriptions.

Alas, one of the fields is almost guaranteed to be a URL, thus
containing a colon, and all of those are fair game in the description
field.

In case anyone is interested: while nats(1) (open-source, part of the
CNCF "NATS" project) is changing fast enough that we probably don't want
the completion shipping with zsh at this time, here's a copy of the
completion I'm using today:

  https://get-nats.io/zsh.complete.nats

The tool is one of those Golang ones which has `--completion-bash` but
not `--completion-zsh` and where with a bit of custom zsh logic we can
do a "better than stock tool" job of generating a reasonably decent and
useful completion.

(I know that I'm misusing the per-flag description by listing it twice in
this way for the two different location but I haven't yet come up with
an easier-to-maintain approach)

-Phil


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: More-verbose tab-completion idiom?
  2022-03-17  2:21   ` Phil Pennock
@ 2022-03-17 16:30     ` Daniel Shahaf
  2022-03-17 20:44     ` Bart Schaefer
  1 sibling, 0 replies; 11+ messages in thread
From: Daniel Shahaf @ 2022-03-17 16:30 UTC (permalink / raw)
  To: Phil Pennock; +Cc: Zsh Users

Phil Pennock wrote on Wed, Mar 16, 2022 at 22:21:44 -0400:
> On 2022-03-16 at 18:20 -0700, Bart Schaefer wrote:
> > but that assumes you don't have colons or commas or braces in the keys
> > or descriptions.
> 
> Alas, one of the fields is almost guaranteed to be a URL, thus
> containing a colon, and all of those are fair game in the description
> field.
> 
> In case anyone is interested: while nats(1) (open-source, part of the
> CNCF "NATS" project) is changing fast enough that we probably don't want
> the completion shipping with zsh at this time, here's a copy of the
> completion I'm using today:
> 
>   https://get-nats.io/zsh.complete.nats

Review in unidiff form.  Meant as suggestions to pick and choose from.

I forgot to annotate a few other function definitions with the same
"don't unconditionaly redefine" idiom.

Cheers,

Daniel


[[[
--- https://get-nats.io/zsh.complete.nats
+++ https://get-nats.io/zsh.complete.nats
@@ -23,7 +23,7 @@
 
 # extra-verbose is documented as for features which will slow completion speed.
 if zstyle -t ":completion:${curcontext}:" extra-verbose; then
-  if (( $+commands[jq] )); then
+  if type jq > /dev/null; then
     nats_everbose=1
   else
     : # should we report this back as an error somehow?
@@ -32,15 +32,16 @@
 
 local -r nats_ctxdir="${XDG_CONFIG_HOME:-$HOME/.config}/nats/context"
 
-nats_contexts=( "$nats_ctxdir"/*(:t:r) )
+nats_contexts=( "$nats_ctxdir"/*(N:t:r) )
 
 # TODO: come up with a cache expiration strategy and integrate this with use-cache
 # or at least a global variable.
+(( ${+functions[_nats_context_names]} )) ||
 _nats_context_names() {
   if (( nats_everbose )); then
     described_contexts=()
     for nctx in "${nats_contexts[@]}"; do
-      described_contexts+=("${nctx//:/\\:}:$(jq -r .description < "$nats_ctxdir/$nctx.json")")
+      described_contexts+=("${nctx//:/\\:}:$(_call_program jq "jq -r .description < \"${(q)nats_ctxdir}/${(q)nctx}.json\"")")
     done
     _describe nats-contexts described_contexts
   else
@@ -55,7 +56,7 @@
     ;;
 esac
 
-nats_decorate_flags_desc=(
+nats_decorate_flags_desc=( # this assumes zsh is-at-least 5.5
 	[context]='NATS user context'
 	[tlscert]='TLS client auth public certificate'
 	[tlskey]='TLS client auth private key'
@@ -86,12 +87,12 @@
 
 # We populate a complete set first, so that even if we don't have more details below,
 # we can still tab-complete it; it will just be missing some data
-nats_commands=( $(${words[1]} --completion-bash ${words[1]}) )
+nats_commands=( $(_call_program completion-bash "${words[1]} --completion-bash ${words[1]}") )
 
 # Most flags can appear anywhere; this is not a git-style "top command flags"
 # vs "subcommand flags", but instead "one pool of flags which gains extra
 # entries for some subcommands".
-nats_flags=( $(${words[1]} --completion-bash ${words[1]} --) )
+nats_flags=( $(${words[1]} --completion-bash ${words[1]} --) ) # TODO add _call_program
 _nats_decorate_flags() {
   #zle -M "decorating ..."; zle -R
   local flag directive
@@ -135,7 +136,7 @@
   ;;
 (after-command)
   curcontext=${curcontext%:*:*}:nats-$words[1]:
-  nats_sub=( $("$cmdword" --completion-bash "${words[@]}") )
+  nats_sub=( $("$cmdword" --completion-bash "${words[@]}") ) # TODO add _call_program
   if [[ ${#nats_sub} -eq 0 ]]; then
     # terminal
     nats_flags=( $("$cmdword" --completion-bash "${words[@]}" --) )
]]]

> (I know that I'm misusing the per-flag description by listing it twice in
> this way for the two different location but I haven't yet come up with
> an easier-to-maintain approach)
> 
> -Phil
> 


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: More-verbose tab-completion idiom?
  2022-03-17  2:21   ` Phil Pennock
  2022-03-17 16:30     ` Daniel Shahaf
@ 2022-03-17 20:44     ` Bart Schaefer
  2022-03-17 21:38       ` Phil Pennock
  1 sibling, 1 reply; 11+ messages in thread
From: Bart Schaefer @ 2022-03-17 20:44 UTC (permalink / raw)
  To: Phil Pennock; +Cc: Zsh Users

On Wed, Mar 16, 2022 at 7:21 PM Phil Pennock
<zsh-workers+phil.pennock@spodhuis.org> wrote:
>
> Alas, one of the fields is almost guaranteed to be a URL, thus
> containing a colon, and all of those are fair game in the description
> field.

Are the key-value pairs at least all on one line each?  Just choosing
a json file that's lying around on my Ubuntu:

json2hash () {
  zmodload zsh/mapfile
  setopt localoptions extendedglob
  # Might have to undo gmail line wrapping here
  typeset -gA $1=(
${(z)${(@)${(f)mapfile[$2]}:#[{}]}/(#b)([^:]#):(*)/${(Q)match[1]}
${(q)${(z)${match[2]%,}}}} )
}
json2hash scopes /usr/share/unity/client-scopes.json
typeset -p scopes


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: More-verbose tab-completion idiom?
  2022-03-17 20:44     ` Bart Schaefer
@ 2022-03-17 21:38       ` Phil Pennock
  2022-03-18  0:28         ` Daniel Shahaf
  0 siblings, 1 reply; 11+ messages in thread
From: Phil Pennock @ 2022-03-17 21:38 UTC (permalink / raw)
  To: Bart Schaefer; +Cc: Zsh Users

On 2022-03-17 at 13:44 -0700, Bart Schaefer wrote:
> Are the key-value pairs at least all on one line each?  Just choosing
> a json file that's lying around on my Ubuntu:

Yes, yes they are.
For now.  And I'm in a position to chat with the tool maintainer and try
to make sure they stay that way.

> json2hash () {
>   zmodload zsh/mapfile
>   setopt localoptions extendedglob
>   # Might have to undo gmail line wrapping here
>   typeset -gA $1=(
> ${(z)${(@)${(f)mapfile[$2]}:#[{}]}/(#b)([^:]#):(*)/${(Q)match[1]}
> ${(q)${(z)${match[2]%,}}}} )
> }
> json2hash scopes /usr/share/unity/client-scopes.json
> typeset -p scopes

Switching from `jq` to this:

  described_contexts+=("${nctx//:/\\:}:${${${${(@M)${(f)mapfile[$nats_ctxdir/$nctx.json]}:#[[:space:]]##\"description\":*}#*: \"}%,}%\"}")

means that the time to complete, across 35 files, drops from "a few
seconds where things appear to have hung" to "faster than I can notice",
so I am going to publish a version using this, and most of Daniel's
suggestions, in a few minutes.  I just have to switch from
"extra-verbose" to "verbose" simply because of the difference in
overhead now.

Thank you!

-Phil


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: More-verbose tab-completion idiom?
  2022-03-17 21:38       ` Phil Pennock
@ 2022-03-18  0:28         ` Daniel Shahaf
  2022-03-18  1:16           ` Phil Pennock
  0 siblings, 1 reply; 11+ messages in thread
From: Daniel Shahaf @ 2022-03-18  0:28 UTC (permalink / raw)
  To: Phil Pennock; +Cc: Zsh Users

Phil Pennock wrote on Thu, 17 Mar 2022 21:38 +00:00:
> I just have to switch from "extra-verbose" to "verbose" simply because
> of the difference in overhead now.

As mentioned, 'verbose' is on by default, so you need s/zstyle -t/zstyle -T/.

Cheers,

Daniel


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: More-verbose tab-completion idiom?
  2022-03-18  0:28         ` Daniel Shahaf
@ 2022-03-18  1:16           ` Phil Pennock
  0 siblings, 0 replies; 11+ messages in thread
From: Phil Pennock @ 2022-03-18  1:16 UTC (permalink / raw)
  To: Daniel Shahaf; +Cc: Zsh Users

On 2022-03-18 at 00:28 +0000, Daniel Shahaf wrote:
> Phil Pennock wrote on Thu, 17 Mar 2022 21:38 +00:00:
> > I just have to switch from "extra-verbose" to "verbose" simply because
> > of the difference in overhead now.
> 
> As mentioned, 'verbose' is on by default, so you need s/zstyle -t/zstyle -T/.

*sigh*  I missed the implication there, will fix now.  Tested and
confirmed.  Thanks.

Note that a grep over the zsh code-base for `zstyle .* verbose` shows
that things are inconsistent here.  Almost 1/3 of checks are using '-t'.

% echo ${(D)PWD}
~/src/zsh/code
% ag 'zstyle -[tT] \S+\s+verbose' | grep -c 'zstyle -T'
22
% ag 'zstyle -[tT] \S+\s+verbose' | grep -c 'zstyle -t'
9

-Phil


^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2022-03-18  1:17 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-03-17  0:26 More-verbose tab-completion idiom? Phil Pennock
2022-03-17  0:50 ` Daniel Shahaf
2022-03-17  1:26   ` Phil Pennock
2022-03-17  1:20 ` Bart Schaefer
2022-03-17  1:24   ` Bart Schaefer
2022-03-17  2:21   ` Phil Pennock
2022-03-17 16:30     ` Daniel Shahaf
2022-03-17 20:44     ` Bart Schaefer
2022-03-17 21:38       ` Phil Pennock
2022-03-18  0:28         ` Daniel Shahaf
2022-03-18  1:16           ` Phil Pennock

Code repositories for project(s) associated with this inbox:

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).