I have the below setting in my config as recommended by many scrolling packages like ultra-scroll-mac.

(setq scroll-conservatively 101)

The issue is, when using this config with lsp-mode, xref-go-back will not recenter the point to the middle of the window, but instead it recenter the point to the bottom of the window.

For example, before xref-find-definitions

enter image description here

after xref-find-definitions

enter image description here

after xref-go-back

enter image description here

I tested in a emacs -q settings with the config below, I am not sure if it's a lsp-mode issue so I have not reported it there. Also the issue is gone if scroll-conservatively is 0 or not using lsp-mode (e.g. using xref-go-back in plain emacs-lisp-mode).

I tried something like

(defun xref-go-back-fixes (orig-func &rest args)
    (let ((scroll-conservatively 0))
      (apply orig-func args)))
  (advice-add 'xref-go-back :around #'xref-go-back-fixes)

But it does not work. Unless I eval (setq scroll-conservatively 0) in the minibuffer, the issue is still there.

Any help or suggestion will be greatly appreciated!

;; -*- lexical-binding: t; -*-

(defvar elpaca-installer-version 0.6)
(defvar elpaca-directory (expand-file-name "elpaca/" user-emacs-directory))
(defvar elpaca-builds-directory (expand-file-name "builds/" elpaca-directory))
(defvar elpaca-repos-directory (expand-file-name "repos/" elpaca-directory))
(defvar elpaca-order '(elpaca :repo "https://github.com/progfolio/elpaca.git"
                              :ref nil
                              :files (:defaults "elpaca-test.el" (:exclude "extensions"))
                              :build (:not elpaca--activate-package)))
(let* ((repo  (expand-file-name "elpaca/" elpaca-repos-directory))
       (build (expand-file-name "elpaca/" elpaca-builds-directory))
       (order (cdr elpaca-order))
       (default-directory repo))
  (add-to-list 'load-path (if (file-exists-p build) build repo))
  (unless (file-exists-p repo)
    (make-directory repo t)
    (when (< emacs-major-version 28) (require 'subr-x))
    (condition-case-unless-debug err
        (if-let ((buffer (pop-to-buffer-same-window "*elpaca-bootstrap*"))
                 ((zerop (call-process "git" nil buffer t "clone"
                                       (plist-get order :repo) repo)))
                 ((zerop (call-process "git" nil buffer t "checkout"
                                       (or (plist-get order :ref) "--"))))
                 (emacs (concat invocation-directory invocation-name))
                 ((zerop (call-process emacs nil buffer nil "-Q" "-L" "." "--batch"
                                       "--eval" "(byte-recompile-directory \".\" 0 'force)")))
                 ((require 'elpaca))
                 ((elpaca-generate-autoloads "elpaca" repo)))
            (progn (message "%s" (buffer-string)) (kill-buffer buffer))
          (error "%s" (with-current-buffer buffer (buffer-string))))
      ((error) (warn "%s" err) (delete-directory repo 'recursive))))
  (unless (require 'elpaca-autoloads nil t)
    (require 'elpaca)
    (elpaca-generate-autoloads "elpaca" repo)
    (load "./elpaca-autoloads")))
(add-hook 'after-init-hook #'elpaca-process-queues)
(elpaca `(,@elpaca-order))

(elpaca elpaca-use-package
  (setq elpaca-use-package-by-default t))


(setq use-package-verbose nil
      use-package-enable-imenu-support t
      use-package-always-defer t)

(add-to-list 'auto-mode-alist '("\\.rs\\'" . rust-ts-mode))

(use-package lsp-mode
  :defer 3
  :diminish (lsp-mode)
  :hook ((rust-ts-mode)
         . (lambda () (run-with-idle-timer 0.2 nil #'lsp-deferred))))

(use-package lsp-rust
  :elpaca nil
  :demand t
  :after (:all lsp-mode rust-ts-mode)
  :init (setq lsp-rust-clippy-preference "on"
              lsp-rust-analyzer-cargo-watch-command "clippy"))


  • It does sound like an lsp-mode issue (with a bug report). But to confirm that it's not somehow a limitation of the LSP protocol, you can also try reproducing this problem with eglot.
    – Dmitry
    Jan 17 at 3:31
  • @Dmitry After a quick test, I found that the same issue exists with eglot. Jan 17 at 4:05
  • Ah yeah, I can reproduce this with Elisp too. See the answer below.
    – Dmitry
    Jan 17 at 4:37

1 Answer 1


This is in fact one of the effects of setting scroll-conservatively: when a point moves inside a buffer, the window is scrolled in this particular way.

Anyway, to solve this specifically for xref-go-back, at least, you can add recenter to xref-after-return-hook.

Just like in xref-after-jump-hook where it's already present.

  • 1
    Strange, I can not reproduce this in non lsp-modes . Anyway, your answer solved the question. Thank you very much for helping to fix this long-live super annoying issue for me. And I like you company package. Jan 17 at 5:33
  • You're welcome!
    – Dmitry
    Jan 17 at 22:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.