[Feature request] search buffers by project name.
hanjaelee opened this issue · comments
I want to search buffers by projectile project name. then It will be more productive for me.
Or It will be good to search it by filepath or other infomation ivy-rich gives like buffer mode
I think for now, the easiest way to do this is to use a custom function to complete buffers.
For example,
(sorry I do not know a proper way to embed the codes, so I chose to post a photo.)
If you use the above function as the collection argument to ivy-read
(with dynamic-collection
set to t
), then when the input starts with a space, it will complete in the hidden buffers; if the input starts with -, it will also search for buffers whose major modes match the input; if the input starts with /, it will also search for buffers whose file paths match the input.
@JSDurand Can you copy and paste the code wrapped with `?
I found that wrapping the code with three back-ticks makes the code look a lot nicer.
(defun durand-complete-buffer (str)
"Complete buffers; intended to be used as `collection' of `ivy-read' with `dynamic-collection' set to t.
If STR starts with \"-\", then complete also with mode name;
if STR starts with \"/\", then complete also with the file name;
if STR starts with a space, then consider also hidden buffers."
(cl-loop for buffer being buffers
when (let* ((nom (buffer-name buffer))
(re-str (funcall (or (ivy-state-re-builder ivy-last)
'ivy--regex-fuzzy)
str))
(matcher (if (stringp re-str) 'string-match 'ivy-re-match)))
(cond
((and (> (length str) 0)
(= (aref str 0) 32)
(= (aref nom 0) 32))
(funcall matcher re-str nom))
((= (aref nom 0) 32) nil)
((and (> (length str) 0)
(= (aref str 0) ?-))
(let* ((re-str
(funcall (or (ivy-state-re-builder ivy-last)
'ivy--regex-fuzzy)
(substring str 1)))
(matcher (if (stringp re-str) 'string-match 'ivy-re-match)))
(or (funcall matcher re-str nom)
(funcall matcher re-str
(ivy-rich-switch-buffer-major-mode
nom)))))
((and (> (length str) 0)
(= (aref str 0) ?/))
(let* ((re-str
(funcall (or (ivy-state-re-builder ivy-last)
'ivy--regex-fuzzy)
(substring str 1)))
(matcher (if (stringp re-str) 'string-match 'ivy-re-match)))
(or (funcall matcher re-str nom)
(funcall matcher re-str
(ivy-rich-switch-buffer-path nom)))))
(t (funcall matcher re-str nom))))
collect (buffer-name buffer)))
This function might not be very thoughtful, so feel free to do what you like to it to fulfill your purposes. :)
Thanks
I'm currently looking to do exactly that: when I do C-x b
(ivy-switch-buffer
) I would like to have a way to filter (or search, refine) by project name first (as it is being displayed by ivy-rich
). I'm not sure if it's really possible but this seems like an interesting starting point to investigate further.
I have proposed a simple modification to ivy which allows to filter based on additional columns supplied by ivy-rich (or any user-supplied transformer function), on a per-command basis (i.e. in my personal case I use it only to modify the behavior of ivy-switch-buffer
, as the extra cost of computing the transformations on the fly is low enough to be acceptable, which might not be the case with other functions).