-
Notifications
You must be signed in to change notification settings - Fork 280
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix an issue where moving the cursor to end of the buffer would result in no visible text #1938
base: master
Are you sure you want to change the base?
Fix an issue where moving the cursor to end of the buffer would result in no visible text #1938
Conversation
9d07b8e
to
9b0ff18
Compare
Thanks for the PR! Could you please try to give reproduction steps? Workarounds that cannot be verified as necessary make me uneasy, as they are impossible to remove later. But this also sounds more like a GNU Emacs bug, and in that case it ought to be fixed there instead? |
Thanks for your feedback! I understand your concern about unverifiable workarounds and I agree that they should be avoided where possible. But in this case, the issue is difficult to reproduce consistently. To attempt to trigger it, try opening multiple files and pressing I am not sure whether this is a bug in GNU/Emacs. It does not seem to be the responsibility of Even the built-in (defun end-of-buffer (&optional arg)
"Move point to the end of the buffer.
With numeric arg N, put point N/10 of the way from the end.
If the buffer is narrowed, this command uses the end of the
accessible part of the buffer.
Push mark at previous position, unless either a \\[universal-argument] prefix
is supplied, or Transient Mark mode is enabled and the mark is active."
(declare (interactive-only "use `(goto-char (point-max))' instead."))
(interactive "^P")
(or (consp arg) (region-active-p) (push-mark))
(let ((size (- (point-max) (point-min))))
(goto-char (if (and arg (not (consp arg)))
(- (point-max)
(/ (* size (prefix-numeric-value arg)) 10))
(point-max))))
;; If we went to a place in the middle of the buffer,
;; adjust it to the beginning of a line.
(cond ((and arg (not (consp arg))) (forward-line 1))
((and (eq (current-buffer) (window-buffer))
(> (point) (window-end nil t)))
;; If the end of the buffer is not already on the screen,
;; then scroll specially to put it near, but not at, the bottom.
(overlay-recenter (point))
;; FIXME: Arguably if `scroll-conservatively' is set, then
;; we should pass -1 to `recenter'.
(recenter (if (and scroll-minibuffer-conservatively
(window-minibuffer-p))
-1 -3)))))
The Emacs developers added |
Hello @axelf4, I finally found a way to reproduce the issue. Environment
Steps to reproduce the issueStep 1
Step 2Repeat the following steps many times until the issue happens:
|
Great!
Hmm, I got the impression that redisplay should handle this from the
The The drawback of the proposed fix is that it changes the behavior of G: Instead of obeying @tomdl89, any thoughts? |
Thank you for pointing this out. The value of This pull request addresses an edge case where the user opts to set |
I agree with @axelf4 about the drawback mentioned, although I guess this could be addressed by checking the value of My main problem with this PR is that I can't replicate it at all, even with a high value of
|
You can replicate the issue in Emacs 30 on Linux by following these steps:
|
Ah, I think I can replicate. I think you confused me with the phrase "no visible text". Your steps result in a buffer with one line of visible text, at the top of the window. And as the convention for most text files is to leave one blank line at the end of the file, this means there is no visible text. Right? |
Yes, by "no visible text," I meant that the cursor and window start are at (In my configuration, |
Understood. So I think replacing (recenter (and (< 100 scroll-conservatively) -1)) Could be an improvement. That means it will emulate vim's behaviour for people who have set |
42c3838
to
2169b25
Compare
I updated the pull request. Just out of curiosity, why specifically |
According to
|
(for that reason, I don't think 10000 or |
It makes sense. Thank you for clarifying, @tomdl89. |
Would this version be better? (recenter (and (<= 100 scroll-conservatively) -1)) |
The docstring says
not
so, no, I don't think your version would be better.
(< 100 x) is equivalnt to 100 < x in normal maths. For that reason, I find it easier to read |
2169b25
to
74608d1
Compare
I wrote my response too quickly. Here is what I intended to express:
This means that:
I believe there is a small issue with the change you proposed: (recenter (and (< 100 scroll-conservatively) -1)) This is what the above will do:
I have changed my pull request to the following instead: (recenter (and (> 100 scroll-conservatively) -1))
|
74608d1
to
5858b35
Compare
OK, your new approach works just as fine for me. But I still think (>= scroll-conservatively 100) needs to be (> scroll-conservatively 100) because of |
6a4fcaf
to
6384db5
Compare
While Emacs recenters the screen using To align with Vim's behavior, we should use |
2dc1fe0
to
697771c
Compare
When the user sets `scroll-conservatively` to a value greater than 100, moving the cursor to `(point-max)` with `(evil-goto-line nil)` can cause all text to be positioned above the window start, making it invisible to the user. This issue is more likely to occur after scaling the text using functions such as `text-scale-increase` or `text-scale-set`. This commit resolves this issue by adjusting the window's view using `(recenter -1)`. By doing so, it prevents the cursor from being placed off-screen, ensuring that the user can always see the relevant text when moving to the end of the buffer. When `scroll-conservatively` is less than or equal to 100, Emacs recenters the screen using `(recenter nil)`, which recenters with point on the middle line. This behavior does not match Vim's. To align with Vim's behavior, we use `(recenter -1)`, regardless of the value of `scroll-conservatively`.
697771c
to
4dc283c
Compare
This PR is getting really noisy with force-pushes. Can you let me know when you have stopped so I can take a look at the code and review? |
I had to add a few additional details to the commit message. I've now finished modifying it. |
This pull request fixes an issue where using
(evil-goto-line nil)
to move the cursor to the end of the buffer would result in no visible text because of(goto-char (point-max))
.This issue is difficult to reproduce because it doesn't always occur. I was fortunate enough to encounter it today, and the provided patch fixes the problem. This patch draws inspiration from the built-in
(end-of-buffer)
function, which does not exhibit the same issue as calling(evil-goto-line nil)
.