Skip to content

Commit 37f6b6b

Browse files
aikrahguzarRahguzar
and
Rahguzar
authored
Add previous inputs to defaults in multi-selection
Close #714 Co-authored-by: Rahguzar <[email protected]>
1 parent a9fae9c commit 37f6b6b

File tree

2 files changed

+36
-14
lines changed

2 files changed

+36
-14
lines changed

README.org

+10
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,8 @@ You then have two ways to access these strings from the completion prompt:
216216
1. by using =M-n= from the prompt, which will cycle through the strings
217217
2. by calling =citar-insert-preset= with a keybinding, and then selecting the string
218218

219+
If you want to select multiple candidates using the same search term =M-n= also recalls the previous input, so you can use =TAB= to select one candidate then press =M-n= to quickly insert the previous search term again (see notes below for some caveats).
220+
219221
=citar= also preserves the history of your selections (see caveat below about multiple candidate selection though), which are also accessible in your completion UI, but by using =M-p=.
220222
You can save this history across sessions by adding =citar-history= to =savehist-additional-variables=.
221223

@@ -238,6 +240,14 @@ The ~citar-notes-sources~ variable configures note backends, and ~citar-notes-so
238240
A backend primarily specifies functions to update the Citar display, to create the completion candidates, and to open existing and new notes.
239241
See the ~citar-notes-sources~ docstring for details, and the =citar-register-notes-source= and =citar-remove-notes-source= convenience functions.
240242

243+
Using =M-n= to recall the previous input only works when selecting multiple candidates during a single =citar-command=. If you use =vertico=, =vertico-repeat= provides similar functionality for rerunning the commands with the last input.
244+
245+
By default =Emacs= leaves the point at the beginning of input if you press =M-n= with minibuffer empty. If you want to change this behavior and instead leave the point at the end of input use,
246+
247+
#+BEGIN_SRC emacs-lisp
248+
(advice-add 'goto-history-element :after (defun my-end-of-buffer (&rest _) (goto-char (point-max))))
249+
#+END_SRC
250+
241251
** Files, file association and file-field parsing
242252

243253
If you have ~citar-library-paths~ set, the relevant open commands will look in those directories for file names of =CITEKEY.EXTENSION=.

citar.el

+26-14
Original file line numberDiff line numberDiff line change
@@ -584,10 +584,17 @@ to filter them."
584584
SEL is the key which should be used for selection. EXIT is the key which
585585
is used for exiting the minibuffer during completing read.")
586586

587+
(defvar citar--multiple-last-input nil
588+
"Variable used to track the input so that it can be restored subsequently.")
589+
587590
(defun citar--multiple-exit ()
588591
"Exit with the currently selected candidates."
589592
(interactive)
590-
(setq unread-command-events (listify-key-sequence (kbd (car citar--multiple-setup)))))
593+
(funcall-interactively (key-binding (kbd (car citar--multiple-setup)))))
594+
595+
(defun citar--multiple-record-input ()
596+
"Record the current minibuffer input."
597+
(setq citar--multiple-last-input (minibuffer-contents-no-properties)))
591598

592599
(defun citar--setup-multiple-keymap ()
593600
"Make a keymap suitable for `citar--select-multiple'."
@@ -596,29 +603,34 @@ is used for exiting the minibuffer during completing read.")
596603
(kbdexit (kbd (cdr citar--multiple-setup))))
597604
(define-key keymap kbdselect (lookup-key keymap kbdexit))
598605
(define-key keymap kbdexit #'citar--multiple-exit)
599-
(use-local-map keymap)))
606+
(use-local-map keymap))
607+
(add-hook 'post-command-hook #'citar--multiple-record-input nil t))
600608

601609
(defun citar--select-multiple (prompt candidates &optional filter history def)
602610
"Select multiple CANDIDATES with PROMPT.
603611
HISTORY is the `completing-read' history argument."
604612
;; Because completing-read-multiple just does not work for long candidate
605613
;; strings, and IMO is a poor UI.
606-
(let* ((selected-hash (make-hash-table :test 'equal)))
607-
(while (let ((initial-history (symbol-value history))
608-
(item (minibuffer-with-setup-hook #'citar--setup-multiple-keymap
609-
(completing-read
610-
(format "%s (%s/%s): " prompt
611-
(hash-table-count selected-hash)
612-
(hash-table-count candidates))
613-
(citar--multiple-completion-table selected-hash candidates filter)
614-
nil t nil history `("" . ,def)))))
615-
(unless (string-empty-p item)
614+
(let* ((selected-hash (make-hash-table :test 'equal))
615+
(command this-command))
616+
(push (setq citar--multiple-last-input "") def)
617+
(while (let* ((initial-history (symbol-value history))
618+
(item (minibuffer-with-setup-hook #'citar--setup-multiple-keymap
619+
(completing-read
620+
(format "%s (%s/%s): " prompt
621+
(hash-table-count selected-hash)
622+
(hash-table-count candidates))
623+
(citar--multiple-completion-table selected-hash candidates filter)
624+
nil t nil history def))))
625+
(push citar--multiple-last-input def)
626+
(unless (string-blank-p citar--multiple-last-input)
616627
(if (not (gethash item selected-hash))
617628
(puthash item t selected-hash)
618629
(remhash item selected-hash)
619630
(set history initial-history)))
620-
(not (or (eq last-command #'citar--multiple-exit)
621-
(string-empty-p item)))))
631+
(not (or (eq this-command #'citar--multiple-exit)
632+
(string-blank-p citar--multiple-last-input))))
633+
(setq this-command command))
622634
(hash-table-keys selected-hash)))
623635

624636
(cl-defun citar--get-resource-candidates (citekeys &key files links notes create-notes)

0 commit comments

Comments
 (0)