From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 19135 invoked from network); 4 Jun 1999 09:34:03 -0000 Received: from sunsite.auc.dk (130.225.51.30) by ns1.primenet.com.au with SMTP; 4 Jun 1999 09:34:03 -0000 Received: (qmail 7154 invoked by alias); 4 Jun 1999 09:33:55 -0000 Mailing-List: contact zsh-workers-help@sunsite.auc.dk; run by ezmlm Precedence: bulk X-No-Archive: yes X-Seq: 6457 Received: (qmail 7147 invoked from network); 4 Jun 1999 09:33:54 -0000 Date: Fri, 4 Jun 1999 11:33:52 +0200 (MET DST) Message-Id: <199906040933.LAA03117@beta.informatik.hu-berlin.de> From: Sven Wischnowsky To: zsh-workers@sunsite.auc.dk Subject: 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 % ls 'fo'o 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 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 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, 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@informatik.hu-berlin.de