Package: emacs;
Reported by: Tak Kunihiro <tkk <at> misasa.okayama-u.ac.jp>
Date: Sat, 21 Oct 2017 04:12:02 UTC
Severity: wishlist
Tags: patch
Done: Eli Zaretskii <eliz <at> gnu.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 28922 in the body.
You can then email your comments to 28922 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
bug-gnu-emacs <at> gnu.org
:bug#28922
; Package emacs
.
(Sat, 21 Oct 2017 04:12:02 GMT) Full text and rfc822 format available.Tak Kunihiro <tkk <at> misasa.okayama-u.ac.jp>
:bug-gnu-emacs <at> gnu.org
.
(Sat, 21 Oct 2017 04:12:02 GMT) Full text and rfc822 format available.Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):
From: Tak Kunihiro <tkk <at> misasa.okayama-u.ac.jp> To: bug-gnu-emacs <at> gnu.org Cc: tkk <at> misasa.okayama-u.ac.jp Subject: Pixel scrolling by frame-char-height Date: Sat, 21 Oct 2017 13:11:14 +0900 (JST)
[Message part 1 (text/plain, inline)]
I'm sending a patch for lisp/pixel-scroll.el. This patch lets mouse wheel scroll vertically by number of pixels returned by `frame-char-height' as suggested as below. https://lists.gnu.org/archive/html/emacs-devel/2017-09/msg00385.html Also, by considering response of display engine as suggested as below, this patch offers stable vertically scrolling even when window is horizontally scrolled. https://lists.gnu.org/archive/html/emacs-devel/2017-10/msg00621.html ChangeLog entry and patch to NEWS also are attached. * ChangeLog 2017-10-21 Tak Kunihiro <tkk <at> misasa.okayama-u.ac.jp> Scroll vertically by number of pixels returned by `frame-char-height' with or without horizontally scrolled * lisp/pixel-scroll.el (pixel-resolution-fine-flag): When t, scroll pixels returned by `frame-char-height'. (pixel-scroll-up): Scroll by `frame-char-height'. Fix algorithm to move cursor to avoid unexpected jump. (pixel-scroll-down): Scroll by `frame-char-height'. (pixel-bob-at-top-p): Consider number of pixels that is about to scroll. (pixel-posn-y-at-point): Consider existence of an overlay string. Return nil when horizontally scrolled. (pixel-point-at-top-p): Consider number of pixels that is about to scroll. Use different algorithm when horizontally scrolled. (pixel-point-at-bottom-p): Consider number of pixels that is about to scroll. Return nil when horizontally scrolled. (pixel-scroll-pixel-down): Move cursor when horizontally scrolled. (pixel--whistlestop-line-up): Change cosmetics and move cursor when horizontally scrolled. (pixel-line-height): Call `pixel-visual-line-height' instead of `line-pixel-height'. (pixel-visual-line-height): New function to return height in pixels of text line where cursor is with or without horizontally scrolled, considering response of display engine. (pixel-visible-pos-in-window): New function to return position of a char shown on text line where cursor is on screen with or without horizontally scrolled.
[pixel-scroll.patch (text/x-patch, inline)]
diff --git a/lisp/pixel-scroll.el b/lisp/pixel-scroll.el old mode 100644 new mode 100755 index 4f183addaa..e5c1dad1eb --- a/cygdrive/c/Users/dream/Downloads/emacs/lisp/pixel-scroll.el +++ b/cygdrive/c/Users/dream/.emacs.d/site-lisp/pixel-scroll.el @@ -74,10 +74,13 @@ More wait will result in slow and gentle scroll.") (defvar pixel-resolution-fine-flag nil - "Set scrolling resolution to a pixel instead of a line. -After a pixel scroll, typing C-n or C-p scrolls the window to -make it fully visible, and undoes the effect of the pixel-level -scroll.") + "Set scrolling resolution to pixels instead of a line. +When it is t, scrolling resolution is number of pixels obtained +by `frame-char-height' instead of a line. When it is number, +scrolling resolution is set to number of pixels specified. In +case you need scrolling resolution of a pixel, set to 1. After a +pixel scroll, typing C-n or C-p scrolls the window to make it +fully visible, and undoes the effect of the pixel-level scroll.") ;;;###autoload (define-minor-mode pixel-scroll-mode @@ -102,13 +105,16 @@ This is an alternative of `scroll-up'. Scope moves downward." (interactive) (or arg (setq arg 1)) (dotimes (ii arg) ; move scope downward - (if (pixel-eob-at-top-p) ; when end-of-the-buffer is close - (scroll-up 1) ; relay on robust method - (when (pixel-point-at-top-p) ; prevent too late - (vertical-motion 1)) ; move point downward - (pixel-scroll-pixel-up (if pixel-resolution-fine-flag - 1 - (pixel-line-height)))))) ; move scope downward + (let ((amt (if pixel-resolution-fine-flag + (if (integerp pixel-resolution-fine-flag) + pixel-resolution-fine-flag + (frame-char-height)) + (pixel-line-height)))) + (if (pixel-eob-at-top-p) ; when end-of-the-buffer is close + (scroll-up 1) ; relay on robust method + (while (pixel-point-at-top-p amt) ; prevent too late (multi tries) + (vertical-motion 1)) ; move point downward + (pixel-scroll-pixel-up amt))))) ; move scope downward (defun pixel-scroll-down (&optional arg) "Scroll text of selected window down ARG lines. @@ -116,48 +122,61 @@ This is and alternative of `scroll-down'. Scope moves upward." (interactive) (or arg (setq arg 1)) (dotimes (ii arg) - (if (or (pixel-bob-at-top-p) ; when beginning-of-the-buffer is seen - (pixel-eob-at-top-p)) ; for file with a long line - (scroll-down 1) ; relay on robust method - (while (pixel-point-at-bottom-p) ; prevent too late (multi tries) - (vertical-motion -1)) - (pixel-scroll-pixel-down (if pixel-resolution-fine-flag - 1 - (pixel-line-height -1)))))) - -(defun pixel-bob-at-top-p () - "Return non-nil if beginning of buffer is at top of window." - (equal (window-start) (point-min))) + (let ((amt (if pixel-resolution-fine-flag + (if (integerp pixel-resolution-fine-flag) + pixel-resolution-fine-flag + (frame-char-height)) + (pixel-line-height -1)))) + (if (or (pixel-bob-at-top-p amt) ; when beginning-of-the-buffer is seen + (pixel-eob-at-top-p)) ; for file with a long line + (scroll-down 1) ; relay on robust method + (while (pixel-point-at-bottom-p amt) ; prevent too late (multi tries) + (vertical-motion -1)) + (pixel-scroll-pixel-down amt))))) + +(defun pixel-bob-at-top-p (amt) + "Return non-nil if beginning of buffer is at top of window on coming scroll of AMT pixels." + (and (equal (window-start) (point-min)) + (< (window-vscroll nil t) amt))) (defun pixel-eob-at-top-p () "Return non-nil if end of buffer is at top of window." (<= (count-lines (window-start) (window-end)) 2)) ; count-screen-lines (defun pixel-posn-y-at-point () - "Return y coordinates of point in pixels of current window." - (let ((hscroll0 (window-hscroll)) - (y (cdr (posn-x-y (posn-at-point))))) - ;; when point is out of scope by hscroll - (unless y - (save-excursion - (set-window-hscroll nil (current-column)) - (setq y (cdr (posn-x-y (posn-at-point)))) - (set-window-hscroll nil hscroll0))) - y)) - -(defun pixel-point-at-top-p () - "Return if point is located at top of a window." - (let* ((y (pixel-posn-y-at-point)) - (top-margin y)) - (< top-margin (pixel-line-height)))) - -(defun pixel-point-at-bottom-p () - "Return if point is located at bottom of a window." - (let* ((y (pixel-posn-y-at-point)) - (edges (window-inside-pixel-edges)) + "Return y coordinates of point in pixels of current window. +This returns nil when horizontally scrolled." + (when (equal (window-hscroll) 0) + (save-excursion + ;; When there's an overlay string on a line, move + ;; point by (beginning-of-visual-line). + (beginning-of-visual-line) + ;; (- (cadr (pos-visible-in-window-p (point) nil t)) + ;; (line-pixel-height)) + (cdr (posn-x-y (posn-at-point)))))) + +(defun pixel-point-at-top-p (amt) + "Return if point is located at top of a window on coming scroll of AMT pixels. +When location of point was not obtained, this returns if point is at top of window." + (let ((y (pixel-posn-y-at-point)) + top-margin) + (cond + (y + (setq top-margin y) + (< top-margin amt)) + (t + (<= (count-lines (window-start) (point)) 1))))) + +(defun pixel-point-at-bottom-p (amt) + "Return if point is located at bottom of a window on coming scroll of AMT pixels. +When location of point was not obtained, this returns nil." + (let* ((edges (window-inside-pixel-edges)) (height (- (nth 3 edges) (nth 1 edges))) ; (- bottom top) - (bottom-margin (- height (+ y (line-pixel-height))))) ; bottom margin - (< bottom-margin (pixel-line-height -1)))) ; coming unseen line + (y (pixel-posn-y-at-point)) + bottom-margin) + (when y + (setq bottom-margin (- height (+ y (pixel-visual-line-height)))) + (< bottom-margin amt)))) ; coming unseen line (defun pixel-scroll-pixel-up (amt) "Scroll text of selected windows up AMT pixels. @@ -173,8 +192,12 @@ Scope moves upward." (while (> amt 0) (let ((vs (window-vscroll nil t))) (if (equal vs 0) - (pixel-scroll-down-and-set-window-vscroll - (1- (pixel-line-height -1))) + (progn + ;; On horizontal scrolling, move cursor. + (when (> (window-hscroll) 0) + (vertical-motion -1)) + (pixel-scroll-down-and-set-window-vscroll + (1- (pixel-line-height -1)))) (set-window-vscroll nil (1- vs) t)) (setq amt (1- amt)) (sit-for pixel-wait)))) @@ -189,11 +212,16 @@ Scope moves downward. This function returns number of pixels that was scrolled." (let* ((src (window-vscroll nil t)) ; EXAMPLE (initial) @0 @8 @88 (height (pixel-line-height)) ; 25 25 23 - (line (1+ (/ src height))) ; catch up + one line Ä1 Ä1 Ä4 + (line (1+ (/ src height))) ; catch up + one line 1 1 4 (dst (* line height)) ; goal @25 @25 @92 (delta (- dst src))) ; pixels to be scrolled 25 17 4 (pixel--whistlestop-pixel-up (1- delta)) ; until one less @24 @24 @91 - (scroll-up line) (sit-for pixel-wait) ; scroll 1 pixel @0 @0 @0 + (dotimes (ii line) + ;; On horizontal scrolling, move cursor. + (when (> (window-hscroll) 0) + (vertical-motion 1)) + (scroll-up 1)) + (sit-for pixel-wait) ; scroll 1 pixel @0 @0 @0 delta)) (defun pixel--whistlestop-pixel-up (n) @@ -211,9 +239,60 @@ unseen line above the first line, respectively, is provided." (or pos (setq pos (window-start))) (when (< pos 0) (setq pos (pixel-point-at-unseen-line))) - (save-excursion - (goto-char pos) - (line-pixel-height))) ; frame-char-height + (let ((vs1 (window-vscroll nil t)) + height) + (set-window-vscroll nil 0 t) + (save-excursion + (goto-char pos) + (setq height (pixel-visual-line-height))) ; line-pixel-height, frame-char-height + (set-window-vscroll nil vs1 t) + height)) + +(defun pixel-visual-line-height () + "Return height in pixels of text line where cursor is in the selected window." + (let ((pos (pixel-visible-pos-in-window))) + (cond + ;; When a char of line is shown, obtain height by + ;; (line-pixel-height). + (pos (save-excursion (goto-char pos) (line-pixel-height))) + ;; When no char of line is shown but the line is at the top, + ;; obtain height by (line-pixel-height). This is based on + ;; expected response from display engine. See following + ;; discussion. + ;; https://lists.gnu.org/archive/html/emacs-devel/2017-10/msg00621.html + ((equal (count-lines (window-start) (point)) 1) + (line-pixel-height)) + ;; No char of line is shown and the line is not at the top, + ;; obtain height by (frame-char-height). + (t (frame-char-height))))) + +(defun pixel-visible-pos-in-window () + "Return position of a char shown on text line where cursor is in the selected window. +This will look for positions of point and end-of-visual-line, +then positions from beginning-of-visual-line to +end-of-visual-line. When no char in a line is shown, this +returns nil." + (let* ((beginning-of-visual-line-pos (save-excursion (beginning-of-visual-line) (point))) + (end-of-visual-line-pos (save-excursion (end-of-visual-line) (point))) + (pos-list (number-sequence beginning-of-visual-line-pos end-of-visual-line-pos)) + (edges (window-inside-pixel-edges)) + (width (- (nth 2 edges) (nth 0 edges))) + posn-x + visible-pos) + ;; Optimize list of position to be surveyed. + (push end-of-visual-line-pos pos-list) + (push (point) pos-list) + (delete-dups pos-list) + ;; Find out a char with position X that is more than zero and less than width of screen. + (while (and (not visible-pos) + pos-list) + (setq posn-x (car (pos-visible-in-window-p (car pos-list) nil t))) + (if (and posn-x + (<= 0 posn-x) + (< posn-x width)) + (setq visible-pos (car pos-list)) + (setq pos-list (cdr pos-list)))) + visible-pos)) (defun pixel-point-at-unseen-line () "Return the character position of line above the selected window.
[NEWS.patch (text/x-patch, inline)]
diff --git a/etc/NEWS b/etc/NEWS old mode 100644 new mode 100755 index 74d6e8bf1c..d9eb4f9462 --- a/cygdrive/c/Users/dream/Downloads/emacs/etc/NEWS +++ b/cygdrive/c/Users/dream/Dropbox/Downloads <at> TK/NEWS @@ -76,6 +76,12 @@ globally or for individual definitions. the XTerm window title. This feature is experimental and is disabled by default. +** Pixel-Scroll + +--- +*** Now scroll vertically by number of pixels returned by +'frame-char-height' when 'pixel-resolution-fine-flag' is set to t. + * New Modes and Packages in Emacs 27.1
Eli Zaretskii <eliz <at> gnu.org>
:Tak Kunihiro <tkk <at> misasa.okayama-u.ac.jp>
:Message #10 received at 28922-done <at> debbugs.gnu.org (full text, mbox):
From: Eli Zaretskii <eliz <at> gnu.org> To: Tak Kunihiro <tkk <at> misasa.okayama-u.ac.jp> Cc: 28922-done <at> debbugs.gnu.org Subject: Re: bug#28922: Pixel scrolling by frame-char-height Date: Fri, 27 Oct 2017 17:24:17 +0300
> Date: Sat, 21 Oct 2017 13:11:14 +0900 (JST) > From: Tak Kunihiro <tkk <at> misasa.okayama-u.ac.jp> > Cc: tkk <at> misasa.okayama-u.ac.jp > > I'm sending a patch for lisp/pixel-scroll.el. Thanks, I pushed it to the emacs-26 branch. Please in the future make sure the 1st line of the doc string is not longer than 79 characters, and is a full sentence. Also, please fill the lines in the log entry to be shorter than 75 characters, not including the leading whitespace. And include the bug number in the log message. (I modified your patch to fix all those issues.) > diff --git a/etc/NEWS b/etc/NEWS > old mode 100644 > new mode 100755 > index 74d6e8bf1c..d9eb4f9462 > --- a/cygdrive/c/Users/dream/Downloads/emacs/etc/NEWS > +++ b/cygdrive/c/Users/dream/Dropbox/Downloads <at> TK/NEWS > @@ -76,6 +76,12 @@ globally or for individual definitions. > the XTerm window title. This feature is experimental and is disabled > by default. > > +** Pixel-Scroll > + > +--- > +*** Now scroll vertically by number of pixels returned by > +'frame-char-height' when 'pixel-resolution-fine-flag' is set to t. I didn't install this part, because pixel-scroll-mode is a new mode and is mentioned as such in NEWS. So everything about it is "new", and there's no need to mention individual changes.
Debbugs Internal Request <help-debbugs <at> gnu.org>
to internal_control <at> debbugs.gnu.org
.
(Sat, 25 Nov 2017 12:24:04 GMT) Full text and rfc822 format available.
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.