cp-switch-project: make action keys consistent with projectile map

This commit is contained in:
Eric Danan 2017-12-12 20:12:23 +01:00
parent e399476439
commit da185eaabc

View file

@ -32,10 +32,13 @@
;; ;;
;; Projectile has native support for using ivy as its completion ;; Projectile has native support for using ivy as its completion
;; system. Counsel-projectile provides further ivy integration into ;; system. Counsel-projectile provides further ivy integration into
;; projectile by taking advantage of ivy's mechanism to select from a ;; projectile by taking advantage of ivy's support for selecting from
;; list of actions and/or apply an action without leaving the ;; a list of actions and applying an action without leaving the
;; comlpetion session. It is inspired by helm-projectile. See the ;; completion session. Concretely, counsel-projectile defines
;; README for more details. ;; replacements for existing projectile commands as well as new
;; commands that have no projectile counterparts. A minor mode is also
;; provided that adds key bindings for all these commands on top of
;; the projectile key bindings.
;; ;;
;;; Code: ;;; Code:
@ -230,20 +233,21 @@ The format is the same as in `org-capture-templates-contexts'."
(defun counsel-projectile--defcustom-action (command action group) (defun counsel-projectile--defcustom-action (command action group)
"Create a custom variable named \"COMMAND-action\" in GROUP, "Create a custom variable named \"COMMAND-action\" in GROUP,
to be used as `:action' parameter for COMMAND's `ivy-read' call. with default value ACTION, to be used as `:action' parameter for
COMMAND's `ivy-read' call.
The variable can hold either a single action function, or an This variable holds either a single action function, or an action
action list whose first element is the index of the default list whose first element is the index of the default action in
action in the list and the remaining elements are the actions (a the list and the remaining elements are the actions (a key, a
key, a function, and a name for each action." function, and a name for each action."
(eval (eval
`(defcustom ,(intern (format "%s-action" command)) `(defcustom ,(intern (format "%s-action" command))
',action ',action
,(format "Action for `%s'. ,(format "Action(s) for `%s'.
This variable can hold either an action function (function of one This variable holds either a single action function (function of
variable, the selected candidate) or an action list consisting one variable, the selected candidate) or an action list
of: consisting of:
- the index of the default action in the list (1 for the first - the index of the default action in the list (1 for the first
action, etc), action, etc),
@ -263,13 +267,41 @@ usual to assign the key \"o\" to the default action." command)
(function :tag "Single action function") (function :tag "Single action function")
(cons :tag "Action list" (cons :tag "Action list"
(integer :tag "Index of default action" :value 1) (integer :tag "Index of default action" :value 1)
(repeat :tag "Available actions" (repeat :tag "Actions"
(list :tag "Action" (list :tag "Action"
(string :tag " key") (string :tag " key")
(function :tag "function") (function :tag "function")
(string :tag " name"))))) (string :tag " name")))))
:group ',group))) :group ',group)))
(defun counsel-projectile--defcustom-sub-action (action sub-action group)
"Create a custom variable named \"ACTION-sub-action\" in GROUP,
with default value SUB-ACTION, to be passed by ACTION to
`counsel-projectile-sub-action'.
This variable holds a list of sub-actions for ACTION (a key, a
function, and a name for each action)."
(eval
`(defcustom ,(intern (format "%s-sub-action" action))
',sub-action
,(format "Sub-action(s) for `%s'.
This variable holds a list of sub-actions, each or which consists
of:
- a key (one-letter string) to call the action,
- an action function of one variable,
- a name (string) for the action.
When `%s' is called, a key is read from the minibuffer and the
corresponding sub-action is executed." action action)
:type '(repeat :tag "Sub-actions"
(list :tag "Sub-action"
(string :tag " key")
(function :tag "function")
(string :tag " name")))
:group ',group)))
(counsel-projectile--defcustom-action (counsel-projectile--defcustom-action
'counsel-projectile-find-file 'counsel-projectile-find-file
'(1 '(1
@ -277,12 +309,12 @@ usual to assign the key \"o\" to the default action." command)
"current window") "current window")
("j" counsel-projectile-find-file-action-other-window ("j" counsel-projectile-find-file-action-other-window
"other window") "other window")
("f" counsel-projectile-find-file-action-find-file-manually
"find file manually")
("x" counsel-projectile-find-file-action-extern ("x" counsel-projectile-find-file-action-extern
"open externally") "open externally")
("r" counsel-projectile-find-file-action-root ("r" counsel-projectile-find-file-action-root
"open as root") "open as root")
("m" counsel-projectile-find-file-action-find-file-manually
"find file manually")
("p" (lambda (_) (counsel-projectile-switch-project)) ("p" (lambda (_) (counsel-projectile-switch-project))
"switch project")) "switch project"))
'counsel-projectile) 'counsel-projectile)
@ -294,7 +326,7 @@ usual to assign the key \"o\" to the default action." command)
"current window") "current window")
("j" counsel-projectile-find-dir-action-other-window ("j" counsel-projectile-find-dir-action-other-window
"other window") "other window")
("f" counsel-projectile-find-file-action-find-file-manually ("m" counsel-projectile-find-file-action-find-file-manually
"find file manually") "find file manually")
("p" (lambda (_) (counsel-projectile-switch-project)) ("p" (lambda (_) (counsel-projectile-switch-project))
"switch project")) "switch project"))
@ -307,7 +339,7 @@ usual to assign the key \"o\" to the default action." command)
"current window") "current window")
("j" switch-to-buffer-other-window ("j" switch-to-buffer-other-window
"other window") "other window")
("f" counsel-projectile-switch-to-buffer-action-find-file-manually ("m" counsel-projectile-switch-to-buffer-action-find-file-manually
"find file manually") "find file manually")
("p" (lambda (_) (counsel-projectile-switch-project)) ("p" (lambda (_) (counsel-projectile-switch-project))
"switch project")) "switch project"))
@ -317,35 +349,45 @@ usual to assign the key \"o\" to the default action." command)
'counsel-projectile-switch-project 'counsel-projectile-switch-project
'(1 '(1
("o" counsel-projectile-switch-project-action ("o" counsel-projectile-switch-project-action
"jump to buffer or file") "jump to a project buffer or file")
("f" counsel-projectile-switch-project-action-find-file ("f" counsel-projectile-switch-project-action-find-file
"jump to file") "jump to a project file")
("F" counsel-projectile-switch-project-action-find-file-manually
"find file manually")
("d" counsel-projectile-switch-project-action-find-dir ("d" counsel-projectile-switch-project-action-find-dir
"jump to directory") "jump to a project directory")
("b" counsel-projectile-switch-project-action-switch-to-buffer ("b" counsel-projectile-switch-project-action-switch-to-buffer
"jump to buffer") "jump to a project buffer")
("s" counsel-projectile-switch-project-action-save-all-buffers ("m" counsel-projectile-switch-project-action-find-file-manually
"save all buffers") "find file manually from project root")
("S" counsel-projectile-switch-project-action-save-all-buffers
"save all project buffers")
("k" counsel-projectile-switch-project-action-kill-buffers ("k" counsel-projectile-switch-project-action-kill-buffers
"kill all buffers") "kill all project buffers")
("r" counsel-projectile-switch-project-action-remove-known-project ("K" counsel-projectile-switch-project-action-remove-known-project
"remove from known projects") "remove project from known projects")
("l" counsel-projectile-switch-project-action-edit-dir-locals ("E" counsel-projectile-switch-project-action-edit-dir-locals
"edit dir-locals") "edit project dir-locals")
("g" counsel-projectile-switch-project-action-vc ("v" counsel-projectile-switch-project-action-vc
"open in vc-dir / magit / monky") "open project in vc-dir / magit / monky")
("e" counsel-projectile-switch-project-action-run-eshell ("s" counsel-projectile-switch-project-action-prefix-search
"start eshell") "search project with ag / rg / grep...")
("G" counsel-projectile-switch-project-action-grep ("x" counsel-projectile-switch-project-action-prefix-shell
"search with grep") "invoke shell / eshell / term from project root...")
("a" counsel-projectile-switch-project-action-ag ("O" counsel-projectile-switch-project-action-org-capture
"search with ag") "org-capture into project"))
("R" counsel-projectile-switch-project-action-rg 'counsel-projectile)
"search with rg")
("c" counsel-projectile-switch-project-action-org-capture (counsel-projectile--defcustom-sub-action
"org-capture")) 'counsel-projectile-switch-project-action-prefix-search
'(("g" counsel-projectile-switch-project-action-grep "Search project with grep")
("s" counsel-projectile-switch-project-action-ag "Search project with ag")
("r" counsel-projectile-switch-project-action-rg "Search project with rg"))
'counsel-projectile)
(counsel-projectile--defcustom-sub-action
'counsel-projectile-switch-project-action-prefix-shell
'(("s" counsel-projectile-switch-project-action-run-shell "Invoke shell from project root")
("e" counsel-projectile-switch-project-action-run-eshell "Invoke eshell from project root")
("t" counsel-projectile-switch-project-action-run-term "Invoke term from project root"))
'counsel-projectile) 'counsel-projectile)
(counsel-projectile--defcustom-action (counsel-projectile--defcustom-action
@ -355,12 +397,12 @@ usual to assign the key \"o\" to the default action." command)
"current window") "current window")
("j" counsel-projectile-action-other-window ("j" counsel-projectile-action-other-window
"other window") "other window")
("f" counsel-projectile-action-find-file-manually
"find file manually")
("x" counsel-projectile-action-file-extern ("x" counsel-projectile-action-file-extern
"open file externally") "open file externally")
("r" counsel-projectile-action-file-root ("r" counsel-projectile-action-file-root
"open file as root") "open file as root")
("m" counsel-projectile-action-find-file-manually
"find file manually")
("p" (lambda (_) (counsel-projectile-switch-project)) ("p" (lambda (_) (counsel-projectile-switch-project))
"switch project")) "switch project"))
'counsel-projectile) 'counsel-projectile)
@ -668,7 +710,7 @@ is called with a prefix argument."
;;;###autoload ;;;###autoload
(defun counsel-projectile-org-capture () (defun counsel-projectile-org-capture ()
"Capture something into the current project. "Org-capture into the current project.
The capture templates are read from the variables The capture templates are read from the variables
`counsel-projectile-org-capture-templates' and `counsel-projectile-org-capture-templates' and
@ -707,6 +749,30 @@ The capture templates are read from the variables
;;; counsel-projectile-switch-project ;;; counsel-projectile-switch-project
(defun counsel-projectile-sub-action (cand sub-actions)
"Read a key from the minibuffer and apply the corresponding
action from SUB-ACTIONS to CAND.
SUB-ACTIONS is list of ivy actions: a key, an action function,
and a name for each action. Binding a key to a call to this
function in an ivy action list makes this key behave like a
prefix key and the keys in SUB-ACTIONS like sub-keys."
;; adapted from `ivy-read-action'
(let* ((hint (funcall ivy-read-action-format-function sub-actions))
(resize-mini-windows t)
(key (string (read-key hint)))
(action-fun (nth 1 (assoc key sub-actions))))
(cond ((member key '("" ""))
(when (eq ivy-exit 'done)
(ivy-resume)))
((null action-fun)
(message "%s is not bound" key)
(when (eq ivy-exit 'done)
(ivy-resume)))
(t
(message "")
(funcall action-fun cand)))))
(defun counsel-projectile-switch-project-by-name (project) (defun counsel-projectile-switch-project-by-name (project)
"Switch to PROJECT. "Switch to PROJECT.
Invokes the command referenced by Invokes the command referenced by
@ -794,11 +860,31 @@ action."
(let ((projectile-switch-project-action 'projectile-vc)) (let ((projectile-switch-project-action 'projectile-vc))
(counsel-projectile-switch-project-by-name project))) (counsel-projectile-switch-project-by-name project)))
(defun counsel-projectile-switch-project-action-run-shell (project)
"Invoke `shell' from PROJECT's root."
(let ((projectile-switch-project-action 'projectile-run-shell))
(counsel-projectile-switch-project-by-name project)))
(defun counsel-projectile-switch-project-action-run-eshell (project) (defun counsel-projectile-switch-project-action-run-eshell (project)
"Start `eshell' from PROJECT's root." "Invoke `eshell' from PROJECT's root."
(let ((projectile-switch-project-action 'projectile-run-eshell)) (let ((projectile-switch-project-action 'projectile-run-eshell))
(counsel-projectile-switch-project-by-name project))) (counsel-projectile-switch-project-by-name project)))
(defun counsel-projectile-switch-project-action-run-term (project)
"Invoke `term' from PROJECT's root."
(let ((projectile-switch-project-action
(lambda ()
(projectile-run-term nil))))
(counsel-projectile-switch-project-by-name project)))
(defun counsel-projectile-switch-project-action-prefix-shell (project)
"Select a sub-action from
`counsel-projectile-switch-project-action-prefix-shell-sub-action'
and apply it to PROJECT."
(counsel-projectile-sub-action
project
counsel-projectile-switch-project-action-prefix-shell-sub-action))
(defun counsel-projectile-switch-project-action-grep (project) (defun counsel-projectile-switch-project-action-grep (project)
"Search PROJECT with `grep'." "Search PROJECT with `grep'."
(let ((projectile-switch-project-action 'counsel-projectile-ag)) (let ((projectile-switch-project-action 'counsel-projectile-ag))
@ -814,6 +900,14 @@ action."
(let ((projectile-switch-project-action 'counsel-projectile-rg)) (let ((projectile-switch-project-action 'counsel-projectile-rg))
(counsel-projectile-switch-project-by-name project))) (counsel-projectile-switch-project-by-name project)))
(defun counsel-projectile-switch-project-action-prefix-search (project)
"Select a sub-action from
`counsel-projectile-switch-project-action-prefix-search-sub-action'
and apply it to PROJECT."
(counsel-projectile-sub-action
project
counsel-projectile-switch-project-action-prefix-search-sub-action))
(defun counsel-projectile-switch-project-action-org-capture (project) (defun counsel-projectile-switch-project-action-org-capture (project)
"Capture something into PROJECT." "Capture something into PROJECT."
(let ((projectile-switch-project-action 'counsel-projectile-org-capture)) (let ((projectile-switch-project-action 'counsel-projectile-org-capture))
@ -821,7 +915,7 @@ action."
;;;###autoload ;;;###autoload
(defun counsel-projectile-switch-project () (defun counsel-projectile-switch-project ()
"Switch to a project." "Switch project."
(interactive) (interactive)
(ivy-read (projectile-prepend-project-name "Switch to project: ") (ivy-read (projectile-prepend-project-name "Switch to project: ")
(if counsel-projectile-remove-current-project (if counsel-projectile-remove-current-project