GNU bug report logs - #18923
Alternative scrolling model

Previous Next

Package: emacs;

Reported by: E Sabof <esabof <at> gmail.com>

Date: Sun, 2 Nov 2014 01:17:03 UTC

Severity: wishlist

Done: Lars Ingebrigtsen <larsi <at> gnus.org>

Bug is archived. No further changes may be made.

To add a comment to this bug, you must first unarchive it, by sending
a message to control AT debbugs.gnu.org, with unarchive 18923 in the body.
You can then email your comments to 18923 AT debbugs.gnu.org in the normal way.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to bug-gnu-emacs <at> gnu.org:
bug#18923; Package emacs. (Sun, 02 Nov 2014 01:17:03 GMT) Full text and rfc822 format available.

Acknowledgement sent to E Sabof <esabof <at> gmail.com>:
New bug report received and forwarded. Copy sent to bug-gnu-emacs <at> gnu.org. (Sun, 02 Nov 2014 01:17:03 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: E Sabof <esabof <at> gmail.com>
To: bug-gnu-emacs <at> gnu.org
Subject: Alternative scrolling model
Date: Sun, 02 Nov 2014 01:15:52 +0000
I've made a prototype for an alternative way to scroll. Essentially scrolling is done pixelwise irrespective of content. Whole lines are scrolled "normally", and the remainder is vscrolled. If the end result is close to a line boundary it gets "snapped" to it.

This prevents unpleasant jumping when encountering an image. It doesn't handle the "image taller than window" case, but it would if `st-height' could measure more accurately.

Evgeni

;; Any vscroll adjustements will be reset by line-move
(require 'cl-lib)
(defun st-message (&rest args)
  ;; (apply 'message args)
  )

(defvar st-ov nil)
(defun st-height (&optional pos)
  "Won't report accurately, if the line is higher than window."
  (cl-flet (( posn-y ()
              (cdr (posn-x-y (or (posn-at-point)
                                 (progn
                                   (vertical-motion 0)
                                   (set-window-start nil (point))
                                   (posn-at-point)))))))
    (save-excursion
      (save-window-excursion
        (let* ((ws (window-vscroll nil t))
               a b)
          (when (cl-plusp ws)
            (set-window-vscroll nil 0 t))
          (setq a (posn-y))
          (vertical-motion 1)
          (setq b (posn-y))
          (when (cl-plusp ws)
            (set-window-vscroll nil ws t))
          (- b a)
          )))))

(cl-defun st-get-lines (ammount)
  "Provide the information required to scroll by AMMOUNT.

AMMOUNT can be positive, if scrolling towards the end of the
buffer, or negative otherwise.

Returns \(list vscroll \(list lines\)\), where \"vscroll\" is the
current \(window-vscroll\) and \"lines\" are the lines are enogh
or more lines required for to scroll."

  (let* (( direction (if (cl-plusp ammount) 1 -1))
         ( vscroll (window-vscroll nil t))
         rows)
    (save-excursion
      (goto-char (window-start))
      (cl-incf ammount vscroll)
      (when (cl-minusp direction)
        (unless (cl-minusp ammount)
          (cl-return-from st-get-lines
            (list vscroll nil)))
        (vertical-motion -1))
      (cl-loop do (push (st-height) rows)
               until (or (zerop (vertical-motion direction))
                         ;; >= ?
                         (>= (cl-reduce '+ rows)
                             (abs ammount))))
      (list vscroll (nreverse rows)))))

(cl-defun st-move (lines vscroll)
  ;; vscroll changes aren't always displayed. Haven't found a work-around for this.
  (let (( ori-point (point))
        ( new-ws
          (save-excursion
            (goto-char (window-start))
            (vertical-motion lines)
            (point))))
    (progn
      (set-window-start nil new-ws)

      ;; If I don't do this, vscroll might get reset to 0

      ;; (point) might change after this

      ;; (window-start) might change after this, if the cursor is positioned on
      ;; that image, and scrolling down. This always happends if image would be
      ;; split at the bottom, but sometimes it happens earlier. What follows is
      ;; a work-around.

      (redisplay t)
      (when (/= (window-start) new-ws)
        ;; (message "HIT")
        (vertical-motion -1)
        (set-window-start nil new-ws)
        (redisplay t)
        )
      )
    (set-window-vscroll nil vscroll t)

    ;; Prevents flashes of incorrectly positioned images

    ;; (window-start) might change after this, if the cursor is on an image and
    ;; it might get divided on the upper edge

    (redisplay t)

    (when (/= (window-start) new-ws)
      ;; (message "HIT2")
      (vertical-motion 1)
      (set-window-start nil new-ws)
      (redisplay t)
      )

    ))

(cl-defun scroll--backtick (&optional (arg 1) pixelwise snap)
  (interactive)

  (let* (( default-height (default-line-height))
         ( pixels-to-move (if pixelwise
                              arg
                            (* arg default-height)))
         ( snap (or snap (/ default-height 2)))
         ( line-info (st-get-lines (- pixels-to-move)))
         ( heights (cadr line-info))
         ( initial-vscroll (car line-info))
         ( excess 0)
         enough-or-too-many-heights
         too-few-heights)

    (if (<= pixels-to-move initial-vscroll)
        (progn
          (setq heights nil
                excess (- initial-vscroll pixels-to-move)))

      (cl-decf pixels-to-move initial-vscroll)

      (setq enough-or-too-many-heights (cl-reduce '+ heights)
            too-few-heights (cl-reduce '+ (butlast heights) :initial-value 0))

      (cond ( (= enough-or-too-many-heights pixels-to-move)
              (st-message "Exact %s" heights)
              )
            ( (> pixels-to-move enough-or-too-many-heights)
              (st-message "Near edge %s > %s"
                          pixels-to-move
                          enough-or-too-many-heights)
              (setq excess 0))

            ( (<= (- enough-or-too-many-heights snap)
                  pixels-to-move)
              (st-message "Snap out")
              (setq excess 0))

            ( (and (cl-plusp too-few-heights)
                   (>= (+ too-few-heights snap)
                       pixels-to-move))
              (st-message "Snap in %s" heights)
              (setq excess 0)
              (setq heights (butlast heights))
              )

            ( t
              (st-message "Default")
              (setq excess (- enough-or-too-many-heights
                              pixels-to-move))
              )))

    (st-move (- (length heights)) excess)

    ))

(cl-defun scroll-tick (&optional (arg 1) pixelwise snap)
  (interactive)
  (cond ( (zerop arg)
          (cl-return-from scroll-tick))
        ( (< arg 0)
          (cl-return-from scroll-tick
            (scroll--backtick (- arg) pixelwise snap))))
  (when st-ov (delete-overlay st-ov))

  (let* (( default-height (default-line-height))
         ( pixels-to-move (if pixelwise
                              arg
                            (* arg default-height)))
         ( snap (or snap (/ default-height 2)))
         ( line-info (st-get-lines pixels-to-move))
         ( heights (cadr line-info))
         ( initial-vscroll (car line-info))
         excess
         enough-or-too-many-heights
         too-few-heights)

    (cl-incf pixels-to-move initial-vscroll)

    (setq enough-or-too-many-heights (cl-reduce '+ heights)
          too-few-heights (cl-reduce '+ (butlast heights) :initial-value 0)
          excess (if (= enough-or-too-many-heights pixels-to-move)
                     0
                   (- pixels-to-move too-few-heights)))
    (cond ( (= enough-or-too-many-heights pixels-to-move)
            (st-message "Exact %s" heights)
            )
          ( (> pixels-to-move enough-or-too-many-heights)
            (st-message "Near edge")
            (setq excess 0))

          ( (<= (- enough-or-too-many-heights snap)
                pixels-to-move)
            (st-message "Snap out")
            (setq excess 0))

          ( (and (cl-plusp too-few-heights)
                 (>= (+ too-few-heights snap)
                     pixels-to-move))
            (st-message "Snap in %s" heights)
            (setq excess 0)
            (setq heights (butlast heights))
            )
          ( t
            (st-message "Default")
            (setq heights (butlast heights))
            ))

    (st-move (length heights) excess)

    ))

;; (global-set-key (kbd "<next>") (lambda () (interactive) (scroll-tick 10)))
;; (global-set-key (kbd "<prior>") (lambda () (interactive) (scroll-tick -10)))

;; TESTS

;; (require 'noflet)

;; (ert-deftest scroll-tick ()
;;   (noflet (( st-move (&rest args) args))
;;     (noflet (( st-get-lines (arg)
;;                '(0 (30))))
;;       ;; Simple V-scroll
;;       (should (equal (scroll-tick 5 t 0)
;;                 '(0 5)))
;;       ;; Simple exact
;;       (should (equal (scroll-tick 30 t 0)
;;                 '(1 0)))

;;       )

;;     (noflet (( st-get-lines (arg)
;;                '(0 (5 30))))
;;       ;; Complete line + vscroll
;;       (should (equal (scroll-tick 15 t 0)
;;                 '(1 10)))
;;       ;; Complete 2 lines
;;       (should (equal (scroll-tick 35 t 0)
;;                 '(2 0)))
;;       )

;;     (noflet (( st-get-lines (arg)
;;                '(5 (10 20))))
;;       ;;
;;       (should (equal (scroll-tick 20 t 0)
;;                 '(1 15)))
;;       ;; Complete 2 lines
;;       (should (equal (scroll-tick 25 t 0)
;;                 '(2 0)))
;;       ))
;;   )

;; (ert-deftest scroll-backtick ()
;;   (noflet (( st-move (&rest args) args))
;;     (noflet (( st-get-lines (arg)
;;                '(0 (30))))
;;       ;; Simple V-scroll
;;       (should (equal (scroll-tick -5 t 0)
;;                 '(-1 25)))
;;       ;; Simple exact
;;       (should (equal (scroll-tick -30 t 0)
;;                 '(-1 0))))

;;     (noflet (( st-get-lines (arg)
;;                '(0 (5 30))))
;;       ;; Complete line + vscroll
;;       (should (equal (scroll-tick -15 t 0)
;;                 '(-2 20)))
;;       ;; Complete 2 lines
;;       (should (equal (scroll-tick -35 t 0)
;;                 '(-2 0)))
;;       )

;;     (noflet (( st-get-lines (arg)
;;                '(5 (10))))

;;       ;; Scroll across existing vscroll + a bit
;;       (should (equal (scroll-tick -10 t 0)
;;                 '(-1 5)))
;;       )

;;     (noflet (( st-get-lines (arg)
;;                '(5 (10 20))))
;;       ;; Scroll up a bit
;;       (should (equal (scroll-tick -1 t 0)
;;                 '(0 4)))
;;       ;; Remove vscroll
;;       (should (equal (scroll-tick -5 t 0)
;;                 '(0 0)))

;;       ;;
;;       (should (equal (scroll-tick -20 t 0)
;;                 '(-2 15)))

;;       )

;;     )
;;   )




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#18923; Package emacs. (Sun, 02 Nov 2014 02:32:01 GMT) Full text and rfc822 format available.

Message #8 received at submit <at> debbugs.gnu.org (full text, mbox):

From: E Sabof <esabof <at> gmail.com>
To: bug-gnu-emacs <at> gnu.org
Subject: Re: bug#18923: Alternative scrolling model
Date: Sun, 02 Nov 2014 02:31:28 +0000
Stefan Monnier <monnier <at> iro.umontreal.ca> writes:

> Sounds nice.  Do you imagine it as a replacement for the existing
> scroll-up/down functions?  Or rather (at least at first) as a separate
> package?
> Also, if something's missing for st-height to get more accurate
> measurements, I suggest you make it a bug report asking for that missing
> info/feature.

I was mostly thinking the first. The only potentially downside I can think of is that it might be slower -- then again I'm just measuring line-heights, and of these there is (at most) only one line that won't eventually be displayed.

If it were to remain mostly elisp, it would need a reliable way to measure the height of a line (essentially a `st-height' replacement), irrespective of whether it's displayed. It has also proven rather difficult to set the window start "absolutely". I've documented my findings in `st-move'.

Evgeni




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#18923; Package emacs. (Sun, 02 Nov 2014 15:15:02 GMT) Full text and rfc822 format available.

Message #11 received at 18923 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: E Sabof <esabof <at> gmail.com>
Cc: 18923 <at> debbugs.gnu.org
Subject: Re: bug#18923: Alternative scrolling model
Date: Sun, 02 Nov 2014 17:14:26 +0200
> From: E Sabof <esabof <at> gmail.com>
> Date: Sun, 02 Nov 2014 01:15:52 +0000
> 
> I've made a prototype for an alternative way to scroll. Essentially scrolling 
> is done pixelwise irrespective of content. Whole lines are scrolled "normally", 
> and the remainder is vscrolled. If the end result is close to a line boundary 
> it gets "snapped" to it.

> This prevents unpleasant jumping when encountering an image. It doesn't handle 
> the "image taller than window" case, but it would if `st-height' could measure 
> more accurately.

Thanks.

What are the advantages of this alternative way of scrolling, beyond
being in Lisp and eliminating the jumps when encountering an image?
(Btw, a test case for the latter would be nice, perhaps as a separate
bug report.)  If the only advantage is better handling of in-line
images, then perhaps fixing the existing implementation is a better
path forward?

Allow me a few comments about the code below.

> (defvar st-ov nil)

Is this overlay used anywhere?  I couldn't find that.

> (defun st-height (&optional pos)
>   "Won't report accurately, if the line is higher than window."
>   (cl-flet (( posn-y ()
>               (cdr (posn-x-y (or (posn-at-point)
>                                  (progn
>                                    (vertical-motion 0)
>                                    (set-window-start nil (point))
>                                    (posn-at-point)))))))

Did you try using pos-visible-in-window-p?  I think it's what you
want.

>           (when (cl-plusp ws)

Why not use '(> ws 0)' instead?  It's marginally faster, I think.

>       (cl-incf ammount vscroll)

Why not use '(setq amount (+ amount vscroll))' instead?  It should be
marginally faster.

>       (when (cl-minusp direction)

Same question as for cl-plusp above.

>       (cl-loop do (push (st-height) rows)
>                until (or (zerop (vertical-motion direction))
>                          ;; >= ?
>                          (>= (cl-reduce '+ rows)
>                              (abs ammount))))

I don't understand why you needed this loop.  Can't you use
window-body-height instead?

Also, if you do need the loop, why is it a good idea to use cl-reduce
here, rather than keeping track of the running sum -- isn't the latter
faster?  (And I don't think you need to keep the 'rows' list, see
below.)

> (cl-defun st-move (lines vscroll)
>   ;; vscroll changes aren't always displayed. Haven't found a work-around for  this.

A recipe to reproduce this problem, perhaps as a separate bug report,
would be nice.

>          ( line-info (st-get-lines pixels-to-move))
>          ( heights (cadr line-info))
>          ( initial-vscroll (car line-info))
>          excess
>          enough-or-too-many-heights
>          too-few-heights)

>     (cl-incf pixels-to-move initial-vscroll)

>     (setq enough-or-too-many-heights (cl-reduce '+ heights)

It looks like you never need the info about the height of the
individual lines, only their sum.  So perhaps st-get-lines shouldn't
return the height info as a list, but as just one number?

>           too-few-heights (cl-reduce '+ (butlast heights) :initial-value 0)

OK, 2 numbers.

> ;; (global-set-key (kbd "<next>") (lambda () (interactive) (scroll-tick 10)))
> ;; (global-set-key (kbd "<prior>") (lambda () (interactive) (scroll-tick -10)))

This doesn't support the equivalent of a nil argument, which means
move by "near full screen".




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#18923; Package emacs. (Sun, 02 Nov 2014 15:17:02 GMT) Full text and rfc822 format available.

Message #14 received at 18923 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: E Sabof <esabof <at> gmail.com>
Cc: 18923 <at> debbugs.gnu.org
Subject: Re: bug#18923: Alternative scrolling model
Date: Sun, 02 Nov 2014 17:16:23 +0200
> From: E Sabof <esabof <at> gmail.com>
> Date: Sun, 02 Nov 2014 02:31:28 +0000
> 
> > Sounds nice.  Do you imagine it as a replacement for the existing
> > scroll-up/down functions?  Or rather (at least at first) as a separate
> > package?
> > Also, if something's missing for st-height to get more accurate
> > measurements, I suggest you make it a bug report asking for that missing
> > info/feature.
> 
> I was mostly thinking the first.

If this is intended as a replacement for the existing functionality,
then it needs to support all the features that the current code
supports.  The list of those features should include at least the
following:

 . the argument to the commands can be nil, which means "almost the
   full window", where "almost full" depends on the value of
   next-screen-context-lines

 . the auto-window-vscroll variable

 . the scroll-preserve-screen-position option

 . signal an error at beginning and end of buffer, subject to the
   value of scroll-error-top-bottom

 . don't let point enter the scroll margin as result of scrolling

 . the window's old_point marker needs to be set after scrolling

There's also a bug when scrolling near the end of buffer: the result
is that the cursor us shown on a line beyond EOB, which should never
happen.

> The only potentially downside I can think of 
> is that it might be slower -- then again I'm just measuring line-heights, and 
> of these there is (at most) only one line that won't eventually be displayed.

It is indeed much slower.  I timed it on xdisp.c using Dmitry's
scroll-up-benchmark function, and found this code to be 3 times slower
than the current implementation.  Turning off font-lock slashes about
40% of the benchmark time, so CC mode fontifications are not the main
reason for the slowdown.  If I compare the existing implementation
with this one on xdisp.c with font-lock-mode turned off in both cases,
this implementation is 16 times slower than what we have now.

For the record, my timings are from an unoptimized build of a recent
trunk, with your code byte-compiled.

The general algorithm seems to be the same as in the current C
implementation, so I doubt an ELisp implementation could match what we
have in speed, let alone be faster.

Now, I personally don't regard the scrolling command as something that
needs to be lightning-fast (although others obviously do, see the
on-going discussions on emacs-devel about that).  But in this case, a
single PageDown keypress takes close to a second to execute, which is
slow enough to annoy.  By contrast, the current implementation is
almost instantaneous.  (Again, this is in an unoptimized build; an
optimized build should be about twice faster, but I think 0.4 sec for
a single scroll might still annoy.)

Finally, it looks like this code forces Emacs to display every single
screen it scrolls through, even when it cannot keep up.  I guess
that's due to the 'redisplay' calls.  This makes the situation where
someone leans on the PageDown key and then releases it very
unpleasant: Emacs keeps scrolling for a long time, and I didn't find a
way of interrupting that.

> If it were to remain mostly elisp, it would need a reliable way to measure the 
> height of a line (essentially a `st-height' replacement), irrespective of 
> whether it's displayed.

Did you try to use pos-visible-in-window-p?  AFAIU, it gives you what
you want, including for lines that are taller than the window.

> It has also proven rather difficult to set the window 
> start "absolutely". I've documented my findings in `st-move'.

Does this happen only when point is on an image?  (The comments in
st-move seem to talk only about this situation.)  If so, could you
show a simple test case to demonstrate the problem?




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#18923; Package emacs. (Sun, 02 Nov 2014 15:57:01 GMT) Full text and rfc822 format available.

Message #17 received at 18923 <at> debbugs.gnu.org (full text, mbox):

From: Stefan Monnier <monnier <at> iro.umontreal.ca>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: 18923 <at> debbugs.gnu.org, E Sabof <esabof <at> gmail.com>
Subject: Re: bug#18923: Alternative scrolling model
Date: Sun, 02 Nov 2014 10:56:15 -0500
>> (cl-incf ammount vscroll)
> Why not use '(setq amount (+ amount vscroll))' instead?  It should be
> marginally faster.

No, it's identical:

   (macroexpand '(cl-incf ammount vscroll))
   => (setq ammount (+ ammount vscroll))

> why is it a good idea to use cl-reduce here,

Because it's a lot more concise.


        Stefan




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#18923; Package emacs. (Sun, 02 Nov 2014 16:07:02 GMT) Full text and rfc822 format available.

Message #20 received at 18923 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Stefan Monnier <monnier <at> iro.umontreal.ca>
Cc: 18923 <at> debbugs.gnu.org, esabof <at> gmail.com
Subject: Re: bug#18923: Alternative scrolling model
Date: Sun, 02 Nov 2014 18:06:07 +0200
> From: Stefan Monnier <monnier <at> iro.umontreal.ca>
> Cc: E Sabof <esabof <at> gmail.com>,  18923 <at> debbugs.gnu.org
> Date: Sun, 02 Nov 2014 10:56:15 -0500
> 
> > why is it a good idea to use cl-reduce here,
> 
> Because it's a lot more concise.

But it causes the loop to repeatedly sum the same numbers, no?




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#18923; Package emacs. (Sun, 02 Nov 2014 16:22:01 GMT) Full text and rfc822 format available.

Message #23 received at 18923 <at> debbugs.gnu.org (full text, mbox):

From: E Sabof <esabof <at> gmail.com>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: 18923 <at> debbugs.gnu.org
Subject: Re: bug#18923: Alternative scrolling model
Date: Sun, 02 Nov 2014 16:21:23 +0000
Eli Zaretskii <eliz <at> gnu.org> writes:

> Thanks.
>
> What are the advantages of this alternative way of scrolling, beyond
> being in Lisp and eliminating the jumps when encountering an image?
> (Btw, a test case for the latter would be nice, perhaps as a separate
> bug report.)  If the only advantage is better handling of in-line
> images, then perhaps fixing the existing implementation is a better
> path forward?

There aren't. Do you have ideas on how this could be accommodated? Technically

> Allow me a few comments about the code below.
>
>> (defvar st-ov nil)
>
> Is this overlay used anywhere?  I couldn't find that.

Developement left-over.

>> (defun st-height (&optional pos)
>>   "Won't report accurately, if the line is higher than window."
>>   (cl-flet (( posn-y ()
>>               (cdr (posn-x-y (or (posn-at-point)
>>                                  (progn
>>                                    (vertical-motion 0)
>>                                    (set-window-start nil (point))
>>                                    (posn-at-point)))))))
>
> Did you try using pos-visible-in-window-p?  I think it's what you
> want.

Reading through the documentation of `pos-visible-in-window-p' didn't suggest how it could be useful. A more descriptive name for the function would be `st-get-pixel-height-of-line-at-point'.

>>           (when (cl-plusp ws)
>
> Why not use '(> ws 0)' instead?  It's marginally faster, I think.
>
>>       (cl-incf ammount vscroll)
>
> Why not use '(setq amount (+ amount vscroll))' instead?  It should be
> marginally faster.
>
>>       (when (cl-minusp direction)
>
> Same question as for cl-plusp above.

I just find infix comparisons somewhat uncomfortable. I can change them for a final implementation.

>>       (cl-loop do (push (st-height) rows)
>>                until (or (zerop (vertical-motion direction))
>>                          ;; >= ?
>>                          (>= (cl-reduce '+ rows)
>>                              (abs ammount))))
>
> I don't understand why you needed this loop.  Can't you use
> window-body-height instead?

What I need mostly depends on the amount of pixels I want to scroll - (for 2 "normal" lines, this loop would run twice) which is usually less than window-body-height, but could potentially be more.

> Also, if you do need the loop, why is it a good idea to use cl-reduce
> here, rather than keeping track of the running sum -- isn't the latter
> faster?  (And I don't think you need to keep the 'rows' list, see
> below.)

I really just wanted something working. And as you suggested below, values for enough-or-too-many-heights, too-few-heights, and probably the number of heights scanned would be sufficient.

>> (cl-defun st-move (lines vscroll)
>>   ;; vscroll changes aren't always displayed. Haven't found a work-around for  this.
>
> A recipe to reproduce this problem, perhaps as a separate bug report,
> would be nice.
>
>>          ( line-info (st-get-lines pixels-to-move))
>>          ( heights (cadr line-info))
>>          ( initial-vscroll (car line-info))
>>          excess
>>          enough-or-too-many-heights
>>          too-few-heights)
>
>>     (cl-incf pixels-to-move initial-vscroll)
>
>>     (setq enough-or-too-many-heights (cl-reduce '+ heights)
>
> It looks like you never need the info about the height of the
> individual lines, only their sum.  So perhaps st-get-lines shouldn't
> return the height info as a list, but as just one number?
>
>>           too-few-heights (cl-reduce '+ (butlast heights) :initial-value 0)
>
> OK, 2 numbers.
>
>> ;; (global-set-key (kbd "<next>") (lambda () (interactive) (scroll-tick 10)))
>> ;; (global-set-key (kbd "<prior>") (lambda () (interactive) (scroll-tick -10)))
>
> This doesn't support the equivalent of a nil argument, which means
> move by "near full screen".

I can implement this if the overall approach gets a green light.

Evgeni




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#18923; Package emacs. (Sun, 02 Nov 2014 16:32:01 GMT) Full text and rfc822 format available.

Message #26 received at 18923 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: E Sabof <esabof <at> gmail.com>
Cc: 18923 <at> debbugs.gnu.org
Subject: Re: bug#18923: Alternative scrolling model
Date: Sun, 02 Nov 2014 18:31:08 +0200
> From: E Sabof <esabof <at> gmail.com>
> Cc: 18923 <at> debbugs.gnu.org
> Date: Sun, 02 Nov 2014 16:21:23 +0000
> 
> > What are the advantages of this alternative way of scrolling, beyond
> > being in Lisp and eliminating the jumps when encountering an image?
> > (Btw, a test case for the latter would be nice, perhaps as a separate
> > bug report.)  If the only advantage is better handling of in-line
> > images, then perhaps fixing the existing implementation is a better
> > path forward?
> 
> There aren't. Do you have ideas on how this could be accommodated? Technically

Sorry, I'm not sure I understand the question.  If you mean how to
avoid jumps with the existing C implementation when there are inline
images, then please show a recipe to see the problem, and let's take
it from there.

> >> (defun st-height (&optional pos)
> >>   "Won't report accurately, if the line is higher than window."
> >>   (cl-flet (( posn-y ()
> >>               (cdr (posn-x-y (or (posn-at-point)
> >>                                  (progn
> >>                                    (vertical-motion 0)
> >>                                    (set-window-start nil (point))
> >>                                    (posn-at-point)))))))
> >
> > Did you try using pos-visible-in-window-p?  I think it's what you
> > want.
> 
> Reading through the documentation of `pos-visible-in-window-p' didn't suggest how it could be useful.

Do you still not understand that?  If so, I will elaborate why I think
that function is what you want.

> A more descriptive name for the function would be `st-get-pixel-height-of-line-at-point'.

Yes, I think I understood that.

> >>       (cl-loop do (push (st-height) rows)
> >>                until (or (zerop (vertical-motion direction))
> >>                          ;; >= ?
> >>                          (>= (cl-reduce '+ rows)
> >>                              (abs ammount))))
> >
> > I don't understand why you needed this loop.  Can't you use
> > window-body-height instead?
> 
> What I need mostly depends on the amount of pixels I want to scroll - (for 2 "normal" lines, this loop would run twice) which is usually less than window-body-height, but could potentially be more.

IME, the most important use case is scrolling by "almost the full
window", in which case it is better to start with window-body-height
and subtract from it, instead of starting with zero and add to it.
The most expensive part here is vertical-motion, so I think you want
to call it as little as possible.

> > This doesn't support the equivalent of a nil argument, which means
> > move by "near full screen".
> 
> I can implement this if the overall approach gets a green light.

I think we need to decide first whether the slowdown is acceptable.
IMO it is too significant to be ignored, if we want to replace
existing code.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#18923; Package emacs. (Sun, 02 Nov 2014 17:44:02 GMT) Full text and rfc822 format available.

Message #29 received at 18923 <at> debbugs.gnu.org (full text, mbox):

From: E Sabof <esabof <at> gmail.com>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: 18923 <at> debbugs.gnu.org
Subject: Re: bug#18923: Alternative scrolling model
Date: Sun, 02 Nov 2014 17:43:35 +0000
Eli Zaretskii <eliz <at> gnu.org> writes:

> Sorry, I'm not sure I understand the question.  If you mean how to
> avoid jumps with the existing C implementation when there are inline
> images, then please show a recipe to see the problem, and let's take
> it from there.

Imagine there is a buffer with which occupies 30% of the window (ex. a diagram in an org-mode buffer). It's positioned at (window-start). I (scroll-up 1). I'd end up scrolling a lot more than the usual (= (default-line-height) 20) pixels, which is what I mean by "jump".

>> >> (defun st-height (&optional pos)
>> >>   "Won't report accurately, if the line is higher than window."
>> >>   (cl-flet (( posn-y ()
>> >>               (cdr (posn-x-y (or (posn-at-point)
>> >>                                  (progn
>> >>                                    (vertical-motion 0)
>> >>                                    (set-window-start nil (point))
>> >>                                    (posn-at-point)))))))
>> >
>> > Did you try using pos-visible-in-window-p?  I think it's what you
>> > want.
>>
>> Reading through the documentation of `pos-visible-in-window-p' didn't suggest how it could be useful.
>
> Do you still not understand that?  If so, I will elaborate why I think
> that function is what you want.

My best guess is that I'd still have to go through a similar procedure of comparing 2 return values for lines that have to be at least partially visible from some position, but I would get more information on partially visible lines. I haven't thought-through all the cases, but it might indeed always work.

>> A more descriptive name for the function would be `st-get-pixel-height-of-line-at-point'.
>
> Yes, I think I understood that.
>
>> >>       (cl-loop do (push (st-height) rows)
>> >>                until (or (zerop (vertical-motion direction))
>> >>                          ;; >= ?
>> >>                          (>= (cl-reduce '+ rows)
>> >>                              (abs ammount))))
>> >
>> > I don't understand why you needed this loop.  Can't you use
>> > window-body-height instead?
>>
>> What I need mostly depends on the amount of pixels I want to scroll - (for 2 "normal" lines, this loop would run twice) which is usually less than window-body-height, but could potentially be more.
>
> IME, the most important use case is scrolling by "almost the full
> window", in which case it is better to start with window-body-height
> and subtract from it, instead of starting with zero and add to it.
> The most expensive part here is vertical-motion, so I think you want
> to call it as little as possible.

window-body-height can be very wrong if a large image is displayed in the buffer. Still some heuristics could be used to speed-up the most common case, all lines being ~= (default-line-height).

>> > This doesn't support the equivalent of a nil argument, which means
>> > move by "near full screen".
>>
>> I can implement this if the overall approach gets a green light.
>
> I think we need to decide first whether the slowdown is acceptable.
> IMO it is too significant to be ignored, if we want to replace
> existing code.

I could define some limit (the pixel height of a window?), and if it was to be exceeded, I'd fall back on the existing or similar approach. I don't know how often people scroll several pages, but it's likely that if they do they would value speed over accuracy.

Evgeni




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#18923; Package emacs. (Sun, 02 Nov 2014 18:23:02 GMT) Full text and rfc822 format available.

Message #32 received at 18923 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: E Sabof <esabof <at> gmail.com>
Cc: 18923 <at> debbugs.gnu.org
Subject: Re: bug#18923: Alternative scrolling model
Date: Sun, 02 Nov 2014 20:22:18 +0200
> From: E Sabof <esabof <at> gmail.com>
> Cc: 18923 <at> debbugs.gnu.org
> Date: Sun, 02 Nov 2014 17:43:35 +0000
> 
> Imagine there is a buffer with which occupies 30% of the window (ex. a diagram in an org-mode buffer). It's positioned at (window-start). I (scroll-up 1). I'd end up scrolling a lot more than the usual (= (default-line-height) 20) pixels, which is what I mean by "jump".

If the problem is only with scrolling by single lines (or small
number of lines), then a very similar problem is already solved in
line-move-partial.  Try C-n in the same situation, and see if that's
what you want.  We could then use the same technique.

> >> >> (defun st-height (&optional pos)
> >> >>   "Won't report accurately, if the line is higher than window."
> >> >>   (cl-flet (( posn-y ()
> >> >>               (cdr (posn-x-y (or (posn-at-point)
> >> >>                                  (progn
> >> >>                                    (vertical-motion 0)
> >> >>                                    (set-window-start nil (point))
> >> >>                                    (posn-at-point)))))))
> >> >
> >> > Did you try using pos-visible-in-window-p?  I think it's what you
> >> > want.
> >>
> >> Reading through the documentation of `pos-visible-in-window-p' didn't suggest how it could be useful.
> >
> > Do you still not understand that?  If so, I will elaborate why I think
> > that function is what you want.
> 
> My best guess is that I'd still have to go through a similar procedure of comparing 2 return values for lines that have to be at least partially visible from some position, but I would get more information on partially visible lines. I haven't thought-through all the cases, but it might indeed always work.

The problem that you faced, as I understand it, was to get the pixel
size of a screen line even if it is only partially visible.  The RTOP
and RBOT values returned by pos-visible-in-window-p give you
information about how many pixels of the line are above the top and
below the bottom of the window.  (For a very tall image or a low
window, both RTOP and RBOT will be non-zero.)  Add those to the
visible height of the line, and AFIU you get what you wanted.  Am I
missing something?

> > IME, the most important use case is scrolling by "almost the full
> > window", in which case it is better to start with window-body-height
> > and subtract from it, instead of starting with zero and add to it.
> > The most expensive part here is vertical-motion, so I think you want
> > to call it as little as possible.
> 
> window-body-height can be very wrong if a large image is displayed in the buffer.

I meant call window-body-height with PIXELWISE non-nil.  Then the
return value doesn't depend on what is displayed, it just gives you
the height of the text area in pixels.  Subtracting from that the
pixel coordinates of point returned by pos-visible-in-window-p or
posn-at-point will give you how many pixels are there to the top and
bottom of the window.  This should eliminate the need to count pixels
by moving one screen line at a time via vertical-motion, which is less
efficient, I think.

> Still some heuristics could be used to speed-up the most common case, all lines being ~= (default-line-height).

This problem is also solved by working in pixels, which is what your
code did anyway.

> > I think we need to decide first whether the slowdown is acceptable.
> > IMO it is too significant to be ignored, if we want to replace
> > existing code.
> 
> I could define some limit (the pixel height of a window?), and if it was to be exceeded, I'd fall back on the existing or similar approach. I don't know how often people scroll several pages, but it's likely that if they do they would value speed over accuracy.

AFAIU, your method isn't more accurate than the existing one, except
in case of images.  If scrolling images by single lines is the issue,
I'm quite sure we can have that with the current C implementation.

So I think the issue of whether the slower speed is acceptable still
stands.  If it is acceptable, then the Lisp implementation should be
improved and enhanced; if it isn't, then the C implementation should
be improved.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#18923; Package emacs. (Sun, 02 Nov 2014 18:26:01 GMT) Full text and rfc822 format available.

Message #35 received at 18923 <at> debbugs.gnu.org (full text, mbox):

From: E Sabof <esabof <at> gmail.com>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: 18923 <at> debbugs.gnu.org
Subject: Re: bug#18923: Alternative scrolling model
Date: Sun, 02 Nov 2014 18:25:28 +0000
Eli Zaretskii <eliz <at> gnu.org> writes:

>> From: E Sabof <esabof <at> gmail.com>
>> Date: Sun, 02 Nov 2014 02:31:28 +0000
>>
>> > Sounds nice.  Do you imagine it as a replacement for the existing
>> > scroll-up/down functions?  Or rather (at least at first) as a separate
>> > package?
>> > Also, if something's missing for st-height to get more accurate
>> > measurements, I suggest you make it a bug report asking for that missing
>> > info/feature.
>>
>> I was mostly thinking the first.
>
> If this is intended as a replacement for the existing functionality,
> then it needs to support all the features that the current code
> supports.  The list of those features should include at least the
> following:
>
>  . the argument to the commands can be nil, which means "almost the
>    full window", where "almost full" depends on the value of
>    next-screen-context-lines

Easy to implement naively, and heuristics should probably be considered.

>  . the auto-window-vscroll variable

I think the variable would no longer be useful with this approach.

>  . the scroll-preserve-screen-position option

Ideally I'd measure the pixel distance from the top and try to restore
it, but alternatives can be considered if this affects performance.

>  . signal an error at beginning and end of buffer, subject to the
>    value of scroll-error-top-bottom

I think I already have the code that determines this case, I just need
to throw errors.

>  . don't let point enter the scroll margin as result of scrolling
>
>  . the window's old_point marker needs to be set after scrolling

I don't fully understand these, but they don't seem too complicated.

> There's also a bug when scrolling near the end of buffer: the result
> is that the cursor us shown on a line beyond EOB, which should never
> happen.

I've noticed this. The point flashes at a wrong position, and then goes
back to "legal" position. I thought this was a display engine bug.

>> The only potentially downside I can think of
>> is that it might be slower -- then again I'm just measuring line-heights, and
>> of these there is (at most) only one line that won't eventually be displayed.
>
> It is indeed much slower.  I timed it on xdisp.c using Dmitry's
> scroll-up-benchmark function, and found this code to be 3 times slower
> than the current implementation.  Turning off font-lock slashes about
> 40% of the benchmark time, so CC mode fontifications are not the main
> reason for the slowdown.  If I compare the existing implementation
> with this one on xdisp.c with font-lock-mode turned off in both cases,
> this implementation is 16 times slower than what we have now.
>
> For the record, my timings are from an unoptimized build of a recent
> trunk, with your code byte-compiled.
>
> The general algorithm seems to be the same as in the current C
> implementation, so I doubt an ELisp implementation could match what we
> have in speed, let alone be faster.
>
> Now, I personally don't regard the scrolling command as something that
> needs to be lightning-fast (although others obviously do, see the
> on-going discussions on emacs-devel about that).  But in this case, a
> single PageDown keypress takes close to a second to execute, which is
> slow enough to annoy.  By contrast, the current implementation is
> almost instantaneous.  (Again, this is in an unoptimized build; an
> optimized build should be about twice faster, but I think 0.4 sec for
> a single scroll might still annoy.)

I'm aware of some inefficiencies in my code. My guess probably doesn't
mean much, but maybe something along 2X could be achieved.

> Finally, it looks like this code forces Emacs to display every single
> screen it scrolls through, even when it cannot keep up.  I guess
> that's due to the 'redisplay' calls.  This makes the situation where
> someone leans on the PageDown key and then releases it very
> unpleasant: Emacs keeps scrolling for a long time, and I didn't find a
> way of interrupting that.

st-move probably shouldn't call (redisplay) at all. I'll see if I can convert my comments to reproducible bugs.

>> If it were to remain mostly elisp, it would need a reliable way to measure the
>> height of a line (essentially a `st-height' replacement), irrespective of
>> whether it's displayed.
>
> Did you try to use pos-visible-in-window-p?  AFAIU, it gives you what
> you want, including for lines that are taller than the window.
>
>> It has also proven rather difficult to set the window
>> start "absolutely". I've documented my findings in `st-move'.
>
> Does this happen only when point is on an image?  (The comments in
> st-move seem to talk only about this situation.)  If so, could you
> show a simple test case to demonstrate the problem?

I think there are ~3 different bugs involved (vscroll not being displayed, vscroll being nullified, and the point-on-image cases). I'll see if I can describe
them better.

Evgeni




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#18923; Package emacs. (Sun, 02 Nov 2014 18:37:02 GMT) Full text and rfc822 format available.

Message #38 received at 18923 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: E Sabof <esabof <at> gmail.com>
Cc: 18923 <at> debbugs.gnu.org
Subject: Re: bug#18923: Alternative scrolling model
Date: Sun, 02 Nov 2014 20:36:00 +0200
> From: E Sabof <esabof <at> gmail.com>
> Cc: 18923 <at> debbugs.gnu.org
> Date: Sun, 02 Nov 2014 18:25:28 +0000
> 
> >  . the auto-window-vscroll variable
> 
> I think the variable would no longer be useful with this approach.

In that case, we should deprecate it.  I see it being used at least in
Gnus.

> > There's also a bug when scrolling near the end of buffer: the result
> > is that the cursor us shown on a line beyond EOB, which should never
> > happen.
> 
> I've noticed this. The point flashes at a wrong position, and then goes
> back to "legal" position.

It doesn't go back on my system, unless I move point in some way.

> I thought this was a display engine bug.

It could be that.

> I'm aware of some inefficiencies in my code. My guess probably doesn't
> mean much, but maybe something along 2X could be achieved.

Speeding up twice might be all we need to get a reasonably fast
implementation.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#18923; Package emacs. (Sun, 02 Nov 2014 19:10:02 GMT) Full text and rfc822 format available.

Message #41 received at 18923 <at> debbugs.gnu.org (full text, mbox):

From: E Sabof <esabof <at> gmail.com>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: 18923 <at> debbugs.gnu.org
Subject: Re: bug#18923: Alternative scrolling model
Date: Sun, 02 Nov 2014 19:09:20 +0000
Eli Zaretskii <eliz <at> gnu.org> writes:
> > Imagine there is a buffer with **AN IMAGE** which occupies 30% of the window (ex. a diagram in an org-mode buffer). It's positioned at (window-start). I (scroll-up 1). I'd end up scrolling a lot more than the usual (= (default-line-height) 20) pixels, which is what I mean by "jump".

> If the problem is only with scrolling by single lines (or small
> number of lines), then a very similar problem is already solved in
> line-move-partial.  Try C-n in the same situation, and see if that's
> what you want.  We could then use the same technique.

I'm not sure that we are talking about the same scenario. I didn't encounter any relevant behavior while using C-n/C-p, when a large image was displayed on the first line (with my default settings or Emacs -Q, both on the latest stable release).

> The problem that you faced, as I understand it, was to get the pixel
> size of a screen line even if it is only partially visible.  The RTOP
> and RBOT values returned by pos-visible-in-window-p give you
> information about how many pixels of the line are above the top and
> below the bottom of the window.  (For a very tall image or a low
> window, both RTOP and RBOT will be non-zero.)  Add those to the
> visible height of the line, and AFIU you get what you wanted.  Am I
> missing something?

Maybe not.

>> > IME, the most important use case is scrolling by "almost the full
>> > window", in which case it is better to start with window-body-height
>> > and subtract from it, instead of starting with zero and add to it.
>> > The most expensive part here is vertical-motion, so I think you want
>> > to call it as little as possible.
>>
>> window-body-height can be very wrong if a large image is displayed in the buffer.
>
> I meant call window-body-height with PIXELWISE non-nil.  Then the
> return value doesn't depend on what is displayed, it just gives you
> the height of the text area in pixels.  Subtracting from that the
> pixel coordinates of point returned by pos-visible-in-window-p or
> posn-at-point will give you how many pixels are there to the top and
> bottom of the window.  This should eliminate the need to count pixels
> by moving one screen line at a time via vertical-motion, which is less
> efficient, I think.

I'm not sure how knowing the distance of a point to the bottom of the window would benefit me, but indeed I could bulk-measure several lines in some cases.

Evgeni




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#18923; Package emacs. (Sun, 02 Nov 2014 19:30:02 GMT) Full text and rfc822 format available.

Message #44 received at 18923 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: E Sabof <esabof <at> gmail.com>
Cc: 18923 <at> debbugs.gnu.org
Subject: Re: bug#18923: Alternative scrolling model
Date: Sun, 02 Nov 2014 21:29:32 +0200
> From: E Sabof <esabof <at> gmail.com>
> Cc: 18923 <at> debbugs.gnu.org
> Date: Sun, 02 Nov 2014 19:09:20 +0000
> 
> 
> Eli Zaretskii <eliz <at> gnu.org> writes:
> > > Imagine there is a buffer with **AN IMAGE** which occupies 30% of the window (ex. a diagram in an org-mode buffer). It's positioned at (window-start). I (scroll-up 1). I'd end up scrolling a lot more than the usual (= (default-line-height) 20) pixels, which is what I mean by "jump".
> 
> > If the problem is only with scrolling by single lines (or small
> > number of lines), then a very similar problem is already solved in
> > line-move-partial.  Try C-n in the same situation, and see if that's
> > what you want.  We could then use the same technique.
> 
> I'm not sure that we are talking about the same scenario. I didn't encounter any relevant behavior while using C-n/C-p, when a large image was displayed on the first line (with my default settings or Emacs -Q, both on the latest stable release).

Tell me how to reproduce the exact problem you are talking about, and
I will see if I understood the situation correctly.

> > I meant call window-body-height with PIXELWISE non-nil.  Then the
> > return value doesn't depend on what is displayed, it just gives you
> > the height of the text area in pixels.  Subtracting from that the
> > pixel coordinates of point returned by pos-visible-in-window-p or
> > posn-at-point will give you how many pixels are there to the top and
> > bottom of the window.  This should eliminate the need to count pixels
> > by moving one screen line at a time via vertical-motion, which is less
> > efficient, I think.
> 
> I'm not sure how knowing the distance of a point to the bottom of the window would benefit me, but indeed I could bulk-measure several lines in some cases.

IMO the most important case is when you need to scroll almost the full
window, in which case the pixel size of the window is the main piece
of information.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#18923; Package emacs. (Sun, 02 Nov 2014 23:12:01 GMT) Full text and rfc822 format available.

Message #47 received at 18923 <at> debbugs.gnu.org (full text, mbox):

From: E Sabof <esabof <at> gmail.com>
To: Stefan Monnier <monnier <at> iro.umontreal.ca>
Cc: 18923 <at> debbugs.gnu.org
Subject: Re: bug#18923: Alternative scrolling model
Date: Sun, 02 Nov 2014 23:10:56 +0000

Stefan Monnier <monnier <at> iro.umontreal.ca> writes:

>> The results should be identical to scroll-up/scroll-down, unless
>> non-standard line heights are encountered.  This means that a) the code would
>> often be "under" such complications, not needing to know about them
>
> AFAIK scroll-margin is handled directly by the scroll-up/down code (tho
> in a partly redundant way, but I believe it's because if we let the
> subsequent redisplay do the job, it doesn't work quite right in all
> cases).
>
>> It's a bit of a bug fix, but ultimately I have no objections. Perhaps it
>> would be easier to estimate the breaking potential once it's "ready".
>
> OTOH to really get a lot of exposure, the best is to just install it
> into Emacs as a replacement ;-)
>
>>> Have you measured the kind of impact it might have on performance?
>>> Obviously, we could/should reimplement some of those functions in C.
>> Right now it's slower, but tolerably so.
>
> There are already cases where Emacs scrolling is perceived as too slow.
> AFAIK in most such cases the problem is due to the font-lock speed,
> which should be unaffected by your code, but I still think actual
> measurements quantifying the slowdown will be important.
>
> BTW, have you looked at the C code of scroll-up/down at all?
> I'm not familiar with it, but it does do pixelwise scrolling to some
> extent as well (tho IIUC only for really tall lines such as those with
> images), so I'm curious to know exactly how the two compare.

I have tried different settings, but they haven't quite worked for me.
But I definitely need to become familiar with the existing
implementation.

Evgeni




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#18923; Package emacs. (Mon, 03 Nov 2014 02:36:02 GMT) Full text and rfc822 format available.

Message #50 received at 18923 <at> debbugs.gnu.org (full text, mbox):

From: Stefan Monnier <monnier <at> iro.umontreal.ca>
To: E Sabof <esabof <at> gmail.com>
Cc: 18923 <at> debbugs.gnu.org
Subject: Re: bug#18923: Alternative scrolling model
Date: Sun, 02 Nov 2014 21:35:44 -0500
>> BTW, have you looked at the C code of scroll-up/down at all?
>> I'm not familiar with it, but it does do pixelwise scrolling to some
>> extent as well (tho IIUC only for really tall lines such as those with
>> images), so I'm curious to know exactly how the two compare.
> I have tried different settings, but they haven't quite worked for me.
> But I definitely need to become familiar with the existing
> implementation.

I don't think the behavior you're looking for can be obtained from the
current C code, indeed, but maybe the needed changes are limited.


        Stefan




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#18923; Package emacs. (Mon, 03 Nov 2014 03:46:02 GMT) Full text and rfc822 format available.

Message #53 received at 18923 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: esabof <at> gmail.com
Cc: 18923 <at> debbugs.gnu.org
Subject: Re: bug#18923: Alternative scrolling model
Date: Mon, 03 Nov 2014 05:45:30 +0200
> Date: Sun, 02 Nov 2014 21:29:32 +0200
> From: Eli Zaretskii <eliz <at> gnu.org>
> Cc: 18923 <at> debbugs.gnu.org
> 
> > > I meant call window-body-height with PIXELWISE non-nil.  Then the
> > > return value doesn't depend on what is displayed, it just gives you
> > > the height of the text area in pixels.  Subtracting from that the
> > > pixel coordinates of point returned by pos-visible-in-window-p or
> > > posn-at-point will give you how many pixels are there to the top and
> > > bottom of the window.  This should eliminate the need to count pixels
> > > by moving one screen line at a time via vertical-motion, which is less
> > > efficient, I think.
> > 
> > I'm not sure how knowing the distance of a point to the bottom of the window would benefit me, but indeed I could bulk-measure several lines in some cases.
> 
> IMO the most important case is when you need to scroll almost the full
> window, in which case the pixel size of the window is the main piece
> of information.

In addition, you could change st-move to work in pixels instead of
lines.  Then you could use posn-at-x-y inside st-move to find the
position at a given Y offset from the current window-start, and move
the new window-start to that position.  This should eliminate the need
to use vertical-motion in st-move even if you need to scroll by one or
a few screen lines.  The conversion of the number of lines to pixels
is straightforward using default-line-height.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#18923; Package emacs. (Mon, 03 Nov 2014 16:04:02 GMT) Full text and rfc822 format available.

Message #56 received at 18923 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Stefan Monnier <monnier <at> iro.umontreal.ca>
Cc: 18923 <at> debbugs.gnu.org, esabof <at> gmail.com
Subject: Re: bug#18923: Alternative scrolling model
Date: Mon, 03 Nov 2014 18:03:32 +0200
> From: Stefan Monnier <monnier <at> iro.umontreal.ca>
> Date: Sun, 02 Nov 2014 21:35:44 -0500
> Cc: 18923 <at> debbugs.gnu.org
> 
> >> BTW, have you looked at the C code of scroll-up/down at all?
> >> I'm not familiar with it, but it does do pixelwise scrolling to some
> >> extent as well (tho IIUC only for really tall lines such as those with
> >> images), so I'm curious to know exactly how the two compare.
> > I have tried different settings, but they haven't quite worked for me.
> > But I definitely need to become familiar with the existing
> > implementation.
> 
> I don't think the behavior you're looking for can be obtained from the
> current C code, indeed, but maybe the needed changes are limited.

The current implementation only uses vscroll for partially visible
screen lines (a.k.a. "glyph rows").  This is by design (and consistent
with what line-move does), but we can decide to change that, if that's
what people want.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#18923; Package emacs. (Mon, 03 Nov 2014 19:03:02 GMT) Full text and rfc822 format available.

Message #59 received at 18923 <at> debbugs.gnu.org (full text, mbox):

From: E Sabof <esabof <at> gmail.com>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: 18923 <at> debbugs.gnu.org, Stefan Monnier <monnier <at> iro.umontreal.ca>
Subject: Re: bug#18923: Alternative scrolling model
Date: Mon, 03 Nov 2014 19:02:35 +0000
Eli Zaretskii <eliz <at> gnu.org> writes:

> The current implementation only uses vscroll for partially visible
> screen lines (a.k.a. "glyph rows").  This is by design (and consistent
> with what line-move does), but we can decide to change that, if that's
> what people want.

Potentially I could try calling Lisp functions from window_scroll_pixel_based, until everything seemed to work. At which point the additional Lisp could be translated to C.

Evgeni




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#18923; Package emacs. (Mon, 04 Nov 2019 09:15:02 GMT) Full text and rfc822 format available.

Message #62 received at 18923 <at> debbugs.gnu.org (full text, mbox):

From: Stefan Kangas <stefan <at> marxist.se>
To: E Sabof <esabof <at> gmail.com>
Cc: 18923 <at> debbugs.gnu.org
Subject: Re: Alternative scrolling model
Date: Mon, 04 Nov 2019 10:14:09 +0100
E Sabof <esabof <at> gmail.com> writes:

> I've made a prototype for an alternative way to scroll. Essentially
> scrolling is done pixelwise irrespective of content. Whole lines are
> scrolled "normally", and the remainder is vscrolled. If the end
> result is close to a line boundary it gets "snapped" to it.
>
> This prevents unpleasant jumping when encountering an image. It
> doesn't handle the "image taller than window" case, but it would if
> `st-height' could measure more accurately.

That was 5 years ago.  Are you still working on this?

Best regards,
Stefan Kangas




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#18923; Package emacs. (Fri, 22 Apr 2022 12:17:01 GMT) Full text and rfc822 format available.

Message #65 received at 18923 <at> debbugs.gnu.org (full text, mbox):

From: Lars Ingebrigtsen <larsi <at> gnus.org>
To: E Sabof <esabof <at> gmail.com>
Cc: 18923 <at> debbugs.gnu.org
Subject: Re: bug#18923: Alternative scrolling model
Date: Fri, 22 Apr 2022 14:16:31 +0200
E Sabof <esabof <at> gmail.com> writes:

> I've made a prototype for an alternative way to scroll. Essentially
> scrolling is done pixelwise irrespective of content. Whole lines are
> scrolled "normally", and the remainder is vscrolled. If the end result
> is close to a line boundary it gets "snapped" to it.
>
> This prevents unpleasant jumping when encountering an image. It
> doesn't handle the "image taller than window" case, but it would if
> `st-height' could measure more accurately.

(I'm going through old bug reports that unfortunately weren't resolved
at the time.)

Skimming this thread, I think the proposed things here were basically
implemented by Po Lu as `pixel-scroll-precision-mode' in Emacs 29, so
I'm therefore closing this bug report.

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no




bug closed, send any further explanations to 18923 <at> debbugs.gnu.org and E Sabof <esabof <at> gmail.com> Request was from Lars Ingebrigtsen <larsi <at> gnus.org> to control <at> debbugs.gnu.org. (Fri, 22 Apr 2022 12:17:02 GMT) Full text and rfc822 format available.

bug archived. Request was from Debbugs Internal Request <help-debbugs <at> gnu.org> to internal_control <at> debbugs.gnu.org. (Sat, 21 May 2022 11:24:06 GMT) Full text and rfc822 format available.

This bug report was last modified 1 year and 339 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.