bug-gnu-emacs
[Top][All Lists]
Advanced

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

bug#28978: 26.0; Regression: separate, dedicated `*Completions*' frame n


From: Drew Adams
Subject: bug#28978: 26.0; Regression: separate, dedicated `*Completions*' frame no longer has parameter `minibuffer'
Date: Sun, 29 Oct 2017 08:59:56 -0700 (PDT)

>  >> I would try (eq (minibuffer-selected-window)
>  >>                 (frame-selected-window this-frame))
>  >
>  > I will try that.  At first sight it solves the problem.
>  > As there are many different use cases I'll need to see
>  > whether it works in all cases and doesn't break anything.
> 
> You never said what you really wanted to achieve.  I guess that you want
> to delete a frame around the time you do some minibuffer interaction and
> base the decision of which frame to delete on whether it is the frame
> initiating that interaction.

I sent the `icicle-delete-windows-on', which includes
the doc string:

 "Delete all windows showing BUFFER.
  If such a window is alone in its frame, then delete
  the frame - unless it is the only frame or a standalone
  minibuffer frame."

It's about deleting _windows_.  It's only about deleting
frames if the windows to be deleted are alone in their
frames - such frames are the only frames that are deleted.

That's what I want to achieve.  Is it not clear?

As for when that function is called from Lisp in my code
(to see its use other than interactive), currently it is
called only in command `icicle-remove-Completions-window'.

But that function is called many times, throughout my
code.  A _typical_ use is to remove the display of
buffer `*Completions*' at the end of a given minibuffer
interaction.  A user can also invoke it during completion
using `C-x 0' - that's the interactive case.

"End of a given minibuffer interaction" might be at or
near the end of a command.  It might be at or near the
end of the use of a minibuffer.  But it might NOT be,
in the case of a recursive minibuffer, or even in the
case of a non-recursive minibuffer with which interaction
is not finished.  E.g., you show completions for `forw',
then you type `x', so your input is `forwx'.  Display
of `*Completions*' is removed because there are none.

`icicle-remove-Completions-window' is invoked to stop
showing `*Completions*' - wherever it might be shown;
nothing more.  And that can be appropriate in lots of
different contexts.  The code:

(defun icicle-remove-Completions-window (&optional force)
  "Remove the `*Completions*' window.
If not called interactively and `*Completions*' is the selected
window, then do not remove it unless optional arg FORCE is non-nil."
  (interactive)
  ;; Do nothing if `*Completions*' is the selected window or the
  ;; minibuffer window is selected and `*Completions*' window was
  ;; selected just before.
  (let ((swin  (selected-window)))
    (when (window-minibuffer-p swin)
      (setq swin  (minibuffer-selected-window)))
    (cond
      (;; `*Completions*' is shown in the selected frame.
       (and (get-buffer-window "*Completions*")
            (or force;; `C-g' gets rid of it even if selected
                (and (window-live-p swin)
                     (not (eq (window-buffer swin)
                              (get-buffer "*Completions*"))))
                (interactive-p)))
       (condition-case nil;; Ignore "Attempt to delete the..."
           (delete-window (get-buffer-window "*Completions*"))
         (error nil))
       (bury-buffer (get-buffer "*Completions*")))
      (;; `*Completions*' is shown in a different frame.
       (and (get-buffer-window "*Completions*" 'visible)
            (or force;; `C-g' gets rid of it even if selected
                (and (window-live-p swin)
                     (not (eq (window-buffer swin)
                              (get-buffer "*Completions*"))))
                (interactive-p)))
       (when (window-dedicated-p
              (get-buffer-window "*Completions*" 'visible))
         (condition-case nil
             (icicle-delete-windows-on "*Completions*")
           (error nil)))
       (bury-buffer (get-buffer "*Completions*"))))))

> If so, then any code based on the value of
> the 'minibuffer' parameter would have been already wrong before my
> change as well - an arbitrary number of frames could have had the
> 'minibuffer' parameter set to nil and there would have been no way to
> tell from that parameter which of them initiated the interaction.

No.  As I said, the code, as it was, works fine in all
Emacs releases.  It does not work in prerelease 26.1.

If multiple frames show the BUFFER (typically
`*Completions*') whose display is to be removed then
the behavior (intended and realized) is to remove all
such displays of BUFFER - i.e., all windows showing
BUFFER.

And no, there is no problem such as (I think) you
describe.  In my own setup (but the code is not just
for my setup) ALL of the frames except my standalone
minibuffer frame have a nil `minibuffer' parameter.
And none are mistakenly removed.  Only the windows
and frames showing BUFFER are affected, and only
windows showing BUFFER are removed.

>  > BTW, I find the doc string for `minibuffer-selected-window'
>  > a bit confusing:
>  >
>  >  Return the window which was selected when entering the minibuffer.
>  >                           ^^^^^^^^^^^^^^^^^^^^^^^^^^
>  >  Returns nil, if selected window is not a minibuffer window.
>  >
>  > The phrase "window which was selected when entering" is
>  > somewhat ambiguous.  It can easily be understood as the
>  > window that was selected before the minibuffer was entered,
>  > rather than the (minibuffer) window that is selected after
>  > the minibuffer was entered.
> 
> Exactly that's the meaning.  I'm afraid you're confusing things here.
> The window returned by that function was the selected window until the
> minibuffer interaction started.

Really?  The window that was selected before minibuffer
interaction?

I truly do not understand, in that case.  And that is
not what I think I see.  If what you say is true then
I should never see that the same minibuffer window 
as `active-minibuffer-window' (or even an inactive
minibuffer window) is itself returned by the function.

How can the minibuffer window that becomes selected
for the minibuffer interaction have been the selected 
window before "the minibuffer interaction started"?

I suppose a _different_ minibuffer window could be
returned, e.g., in the case of a recursive minibuffer.
But so far, what you just said, about the function
returning the window that is selected before the
minibuffer interaction starts, makes no sense to me.
I don't get that.

That description seems to apply to a window showing
`completion-reference-buffer'.  That is not what I
think I see.  Before `M-x', with buffer `foo.el'
current in the selected window, I don't think I ever
see that window as the value of function
`minibuffer-selected-window'.

And even if that is the actual meaning/behavior of
that function, the doc string is not appropriate.
In that case it is inappropriate because it allows
the other meaning: after instead of before.  Either
way, the doc string is misleading/ambiguous.

Let me ask you the same question you asked me about
my function for removing displays of a buffer: what
are the use cases for `minibuffer-selected-window'?
What is it intended for?  I thought I understood it
until your reply saying that it returns the window
selected _before_ the minibuffer interaction.

> When the minibuffer action terminates,
> that function will return nil again.  The active minibuffer 
> window is obviously returned by ‘active-minibuffer-window’.

Yes, `active-minibuffer-window' I understand, and
have been using.  It is `minibuffer-selected-window'
that was, and apparently still is, unclear to me.

>  > I think it would be clearer to identify the "when" clearly
>  > as after entering, not before - when "entering' is unclear,
>  > especially when used with "was" selected.
>  >
>  > (Also, it should probably say "Return nil..." instead of
>  > "Returns nil...".)
> 
> Fixed, hopefully.  I also rewrote the related documentation
> (to some extent).

Could you please post the fixed string here, so I
can see it?  Clearly I don't understand this yet.
Hopefully that will help.  Thx.





reply via email to

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