* Something like `without-redisplay'?
@ 2015-08-31 9:49 Alexander Shukaev
2015-08-31 14:23 ` Eli Zaretskii
0 siblings, 1 reply; 13+ messages in thread
From: Alexander Shukaev @ 2015-08-31 9:49 UTC (permalink / raw)
To: help-gnu-emacs
Hello,
Can redisplay occur during command execution (in between of forms)?
If yes, then wouldn't this produce nasty flickering in some cases
(especially when one manipulates point)? If all the above is true,
then is there some form to protect the code from running redisplay
during its execution?
(without-redisplay
...
...)
Regards,
Alexander
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Something like `without-redisplay'?
2015-08-31 9:49 Something like `without-redisplay'? Alexander Shukaev
@ 2015-08-31 14:23 ` Eli Zaretskii
2015-08-31 19:32 ` Alexander Shukaev
0 siblings, 1 reply; 13+ messages in thread
From: Eli Zaretskii @ 2015-08-31 14:23 UTC (permalink / raw)
To: help-gnu-emacs
> Date: Mon, 31 Aug 2015 11:49:56 +0200
> From: Alexander Shukaev <haroogan@gmail.com>
>
> Can redisplay occur during command execution (in between of forms)?
In general, no. Emacs only enters redisplay when it is idle and no
input is available. But Lisp programs can trigger redisplay by
calling some functions, like sit-for.
> If yes, then wouldn't this produce nasty flickering in some cases
> (especially when one manipulates point)?
It depends on what the Lisp program does.
> If all the above is true, then is there some form to protect the
> code from running redisplay during its execution?
>
> (without-redisplay
It's the default. Just don't anything that will forcefully trigger
redisplay.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Something like `without-redisplay'?
2015-08-31 14:23 ` Eli Zaretskii
@ 2015-08-31 19:32 ` Alexander Shukaev
2015-08-31 23:37 ` Alexander Shukaev
0 siblings, 1 reply; 13+ messages in thread
From: Alexander Shukaev @ 2015-08-31 19:32 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: help-gnu-emacs
>> Can redisplay occur during command execution (in between of forms)?
>
> In general, no. Emacs only enters redisplay when it is idle and no
> input is available. But Lisp programs can trigger redisplay by
> calling some functions, like sit-for.
>
>> If yes, then wouldn't this produce nasty flickering in some cases
>> (especially when one manipulates point)?
>
> It depends on what the Lisp program does.
>
>> If all the above is true, then is there some form to protect the
>> code from running redisplay during its execution?
>>
>> (without-redisplay
>
> It's the default. Just don't anything that will forcefully trigger
> redisplay.
Thanks, Eli.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Something like `without-redisplay'?
2015-08-31 19:32 ` Alexander Shukaev
@ 2015-08-31 23:37 ` Alexander Shukaev
2015-09-01 2:39 ` Eli Zaretskii
0 siblings, 1 reply; 13+ messages in thread
From: Alexander Shukaev @ 2015-08-31 23:37 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: help-gnu-emacs
A couple of related questions. I have written several macros like the
following:
(defmacro devil-without-window-hscroll
(&rest body)
"\
Execute BODY without horizontal scrolling in the selected window."
(declare (debug t)
(indent defun))
`(let ((hscroll (window-hscroll)))
(set-window-hscroll (selected-window) 0)
(unwind-protect
(progn ,@body)
(set-window-hscroll (selected-window) hscroll))))
In brief, these are macros which somehow alter viewport (how window
views a buffer) temporarily and then restore it. For instance, if
`auto-hscroll-mode' is on, should I fear that `set-window-hscroll'
will move point? I personally, have not experienced this problem, but
still I want to know exactly what to expect. For example, would you
recommend to wrap `set-window-hscroll' into `save-excursion' or that
would be redundant? By the way, the same would apply to vertical
changes in viewport (due to vertical scrolling, for example) as Emacs
auto-scrolls (moves point to keep it in viewport) by default. Yet,
again, I've never experienced any problem with this too.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Something like `without-redisplay'?
2015-08-31 23:37 ` Alexander Shukaev
@ 2015-09-01 2:39 ` Eli Zaretskii
2015-09-01 13:56 ` Alexander Shukaev
0 siblings, 1 reply; 13+ messages in thread
From: Eli Zaretskii @ 2015-09-01 2:39 UTC (permalink / raw)
To: help-gnu-emacs
> Date: Tue, 1 Sep 2015 01:37:22 +0200
> From: Alexander Shukaev <haroogan@gmail.com>
> Cc: help-gnu-emacs <help-gnu-emacs@gnu.org>
>
> (defmacro devil-without-window-hscroll
> (&rest body)
> "\
> Execute BODY without horizontal scrolling in the selected window."
> (declare (debug t)
> (indent defun))
> `(let ((hscroll (window-hscroll)))
> (set-window-hscroll (selected-window) 0)
> (unwind-protect
> (progn ,@body)
> (set-window-hscroll (selected-window) hscroll))))
>
> In brief, these are macros which somehow alter viewport (how window
> views a buffer) temporarily and then restore it.
I don't understand the need for that: since redisplay doesn't happen
as long as the code runs, why would you need to manipulate the
viewport like that during the execution, just to have it back by the
time redisplay is about to happen?
> For instance, if `auto-hscroll-mode' is on, should I fear that
> `set-window-hscroll' will move point? I personally, have not
> experienced this problem, but still I want to know exactly what to
> expect. For example, would you recommend to wrap
> `set-window-hscroll' into `save-excursion' or that would be
> redundant? By the way, the same would apply to vertical changes in
> viewport (due to vertical scrolling, for example) as Emacs
> auto-scrolls (moves point to keep it in viewport) by default. Yet,
> again, I've never experienced any problem with this too.
In general, hscroll only scrolls if point goes out of view. Vertical
scroll can happen even with point is in view, under some rare
situations.
But again, I don't understand what you want to accomplish with these
macros, so I cannot answer your questions yet.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Something like `without-redisplay'?
2015-09-01 2:39 ` Eli Zaretskii
@ 2015-09-01 13:56 ` Alexander Shukaev
2015-09-01 14:52 ` Eli Zaretskii
0 siblings, 1 reply; 13+ messages in thread
From: Alexander Shukaev @ 2015-09-01 13:56 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: help-gnu-emacs
>> (defmacro devil-without-window-hscroll
>> (&rest body)
>> "\
>> Execute BODY without horizontal scrolling in the selected window."
>> (declare (debug t)
>> (indent defun))
>> `(let ((hscroll (window-hscroll)))
>> (set-window-hscroll (selected-window) 0)
>> (unwind-protect
>> (progn ,@body)
>> (set-window-hscroll (selected-window) hscroll))))
>>
>> In brief, these are macros which somehow alter viewport (how window
>> views a buffer) temporarily and then restore it.
>
> I don't understand the need for that: since redisplay doesn't happen
> as long as the code runs, why would you need to manipulate the
> viewport like that during the execution, just to have it back by the
> time redisplay is about to happen?
>
>> For instance, if `auto-hscroll-mode' is on, should I fear that
>> `set-window-hscroll' will move point? I personally, have not
>> experienced this problem, but still I want to know exactly what to
>> expect. For example, would you recommend to wrap
>> `set-window-hscroll' into `save-excursion' or that would be
>> redundant? By the way, the same would apply to vertical changes in
>> viewport (due to vertical scrolling, for example) as Emacs
>> auto-scrolls (moves point to keep it in viewport) by default. Yet,
>> again, I've never experienced any problem with this too.
>
> In general, hscroll only scrolls if point goes out of view. Vertical
> scroll can happen even with point is in view, under some rare
> situations.
>
> But again, I don't understand what you want to accomplish with these
> macros, so I cannot answer your questions yet.
This macro is not about redisplay. I just found one corner case when
`evil-previous-visual-line' and `evil-next-visual-line' which are
based on `evil-line-move',
;; The purpose of this function is the provide line motions which
;; preserve the column. This is how `previous-line' and `next-line'
;; work, but unfortunately the behaviour is hard-coded: if and only if
;; the last command was `previous-line' or `next-line', the column is
;; preserved. Furthermore, in contrast to Vim, when we cannot go
;; further, those motions move point to the beginning resp. the end of
;; the line (we never want point to leave its column). The code here
;; comes from simple.el, and I hope it will work in future.
(defun evil-line-move (count &optional noerror)
"A wrapper for line motions which conserves the column.
Signals an error at buffer boundaries unless NOERROR is non-nil."
(cond
(noerror
(condition-case nil
(evil-line-move count)
(error nil)))
(t
(evil-signal-without-movement
(setq this-command (if (>= count 0)
#'next-line
#'previous-line))
(let ((opoint (point)))
(condition-case err
(with-no-warnings
(funcall this-command (abs count)))
((beginning-of-buffer end-of-buffer)
(let ((col (or goal-column
(if (consp temporary-goal-column)
(car temporary-goal-column)
temporary-goal-column))))
(if line-move-visual
(vertical-motion (cons col 0))
(line-move-finish col opoint (< count 0)))
;; Maybe we should just `ding'?
(signal (car err) (cdr err))))))))))
behave incorrectly when window has non-zero horizontal scroll. The
problem might be deep in how Emacs implements `next-line' or
`previous-line' or whatever. But I found a solution, when I use
`evil-previous-visual-line' and `evil-next-visual-line' in my own
functions, I simply wrap their calls into the
`devil-without-window-hscroll' macro, so that during their execution
there is no horizontal scrolling. What is important to me, is that
the point does not unintentionally move as a side effect of
`devil-without-window-hscroll'. That was the question basically: can
the point move due to application of such macros?
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Something like `without-redisplay'?
2015-09-01 13:56 ` Alexander Shukaev
@ 2015-09-01 14:52 ` Eli Zaretskii
2015-09-01 15:24 ` Alexander Shukaev
0 siblings, 1 reply; 13+ messages in thread
From: Eli Zaretskii @ 2015-09-01 14:52 UTC (permalink / raw)
To: help-gnu-emacs
> Date: Tue, 1 Sep 2015 15:56:36 +0200
> From: Alexander Shukaev <haroogan@gmail.com>
> Cc: help-gnu-emacs <help-gnu-emacs@gnu.org>
>
> This macro is not about redisplay. I just found one corner case when
> `evil-previous-visual-line' and `evil-next-visual-line' which are
> based on `evil-line-move',
>
> ;; The purpose of this function is the provide line motions which
> ;; preserve the column. This is how `previous-line' and `next-line'
> ;; work, but unfortunately the behaviour is hard-coded: if and only if
> ;; the last command was `previous-line' or `next-line', the column is
> ;; preserved. Furthermore, in contrast to Vim, when we cannot go
> ;; further, those motions move point to the beginning resp. the end of
> ;; the line (we never want point to leave its column). The code here
> ;; comes from simple.el, and I hope it will work in future.
> (defun evil-line-move (count &optional noerror)
> "A wrapper for line motions which conserves the column.
> Signals an error at buffer boundaries unless NOERROR is non-nil."
> (cond
> (noerror
> (condition-case nil
> (evil-line-move count)
> (error nil)))
> (t
> (evil-signal-without-movement
> (setq this-command (if (>= count 0)
> #'next-line
> #'previous-line))
> (let ((opoint (point)))
> (condition-case err
> (with-no-warnings
> (funcall this-command (abs count)))
> ((beginning-of-buffer end-of-buffer)
> (let ((col (or goal-column
> (if (consp temporary-goal-column)
> (car temporary-goal-column)
> temporary-goal-column))))
> (if line-move-visual
> (vertical-motion (cons col 0))
> (line-move-finish col opoint (< count 0)))
> ;; Maybe we should just `ding'?
> (signal (car err) (cdr err))))))))))
>
> behave incorrectly when window has non-zero horizontal scroll. The
> problem might be deep in how Emacs implements `next-line' or
> `previous-line' or whatever.
More likely, the function in question has bug.
> But I found a solution, when I use `evil-previous-visual-line' and
> `evil-next-visual-line' in my own functions, I simply wrap their
> calls into the `devil-without-window-hscroll' macro, so that during
> their execution there is no horizontal scrolling.
I'd suggest to find the bug in the function and fix it instead.
> What is important to me, is that the point does not unintentionally
> move as a side effect of `devil-without-window-hscroll'. That was
> the question basically: can the point move due to application of
> such macros?
It can in rare cases, if you scroll vertically. It all depends on
what the code does, exactly.
Horizontal scrolling doesn't move point, AFAIR.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Something like `without-redisplay'?
2015-09-01 14:52 ` Eli Zaretskii
@ 2015-09-01 15:24 ` Alexander Shukaev
2015-09-01 15:57 ` Eli Zaretskii
0 siblings, 1 reply; 13+ messages in thread
From: Alexander Shukaev @ 2015-09-01 15:24 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: help-gnu-emacs
>> This macro is not about redisplay. I just found one corner case when
>> `evil-previous-visual-line' and `evil-next-visual-line' which are
>> based on `evil-line-move',
>>
>> ;; The purpose of this function is the provide line motions which
>> ;; preserve the column. This is how `previous-line' and `next-line'
>> ;; work, but unfortunately the behaviour is hard-coded: if and only if
>> ;; the last command was `previous-line' or `next-line', the column is
>> ;; preserved. Furthermore, in contrast to Vim, when we cannot go
>> ;; further, those motions move point to the beginning resp. the end of
>> ;; the line (we never want point to leave its column). The code here
>> ;; comes from simple.el, and I hope it will work in future.
>> (defun evil-line-move (count &optional noerror)
>> "A wrapper for line motions which conserves the column.
>> Signals an error at buffer boundaries unless NOERROR is non-nil."
>> (cond
>> (noerror
>> (condition-case nil
>> (evil-line-move count)
>> (error nil)))
>> (t
>> (evil-signal-without-movement
>> (setq this-command (if (>= count 0)
>> #'next-line
>> #'previous-line))
>> (let ((opoint (point)))
>> (condition-case err
>> (with-no-warnings
>> (funcall this-command (abs count)))
>> ((beginning-of-buffer end-of-buffer)
>> (let ((col (or goal-column
>> (if (consp temporary-goal-column)
>> (car temporary-goal-column)
>> temporary-goal-column))))
>> (if line-move-visual
>> (vertical-motion (cons col 0))
>> (line-move-finish col opoint (< count 0)))
>> ;; Maybe we should just `ding'?
>> (signal (car err) (cdr err))))))))))
>>
>> behave incorrectly when window has non-zero horizontal scroll. The
>> problem might be deep in how Emacs implements `next-line' or
>> `previous-line' or whatever.
>
> More likely, the function in question has bug.
>
>> But I found a solution, when I use `evil-previous-visual-line' and
>> `evil-next-visual-line' in my own functions, I simply wrap their
>> calls into the `devil-without-window-hscroll' macro, so that during
>> their execution there is no horizontal scrolling.
>
> I'd suggest to find the bug in the function and fix it instead.
I'd love to, but I'm no expert with these. Unfortunately, can't
afford some time for this now.
>> What is important to me, is that the point does not unintentionally
>> move as a side effect of `devil-without-window-hscroll'. That was
>> the question basically: can the point move due to application of
>> such macros?
>
> It can in rare cases, if you scroll vertically. It all depends on
> what the code does, exactly.
OK, then here is an example
(save-excursion (scroll-down 10)) ;; just scroll
(previous-line 10) ;; then move point with the method we want
I've tested it and so far, I see no problems with it. I think there
is another option to do the same like this
(save-window-excursion (previous-line 10)) ;; just move point with the
method we want
(save-excursion (scroll-down 10)) ;; then scroll
Which one is more reliable? Can I even expect any problems with these codes?
> Horizontal scrolling doesn't move point, AFAIR.
Even if `auto-hscroll-mode' is on (which it is by default)?
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Something like `without-redisplay'?
2015-09-01 15:24 ` Alexander Shukaev
@ 2015-09-01 15:57 ` Eli Zaretskii
2015-09-01 16:10 ` Alexander Shukaev
2015-09-01 16:47 ` Alexander Shukaev
0 siblings, 2 replies; 13+ messages in thread
From: Eli Zaretskii @ 2015-09-01 15:57 UTC (permalink / raw)
To: help-gnu-emacs
> Date: Tue, 1 Sep 2015 17:24:08 +0200
> From: Alexander Shukaev <haroogan@gmail.com>
> Cc: help-gnu-emacs <help-gnu-emacs@gnu.org>
>
> >> behave incorrectly when window has non-zero horizontal scroll. The
> >> problem might be deep in how Emacs implements `next-line' or
> >> `previous-line' or whatever.
> >
> > More likely, the function in question has bug.
> >
> >> But I found a solution, when I use `evil-previous-visual-line' and
> >> `evil-next-visual-line' in my own functions, I simply wrap their
> >> calls into the `devil-without-window-hscroll' macro, so that during
> >> their execution there is no horizontal scrolling.
> >
> > I'd suggest to find the bug in the function and fix it instead.
>
> I'd love to, but I'm no expert with these. Unfortunately, can't
> afford some time for this now.
Did you report the problem to the maintainer of that code? If not, I
suggest to do that.
> > It can in rare cases, if you scroll vertically. It all depends on
> > what the code does, exactly.
>
> OK, then here is an example
>
> (save-excursion (scroll-down 10)) ;; just scroll
> (previous-line 10) ;; then move point with the method we want
>
> I've tested it and so far, I see no problems with it. I think there
> is another option to do the same like this
>
> (save-window-excursion (previous-line 10)) ;; just move point with the
> method we want
> (save-excursion (scroll-down 10)) ;; then scroll
>
> Which one is more reliable? Can I even expect any problems with these codes?
Not with these, I think. I'm sorry, I cannot give any precise
instructions regarding what not to do, except repeating that in
general it is very unlikely that you will see point moving when Lisp
code takes care to return point to the same place and does not change
the window configuration. I just know that some code paths inside
redisplay are capable of moving point if they otherwise cannot satisfy
the constraints of vertical position of point, such as scroll-margin.
> > Horizontal scrolling doesn't move point, AFAIR.
>
> Even if `auto-hscroll-mode' is on (which it is by default)?
auto-hscroll-mode does the opposite: it scrolls the display to move
point into the view. It doesn't move point.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Something like `without-redisplay'?
2015-09-01 15:57 ` Eli Zaretskii
@ 2015-09-01 16:10 ` Alexander Shukaev
2015-09-01 16:47 ` Alexander Shukaev
1 sibling, 0 replies; 13+ messages in thread
From: Alexander Shukaev @ 2015-09-01 16:10 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: help-gnu-emacs
Understood. Thanks, Eli.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Something like `without-redisplay'?
2015-09-01 15:57 ` Eli Zaretskii
2015-09-01 16:10 ` Alexander Shukaev
@ 2015-09-01 16:47 ` Alexander Shukaev
2015-09-01 17:00 ` Eli Zaretskii
1 sibling, 1 reply; 13+ messages in thread
From: Alexander Shukaev @ 2015-09-01 16:47 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: help-gnu-emacs
>> > Horizontal scrolling doesn't move point, AFAIR.
>>
>> Even if `auto-hscroll-mode' is on (which it is by default)?
>
> auto-hscroll-mode does the opposite: it scrolls the display to move
> point into the view. It doesn't move point.
Does it mean that
(save-excursion
(end-of-visual-line)
(current-column))
has potential to cause unintentional viewport movement?
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Something like `without-redisplay'?
2015-09-01 16:47 ` Alexander Shukaev
@ 2015-09-01 17:00 ` Eli Zaretskii
2015-09-01 17:24 ` Alexander Shukaev
0 siblings, 1 reply; 13+ messages in thread
From: Eli Zaretskii @ 2015-09-01 17:00 UTC (permalink / raw)
To: help-gnu-emacs
> Date: Tue, 1 Sep 2015 18:47:01 +0200
> From: Alexander Shukaev <haroogan@gmail.com>
> Cc: help-gnu-emacs <help-gnu-emacs@gnu.org>
>
> >> > Horizontal scrolling doesn't move point, AFAIR.
> >>
> >> Even if `auto-hscroll-mode' is on (which it is by default)?
> >
> > auto-hscroll-mode does the opposite: it scrolls the display to move
> > point into the view. It doesn't move point.
>
> Does it mean that
>
> (save-excursion
> (end-of-visual-line)
> (current-column))
>
> has potential to cause unintentional viewport movement?
Only if you force redisplay, or change the window width, as part of
the save-excursion form. Otherwise, by the time redisplay is entered,
point is back where it was, and no hscroll will happen.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Something like `without-redisplay'?
2015-09-01 17:00 ` Eli Zaretskii
@ 2015-09-01 17:24 ` Alexander Shukaev
0 siblings, 0 replies; 13+ messages in thread
From: Alexander Shukaev @ 2015-09-01 17:24 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: help-gnu-emacs
>> >> > Horizontal scrolling doesn't move point, AFAIR.
>> >>
>> >> Even if `auto-hscroll-mode' is on (which it is by default)?
>> >
>> > auto-hscroll-mode does the opposite: it scrolls the display to move
>> > point into the view. It doesn't move point.
>>
>> Does it mean that
>>
>> (save-excursion
>> (end-of-visual-line)
>> (current-column))
>>
>> has potential to cause unintentional viewport movement?
>
> Only if you force redisplay, or change the window width, as part of
> the save-excursion form. Otherwise, by the time redisplay is entered,
> point is back where it was, and no hscroll will happen.
Alright, now I understand the recipe. Thanks a lot, Eli.
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2015-09-01 17:24 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-08-31 9:49 Something like `without-redisplay'? Alexander Shukaev
2015-08-31 14:23 ` Eli Zaretskii
2015-08-31 19:32 ` Alexander Shukaev
2015-08-31 23:37 ` Alexander Shukaev
2015-09-01 2:39 ` Eli Zaretskii
2015-09-01 13:56 ` Alexander Shukaev
2015-09-01 14:52 ` Eli Zaretskii
2015-09-01 15:24 ` Alexander Shukaev
2015-09-01 15:57 ` Eli Zaretskii
2015-09-01 16:10 ` Alexander Shukaev
2015-09-01 16:47 ` Alexander Shukaev
2015-09-01 17:00 ` Eli Zaretskii
2015-09-01 17:24 ` Alexander Shukaev
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).