all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
* bug#20100: 24.4.91; Can't scroll a window while in minibuffer
@ 2015-03-13 12:51 Oleh Krehel
  2015-03-13 16:58 ` martin rudalics
  0 siblings, 1 reply; 7+ messages in thread
From: Oleh Krehel @ 2015-03-13 12:51 UTC (permalink / raw)
  To: 20100


I'm trying to write a completion package using `read-from-minibuffer'
combined with `post-command-hook'.

Everything is working OK, except when I want to sync the current
completion candidate (one of buffer's lines) with the corresponding line
in the buffer.

This code, specifically `recenter', doesn't work:

(with-current-buffer buf
  (goto-char (point-min))
  (forward-line (1- num))
  (recenter))

However, this code will scroll the window (`buf' and `wnd' correspond to
each other):

(with-current-buffer buf
  (goto-char (point-min))
  (forward-line (1- num))
  (setf (window-point wnd)
        (point)))

Still, it's not a perfect solution, since even after setting
`window-point', (window-start wnd) and (window-end wnd t) will not
return the correct thing.

I'm pretty sure it's a bug and the code above should work as is, but I'd
also appreciate pointers for achieving the scrolling and window bounds
re-calculation for the current Emacs.

regards,
Oleh





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

* bug#20100: 24.4.91; Can't scroll a window while in minibuffer
  2015-03-13 12:51 bug#20100: 24.4.91; Can't scroll a window while in minibuffer Oleh Krehel
@ 2015-03-13 16:58 ` martin rudalics
  2015-03-13 17:10   ` Oleh Krehel
  0 siblings, 1 reply; 7+ messages in thread
From: martin rudalics @ 2015-03-13 16:58 UTC (permalink / raw)
  To: Oleh Krehel, 20100

 > I'm trying to write a completion package using `read-from-minibuffer'
 > combined with `post-command-hook'.
 >
 > Everything is working OK, except when I want to sync the current
 > completion candidate (one of buffer's lines) with the corresponding line
 > in the buffer.
 >
 > This code, specifically `recenter', doesn't work:
 >
 > (with-current-buffer buf
 >    (goto-char (point-min))
 >    (forward-line (1- num))
 >    (recenter))

I suppose that at the time you invoke `recenter', the selected window
doesn't show `buf'.  When with emacs -Q I do

(let ((buffer (get-buffer-create "*buffer*"))
       (line 0))
   (set-window-buffer nil buffer)
   (with-current-buffer buffer
     (while (< line 100)
       (insert (format "%02d\n" line))
       (setq line (1+ line))))

   (with-current-buffer buffer
     (goto-char (point-min))
     (forward-line 25)
     (recenter)))

then I see the line starting with "25" centered in the selected window.
Can you try modifying my example such that it "doesn't work for you"?

 > However, this code will scroll the window (`buf' and `wnd' correspond to
 > each other):
 >
 > (with-current-buffer buf
 >    (goto-char (point-min))
 >    (forward-line (1- num))
 >    (setf (window-point wnd)
 >          (point)))

The fact that you apparently have to

(setf (window-point wnd) (point))

seems to suport my claim above, namely that `wnd' is not selected at
that time.

 > Still, it's not a perfect solution, since even after setting
 > `window-point', (window-start wnd) and (window-end wnd t) will not
 > return the correct thing.

What is the wrong thing and what would the correct thing be?  The only
function that should work "correctly" here is `set-window-start'.

 > I'm pretty sure it's a bug and the code above should work as is, but I'd
 > also appreciate pointers for achieving the scrolling and window bounds
 > re-calculation for the current Emacs.

Beyond what you can read in the documentations, explaining `recenter' is
hardly possible without explaining redisplay as well.  You have to look
at its implementation.

martin





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

* bug#20100: 24.4.91; Can't scroll a window while in minibuffer
  2015-03-13 16:58 ` martin rudalics
@ 2015-03-13 17:10   ` Oleh Krehel
  2015-03-13 18:16     ` martin rudalics
  0 siblings, 1 reply; 7+ messages in thread
From: Oleh Krehel @ 2015-03-13 17:10 UTC (permalink / raw)
  To: martin rudalics; +Cc: 20100

Hi Martin,

On Fri, Mar 13, 2015 at 5:58 PM, martin rudalics <rudalics@gmx.at> wrote:
>> I'm trying to write a completion package using `read-from-minibuffer'
>> combined with `post-command-hook'.
>>
>> Everything is working OK, except when I want to sync the current
>> completion candidate (one of buffer's lines) with the corresponding line
>> in the buffer.
>>
>> This code, specifically `recenter', doesn't work:
>>
>> (with-current-buffer buf
>>    (goto-char (point-min))
>>    (forward-line (1- num))
>>    (recenter))
>
> I suppose that at the time you invoke `recenter', the selected window
> doesn't show `buf'.  When with emacs -Q I do
>
> (let ((buffer (get-buffer-create "*buffer*"))
>       (line 0))
>   (set-window-buffer nil buffer)
>   (with-current-buffer buffer
>     (while (< line 100)
>       (insert (format "%02d\n" line))
>       (setq line (1+ line))))
>
>   (with-current-buffer buffer
>     (goto-char (point-min))
>     (forward-line 25)
>     (recenter)))
>
> then I see the line starting with "25" centered in the selected window.
> Can you try modifying my example such that it "doesn't work for you"?

You need to be in the minibuffer in order for the effect to occur,
which you're not.

See my question on Emacs Stack Exchange for a simple way to reproduce the issue:
http://emacs.stackexchange.com/questions/9967/how-to-scroll-another-buffer-while-in-minibuffer

However, what I'm actually trying to do is here:
https://raw.githubusercontent.com/abo-abo/swiper/master/ivy.el

> The fact that you apparently have to
>
> (setf (window-point wnd) (point))
>
> seems to suport my claim above, namely that `wnd' is not selected at
> that time.

It is selected, only the minibufer is interfering.

>> Still, it's not a perfect solution, since even after setting
>> `window-point', (window-start wnd) and (window-end wnd t) will not
>> return the correct thing.
>
> What is the wrong thing and what would the correct thing be?  The only
> function that should work "correctly" here is `set-window-start'.

`set-window-start' doesn't work. The issue is that the scroll
happended and visibly the window start has changed, but `window-start`
still returns the old value.

> Beyond what you can read in the documentations, explaining `recenter' is
> hardly possible without explaining redisplay as well.  You have to look
> at its implementation.

Thanks, I might get to that eventually, I just wanted to hear the
expert opinion, maybe this is a
known problem. My current work-around for re-computing the changed
`window-start' and `window-end'
is to call `forward-line' with the window height parameter.

Oleh





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

* bug#20100: 24.4.91; Can't scroll a window while in minibuffer
  2015-03-13 17:10   ` Oleh Krehel
@ 2015-03-13 18:16     ` martin rudalics
  2015-03-13 18:41       ` Oleh Krehel
  0 siblings, 1 reply; 7+ messages in thread
From: martin rudalics @ 2015-03-13 18:16 UTC (permalink / raw)
  To: Oleh Krehel; +Cc: 20100

 > You need to be in the minibuffer in order for the effect to occur,
 > which you're not.

I know but you didn't give a recipe.

 >> The fact that you apparently have to
 >>
 >> (setf (window-point wnd) (point))
 >>
 >> seems to suport my claim above, namely that `wnd' is not selected at
 >> that time.
 >
 > It is selected, only the minibufer is interfering.

It apparently is _not_ selected (at least not in your snippet).  With
emacs -Q evaluate the following code:

(let ((buffer (get-buffer-create "*buffer*"))
       (window (selected-window))
       (line 0))
   (set-window-buffer nil buffer)
   (with-current-buffer buffer
     (while (< line 100)
       (insert (format "%02d\n" line))
       (setq line (1+ line))))

   (with-selected-window (minibuffer-window)
     (with-selected-window window
       (goto-char (point-min))
       (forward-line 25)
       (recenter))
     (insert "This is your minibuffer window!")
     (sit-for 5)))

Can you see the difference?

martin





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

* bug#20100: 24.4.91; Can't scroll a window while in minibuffer
  2015-03-13 18:16     ` martin rudalics
@ 2015-03-13 18:41       ` Oleh Krehel
  2015-03-13 20:58         ` Eli Zaretskii
  2015-03-14  8:17         ` martin rudalics
  0 siblings, 2 replies; 7+ messages in thread
From: Oleh Krehel @ 2015-03-13 18:41 UTC (permalink / raw)
  To: martin rudalics; +Cc: 20100

> It apparently is _not_ selected (at least not in your snippet).  With
> emacs -Q evaluate the following code:
>
> (let ((buffer (get-buffer-create "*buffer*"))
>       (window (selected-window))
>       (line 0))
>   (set-window-buffer nil buffer)
>   (with-current-buffer buffer
>     (while (< line 100)
>       (insert (format "%02d\n" line))
>       (setq line (1+ line))))
>
>   (with-selected-window (minibuffer-window)
>     (with-selected-window window
>       (goto-char (point-min))
>       (forward-line 25)
>       (recenter))
>     (insert "This is your minibuffer window!")
>     (sit-for 5)))
>
> Can you see the difference?

Thanks, using `with-selected-window' instead of `with-current-buffer'
solved it. I thought that they should be equivalent. Apparently they are not.

So the problem is solved, thanks again.

Oleh





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

* bug#20100: 24.4.91; Can't scroll a window while in minibuffer
  2015-03-13 18:41       ` Oleh Krehel
@ 2015-03-13 20:58         ` Eli Zaretskii
  2015-03-14  8:17         ` martin rudalics
  1 sibling, 0 replies; 7+ messages in thread
From: Eli Zaretskii @ 2015-03-13 20:58 UTC (permalink / raw)
  To: Oleh Krehel; +Cc: 20100

> Date: Fri, 13 Mar 2015 19:41:38 +0100
> From: Oleh Krehel <ohwoeowho@gmail.com>
> Cc: 20100@debbugs.gnu.org
> 
> Thanks, using `with-selected-window' instead of `with-current-buffer'
> solved it. I thought that they should be equivalent. Apparently they are not.

with-current-buffer makes the buffer current for the purposes of
editing, but not for the purposes of redisplay.  By contrast,
'recenter' needs a window to do its job, so it must have the buffer
selected in the current window.





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

* bug#20100: 24.4.91; Can't scroll a window while in minibuffer
  2015-03-13 18:41       ` Oleh Krehel
  2015-03-13 20:58         ` Eli Zaretskii
@ 2015-03-14  8:17         ` martin rudalics
  1 sibling, 0 replies; 7+ messages in thread
From: martin rudalics @ 2015-03-14  8:17 UTC (permalink / raw)
  To: Oleh Krehel; +Cc: 20100-done

 > Thanks, using `with-selected-window' instead of `with-current-buffer'
 > solved it. I thought that they should be equivalent. Apparently they are not.

It's a trap.  Commands that implicitly work on the selected window
should not be used programmatically.  Such commands are `recenter',
`enlarge-window', `shrink-window', `split-window-below' and
`split-window-right'.  When used in applications the only way to make
them behave is to wrap them in `with-selected-window' :-(

There are also more specialized commands like `recenter-top-bottom' or
`move-to-window-line-top-bottom' whose doc-strings don't explain what
they do.  Never use them in programs!

martin, closing this bug





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

end of thread, other threads:[~2015-03-14  8:17 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-03-13 12:51 bug#20100: 24.4.91; Can't scroll a window while in minibuffer Oleh Krehel
2015-03-13 16:58 ` martin rudalics
2015-03-13 17:10   ` Oleh Krehel
2015-03-13 18:16     ` martin rudalics
2015-03-13 18:41       ` Oleh Krehel
2015-03-13 20:58         ` Eli Zaretskii
2015-03-14  8:17         ` martin rudalics

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.