refactor!(vertico): crm keybindings behaviour

BREAKING CHANGE: This commit changes the behaviour of the TAB and RET
keys in a consult-completing read multiple session, in order to make
them more intuitive. The behaviour is now:

- TAB: (unchanged) always select or deselect the current candidate, and
  if the candidate is selected, move the index to the next one (this
  allows for pressing TAB repeatedly to select multiple subsequent
  candidates).

- RET: If no candidates have been selected, select the current candidate
  and exit the completion session. If some have been selected, disregard
  the current candidate and exit.

- S-TAB: (new) like TAB, but the keeps the input.
This commit is contained in:
Itai Y. Efrat 2021-12-13 02:19:56 +02:00
parent 5274f1ad4d
commit 4f34635e04
2 changed files with 30 additions and 9 deletions

View file

@ -208,20 +208,40 @@ targets."
;;;###autoload ;;;###autoload
(defun +vertico/crm-select () (defun +vertico/crm-select ()
"Enter candidate in `consult-completing-read-multiple'" "Toggle selection of current candidate in `consult-completing-read-multiple'.
If the candidate has been selected, move the index up by one, to allow for quick
selection of multiple subsequent candidates."
(interactive) (interactive)
(let ((idx vertico--index)) (let* ((selected-p (get-text-property 0 'consult--crm-selected (vertico--candidate)))
(unless (get-text-property 0 'consult--crm-selected (nth vertico--index vertico--candidates)) (goto-idx (+ vertico--index (if selected-p 0 1))))
(setq idx (1+ idx))) (run-at-time 0 nil (cmd! (vertico--goto goto-idx) (vertico--exhibit))))
(run-at-time 0 nil (cmd! (vertico--goto idx) (vertico--exhibit)))) (vertico-exit))
;;;###autoload
(defun +vertico/crm-select-keep-input ()
"Like `+vertico/crm-select', but keeps the current minibuffer input."
(interactive)
(let* ((input (substring-no-properties (car vertico--input)))
(selected-p (get-text-property 0 'consult--crm-selected (vertico--candidate)))
(goto-idx (+ vertico--index (if selected-p 0 1))))
(run-at-time 0 nil (cmd! (insert input) (vertico--exhibit) (vertico--goto goto-idx) (vertico--exhibit))))
(vertico-exit)) (vertico-exit))
;;;###autoload ;;;###autoload
(defun +vertico/crm-exit () (defun +vertico/crm-exit ()
"Enter candidate in `consult-completing-read-multiple'" "Exit `consult-completing-read-multiple' session in a dwim way.
If there are no selected candidates, select the current candidate and exit.
If there are selected candidates, disregard the current candidate and exit."
(interactive) (interactive)
(run-at-time 0 nil #'vertico-exit) (if (consult--crm-selected)
(vertico-exit)) (progn
(when (minibuffer-contents)
(delete-minibuffer-contents)
(vertico--exhibit))
(vertico--goto -1)
(vertico-exit))
(run-at-time 0 nil #'vertico-exit)
(vertico-exit)))
;;;###autoload ;;;###autoload
(defun +vertico--consult--fd-builder (input) (defun +vertico--consult--fd-builder (input)

View file

@ -146,7 +146,8 @@ orderless."
:items ,(lambda () (mapcar #'buffer-name (org-buffer-list))))) :items ,(lambda () (mapcar #'buffer-name (org-buffer-list)))))
(add-to-list 'consult-buffer-sources '+vertico--consult-org-source 'append)) (add-to-list 'consult-buffer-sources '+vertico--consult-org-source 'append))
(map! :map consult-crm-map (map! :map consult-crm-map
:desc "Select candidate" "TAB" #'+vertico/crm-select :desc "Select candidate" [tab] #'+vertico/crm-select
:desc "Select candidate and keep input" [backtab] #'+vertico/crm-select-keep-input
:desc "Enter candidates" "RET" #'+vertico/crm-exit)) :desc "Enter candidates" "RET" #'+vertico/crm-exit))