From: Felician Nemeth <felician.nemeth@gmail.com>
To: joaotavora@gmail.com
Cc: martin rudalics <rudalics@gmx.at>, Eli Zaretskii <eliz@gnu.org>,
Alan Donovan <adonovan@google.com>,
70193@debbugs.gnu.org
Subject: bug#70193: [PATCH] Re: bug#70193: Acknowledgement (eglot: RFE: recenter buffer upon showDocument request)
Date: Wed, 17 Apr 2024 11:15:25 +0200 [thread overview]
Message-ID: <87sezkcpua.fsf_-_@betli.tmit.bme.hu> (raw)
In-Reply-To: <CAPVWWDXd33XGG66YJuLn+Q0tfFkdvt2MXcDpe2TdNoaf1A3kpg@mail.gmail.com> (Alan Donovan's message of "Sat, 13 Apr 2024 12:36:41 -0400")
[-- Attachment #1: Type: text/plain, Size: 566 bytes --]
Hi João,
I've attached a patch fixing this issue. It includes Martin's new
recenter-region.
This is the original report:
> In eglot 1.17, the LSP showDocument downcall opens the designated
> file, moves the cursor to the designated position, and raises the
> frame. One other thing it could do to make it easier to see where the
> cursor is would be to recenter the buffer.
>
> The patch below is a minimal fix; the discussion at
> https://github.com/joaotavora/eglot/discussions/1382 suggests a couple
> of possible refinements.
Thanks.
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Eglot-Recenter-buffer-upon-showDocument-request-bug-.patch --]
[-- Type: text/x-diff, Size: 5166 bytes --]
From 9496ee48c77f60c17387b4331911ba7ad5642c0e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Felici=C3=A1n=20N=C3=A9meth?= <felician.nemeth@gmail.com>
Date: Wed, 17 Apr 2024 10:47:03 +0200
Subject: [PATCH] Eglot: Recenter buffer upon showDocument request (bug#70193)
* lisp/progmodes/eglot.el (eglot--window-recenter-region): New
defun.
(eglot-handle-request window/showDocument): Try to show the whole
selection centered; in prog modes, try to show preceding comments
as well.
Co-authored-by: Martin Rudalics <rudalics@gmx.at>
---
lisp/progmodes/eglot.el | 91 +++++++++++++++++++++++++++++++++++++++--
1 file changed, 87 insertions(+), 4 deletions(-)
diff --git a/lisp/progmodes/eglot.el b/lisp/progmodes/eglot.el
index 5e4f7bba679..cbadd495b28 100644
--- a/lisp/progmodes/eglot.el
+++ b/lisp/progmodes/eglot.el
@@ -2488,6 +2488,76 @@ eglot-handle-request
"Handle server request workspace/workspaceFolders."
(eglot-workspace-folders server))
+(defun eglot--window-recenter-region (&optional from to window buffer)
+ "Center region and return window start position for recentered region.
+WINDOW specifies the window whose start position to return and defaults
+to the selected window. BUFFER specifies the buffer supposed to contain
+the region and defaults to WINDOW's buffer. FROM and TO specify the
+beginning and end of the region in BUFFER and default to the active
+region or the entire text of BUFFER."
+ (let* ((window (or window (selected-window)))
+ (buffer (or buffer (window-buffer window)))
+ (from (or from
+ (and (eq buffer (current-buffer))
+ (region-active-p)
+ (region-beginning))
+ (with-current-buffer buffer
+ (point-min))))
+ (to (or to
+ (and (eq buffer (current-buffer))
+ (region-active-p)
+ (region-end))
+ (with-current-buffer buffer
+ (point-max))))
+ (body-width (window-body-width window t))
+ (body-height (window-body-height window t))
+ old-buffer old-point
+ remainder height start prev)
+ ;; If WINDOW doesn't show BUFFER, save its buffer, start and point
+ ;; positions.
+ (unless (eq (window-buffer window) buffer)
+ (setq old-buffer (window-buffer window))
+ (setq old-point (window-point window))
+ (set-window-buffer window buffer))
+
+ ;; The amount of pixels by which the region can be scrolled down in
+ ;; the window. Initially, half of the difference of the height of
+ ;; the window's body and that of the region.
+ (setq remainder
+ (round
+ (/ (- body-height
+ (cdr (window-text-pixel-size
+ window from to body-width body-height)))
+ 2.0)))
+
+ ;; Now move back and subtract the height of one line preceding the
+ ;; region until the remainder has been used.
+ (save-excursion
+ (goto-char from)
+ (setq start (pos-bol))
+ (while (and (not (bobp))
+ (>= remainder 0)
+ (setq prev (pos-bol 0))
+ (setq height (cdr (window-text-pixel-size
+ window prev start
+ body-width body-height)))
+ ;; At least half of the line should fit.
+ (>= remainder (/ height 2.0)))
+ (setq remainder (- remainder height))
+ (setq start prev)
+ (goto-char start)))
+
+ ;; Restore WINDOW's old buffer, start and point.
+ (when old-buffer
+ (set-window-buffer window old-buffer)
+ (set-window-point window old-point)
+ (set-window-start window old-point))
+
+ (set-window-start window start)
+
+ ;; Return the new start position.
+ start))
+
(cl-defmethod eglot-handle-request
(_server (_method (eql window/showDocument)) &key
uri external takeFocus selection)
@@ -2510,10 +2580,23 @@ eglot-handle-request
((display-buffer (current-buffer))))
(when selection
(pcase-let ((`(,beg . ,end) (eglot-range-region selection)))
- ;; FIXME: it is very naughty to use someone else's `--'
- ;; function, but `xref--goto-char' happens to have
- ;; exactly the semantics we want vis-a-vis widening.
- (xref--goto-char beg)
+ (with-selected-window (get-buffer-window (current-buffer))
+ ;; FIXME: it is very naughty to use someone else's `--'
+ ;; function, but `xref--goto-char' happens to have
+ ;; exactly the semantics we want vis-a-vis widening.
+ (xref--goto-char end)
+ (xref--goto-char beg)
+ (eglot--window-recenter-region beg end)
+
+ (when (derived-mode-p 'prog-mode)
+ (let ((recentered-visible (pos-visible-in-window-p end))
+ (recentered-start (window-start)))
+ (reposition-window) ; Try to show preceding comments.
+ (when (and recentered-visible
+ (not (pos-visible-in-window-p end)))
+ ;; reposition-window ruined visibility of selection.
+ (set-window-start nil recentered-start)))))
+
(pulse-momentary-highlight-region beg end 'highlight)))))))
(t (setq success :json-false)))
`(:success ,success)))
--
2.39.2
next prev parent reply other threads:[~2024-04-17 9:15 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-04-04 13:17 bug#70193: eglot: RFE: recenter buffer upon showDocument request Alan Donovan via Bug reports for GNU Emacs, the Swiss army knife of text editors
[not found] ` <handler.70193.B.171223666917509.ack@debbugs.gnu.org>
2024-04-04 13:32 ` bug#70193: Acknowledgement (eglot: RFE: recenter buffer upon showDocument request) Alan Donovan via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-04-04 14:43 ` Felician Nemeth
2024-04-05 9:07 ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-04-05 13:53 ` Felician Nemeth
2024-04-07 7:30 ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-04-13 8:08 ` Eli Zaretskii
2024-04-13 9:10 ` Felician Nemeth
2024-04-13 16:36 ` Alan Donovan via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-04-17 9:15 ` Felician Nemeth [this message]
2024-04-17 12:13 ` bug#70193: [PATCH] " João Távora
2024-04-23 7:43 ` Felician Nemeth
2024-04-23 9:27 ` João Távora
2024-04-24 16:37 ` Juri Linkov
2024-04-24 20:14 ` João Távora
2024-04-27 10:25 ` Philip Kaludercic
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87sezkcpua.fsf_-_@betli.tmit.bme.hu \
--to=felician.nemeth@gmail.com \
--cc=70193@debbugs.gnu.org \
--cc=adonovan@google.com \
--cc=eliz@gnu.org \
--cc=joaotavora@gmail.com \
--cc=rudalics@gmx.at \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this external index
https://git.savannah.gnu.org/cgit/emacs.git
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.