branch: master commit 2f1133a158bad191d169f0b05b08ba2546b9ab7d Author: Oleh Krehel <ohwoeo...@gmail.com> Commit: Oleh Krehel <ohwoeo...@gmail.com>
ivy.el (ivy-occur): Add and bind to "C-c o" * ivy.el (ivy-minibuffer-map): Update. (ivy-occur-action): (ivy-occur-last): (ivy-occur-map): New defvar. (ivy-occur): New command. (ivy-occur-click): New command bound to mouse click. (ivy-occur-press): New command bound to "RET" press. `ivy-occur' allows to store the current completion session for further use. An unlimited amount of these sessions can be used, each in its own buffer. --- ivy.el | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 69 insertions(+), 0 deletions(-) diff --git a/ivy.el b/ivy.el index 10c019d..aacdcf4 100644 --- a/ivy.el +++ b/ivy.el @@ -170,6 +170,7 @@ Only \"./\" and \"../\" apply here. They appear in reverse order." (define-key map (kbd "S-SPC") 'ivy-restrict-to-matches) (define-key map (kbd "M-w") 'ivy-kill-ring-save) (define-key map (kbd "C-'") 'ivy-avy) + (define-key map (kbd "C-c o") 'ivy-occur) map) "Keymap used in the minibuffer.") (autoload 'hydra-ivy/body "ivy-hydra" "" t) @@ -2063,6 +2064,74 @@ If the region is active, forward to `kill-ring-save' instead." ivy--old-cands "\n")))) +(defvar-local ivy-occur-action nil + "Function to call for each line in *ivy-occur* buffer.") + +(defvar-local ivy-occur-last nil + "Buffer-local value of `ivy-last'.") + +(defvar ivy-occur-map + (let ((map (make-sparse-keymap))) + (define-key map [mouse-1] 'ivy-occur-click) + (define-key map (kbd "RET") 'ivy-occur-press) + map) + "Keymap used in *ivy-occur* buffers.") + +(defun ivy-occur () + "Stop completion and put the current matches into a new buffer. + +The new buffer will also remember the current action. + +While in the *ivy-occur* buffer, selecting a cadidate with RET or +a mouse click will call the action for that candidate. + +It's possible to have an unlimited amount of *ivy-occur* buffers." + (interactive) + (ivy-quit-and-run + (let (caller) + (pop-to-buffer + (generate-new-buffer + (format "*ivy-occur%s*" + (if (setq caller (ivy-state-caller ivy-last)) + (concat " " (prin1-to-string caller)) + "")))) + (read-only-mode) + (setq ivy-occur-action (ivy--get-action ivy-last)) + (setq-local ivy--directory ivy--directory) + (setq ivy-occur-last ivy-last) + (let ((inhibit-read-only t)) + (erase-buffer) + (insert (format "%d candidates:\n" (length ivy--old-cands))) + (dolist (cand ivy--old-cands) + (let ((str (concat " " cand))) + (add-text-properties + 0 (length str) + `(mouse-face + highlight + help-echo "mouse-1: call ivy-action" + keymap ,ivy-occur-map) + str) + (insert str "\n"))))))) + +(defun ivy-occur-click (event) + "Execute action for the current candidate. +EVENT gives the mouse position." + (interactive "e") + (let ((window (posn-window (event-end event))) + (pos (posn-point (event-end event)))) + (with-current-buffer (window-buffer window) + (goto-char pos) + (ivy-occur-press)))) + +(defun ivy-occur-press () + "Execute action for the current candidate." + (interactive) + (let ((ivy-last ivy-occur-last)) + (funcall ivy-occur-action + (buffer-substring + (+ 4 (line-beginning-position)) + (line-end-position))))) + (defun ivy-insert-current () "Make the current candidate into current input. Don't finish completion."