ivy-rich--switch-buffer-root-and-filename is broken (report with probable fix)
bymoz089 opened this issue · 6 comments
function ivy-rich--switch-buffer-root-and-filename
is broken. It returns always nil
if the file is not part of a project (or projectile is not installed).
How to reproduce: open a file like "/tmp/foo.txt" and then switch buffers with ivy-switch-buffer
, while ivy-rich
is activated. You will see, that there is no path listed at candidate foo.txt
.
Folowing code is a try to fix this function:
(defun ivy-rich--switch-buffer-root-and-filename (candidate)
(let* ((buffer (get-buffer candidate))
(truenamep t))
(cl-destructuring-bind
(filename directory mode)
(ivy-rich--local-values buffer '(buffer-file-name default-directory major-mode))
;; Only make sense when `filename' and `root' are both not `nil'
(unless (and filename
directory
(if (file-remote-p filename) ivy-rich-parse-remote-buffer t)
(not (eq mode 'dired-mode)))
(setq truenamep nil))
(when (and truenamep
(ivy-rich-switch-buffer-in-project-p candidate))
;; Find the project root directory or `default-directory'
(setq directory (cond ((bound-and-true-p projectile-mode)
(or (ivy-rich--local-values buffer 'projectile-project-root)
(with-current-buffer buffer
(projectile-project-root))))
((require 'project nil t)
(with-current-buffer buffer
(setq truenamep nil)
(car (project-roots (project-current))))))))
(if truenamep
(progn
(setq filename (or (ivy-rich--local-values buffer 'buffer-file-truename)
(file-truename filename)))
(cons (expand-file-name directory)
(expand-file-name filename)))))))
Hi, sorry for the late reply. I'm not sure whether the original purpose of ivy-rich--switch-buffer-root-and-filename
is to only work with project.el
or projectile.el
. Please give me some time to read the logs...
@styx00 About the columns widths, I personally prefer percentages like
ivy-switch-buffer
(:columns ((ivy-rich-switch-buffer-candidate (:width 0.25))
(ivy-rich-switch-buffer-size (:width 0.05))
(ivy-rich-switch-buffer-indicators (:width 0.05 :face error :align right))
(ivy-rich-switch-buffer-major-mode (:width 0.1 :face warning))
(ivy-rich-switch-buffer-project (:width 0.15 :face success))
(ivy-rich-switch-buffer-path (:width (lambda (x)
(ivy-rich-switch-buffer-shorten-path x (ivy-rich-minibuffer-width 0.4))))))
:predicate
(lambda (cand)
(get-buffer cand)))
I'm not a user of projectile.el
. The following is an ad-hoc fix to show the path up to dirname.
In order to show the path, some lines are commented out.
(defun ivy-rich--switch-buffer-root-and-filename (candidate)
(when-let (;; (root (ivy-rich-switch-buffer-root candidate))
(dir (ivy-rich--switch-buffer-directory candidate)))
(when (bound-and-true-p projectile-mode)
(setq dir (or (file-name-directory
(or (ivy-rich--local-values
candidate 'buffer-file-truename)
""))
(file-truename dir))))
(cons ;; (expand-file-name root)
""
(expand-file-name dir))))
My home-baked fallback when there's no project root.
(defadvice! ivy-rich-no-project-fallback (orig-fn candidate)
:around #'ivy-rich--switch-buffer-root-and-filename
(if-let ((result (funcall orig-fn candidate)))
result
(cons ""
(expand-file-name (ivy-rich--switch-buffer-directory candidate)))))
Or like this ?
(defun ivy-rich-no-project-fallback (orig-fn candidate)
(if-let ((result (funcall orig-fn candidate)))
result
(cons ""
(expand-file-name (ivy-rich--switch-buffer-directory candidate)))))
(advice-add #'ivy-rich--switch-buffer-root-and-filename
:around #'ivy-rich-no-project-fallback)
Or like this ?
(defun ivy-rich-no-project-fallback (orig-fn candidate) (if-let ((result (funcall orig-fn candidate))) result (cons "" (expand-file-name (ivy-rich--switch-buffer-directory candidate))))) (advice-add #'ivy-rich--switch-buffer-root-and-filename :around #'ivy-rich-no-project-fallback)
Oh yes indeed. I am using doom emacs and defadvice!
is a doom macro. Basically the same as what you wrote there.