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

Re: completion for compilers (cc, gcc...) and -o



Vincent Lefevre wrote on Mon, 04 May 2020 01:17 +0200:
> On 2020-05-02 00:43:47 +0000, Daniel Shahaf wrote:
> > Vincent Lefevre wrote on Fri, 01 May 2020 03:11 +0200:  
> > > On 2020-04-30 22:05:32 +0000, Daniel Shahaf wrote:  
> > > > Vincent Lefevre wrote on Thu, 30 Apr 2020 20:17 +00:00:    
> > > > > On 2020-04-30 18:14:59 +0000, Daniel Shahaf wrote:    
> > > > > > Vincent Lefevre wrote on Thu, 30 Apr 2020 10:51 +0200:    
> > > > > > > The -o option is currently handled by
> > > > > > > 
> > > > > > >   '-o:output file:_files -g "^*.(c|h|cc|C|cxx)(-.)"'
> > > > > > > 
> > > > > > > I wonder whether .i files (preprocessed files, e.g. for bug reports)
> > > > > > > should be excluded too. One can choose such files for output with
> > > > > > > "gcc -E", but:
> > > > > > >   * in this case, one generally chooses to use the shorter ">" (or a
> > > > > > >     pipe) rather than "-o" (gcc -E file.c > file.i);    
> > > > > > 
> > > > > > I don't see how the existence of other ways to create .i files is
> > > > > > a reason not to complete .i files after -o.    
> > > > > 
> > > > > I've googled a bit, and most examples with -E and storage in a file
> > > > > used the redirection.    
> > > > 
> > > > You've got your conditional probabilities backwards.  The _a priori_
> > > > likelihood that -o should be used to create a .i file is irrelevant to
> > > > what should be completed after -o.    
> > > 
> > > The issue is that with a completion result on -o that is unexpected by
> > > the user, there is a risk of destroying a source file, while the user
> > > may expect something more sensible.  
> > 
> > That'd be a pilot error.  People should read command lines before
> > executing them.  That's also why _rm doesn't filter out source files,
> > even though rm(1) is as likely to destroy source files as the -o option
> > in _gcc.  
> 
> I type / validate commands quite quickly in general. So, I have some
> protections, e.g. "rm" aliased to "rm -i" (ditto for cp and mv), and
> I use NO_CLOBBER. But for -o, there is no protection if the target
> already exists.

On the one hand:

The user typed the -o, so the user may be presumed to know that it's
destructive.  The user typed <TAB>, which completes existing filenames.
Caveat emptor.

On the other hand:

We do have the RM_STAR_SILENT warning.  The rationale behind that
warning is that people are going to make typos and execute the command
line before they notice them (e.g., `rm * .txt`).  In comparison, the
_gcc case is going to involve inputs along the lines of «gcc -Wall -E -o
<TAB> -std=c89 foo.c».  The command line will be longer, so there'll be
more time to catch the typo before executing it); the failure mode, were
the safety net not in place, would be more benign (only one file is
lost); and completion is involved, which is generally an interactive
process.

---

In balance, I'm not convinced that protection should be added.

I suppose you could implement in gcc the equivalent of rm's -i flag.
That would be analogous to the two examples you gave.

> > Besides, source files are generally in version control, so the
> > destruction will generally be reversible (up to local mods).  
> 
> Generally, but not .i files. I've never seen such files in sources.
> Actually, the only use of .i files I've heard of is testcases for
> compilers. The first step is to generate the .i file, normally
> with a command like "gcc -E [options] file.c > file.i", then do
> a sequence of reduction steps on the .i file in order to get a
> minimal testcase.

Sorry, I don't follow.  What has this got to do with the expected
completions after -o?

> > > And note that after all, filename extensions are just conventions,
> > > and the whole completion system is based on it, so that for instance,
> > > completion on "[unxz] -c" will not propose filenames that do not end with
> > > ".xz" (except when there are no other candidates), even though there
> > > may be unlikely candidates without a ".xz" suffix.  
> > 
> > I can't quite parse this paragraph, sorry.  
> 
> Sorry, I meant "unxz -c". In general, xz-compressed files will
> have a ".xz" extension, but this is not mandatory (with sometimes
> a good reason: one can imagine a text-based file format with its
> own extension but compressed with xz), and "unxz -c" will happily
> decompress such a file (to stdout). However, zsh assumes the .xz
> extension by default in unxz completion.
> 
> In short, with its completion rules, zsh makes arbitrary choices
> about what to complete, based on the common usage. And I think
> that the same kind of choice should be done concerning .i files.

The choices aren't "arbitrary"; they are designed to be useful in the
common case.  Thus, by this line of reasoning, you should be making the
case that users who type -o when a .i file exists in the directory will
seldom if ever want to complete it — which is exactly what I've repeatedly
asked you to explain.

You have argued that _you personally_ would like _gcc to catch errors
for you because you read command lines very quickly.  However, that's
just your personal use, not a general argument, and accordingly the way
to handle it is in your dotfiles.

> > > I would say only with -E, then.  
> > 
> > Maybe complete them always, but not under the same tag as output files
> > which aren't intermediate files (such as .so files)?  When the user has
> > typed «cc -o <TAB>», we don't know whether the user intends to create
> > a .i, or .o, or .exe, or .so, but in any case separating the possibilities
> > by type (= set of extensions) is likely to be helpful.  
> 
> The user would probably have chosen the type of generation before
> the -o. For instance, if the directory contains file.c, then "file"
> should be regarded as a prefix candidate in what follows:
⋮
>   cc -o <TAB>
> 
> should just complete to "file", and the user could add an extension
> if he wishes to do so.

Or maybe it could offer file.o, file.i, file.so, file.exe as completions
and let the user choose among them the usual way.

> For instance, if a directory contains:
> 
>   bar.c
>   foo.i
>   obj.o
> 
> and the completion should give a .o file (due to the -c as above),
> then the possible completions are
> 
>   bar.o   (because of bar.c)
>   foo.o   (because of foo.i)
>   obj.o   (usual completion to files that already exist)
> 
> With -E, bar.i should be a possible completion, but I have some
> objection concerning foo.i (as I've said earlier).

So you're saying that an existing obj.o should be completed after -c but
an existing foo.i shouldn't be after -E?  Special cases are generally
better avoided.

> [...]

Cheers,

Daniel



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