zsh-users
 help / color / mirror / code / Atom feed
* Completions from file with zcompsys
@ 2017-06-20  7:46 Dominik Vogt
  2017-06-20 17:27 ` Bart Schaefer
  0 siblings, 1 reply; 6+ messages in thread
From: Dominik Vogt @ 2017-06-20  7:46 UTC (permalink / raw)
  To: zsh-users

Back in the time of compctl there were a lot of hand written
completions in my config, but compsys this has all gone away for
the default completions on the system.  Now I need something
special for a hand written command, and the amount of
documentation in the zshcompsys and zshcompwid manpages is
overwhelming.  Are there some quick instructions instructions or a
cheat sheet on the new completion system somewhere?

The task at hand is:  Some command, say "foo", takes lines from a
certain, pre-written, sorted file as possible completions.  (The
lines are actually latin plant names which should not matter.),
e.g.:

-- snip --
...
Chenopodium acuminatum
Chenopodium album
Daucus carota
...
-- snip --

And I want to type things like

  $ foo Cheno<TAB>alb<TAB>   # -> Chenopodium album
  $ foo Che*a<TAB>           # -> Chenopodium a

(using menu completion, not expanding the * to all matching
completions).  This is probably only one or two lines in the
config.

Ciao

Dominik ^_^  ^_^

-- 

Dominik Vogt


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

* Re: Completions from file with zcompsys
  2017-06-20  7:46 Completions from file with zcompsys Dominik Vogt
@ 2017-06-20 17:27 ` Bart Schaefer
  2017-06-20 18:02   ` Dominik Vogt
  0 siblings, 1 reply; 6+ messages in thread
From: Bart Schaefer @ 2017-06-20 17:27 UTC (permalink / raw)
  To: zsh-users, zsh-users; +Cc: dominik.vogt

On Jun 20,  8:46am, Dominik Vogt wrote:
}
} Are there some quick instructions instructions or a
} cheat sheet on the new completion system somewhere?

http://zsh.sourceforge.net/Guide/zshguide06.html#l144   (perhaps?)

} And I want to type things like
} 
}   $ foo Cheno<TAB>alb<TAB>   # -> Chenopodium album
}   $ foo Che*a<TAB>           # -> Chenopodium a
} 
} (using menu completion, not expanding the * to all matching
} completions).

The latter one could be tricky because you will have to prevent the "*"
from being expanded as a file glob.

Do you want the expansions exactly as you wrote them, or should the
spaces be quoted?  E.g. do you want to end up with something like one
of

    $ foo 'Chenopodium album'
    $ foo Chenopodium\ album          <-- this one is the easy one below

or instead

    $ foo Chenopodium album

?? The latter will be a bit more work because you will have to account
for the first word when completing the second word.

In any case, the procedure is to create a function that produces a list
of words and then passes them to the "compadd" builtin.  The list does
not have to be filtered against the command line (except in the "a bit
more work" case I just mentioned) because compadd will take care of
that part.  Then you pass the names of that function and of the command
to the "compdef" function.

You can also pass a string to be eval'd to compdef, so the simplest answer
to your question is (guessing at a file name)

    compdef 'compadd ${(f)"$(<~/latin-plant-names.txt)"}' foo

Then to get the "*"-expansion you will need to add the _match function
to your completer zstyle.  Example might be

    zstyle ':completion:*' completer _complete _match

but adjust the placement of _match to fit whatever your current list of
completers contains.  It would normally be anywhere after _complete.

If the above doesn't satisfy, we can go into more detail about how to
change or remove the quoting.


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

* Re: Completions from file with zcompsys
  2017-06-20 17:27 ` Bart Schaefer
@ 2017-06-20 18:02   ` Dominik Vogt
  2017-06-20 19:32     ` Bart Schaefer
  0 siblings, 1 reply; 6+ messages in thread
From: Dominik Vogt @ 2017-06-20 18:02 UTC (permalink / raw)
  To: zsh-users

On Tue, Jun 20, 2017 at 10:27:27AM -0700, Bart Schaefer wrote:
> On Jun 20,  8:46am, Dominik Vogt wrote:
> }
> } Are there some quick instructions instructions or a
> } cheat sheet on the new completion system somewhere?
> 
> http://zsh.sourceforge.net/Guide/zshguide06.html#l144   (perhaps?)
> 
> } And I want to type things like
> } 
> }   $ foo Cheno<TAB>alb<TAB>   # -> Chenopodium album
> }   $ foo Che*a<TAB>           # -> Chenopodium a
> } 
> } (using menu completion, not expanding the * to all matching
> } completions).
> 
> The latter one could be tricky because you will have to prevent the "*"
> from being expanded as a file glob.

If a different "globbing" character would be easier to implement,
or a completely different way to allow partial searches in both
words of the plant name at the same time, that's fine as well.  It
does not have to be the asterisk.  Maybe just moving the cursor to
the beginning of the second word before pressing <TAB> is good
enough.

> Do you want the expansions exactly as you wrote them, or should the
> spaces be quoted?  E.g. do you want to end up with something like one
> of
> 
>     $ foo 'Chenopodium album'
>     $ foo Chenopodium\ album          <-- this one is the easy one below

Yep.  All the command will do is print its arguments, one per
line, so the spaces need to be quoted.  The purpose of the
"command" is to transfer lists of plants I've seen outside from
a notebook (paper) to a file.  Such names are very repetitive so
completion would save a lot of work, and it perfectly suits the
problem to solve.

> You can also pass a string to be eval'd to compdef, so the simplest answer
> to your question is (guessing at a file name)
> 
>     compdef 'compadd ${(f)"$(<~/latin-plant-names.txt)"}' foo

Ah, that seems to be even simpler than the old system.  Since I've
switched to the new completion system I really had no need to
define custom completions, so there was no chance to learn about
it.  :-)

> Then to get the "*"-expansion you will need to add the _match function
> to your completer zstyle.  Example might be
> 
>     zstyle ':completion:*' completer _complete _match
> 
> but adjust the placement of _match to fit whatever your current list of
> completers contains.  It would normally be anywhere after _complete.

Okay, I'll read up on this part to figure out how it works
exactly.  Thanks for your advice.

--

Trying that there is a slight problem.  The file has 9529 lines;
now, when you type something like

  Chenopodium x<TAB>

(where no such taxon exists in the file), zsh starts gobbling 100%
cpu for about half a minute before completing an approximate
match.  This has probably to do with these zstyle lines:

  zstyle ':completion:*' completer _complete _match _approximate
  zstyle ':completion:*:match:*' original only
  zstyle -e ':completion:*:approximate:*' max-errors 'reply=($((($#PREFIX+$#SUFFIX)/3))numeric)'

Hm, it even takes a lot of time with just

  zstyle ':completion:*:approximate:*' max-errors 1 numeric

(zsh-4.3.17)

Ciao

Dominik ^_^  ^_^

-- 

Dominik Vogt


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

* Re: Completions from file with zcompsys
  2017-06-20 18:02   ` Dominik Vogt
@ 2017-06-20 19:32     ` Bart Schaefer
  2017-06-20 21:42       ` Dominik Vogt
  0 siblings, 1 reply; 6+ messages in thread
From: Bart Schaefer @ 2017-06-20 19:32 UTC (permalink / raw)
  To: zsh-users

On Jun 20,  7:02pm, Dominik Vogt wrote:
} 
} If a different "globbing" character would be easier to implement

No, that would not be easier.

} or a completely different way to allow partial searches in both
} words of the plant name at the same time

I can't think of anything that wouldn't require you to restructure the
file e.g. with colons instead of spaces.

} Trying that there is a slight problem.  The file has 9529 lines;
} now, when you type something like
} 
}   Chenopodium x<TAB>

OK, here you have two words but you haven't quoted them.  So the match
is going to only be on "x" -- completion is tightly bound to the shell
parser idea of a "word".  You need to start from

  $ foo 'Chenopodium x<TAB>

(in which case completion will supply the closing quote) or 

  $ foo Chenopodium\ x<TAB>

Or you need to use a different key binding that will back up and grab
both words before invoking completion.

} (where no such taxon exists in the file), zsh starts gobbling 100%
} cpu for about half a minute before completing an approximate
} match.

Yeah, approximate isn't going to deal well with that much data, it has
to try multiple different substrings of the input word against every
word passed to compadd.  Although in the example above the fact that
it is looking for every word that has something that might be mistaken
for an "x" may make it worse.

For this you might want to write a real function and run "agrep" or "fzf"
or something like those, to pre-filter the file contents before passing
to compadd.

}   zstyle ':completion:*' completer _complete _match _approximate
}   zstyle ':completion:*:match:*' original only
}   zstyle -e ':completion:*:approximate:*' max-errors 'reply=($((($#PREFIX+$#SUFFIX)/3))numeric)'

There's a typo in that last line, there should be a space before the
word "numeric".


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

* Re: Completions from file with zcompsys
  2017-06-20 19:32     ` Bart Schaefer
@ 2017-06-20 21:42       ` Dominik Vogt
  2017-06-20 23:31         ` Bart Schaefer
  0 siblings, 1 reply; 6+ messages in thread
From: Dominik Vogt @ 2017-06-20 21:42 UTC (permalink / raw)
  To: zsh-users

On Tue, Jun 20, 2017 at 12:32:15PM -0700, Bart Schaefer wrote:
> On Jun 20,  7:02pm, Dominik Vogt wrote:
> } Trying that there is a slight problem.  The file has 9529 lines;
> } now, when you type something like
> } 
> }   Chenopodium x<TAB>
> 
> OK, here you have two words but you haven't quoted them.  So the match
> is going to only be on "x" -- completion is tightly bound to the shell
> parser idea of a "word".  You need to start from
> 
>   $ foo 'Chenopodium x<TAB>
> 
> (in which case completion will supply the closing quote) or 
> 
>   $ foo Chenopodium\ x<TAB>

That was really just a typo in the mail.  On the command line, the
space was quotred.

> Or you need to use a different key binding that will back up and grab
> both words before invoking completion.

That youldn't help because a taxon can be one to four words, at
least, possibly more.

> } (where no such taxon exists in the file), zsh starts gobbling 100%
> } cpu for about half a minute before completing an approximate
> } match.
> 
> Yeah, approximate isn't going to deal well with that much data, it has
> to try multiple different substrings of the input word against every
> word passed to compadd.  Although in the example above the fact that
> it is looking for every word that has something that might be mistaken
> for an "x" may make it worse.

Isn't there a way to switch it off for a specific command?
Reading the examples I'd have guessed that 

  zstyle ':completion:*' completer _complete _match _approximate
  zstyle ':completion:*:*:foo' completer _complete _match

Would turn off the _approximate completer for the foo command, but
it doesn't.

> For this you might want to write a real function and run "agrep" or "fzf"
> or something like those, to pre-filter the file contents before passing
> to compadd.

Well, keeping this in mind; the approximation stuff may not be
that important anyway.

> }   zstyle ':completion:*' completer _complete _match _approximate
> }   zstyle ':completion:*:match:*' original only
> }   zstyle -e ':completion:*:approximate:*' max-errors 'reply=($((($#PREFIX+$#SUFFIX)/3))numeric)'
> 
> There's a typo in that last line, there should be a space before the
> word "numeric".

Oops.

Ciao

Dominik ^_^  ^_^

-- 

Dominik Vogt


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

* Re: Completions from file with zcompsys
  2017-06-20 21:42       ` Dominik Vogt
@ 2017-06-20 23:31         ` Bart Schaefer
  0 siblings, 0 replies; 6+ messages in thread
From: Bart Schaefer @ 2017-06-20 23:31 UTC (permalink / raw)
  To: zsh-users

On Jun 20, 10:42pm, Dominik Vogt wrote:
}
} Reading the examples I'd have guessed that 
} 
}   zstyle ':completion:*' completer _complete _match _approximate
}   zstyle ':completion:*:*:foo' completer _complete _match
} 
} Would turn off the _approximate completer for the foo command, but
} it doesn't.

Yeah, the "completer" style is looked up very early, before the command
line has even been analyzed to figure out what command word is the
active context.

However, for _approximate specifically, you can do this:

   zstyle -e ':completion:*:approximate:*' max-errors \
     '[[ $words[1] = foo ]] && reply=(0) || \
      reply=($((($#PREFIX+$#SUFFIX)/3)) numeric)'


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

end of thread, other threads:[~2017-06-20 23:30 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-06-20  7:46 Completions from file with zcompsys Dominik Vogt
2017-06-20 17:27 ` Bart Schaefer
2017-06-20 18:02   ` Dominik Vogt
2017-06-20 19:32     ` Bart Schaefer
2017-06-20 21:42       ` Dominik Vogt
2017-06-20 23:31         ` Bart Schaefer

Code repositories for project(s) associated with this public 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).