Skip to content

Commit

Permalink
Add previous inputs to defaults in multi-selection
Browse files Browse the repository at this point in the history
Close #714

Co-authored-by: Rahguzar <[email protected]>
  • Loading branch information
aikrahguzar and Rahguzar authored Jan 1, 2023
1 parent a9fae9c commit 37f6b6b
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 14 deletions.
10 changes: 10 additions & 0 deletions README.org
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,8 @@ You then have two ways to access these strings from the completion prompt:
1. by using =M-n= from the prompt, which will cycle through the strings
2. by calling =citar-insert-preset= with a keybinding, and then selecting the string

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).

=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=.
You can save this history across sessions by adding =citar-history= to =savehist-additional-variables=.

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

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.

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,

#+BEGIN_SRC emacs-lisp
(advice-add 'goto-history-element :after (defun my-end-of-buffer (&rest _) (goto-char (point-max))))
#+END_SRC

** Files, file association and file-field parsing

If you have ~citar-library-paths~ set, the relevant open commands will look in those directories for file names of =CITEKEY.EXTENSION=.
Expand Down
40 changes: 26 additions & 14 deletions citar.el
Original file line number Diff line number Diff line change
Expand Up @@ -584,10 +584,17 @@ to filter them."
SEL is the key which should be used for selection. EXIT is the key which
is used for exiting the minibuffer during completing read.")

(defvar citar--multiple-last-input nil
"Variable used to track the input so that it can be restored subsequently.")

(defun citar--multiple-exit ()
"Exit with the currently selected candidates."
(interactive)
(setq unread-command-events (listify-key-sequence (kbd (car citar--multiple-setup)))))
(funcall-interactively (key-binding (kbd (car citar--multiple-setup)))))

(defun citar--multiple-record-input ()
"Record the current minibuffer input."
(setq citar--multiple-last-input (minibuffer-contents-no-properties)))

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

(defun citar--select-multiple (prompt candidates &optional filter history def)
"Select multiple CANDIDATES with PROMPT.
HISTORY is the `completing-read' history argument."
;; Because completing-read-multiple just does not work for long candidate
;; strings, and IMO is a poor UI.
(let* ((selected-hash (make-hash-table :test 'equal)))
(while (let ((initial-history (symbol-value history))
(item (minibuffer-with-setup-hook #'citar--setup-multiple-keymap
(completing-read
(format "%s (%s/%s): " prompt
(hash-table-count selected-hash)
(hash-table-count candidates))
(citar--multiple-completion-table selected-hash candidates filter)
nil t nil history `("" . ,def)))))
(unless (string-empty-p item)
(let* ((selected-hash (make-hash-table :test 'equal))
(command this-command))
(push (setq citar--multiple-last-input "") def)
(while (let* ((initial-history (symbol-value history))
(item (minibuffer-with-setup-hook #'citar--setup-multiple-keymap
(completing-read
(format "%s (%s/%s): " prompt
(hash-table-count selected-hash)
(hash-table-count candidates))
(citar--multiple-completion-table selected-hash candidates filter)
nil t nil history def))))
(push citar--multiple-last-input def)
(unless (string-blank-p citar--multiple-last-input)
(if (not (gethash item selected-hash))
(puthash item t selected-hash)
(remhash item selected-hash)
(set history initial-history)))
(not (or (eq last-command #'citar--multiple-exit)
(string-empty-p item)))))
(not (or (eq this-command #'citar--multiple-exit)
(string-blank-p citar--multiple-last-input))))
(setq this-command command))
(hash-table-keys selected-hash)))

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

0 comments on commit 37f6b6b

Please sign in to comment.