From d428d08015f83fe91c058abf7f1fa95657e90483 Mon Sep 17 00:00:00 2001 From: Eric Danan Date: Sat, 17 Mar 2018 00:08:06 +0100 Subject: [PATCH] Add action to kill buffer --- README.md | 10 ++++++++-- counsel-projectile.el | 46 +++++++++++++++++++++++++++++++++++++++---- 2 files changed, 50 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 44f213c..d0c202f 100644 --- a/README.md +++ b/README.md @@ -79,11 +79,14 @@ This command lets you quickly jump to a project buffer or file. It uses ivy to d | :----------- | :--------------------------------------------------------------------------------- | | o | Open buffer or file in current window (default action) | | j | Open buffer or file in other window | +| k | Kill buffer (does nothing for files) | | x | Open file externally (does nothing for buffers) | | r | Open file as root (does nothing for buffers) | -| m | Find file manually: call `counsel-find-file` from buffer or file's directory | +| m | Find file manually: call `counsel-find-file` from buffer or file's directory | | p | Switch project: call `counsel-projectile-switch-project` (see below) | +The key binding C-c C-k can also be used from the minibuffer to kill the buffer corresponding to the current candidate (same as C-M-o k). + If not called inside a project, `counsel-projectile` first offers to select a project to switch to by calling `counsel-projectile-switch-project` (see below). Once you select a project and hit RET, it lets you jump to a buffer or file in this project as described above. ## The `counsel-projectile-switch-project` command Default key binding: C-c p p. @@ -144,8 +147,11 @@ This command is a replacement for `projectile-switch-to-buffer`. It displays a l | :----------- | :------------------------------------------------------------------------- | | o | Open buffer in current window (default action) | | j | Open buffer in other window | -| m | Find file manually: call `counsel-find-file` from buffer's directory | +| k | Kill buffer | +| m | Find file manually: call `counsel-find-file` from buffer's directory | | p | Switch project: call `counsel-projectile-switch-project` (see above) | + +The key binding C-c C-k can also be used from the minibuffer to kill the buffer corresponding to the current candidate (same as C-M-o k). ## The `counsel-projectile-grep` command Default key binding: C-c p s g. diff --git a/counsel-projectile.el b/counsel-projectile.el index 048f2a8..13d4ded 100644 --- a/counsel-projectile.el +++ b/counsel-projectile.el @@ -445,13 +445,25 @@ candidates list of `counsel-projectile-switch-to-buffer' and "current window") ("j" switch-to-buffer-other-window "other window") + ("k" ivy--kill-buffer-action + "kill") ("m" counsel-projectile-switch-to-buffer-action-find-file-manually "find file manually") ("p" (lambda (_) (counsel-projectile-switch-project)) "switch project")) 'counsel-projectile) -(defun counsel-projectile--project-buffers () +(defvar counsel-projectile-switch-to-buffer-map + (let ((map (make-sparse-keymap))) + (define-key map (kbd "C-c C-k") (lambda () + (interactive) + (ivy--kill-buffer-action (ivy-state-current ivy-last)))) + map) + "Keymap for `counsel-projectile-switch-to-buffer'.") + +(defun counsel-projectile--project-buffers (&rest _) + ;; The ignored arguments are so that the function can be used as + ;; collection function in `counsel-projectile-switch-to-buffer'. "Return a list of buffers in the current project. Like `projectile-project-buffer-names', but propertize buffer @@ -481,11 +493,15 @@ names as in `ivy--buffer-list', and remove current buffer if "Jump to a buffer in the current project." (interactive) (ivy-read (projectile-prepend-project-name "Switch to buffer: ") - (counsel-projectile--project-buffers) + ;; We use a collection function so that it is called each + ;; time the `ivy-state' is reset. This is needed for the + ;; "kill buffer" action. + #'counsel-projectile--project-buffers :matcher #'ivy--switch-buffer-matcher :require-match t :sort t :action counsel-projectile-switch-to-buffer-action + :keymap counsel-projectile-switch-to-buffer-map :caller 'counsel-projectile-switch-to-buffer)) (unless (assq #'counsel-projectile-switch-to-buffer ivy-sort-functions-alist) @@ -1102,6 +1118,8 @@ action." "current window") ("j" counsel-projectile-action-other-window "other window") + ("k" counsel-projectile-action-kill-buffer + "kill buffer") ("x" counsel-projectile-action-file-extern "open file externally") ("r" counsel-projectile-action-file-root @@ -1112,6 +1130,14 @@ action." "switch project")) 'counsel-projectile) +(defvar counsel-projectile-map + (let ((map (make-sparse-keymap))) + (define-key map (kbd "C-c C-k") (lambda () + (interactive) + (counsel-projectile-action-kill-buffer (ivy-state-current ivy-last)))) + map) + "Keymap for `counsel-projectile'.") + (defvar counsel-projectile--buffers nil "Stores a list of project buffers.") @@ -1119,7 +1145,9 @@ action." "Stores a list of project files that are not currently visited by a buffer.") -(defun counsel-projectile--project-buffers-and-files () +(defun counsel-projectile--project-buffers-and-files (&rest _) + ;; The ignored arguments are so that the function can be used as + ;; collection function in `counsel-projectile'. "Return a list of buffers and files in the current project." (append (setq counsel-projectile--buffers @@ -1153,6 +1181,12 @@ files." (switch-to-buffer-other-window name) (counsel-projectile-find-file-action-other-window name))) +(defun counsel-projectile-action-kill-buffer (name) + "Kill buffer named NAME." + (if (member name counsel-projectile--buffers) + (ivy--kill-buffer-action name) + (message "This action only applies to buffers."))) + (defun counsel-projectile-action-find-file-manually (name) "Call `counsel-find-file' from default directory of buffer directory of file named NAME." @@ -1190,11 +1224,15 @@ If not inside a project, call `counsel-projectile-switch-project'." (counsel-projectile-switch-project) (projectile-maybe-invalidate-cache arg) (ivy-read (projectile-prepend-project-name "Load buffer or file: ") - (counsel-projectile--project-buffers-and-files) + ;; We use a collection function so that it is called each + ;; time the `ivy-state' is reset. This is needed for the + ;; "kill buffer" action. + #'counsel-projectile--project-buffers-and-files :matcher #'counsel-projectile--matcher :require-match t :sort t :action counsel-projectile-action + :keymap counsel-projectile-map :caller 'counsel-projectile))) (unless (assq #'counsel-projectile ivy-sort-functions-alist)