emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[nongnu] elpa/evil 1be2289b36 1/2: Use scroll-preserve-screen-position f


From: ELPA Syncer
Subject: [nongnu] elpa/evil 1be2289b36 1/2: Use scroll-preserve-screen-position for C-u/C-d
Date: Mon, 9 Jan 2023 05:58:54 -0500 (EST)

branch: elpa/evil
commit 1be2289b360bef05f306517732d9e462291abb6d
Author: Axel Forsman <axelsfor@gmail.com>
Commit: Axel Forsman <axelsfor@gmail.com>

    Use scroll-preserve-screen-position for C-u/C-d
    
    The built-in functions scroll-up/-down already support optionally
    preserving the cursor screen position while scrolling via CTRL-U and
    CTRL-D. This makes it unnecessary to do it manually through
    
        (let ((xy (evil-posn-x-y (posn-at-point))))
          ...
          (goto-char (posn-point (posn-at-x-y (car xy) (cdr xy)))))
---
 evil-commands.el | 129 ++++++++++++++++++++++++++-----------------------------
 evil-common.el   | 100 +++++++++++++-----------------------------
 2 files changed, 91 insertions(+), 138 deletions(-)

diff --git a/evil-commands.el b/evil-commands.el
index 915f26e27d..1ebcdcfdf0 100644
--- a/evil-commands.el
+++ b/evil-commands.el
@@ -221,10 +221,9 @@ line if `visual-line-mode' is active and
 `evil-respect-visual-line-mode' is non-nil.  If COUNT is given,
 move COUNT - 1 screen lines downward first."
   :type inclusive
-  (if (and (fboundp 'end-of-visual-line)
-           evil-respect-visual-line-mode
+  (if (and evil-respect-visual-line-mode
            visual-line-mode)
-      (end-of-visual-line count)
+      (evil-end-of-visual-line count)
     (evil-end-of-line count)))
 
 (evil-define-motion evil-middle-of-visual-line ()
@@ -234,9 +233,8 @@ move COUNT - 1 screen lines downward first."
   (evil-with-restriction
       nil
       (save-excursion (end-of-visual-line) (point))
-    (move-to-column (+ (current-column)
-                       -1
-                       (/ (with-no-warnings (window-body-width)) 2)))))
+    (move-to-column
+     (+ (current-column) -1 (/ (window-body-width) 2)))))
 
 (evil-define-motion evil-percentage-of-line (count)
   "Move the cursor to COUNT % of the width of the current line.
@@ -959,9 +957,7 @@ In Insert state, insert a newline and indent."
   "Move the cursor to the middle line in the window."
   :jump t
   :type line
-  (evil-ensure-column
-    (move-to-window-line
-     (/ (1+ (save-excursion (move-to-window-line -1))) 2))))
+  (evil-ensure-column (move-to-window-line nil)))
 
 (evil-define-motion evil-window-bottom (count)
   "Move the cursor to line COUNT from the bottom of the window."
@@ -989,78 +985,80 @@ In Insert state, insert a newline and indent."
 
 (evil-define-command evil-scroll-count-reset ()
   "Set `evil-scroll-count' to 0.
-`evil-scroll-up' and `evil-scroll-down' will scroll
-for a half of the screen(default)."
+`evil-scroll-up' and `evil-scroll-down' will then scroll by half of
+the screen (the default)."
   :repeat nil
   :keep-visual t
   (interactive)
   (setq evil-scroll-count 0))
 
+;; With `scroll-preserve-screen-position' `scroll-up'/`scroll-down'
+;; target the same cursor pixel Y-coordinate while `last-command' has
+;; the `scroll-command' property. However the target needs updating
+;; when e.g. scrolling maximally to the first or last line and then
+;; switching scroll direction. Do this by resetting `last-command'
+;; when `real-this-command' (`evil-ensure-column' modifies
+;; `this-command') changed from last value:
+
 (evil-define-command evil-scroll-up (count)
   "Scroll the window and the cursor COUNT lines upwards.
-If COUNT is not specified the function scrolls down
-`evil-scroll-count', which is the last used count.
+If COUNT is not specified the function scrolls up `evil-scroll-count'
+lines, which is the last used count.
 If the scroll count is zero the command scrolls half the screen."
   :repeat nil
   :keep-visual t
   (interactive "<c>")
+  (when (= (line-beginning-position) (point-min))
+    (signal 'beginning-of-buffer nil))
+  (setq count (or count (max 0 evil-scroll-count))
+        evil-scroll-count count)
+  (when (zerop count) (setq count (/ (window-body-height) 2)))
   (evil-ensure-column
-    (setq count (or count (max 0 evil-scroll-count))
-          evil-scroll-count count
-          this-command 'next-line)
-    (when (= (point-min) (line-beginning-position))
-      (signal 'beginning-of-buffer nil))
-    (when (zerop count)
-      (setq count (/ (window-body-height) 2)))
-    (let ((xy (evil-posn-x-y (posn-at-point))))
+    (let ((opoint (point)))
       (condition-case nil
-          (progn
-            (scroll-down count)
-            (goto-char (posn-point (posn-at-x-y (car xy) (cdr xy)))))
-        (beginning-of-buffer
-         (condition-case nil
-             (with-no-warnings (previous-line count))
-           (beginning-of-buffer)))))))
+          (let ((scroll-preserve-screen-position 'always)
+                (last-command (when (eq real-last-command real-this-command)
+                                real-last-command)))
+            (scroll-down count))
+        (:success
+         ;; Redo if `scroll-down' only did partial scroll up to BOB
+         (when (<= (window-start) (point-min))
+           (goto-char opoint)
+           (vertical-motion (- count))))
+        (beginning-of-buffer (vertical-motion (- count)))))))
+(put 'evil-scroll-up 'scroll-command t)
 
 (evil-define-command evil-scroll-down (count)
   "Scroll the window and the cursor COUNT lines downwards.
 If COUNT is not specified the function scrolls down
-`evil-scroll-count', which is the last used count.
+`evil-scroll-count' lines, which is the last used count.
 If the scroll count is zero the command scrolls half the screen."
   :repeat nil
   :keep-visual t
   (interactive "<c>")
+  (when (= (line-end-position) (point-max))
+    (signal 'end-of-buffer nil))
+  (setq count (or count (max 0 evil-scroll-count))
+        evil-scroll-count count)
+  (when (zerop count) (setq count (/ (window-body-height) 2)))
   (evil-ensure-column
-    (setq count (or count (max 0 evil-scroll-count))
-          evil-scroll-count count
-          this-command 'next-line)
-    (when (eobp) (signal 'end-of-buffer nil))
-    (when (zerop count)
-      (setq count (/ (window-body-height) 2)))
     ;; BUG #660: First check whether the eob is visible.
     ;; In that case we do not scroll but merely move point.
     (if (<= (point-max) (window-end))
-        (with-no-warnings (next-line count nil))
-      (let ((xy (evil-posn-x-y (posn-at-point))))
-        (condition-case nil
-            (progn
-              (scroll-up count)
-              (let* ((wend (window-end nil t))
-                     (p (posn-at-x-y (car xy) (cdr xy)))
-                     (margin (max 0 (- scroll-margin
-                                       (cdr (posn-col-row p))))))
-                (goto-char (posn-point p))
-                ;; ensure point is not within the scroll-margin
-                (when (> margin 0)
-                  (with-no-warnings (next-line margin))
-                  (recenter scroll-margin))
-                (when (<= (point-max) wend)
-                  (save-excursion
-                    (goto-char (point-max))
-                    (recenter (- (max 1 scroll-margin)))))))
-          (end-of-buffer
-           (goto-char (point-max))
-           (recenter (- (max 1 scroll-margin)))))))))
+        (vertical-motion count)
+      (condition-case nil
+          (let ((scroll-preserve-screen-position 'always)
+                (last-command (when (eq real-last-command real-this-command)
+                                real-last-command)))
+            (scroll-up count))
+        (:success
+         ;; If EOB became visible: Scroll it to the bottom
+         (save-excursion
+           (goto-char (window-start))
+           (vertical-motion (max 0 (- (window-height) 1 scroll-margin)))
+           (when (<= (point-max) (point)) (recenter -1))))
+        (end-of-buffer (goto-char (point-max)) (recenter -1))))))
+(put 'evil-scroll-down 'scroll-command t)
 
 (evil-define-command evil-scroll-page-up (count)
   "Scroll the window COUNT pages upwards."
@@ -4296,8 +4294,8 @@ SIDE has the same meaning as in `split-window'.
 
 Note, this function only operates on the window tree rooted in
 the frame's main window and effectively preserves any side
-windows \(i.e. windows with a valid window-side window
-parameter\)."
+windows (i.e. windows with a valid window-side window
+parameter)."
   (evil-save-side-windows
     (unless (one-window-p)
       (save-excursion
@@ -4314,14 +4312,10 @@ parameter\)."
       (balance-windows))))
 
 (defun evil-alternate-buffer (&optional window)
-  "Return the last buffer WINDOW has displayed other than the
-current one (equivalent to Vim's alternate buffer).
-
-Return the first item in `window-prev-buffers' that isn't
-`window-buffer' of WINDOW."
+  "Return the last buffer WINDOW has displayed other than the current one.
+This is equivalent to Vim's alternate buffer."
   ;; If the last buffer visited has been killed, then `window-prev-buffers'
-  ;; returns a list with `current-buffer' at the head, we account for this
-  ;; possibility.
+  ;; returns a list with `window-buffer' at the head.
   (let* ((prev-buffers (window-prev-buffers))
          (head (car prev-buffers)))
     (if (eq (car head) (window-buffer window))
@@ -4329,12 +4323,11 @@ Return the first item in `window-prev-buffers' that 
isn't
       head)))
 
 (evil-define-command evil-switch-to-windows-last-buffer ()
-  "Switch to current windows last open buffer."
+  "Switch to the last open buffer of the current window."
   :repeat nil
   (let ((previous-place (evil-alternate-buffer)))
     (when previous-place
-      (switch-to-buffer (car previous-place))
-      (goto-char (car (last previous-place))))))
+      (switch-to-buffer (car previous-place)))))
 
 (evil-define-command evil-window-delete ()
   "Delete the current window.
diff --git a/evil-common.el b/evil-common.el
index a9d511f257..26015984cc 100644
--- a/evil-common.el
+++ b/evil-common.el
@@ -39,12 +39,9 @@
 (declare-function evil-ex-p "evil-ex")
 (declare-function evil-set-jump "evil-jumps")
 
-(condition-case nil
-    (require 'windmove)
-  (error
-   (message "evil: Could not load `windmove', \
-window commands not available.")
-   nil))
+(unless (require 'windmove nil t)
+  (message "evil: Could not load `windmove', \
+window commands not available."))
 
 ;;; Compatibility with different Emacs versions
 
@@ -880,44 +877,6 @@ Inhibits echo area messages, mode line updates and cursor 
changes."
   `(let ((evil-no-display t))
      ,@body))
 
-(defvar evil-cached-header-line-height nil
-  "Cached height of the header line.
-Used for fallback implementation on older Emacsen.")
-
-(defun evil-header-line-height ()
-  "Return the height of the header line.
-If there is no header line, return 0.
-Used as a fallback implementation of `window-header-line-height' on
-older Emacsen."
-  (let ((posn (posn-at-x-y 0 0)))
-    (or (when (eq (posn-area posn) 'header-line)
-          (cdr (posn-object-width-height posn)))
-        0)))
-
-(defun evil-posn-x-y (position)
-  "Return the x and y coordinates in POSITION.
-This function returns y offset from the top of the buffer area including
-the header line and the tab line (on Emacs 27 and later versions).
-
-On Emacs 24 and later versions, the y-offset returned by
-`posn-at-point' is relative to the text area excluding the header
-line and the tab line, while y offset taken by `posn-at-x-y' is relative to
-the buffer area including the header line and the tab line.
-This asymmetry is by design according to GNU Emacs team.
-This function fixes the asymmetry between them.
-
-Learned from mozc.el."
-  (let ((xy (posn-x-y position)))
-    (when header-line-format
-      (setcdr xy (+ (cdr xy)
-                    (or (and (fboundp 'window-header-line-height)
-                             (window-header-line-height))
-                        evil-cached-header-line-height
-                        (setq evil-cached-header-line-height 
(evil-header-line-height))))))
-    (when (fboundp 'window-tab-line-height)
-      (setcdr xy (+ (cdr xy) (window-tab-line-height))))
-    xy))
-
 (defun evil-count-lines (beg end)
   "Return absolute line-number-difference betweeen `beg` and `end`.
 This should give the same results no matter where on the line `beg`
@@ -987,34 +946,36 @@ See also `evil-save-goal-column'."
   "Execute BODY so that column after execution is correct.
 If `evil-start-of-line' is nil, treat BODY as if it were a `next-line' command.
 This mostly copies the approach of Emacs' `line-move-1', but is modified
-so it is more compatible with Evil's notions of eol & tracking."
-  (declare (indent defun)
-           (debug t))
+so it is more compatible with Evil's notion of EOL tracking."
+  (declare (indent defun) (debug t))
   `(progn
      (unless evil-start-of-line
        (setq this-command 'next-line
              temporary-goal-column
-             (cond
-              ((memq last-command '(next-line previous-line))
-               (if (consp temporary-goal-column)
-                   ;; Guard against a negative value as `temporary-goal-column'
-                   ;; may have a negative component when both `whitespace-mode'
-                   ;; and `display-line-numbers-mode' are enabled (#1297).
-                   (max 0 (+ (truncate (car temporary-goal-column))
-                             (cdr temporary-goal-column)))
-                 temporary-goal-column))
-              ((and track-eol (eolp) (not (bolp))) most-positive-fixnum)
-              (t (current-column)))))
+             (cond ((memq last-command '(next-line previous-line))
+                    temporary-goal-column)
+                   ((and track-eol (eolp) (not (bolp))) most-positive-fixnum)
+                   (t (current-column)))))
      ,@body
      (if evil-start-of-line
          (evil-first-non-blank)
-       (line-move-to-column (or goal-column temporary-goal-column)))))
+       (line-move-to-column
+        (or goal-column
+            (if (consp temporary-goal-column)
+                ;; Guard against a negative value as `temporary-goal-column'
+                ;; may have a negative component when both `whitespace-mode'
+                ;; and `display-line-numbers-mode' are enabled (#1297).
+                (max 0 (+ (truncate (car temporary-goal-column))
+                          (cdr temporary-goal-column)))
+              temporary-goal-column))))))
 
 (defun evil-narrow (beg end)
   "Restrict the buffer to BEG and END.
 BEG or END may be nil, specifying a one-sided restriction including
 `point-min' or `point-max'. See also `evil-with-restriction.'"
-  (narrow-to-region (or beg (point-min)) (or end (point-max))))
+  (narrow-to-region
+   (if beg (max beg (point-min)) (point-min))
+   (if end (min end (point-max)) (point-max))))
 
 (defmacro evil-with-restriction (beg end &rest body)
   "Execute BODY with the buffer narrowed to BEG and END.
@@ -1392,22 +1353,21 @@ If STATE is given it used a parsing state at point."
 (defun evil-line-move (count &optional noerror)
   "Like `line-move' but conserves the column.
 Signals an error at buffer boundaries unless NOERROR is non-nil."
-  (setq this-command (if (< count 0) #'previous-line #'next-line))
+  (setq this-command (if (< count 0) 'previous-line 'next-line))
   (let ((last-command
          ;; Reset tmp goal column between visual/logical movement
          (when (or (eq line-move-visual (consp temporary-goal-column))
                    (eq temporary-goal-column most-positive-fixnum))
            last-command))
         (opoint (point)))
-    (evil-signal-without-movement
-      (condition-case err
-          (line-move count)
-        ((beginning-of-buffer end-of-buffer)
-         (let ((col (or goal-column
-                        (car-safe temporary-goal-column)
-                        temporary-goal-column)))
-           (line-move-finish col opoint (< count 0))
-           (unless noerror (signal (car err) (cdr err)))))))))
+    (condition-case err
+        (line-move count)
+      ((beginning-of-buffer end-of-buffer)
+       (let ((col (or goal-column
+                      (car-safe temporary-goal-column)
+                      temporary-goal-column)))
+         (line-move-finish col opoint (< count 0)))
+       (or noerror (/= (point) opoint) (signal (car err) (cdr err)))))))
 
 (defun evil-forward-syntax (syntax &optional count)
   "Move point to the end or beginning of a sequence of characters in



reply via email to

[Prev in Thread] Current Thread [Next in Thread]