Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: Better completion in quotes



No patch yet, because this may get so complicated that I want to hear
your opinions first. So this is just another list of things I'm
thinking about. I've also found some more problems...

There are two main problems: (1) make zsh correctly handle completion
of quoted words and (2) allow completion on separate words in quoted
strings.

1) We make get_comp_string() always return quoted strings as a whole,
   in the form the lexer returns them. We could then look if the word
   begins with a quote, remember that and use this information to
   offer automatically inserted ending-quotes. But there is this
   problem:

     % touch 'foo bar'
     % ls f'o<TAB>
     % ls 'fo'o<TAB>

   I.e. the quotes need not be at the beginning or there may be
   `closed' quotes. Note also that the second example may be more
   complicated if we have a partial-word matching specification.
   This means that we would have to keep information about quotes in
   the word and we have to re-insert them the way we do it for braces
   already. But this is hard to implement and it wouldn't be enough:

     % compctl -M 'r:|-=*'
     % touch 'foo bar-bar foo'
     % ls f-'b<TAB>

   Here we would have to produce foo\ bar-'bar foo'. So we would also
   have quote different parts of the strings to insert differently.
   This would be so hard to implement that I don't want to think any
   further in this direction.
   So, as a much simpler solution I suggest to make the completion
   code turn strings with quotes into a generic quoted form, using
   backslashes. But it is a bit ugly that

     % ls 'foo b<TAB>

   would be turned into foo\ bar. If this is unacceptable, we could
   treat strings beginning with a quote as a special case and have the 
   code re-insert the quote at the beginning and automatically insert
   the closing quote, that wouldn't be too hard, but I'm not sure I
   like this special casing. I could be convinced, though.
   We'll also have to make sure that the quotes aren't removed if they
   are really needed, as in ${"${...}"}, but I think this is mostly a
   question of when to (internally) un-quote the string. If anyone can 
   think of other places where we have to be careful, I'd like to hear 
   about them.

2) I still like the option Bart suggested and would like to make it
   work. Since I've written 6417 mostly about it, only a short
   description:
   We have a flag for compctl, say -1 (until we find the best
   character for it) which says that the string completion is
   currently using hsould be split into separate words and completion
   should work on these. The syntax would be the same as for -l,
   i.e. with an optional command name.
   Internally this would use either the lexer or some space-splitting
   code to get at the words, I'm not yet sure which would be easier
   (splitting at spaces can get complicated with nested quotes, of
   course). With compctl this would just do another search for the
   command name, and complete using the compctl for that, as with -l.
   We could also add a -x test to allow users to test if the current
   string was quoted or not. Since the sub-compctl would complete the
   parts of the original string as if it weren't quoted, there are
   probably some nasty effects waiting for us when matches are
   generated for both the whole string and a part of it. I don't
   expect this to happen very often (or to be of any interest very
   often), though. If you special case words quoted at the beginning
   this will happen even less often and I think making -1 recursive is 
   easier to implement (and probably more powerful) than making -1 an
   option without arguments that changes the way the surrounding
   options use the current word. We'll see.
   For the new completion system, this is a bit more problematic
   because there we can't do such a C-code-controlled recursion.
   Instead, I suggest a new option to compset, say -q, that makes the
   special parameters be set up so that following shell code works on
   the separate parts of the current word. I.e. the parts would be
   stored in $words, ${PRE,SUF}FIX would be change, and so on. The
   problem is that we need a way to tell the completion (C-)code that
   we are currently working only on a part of the original string. We
   need this information anyway, but for the new completion system the 
   question is if we make it user-visible or not. If we want to make
   it visible, we would add another prefix/suffix-pair, say Q{PRE,SUF}FIX.
   So if we do "foo b<TAB>, compset would store `b' in PREFIX, and
   `foo ' in QPREFIX. The C-code would then use those values to build
   the strings that are used to replace the whole original string
   (which is `foo b'). This is a bit ugly, because this string would
   also be stored in $words (as `(foo b)'), but maybe this isn't that
   problematic. We could also make Q{PRE,SUF}FIX read-only, just to
   make sure that the result isn't complete garbage (but that can't be 
   guaranteed in the new completion system anyway...).
   Finally, we wouldhave to change the quote* keys of compstate,
   making them reflect whether a `compset -q' is currently in effect
   (with what kind of quotes removed -- this can get complicated to
   implement), and probably whether calling `compset -q' might be a
   good idea, because there are quotes

Ok, that's as far as I can think now. I really want a (near-to-)final
solution for all this quoting stuff, to avoid such question as we have 
seen several times lately (and to get rid of that comment in
get_comp_string()).

If anyone sees a better solution or has other ideas or comments,
please let me know.


Bye
 Sven


--
Sven Wischnowsky                         wischnow@xxxxxxxxxxxxxxxxxxxxxxx



Messages sorted by: Reverse Date, Date, Thread, Author