Skip to content

CIDER session is lost when navigating to definition #3250

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

Closed
mmontone opened this issue Sep 21, 2022 · 3 comments · Fixed by #3412
Closed

CIDER session is lost when navigating to definition #3250

mmontone opened this issue Sep 21, 2022 · 3 comments · Fixed by #3412
Assignees

Comments

@mmontone
Copy link

mmontone commented Sep 21, 2022

Hi,

when navigating to a definition via xref-find-definition (M-.), if the target buffer is not part of the Clojure project I'm in, the buffer is 'unlinked', and so I cannot continue navigating or evaluate Clojure code in the new buffer, unless I manually link it with sesman-link-buffer.

So, I've added this to my .emacs, that propagates the current CIDER session to the definition buffer:

(defun cider--xref-show-definitions-buffer (fetcher alist)
  "Propagate the CIDER session to the definitions buffer."
  (let ((session (sesman-current-session 'CIDER)))
    (xref-show-definitions-buffer fetcher alist)
    (sesman-link-with-buffer nil session)))

(add-hook 'cider-mode-hook
	  (lambda ()
	    (setq-local xref-show-definitions-function 'cider--xref-show-definitions-buffer)))

Not sure if this is the best fix, but it does the job for me.

@vemv vemv self-assigned this Jul 27, 2023
@vemv vemv pinned this issue Aug 4, 2023
@vemv
Copy link
Member

vemv commented Aug 14, 2023

I cannot reproduce this although I think I've seen it happen. Also, definitely have heard of it happening to other people (e.g. today)

@bbatsov , do you recall what the mechanism is for making sure a Sesman session is 'inherited' from one buffer to a new one (the new one being that M-. brought you to)?

I thought it had to do with default-directory but it's not necessarily the case, from what I've tried.

@vemv
Copy link
Member

vemv commented Aug 14, 2023

Ok, this summarizes it https://docs.cider.mx/cider/usage/managing_connections.html#friendly-sessions

A way to debug this is by

  • ensuring the current buffer is the problematic one (e.g. place the cursor over the buffer that M-. just brought you to)
  • running the same code that cl-defmethod sesman-friendly-session-p would, e.g.:
(mapcar (lambda (session)
          (sesman-friendly-session-p 'CIDER session))
        (sesman--all-system-sessions 'CIDER))

The resulting list should include at least one truthy item.

If not, one has to debug why. Get started by inlining CIDER's sesman-friendly-session-p code into the lambda:

(mapcar (lambda (session)
          (setcdr session (seq-filter #'buffer-live-p (cdr session)))
          (when-let* ((repl (cadr session))
                      (proc (get-buffer-process repl))
                      (file (file-truename (or (buffer-file-name) default-directory))))
            ;; With avfs paths look like /path/to/.avfs/path/to/some.jar#uzip/path/to/file.clj
            (when (string-match-p "#uzip" file)
              (let ((avfs-path (directory-file-name (expand-file-name (or (getenv "AVFSBASE")  "~/.avfs/")))))
                (setq file (replace-regexp-in-string avfs-path "" file t t))))
            (when (process-live-p proc)
              (let* ((classpath (or (process-get proc :cached-classpath)
                                    (let ((cp (with-current-buffer repl
                                                (cider-classpath-entries))))
                                      (process-put proc :cached-classpath cp)
                                      cp)))
                     (classpath-roots (or (process-get proc :cached-classpath-roots)
                                          (let ((cp (thread-last
                                                        classpath
                                                      (seq-filter (lambda (path) (not (string-match-p "\\.jar$" path))))
                                                      (mapcar #'file-name-directory)
                                                      (seq-remove  #'null)
                                                      (seq-uniq))))
                                            (process-put proc :cached-classpath-roots cp)
                                            cp))))
                (or (seq-find (lambda (path) (string-prefix-p path file))
                              classpath)
                    (seq-find (lambda (path) (string-prefix-p path file))
                              classpath-roots))))))
        (sesman--all-system-sessions 'CIDER))

...it should return the same as before. Then, one has to figure out why it doesn't include at least one truthy element. Add some messages or setqs to determine why the file is not considered a part of the classpath/classpath-roots.

@igrishaev
Copy link

Thank you @mmontone for sharing that code! It works for me too.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants