emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

RE: 23.0.60; doc string of minibuffer-completing-file-name


From: Drew Adams
Subject: RE: 23.0.60; doc string of minibuffer-completing-file-name
Date: Sun, 20 Apr 2008 01:38:16 -0700

> > > "Non-nil and non-`lambda' means completing file names."
> >  
> > > Is that correct? It doesn't seem so, by looking at the C 
> > > code (but I'm no expert on that).
> >  
> > Indeed, thank you.  Fixed.
> 
> Are you sure?  I see this fragment in minibuf.c:
> 
>   /* If this minibuffer is reading a file name, that doesn't mean
>      recursive ones are.  But we cannot set it to nil, because
>      completion code still need to know the minibuffer is completing a
>      file name.  So use `lambda' as intermediate value meaning
>      "t" in this minibuffer, but "nil" in next minibuffer.  */
>   if (!NILP (Vminibuffer_completing_file_name))
>     Vminibuffer_completing_file_name = Qlambda;
> 
> So it sounds like `lambda' is used in recursive minibuffers.  Am I
> missing something?

Yes, I saw that. No, I'm not sure. My impression is that the value of `lambda'
is temporary, until the recursive minibuffer gets its correct value of nil -
that is, until the recursive call to read_minibuf.

At this point in the code it cannot yet be set to nil (for the next invocation),
because the current invocation still needs to treat it as non-nil. AFAICT, it is
the completion code that does that: tests whether it is currently non-nil.

Note that right at the beginning of read_minibuf, a `lambda' value set by the
parent invocation is converted to a nil value for this (recursive) invocation:

/* If Vminibuffer_completing_file_name is `lambda' on entry, it was t
     in previous recursive minibuffer, but was not set explicitly
     to t for this invocation, so set it to nil in this minibuffer.
     Save the old value now, before we change it.  */

  specbind (intern ("minibuffer-completing-file-name"),
Vminibuffer_completing_file_name);
  if (EQ (Vminibuffer_completing_file_name, Qlambda))
    Vminibuffer_completing_file_name = Qnil;

The phrase "in a previous recursive minibuffer" is I think poor here. It was in
a previous minibuffer, but not necessarily a recursive one - it is _this_
invocation that is recursive (if the value is `lambda'). Otherwise, the comment
is good - it is this comment that explains what the value of `lambda' means.

The following read_minibuf call from completing-read treats nil and `lambda' the
same way when determining the map to use:

val = read_minibuf (NILP (require_match)
                      ? (NILP (Vminibuffer_completing_file_name)
                         || EQ (Vminibuffer_completing_file_name, Qlambda)
                         ? Vminibuffer_local_completion_map
                         : Vminibuffer_local_filename_completion_map)
                      : (NILP (Vminibuffer_completing_file_name)
                         || EQ (Vminibuffer_completing_file_name, Qlambda)
                         ? Vminibuffer_local_must_match_map
                         : Vminibuffer_local_must_match_filename_map),
                      init, prompt, make_number (pos), 0,
                      histvar, histpos, def, 0,
                      !NILP (inherit_input_method));

So it is _not_ for this use that `lambda' was kept non-nil.

do_completion is one place where `lambda' is used temporarily to signify non-nil
during this invocation (it will become nil in a future recursive call). This
happens right after try_completion is called:

if (! NILP (Vminibuffer_completing_file_name)
          && SREF (completion, SBYTES (completion) - 1) == '/'
...

And here is another such place, in minibuffer-complete-word (again, after
try_completion) - there are two such places in this function:

    /* If reading a file name,
       expand any $ENVVAR refs in the buffer and in TEM.  */
    if (! NILP (Vminibuffer_completing_file_name))
      {
        Lisp_Object substituted;
        substituted = Fsubstitute_in_file_name (tem);
...

So AFAICT, the idea is just to save the current non-nil value for use during the
completion code of this invocation, while nevertheless preparing a nil value to
be used in the recursive call.

I would say that this motivation could be made clearer in the code, both in
comments and perhaps by using a more parlant non-nil value than `lambda'.
`lambda' signifies on entry that this is a recursive call and the value should
be nil, that's all.

Again, no, I'm not sure. (1) I'm no C expert. (2) I didn't study the code in
detail.






reply via email to

[Prev in Thread] Current Thread [Next in Thread]