cp-find-file: make matcher customizable and provide basename matcher
Closes #72
This commit is contained in:
parent
e8eee886b7
commit
222b6ac531
2 changed files with 73 additions and 4 deletions
|
|
@ -224,6 +224,10 @@ Templates contexts are read from the variable `counsel-projectile-org-capture-te
|
|||
By default, when calling `counsel-projectile-switch-project`, the current project (if any) is included in the candidates list and preselected. Similarly, when calling `counsel-projectile-switch-to-buffer`, the current buffer is included in the candidates list and preselected. If you prefer removing these elements from the candidate lists of these commands, you can set the variables `counsel-projectile-remove-current-project` and `counsel-projectile-remove-current-buffer` accordingly.
|
||||
## Initial input for the project search commands
|
||||
If you want some initial input to be inserted in the minibuffer every time you call `counsel-projectile-grep`, `counsel-projectile-ag`, or `counsel-projectile-rg`, you can customize the variables `counsel-projectile-grep-initial-input`, `counsel-projectile-ag-initial-input`, or `counsel-projectile-rg-initial-input` accordingly. Each of these variable, if non `nil`, should hold a Lisp expression whose evaluation yields the initial input string. If you use the Customize interface, some choices are proposed based on various versions of the `thing-at-point` function. Note that you can always insert the value of `(ivy-thing-at-point)` by hitting <kbd>M-n</kbd> in the minibuffer.
|
||||
## Matcher for `counsel-projectile-find-file`
|
||||
By default, the command `counsel-projectile-find-file` relies on the the matcher of the command `counsel-find-file` to display files matching minibuffer input, allowing to ignore some files based on the variable `counsel-find-file-ignore-regexp`. It is possible to use another matcher by setting the variable `counsel-projectile-find-file-matcher`. Some choices are proposed if you use the Customize interface, in particular the `counsel-projectile-find-file-matcher-basename` matcher which is provided by counsel-projectile and only displays files whose basename matches the minibuffer input (if there is none, it shows all matching files).
|
||||
|
||||
The matcher specified by `counsel-find-file-ignore-regexp` is also used by `counsel-projectile` to match files.
|
||||
## Sorting candidates
|
||||
The following commands allow to modify the way candidates are sorted:
|
||||
- `counsel-projectile`
|
||||
|
|
|
|||
|
|
@ -244,6 +244,35 @@ If anything goes wrong, throw an error and do not modify ACTION-VAR."
|
|||
|
||||
;;;; counsel-projectile-find-file
|
||||
|
||||
(defcustom counsel-projectile-find-file-matcher 'counsel--find-file-matcher
|
||||
"Function returning candidates matching minibuffer input in
|
||||
`counsel-projectile-find-file', also used to match files in
|
||||
`counsel-projectile'.
|
||||
|
||||
Several choices are proposed:
|
||||
|
||||
- Ivy generic matcher (`ivy--re-filter'). This is the matcher
|
||||
used by default in all ivy commands.
|
||||
|
||||
- Counsel matcher (`counsel--find-file-matcher'). This is the
|
||||
matcher used in `counsel-find-file', allowing to ignore some
|
||||
files based on `counsel-find-file-ignore-regexp'.
|
||||
|
||||
- Counsel-projectile basename
|
||||
matcher (`counsel-projectile-basename-matcher'). This one only
|
||||
displays files whose basename matches minibuffer input, or if
|
||||
there is none all files whose name (relative to the project
|
||||
root) matches. It also uses the counsel matcher to ignore some
|
||||
files.
|
||||
|
||||
It is also possible to use a custom matcher. It must be a function taking two argument, the regexp and the candidates (see e.g. `counsel--find-file-matcher')."
|
||||
:type '(choice
|
||||
(const :tag "Ivy generic matcher" ivy--re-filter)
|
||||
(const :tag "Counsel matcher" counsel--find-file-matcher)
|
||||
(const :tag "Counsel-projectile basename matcher" counsel-projectile-find-file-matcher-basename)
|
||||
(function :tag "Custom function"))
|
||||
:group 'counsel-projectile)
|
||||
|
||||
(counsel-projectile--defcustom-action
|
||||
'counsel-projectile-find-file
|
||||
'(1
|
||||
|
|
@ -261,6 +290,41 @@ If anything goes wrong, throw an error and do not modify ACTION-VAR."
|
|||
"switch project"))
|
||||
'counsel-projectile)
|
||||
|
||||
(defun counsel-projectile-find-file-matcher-basename (regexp candidates)
|
||||
"Return the list of CANDIDATES whose basename matches REGEXP,
|
||||
or if there is none the list of all CANDIDATES matching REGEXP.
|
||||
Also uses `counsel--find-file-matcher' to ignore candidates based
|
||||
on `counsel-find-file-ignore-regexp'."
|
||||
(let ((cands (ivy--re-filter regexp candidates)))
|
||||
(or (and (not (string= ivy-text ""))
|
||||
;; We first filter `cands' to retain only matches in file
|
||||
;; basename. This is almost copied from `ivy--re-filter'
|
||||
;; because we can't quite use it directly.
|
||||
(let ((re-list (if (stringp regexp)
|
||||
(list (cons regexp t))
|
||||
regexp))
|
||||
(res cands))
|
||||
(dolist (re re-list)
|
||||
(setq res
|
||||
(ignore-errors
|
||||
(funcall
|
||||
(if (cdr re)
|
||||
#'cl-remove-if-not
|
||||
#'cl-remove-if)
|
||||
(let ((re-str (car re)))
|
||||
(lambda (x)
|
||||
(string-match re-str
|
||||
(file-name-nondirectory x))))
|
||||
res))))
|
||||
;; We then apply `counsel--find-file-matcher' to `res'
|
||||
;; so we can honor `ivy-use-ignore', but we don't need
|
||||
;; to filter again.
|
||||
(counsel--find-file-matcher nil res)))
|
||||
;; We apply `counsel--find-file-matcher' to `cands' so we can
|
||||
;; honor `ivy-use-ignore', but we don't need to filter
|
||||
;; again.
|
||||
(counsel--find-file-matcher nil cands))))
|
||||
|
||||
(defun counsel-projectile-find-file-action (file)
|
||||
"Find FILE and run `projectile-find-file-hook'."
|
||||
(find-file (projectile-expand-root file))
|
||||
|
|
@ -303,7 +367,7 @@ With a prefix ARG, invalidate the cache first."
|
|||
(projectile-maybe-invalidate-cache arg)
|
||||
(ivy-read (projectile-prepend-project-name "Find file: ")
|
||||
(projectile-current-project-files)
|
||||
:matcher #'counsel--find-file-matcher
|
||||
:matcher counsel-projectile-find-file-matcher
|
||||
:require-match t
|
||||
:sort t
|
||||
:action counsel-projectile-find-file-action
|
||||
|
|
@ -1071,10 +1135,11 @@ action."
|
|||
(defun counsel-projectile--matcher (regexp _candidates)
|
||||
"Return REGEXP-matching CANDIDATES for `counsel-projectile'.
|
||||
|
||||
Relies on `ivy--switch-buffer-matcher' and
|
||||
`counsel--find-file-matcher'."
|
||||
Relies on `ivy--switch-buffer-matcher' for buffers and the
|
||||
matcher specified in `counsel-projectile-find-file-matcher' for
|
||||
files."
|
||||
(append (ivy--switch-buffer-matcher regexp counsel-projectile--buffers)
|
||||
(counsel--find-file-matcher regexp counsel-projectile--non-visited-files)))
|
||||
(funcall counsel-projectile-find-file-matcher regexp counsel-projectile--non-visited-files)))
|
||||
|
||||
(defun counsel-projectile-action (name)
|
||||
"Switch to buffer or find file named NAME."
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue