all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
* Switch buffers without modifying the buffer list ordering?
@ 2022-01-30 21:26 Augusto Stoffel
  2022-01-31  8:42 ` martin rudalics
                   ` (2 more replies)
  0 siblings, 3 replies; 8+ messages in thread
From: Augusto Stoffel @ 2022-01-30 21:26 UTC (permalink / raw)
  To: emacs-devel; +Cc: Daniel Mendler, Omar Antolín Camarena

With the following code, I can verify that the NORECORD argument of
`switch-to-buffer' does what it promises:

```
(progn
  (switch-to-buffer "A")
  (switch-to-buffer "B" 'norecord)
  (car (buffer-list)))
```

Namely, this makes buffer B current, but returns #<buffer A>.

Now, here's a catch: if next I type `M-x (car (buffer-list))', I get
#<buffer B> instead of #<buffer A>.  Why does that happen, and is there
a way to switch to buffer B and *really* not modify the buffer list
ordering?

I'm asking this because of an issue with the live preview feature of the
Consult package.  Very succinctly, the idea here is to temporarily
change the current buffer during a `completing-read' call, in order to
display more information about the candidates.  When the
`completing-read' ends, we would like to restore the original order of
the buffer list.  There seems to be no simple way to achieve that, and
some kludge like the following seems necessary.  Any better suggestions?

```
(let ((buffers (buffer-list)))
    (unwind-protect
        <do the completing-read with live preview>
      (save-window-excursion
        ;; Restore the original buffer list ordering
        (dolist (buffer buffers)
          (when (buffer-live-p buffer)
            (bury-buffer-internal buffer))))))
```



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Switch buffers without modifying the buffer list ordering?
  2022-01-30 21:26 Switch buffers without modifying the buffer list ordering? Augusto Stoffel
@ 2022-01-31  8:42 ` martin rudalics
  2022-02-01 18:46   ` Augusto Stoffel
  2022-02-02 11:24   ` Kevin Vigouroux via Emacs development discussions.
  2022-02-01 14:35 ` Kevin Vigouroux via Users list for the GNU Emacs text editor
  2022-02-01 14:48 ` Kevin Vigouroux via Emacs development discussions.
  2 siblings, 2 replies; 8+ messages in thread
From: martin rudalics @ 2022-01-31  8:42 UTC (permalink / raw)
  To: Augusto Stoffel, emacs-devel; +Cc: Daniel Mendler, Omar Antolín Camarena

 > With the following code, I can verify that the NORECORD argument of
 > `switch-to-buffer' does what it promises:
 >
 > ```
 > (progn
 >    (switch-to-buffer "A")
 >    (switch-to-buffer "B" 'norecord)
 >    (car (buffer-list)))
 > ```
 >
 > Namely, this makes buffer B current, but returns #<buffer A>.
 >
 > Now, here's a catch: if next I type `M-x (car (buffer-list))',

... M-: (car (buffer-list)) I suppose ...

 > I get
 > #<buffer B> instead of #<buffer A>.  Why does that happen, and is there
 > a way to switch to buffer B and *really* not modify the buffer list
 > ordering?

It's restoring the window configuration after reading from the
minibuffer but before evaluating the expression you typed that gets in
the way.  Try with emacs -Q and evaluate the forms below step by step

(display-buffer "*Messages*")

(defun foo ()
   (message
    "%s - %s" (selected-window) (car (buffer-list))))

(add-hook 'buffer-list-update-hook 'foo)

(progn
   (switch-to-buffer "A")
   (switch-to-buffer "B" 'norecord)
   (car (buffer-list)))

and now type M-: (car (buffer-list)).  This gets me in the *Messages*
buffer

#<window 3 on A> - A [3 times]
#<buffer A>
#<window 3 on B> - A
#<window 4 on  *Minibuf-1*> -  *Minibuf-1* [4 times]
#<window 3 on B> - B [2 times]
#<buffer B>

Now try again the same scenario but first evaluate

(setq read-minibuffer-restore-windows nil)

which gets me here the

#<window 3 on A> - A [3 times]
#<buffer A>

you probably expected.

 > I'm asking this because of an issue with the live preview feature of the
 > Consult package.  Very succinctly, the idea here is to temporarily
 > change the current buffer during a `completing-read' call, in order to
 > display more information about the candidates.  When the
 > `completing-read' ends, we would like to restore the original order of
 > the buffer list.  There seems to be no simple way to achieve that, and
 > some kludge like the following seems necessary.  Any better suggestions?
 >
 > ```
 > (let ((buffers (buffer-list)))
 >      (unwind-protect
 >          <do the completing-read with live preview>
 >        (save-window-excursion
 >          ;; Restore the original buffer list ordering
 >          (dolist (buffer buffers)
 >            (when (buffer-live-p buffer)
 >              (bury-buffer-internal buffer))))))

That's a different issue.  'buffer-list' is a function that returns a
list from the internal C variable Vbuffer_alist - a variable, Lisp code
is not allowed to modify directly.  In order to modify Vbuffer_alist, a
Lisp programmer has to bury buffers in precisely the same way as you do.

You could try coming up with a macro, say 'with-buffer-list-unmodified'
(where you probably should suspend calling 'buffer-list-update-hook'
while running it).

martin



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Switch buffers without modifying the buffer list ordering?
  2022-01-30 21:26 Switch buffers without modifying the buffer list ordering? Augusto Stoffel
  2022-01-31  8:42 ` martin rudalics
@ 2022-02-01 14:35 ` Kevin Vigouroux via Users list for the GNU Emacs text editor
  2022-03-25 22:25   ` Samuel Wales
  2022-02-01 14:48 ` Kevin Vigouroux via Emacs development discussions.
  2 siblings, 1 reply; 8+ messages in thread
From: Kevin Vigouroux via Users list for the GNU Emacs text editor @ 2022-02-01 14:35 UTC (permalink / raw)
  To: help-gnu-emacs

`buffer-list' displays the buffers in a specific order: the buffer in
the selected window is displayed first.

I don’t really understand how it works, but we can see that the buffer
appears at the end of the list when we select another window before
evaluating the expression `(buffer-list)'.
-- 
Best regards,
Kevin Vigouroux



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Switch buffers without modifying the buffer list ordering?
  2022-01-30 21:26 Switch buffers without modifying the buffer list ordering? Augusto Stoffel
  2022-01-31  8:42 ` martin rudalics
  2022-02-01 14:35 ` Kevin Vigouroux via Users list for the GNU Emacs text editor
@ 2022-02-01 14:48 ` Kevin Vigouroux via Emacs development discussions.
  2 siblings, 0 replies; 8+ messages in thread
From: Kevin Vigouroux via Emacs development discussions. @ 2022-02-01 14:48 UTC (permalink / raw)
  To: emacs-devel; +Cc: Augusto Stoffel

`buffer-list' displays the buffers in a specific order: the buffer in
the selected window is displayed first.

I don’t really understand how it works, but we can see that the buffer
appears at the end of the list when we select another window before
evaluating the expression `(buffer-list)'.
-- 
Best regards,
Kevin Vigouroux



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Switch buffers without modifying the buffer list ordering?
  2022-01-31  8:42 ` martin rudalics
@ 2022-02-01 18:46   ` Augusto Stoffel
  2022-02-02 11:24   ` Kevin Vigouroux via Emacs development discussions.
  1 sibling, 0 replies; 8+ messages in thread
From: Augusto Stoffel @ 2022-02-01 18:46 UTC (permalink / raw)
  To: martin rudalics; +Cc: Daniel Mendler, Omar Antolín Camarena, emacs-devel

Thanks, this essentially clarifies everything.

On Mon, 31 Jan 2022 at 09:42, martin rudalics <rudalics@gmx.at> wrote:

>> With the following code, I can verify that the NORECORD argument of
>> `switch-to-buffer' does what it promises:
>>
>> ```
>> (progn
>>    (switch-to-buffer "A")
>>    (switch-to-buffer "B" 'norecord)
>>    (car (buffer-list)))
>> ```
>>
>> Namely, this makes buffer B current, but returns #<buffer A>.
>>
>> Now, here's a catch: if next I type `M-x (car (buffer-list))',
>
> ... M-: (car (buffer-list)) I suppose ...
>
>> I get
>> #<buffer B> instead of #<buffer A>.  Why does that happen, and is there
>> a way to switch to buffer B and *really* not modify the buffer list
>> ordering?
>
> It's restoring the window configuration after reading from the
> minibuffer but before evaluating the expression you typed that gets in
> the way.  Try with emacs -Q and evaluate the forms below step by step
>
> (display-buffer "*Messages*")
>
> (defun foo ()
>   (message
>    "%s - %s" (selected-window) (car (buffer-list))))
>
> (add-hook 'buffer-list-update-hook 'foo)
>
> (progn
>   (switch-to-buffer "A")
>   (switch-to-buffer "B" 'norecord)
>   (car (buffer-list)))
>
> and now type M-: (car (buffer-list)).  This gets me in the *Messages*
> buffer
>
> #<window 3 on A> - A [3 times]
> #<buffer A>
> #<window 3 on B> - A
> #<window 4 on  *Minibuf-1*> -  *Minibuf-1* [4 times]
> #<window 3 on B> - B [2 times]
> #<buffer B>
>
> Now try again the same scenario but first evaluate
>
> (setq read-minibuffer-restore-windows nil)
>
> which gets me here the
>
> #<window 3 on A> - A [3 times]
> #<buffer A>
>
> you probably expected.
>
>> I'm asking this because of an issue with the live preview feature of the
>> Consult package.  Very succinctly, the idea here is to temporarily
>> change the current buffer during a `completing-read' call, in order to
>> display more information about the candidates.  When the
>> `completing-read' ends, we would like to restore the original order of
>> the buffer list.  There seems to be no simple way to achieve that, and
>> some kludge like the following seems necessary.  Any better suggestions?
>>
>> ```
>> (let ((buffers (buffer-list)))
>>      (unwind-protect
>>          <do the completing-read with live preview>
>>        (save-window-excursion
>>          ;; Restore the original buffer list ordering
>>          (dolist (buffer buffers)
>>            (when (buffer-live-p buffer)
>>              (bury-buffer-internal buffer))))))
>
> That's a different issue.  'buffer-list' is a function that returns a
> list from the internal C variable Vbuffer_alist - a variable, Lisp code
> is not allowed to modify directly.  In order to modify Vbuffer_alist, a
> Lisp programmer has to bury buffers in precisely the same way as you do.
>
> You could try coming up with a macro, say 'with-buffer-list-unmodified'
> (where you probably should suspend calling 'buffer-list-update-hook'
> while running it).
>
> martin



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Switch buffers without modifying the buffer list ordering?
  2022-01-31  8:42 ` martin rudalics
  2022-02-01 18:46   ` Augusto Stoffel
@ 2022-02-02 11:24   ` Kevin Vigouroux via Emacs development discussions.
  1 sibling, 0 replies; 8+ messages in thread
From: Kevin Vigouroux via Emacs development discussions. @ 2022-02-02 11:24 UTC (permalink / raw)
  To: emacs-devel; +Cc: martin rudalics

The NORECORD argument of `switch-to-buffer' is actually passed to
`select-window' (see its docstring).

#+begin_quote
Optional second arg NORECORD non-nil means do not put this buffer at the
front of the buffer list and do not make this window the most recently
selected one.  Also, do not mark WINDOW for redisplay unless NORECORD
equals the special symbol ‘mark-for-redisplay’.
#+end_quote

Anyway, `switch-to-buffer' displays the buffer in some window and
finally selects that window.

#+begin_quote
Also note that the main editor command loop sets the current buffer to
the buffer of the selected window before each command.
#+end_quote

The displayed buffer is in the selected window, so the command loops
sets the current buffer to this buffer.

⏵ Emacs Lisp Ref. Manual — 27.8 “The Buffer List”.

#+begin_quote
A buffer moves to the front of this list whenever it is chosen for
display in a window (*note Switching Buffers) or a window displaying
it is selected (see Selecting Windows).
#+end_quote

If we select another window, we see that everything works as you expected.
-- 
Kevin Vigouroux
Best regards



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Switch buffers without modifying the buffer list ordering?
  2022-02-01 14:35 ` Kevin Vigouroux via Users list for the GNU Emacs text editor
@ 2022-03-25 22:25   ` Samuel Wales
  2022-03-29  6:03     ` Kevin Vigouroux via Users list for the GNU Emacs text editor
  0 siblings, 1 reply; 8+ messages in thread
From: Samuel Wales @ 2022-03-25 22:25 UTC (permalink / raw)
  To: Kevin Vigouroux, help-gnu-emacs

fwiw i also have similar issues as i have f keys bound to next and
prev buffers and want things like recent stuff nearby.

others know more, but i think the buffer list is only partly under
user control.  if you go through contortions like a loop or somthing
it might be possible to do anything you want with it, but that's more
of a workaround than an actual control of it.

to address your subject header q, windows and buffers are different.

but ime various operations can change the buffer list unexpectedly, as
evidenced by familairity with it used in a use case where you use next
and prev a lot.  switching windows might be one of them.  also a lot
of commands do bury-buffer.

i have noticed tht a strange operation that seems outwardly like it
should maybe be a noop someties fixes the problem of a buffer
"disappearing" from the buffer list [i.e. going to someplace that is
not nearby wrt next and prev].

i have also noticed that emacs treats buffers differently in the
buffer list if they have different names.  i am not sure about leading
spc buffers, but *buffers* are definitely treated differently.  i
think they can disappear more.

i have resorted to doing the seeming noop in defadvice and in ariosu
places just to guard superstitiously against the disappearing buffer
problem.  idk if tht problem is related to yours, but it probably is.

here it is
(switch-to-buffer (current-buffer))


On 2/1/22, Kevin Vigouroux via Users list for the GNU Emacs text
editor <help-gnu-emacs@gnu.org> wrote:
> `buffer-list' displays the buffers in a specific order: the buffer in
> the selected window is displayed first.
>
> I don’t really understand how it works, but we can see that the buffer
> appears at the end of the list when we select another window before
> evaluating the expression `(buffer-list)'.
> --
> Best regards,
> Kevin Vigouroux
>
>


-- 
The Kafka Pandemic

A blog about science, health, human rights, and misopathy:
https://thekafkapandemic.blogspot.com



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Switch buffers without modifying the buffer list ordering?
  2022-03-25 22:25   ` Samuel Wales
@ 2022-03-29  6:03     ` Kevin Vigouroux via Users list for the GNU Emacs text editor
  0 siblings, 0 replies; 8+ messages in thread
From: Kevin Vigouroux via Users list for the GNU Emacs text editor @ 2022-03-29  6:03 UTC (permalink / raw)
  To: Samuel Wales; +Cc: help-gnu-emacs

My mistake, I replied on the wrong mailing list. The original thread was on
emacs-devel.

▶ https://lists.gnu.org/archive/html/emacs-devel/2022-02/msg00063.html
-- 
Best regards,
Kevin Vigouroux



^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2022-03-29  6:03 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-01-30 21:26 Switch buffers without modifying the buffer list ordering? Augusto Stoffel
2022-01-31  8:42 ` martin rudalics
2022-02-01 18:46   ` Augusto Stoffel
2022-02-02 11:24   ` Kevin Vigouroux via Emacs development discussions.
2022-02-01 14:35 ` Kevin Vigouroux via Users list for the GNU Emacs text editor
2022-03-25 22:25   ` Samuel Wales
2022-03-29  6:03     ` Kevin Vigouroux via Users list for the GNU Emacs text editor
2022-02-01 14:48 ` Kevin Vigouroux via Emacs development discussions.

Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.