[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