Skip to content

Commit

Permalink
Improve completing-read-multiple
Browse files Browse the repository at this point in the history
  • Loading branch information
clemera committed Apr 24, 2020
1 parent 96e45e9 commit b000e57
Showing 1 changed file with 50 additions and 20 deletions.
70 changes: 50 additions & 20 deletions selectrum.el
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
(require 'regexp-opt)
(require 'seq)
(require 'subr-x)
(require 'crm)

;;;; Faces

Expand Down Expand Up @@ -869,11 +870,15 @@ Otherwise just return CANDIDATE."
(remove-text-properties
0 (length candidate)
'(face selectrum-current-candidate) candidate)
(apply
#'run-hook-with-args
'selectrum-candidate-selected-hook
candidate selectrum--read-args)
(setq selectrum--result (selectrum--get-full candidate))
(setq selectrum--result
(if (and crm-completion-table
(string-match crm-separator selectrum--previous-input-string))
selectrum--previous-input-string
(apply
#'run-hook-with-args
'selectrum-candidate-selected-hook
candidate selectrum--read-args)
(selectrum--get-full candidate)))
(when (string-empty-p selectrum--result)
(setq selectrum--result (or selectrum--default-candidate "")))
(let ((inhibit-read-only t))
Expand Down Expand Up @@ -942,7 +947,15 @@ ignores the currently selected candidate, if one exists."
(let* ((candidate (nth selectrum--current-candidate-index
selectrum--refined-candidates))
(full (selectrum--get-full candidate)))
(insert full)
(insert (if (not crm-completion-table)
full
(let ((string ""))
(dolist (str (butlast
(split-string
selectrum--previous-input-string
crm-separator)))
(setq string (concat string str ",")))
(concat string full))))
(add-to-history minibuffer-history-variable full)
(apply
#'run-hook-with-args
Expand Down Expand Up @@ -981,10 +994,19 @@ ARG has same meaning as in `previous-history-element'."
(when (eq history t)
(user-error "No history is recorded for this command"))
(let ((result (selectrum-read "History: " history)))
(if (and selectrum--match-required-p
(not (member result selectrum--refined-candidates)))
(user-error "That history element is not one of the candidates")
(selectrum--exit-with result)))))
(cond ((and selectrum--match-required-p
crm-completion-table
(not (cl-every (lambda (i)
(member i selectrum--refined-candidates))
(split-string result crm-separator t))))
(user-error
"History element contains elements not present in candidates"))
((and selectrum--match-required-p
(not crm-completion-table)
(not (member result selectrum--refined-candidates)))
(user-error "History element is not one of the candidates"))
(t
(selectrum--exit-with result))))))

;;;; Main entry points

Expand Down Expand Up @@ -1125,20 +1147,28 @@ HIST, DEF, and INHERIT-INPUT-METHOD, see `completing-read'."

;;;###autoload
(defun selectrum-completing-read-multiple
(prompt table &optional
predicate require-match initial-input
hist def inherit-input-method)
(prompt table &optional predicate require-match initial-input
hist def _inherit-input-method)
"Read one or more choices using Selectrum.
Replaces `completing-read-multiple'. For PROMPT, TABLE,
PREDICATE, REQUIRE-MATCH, INITIAL-INPUT, HIST, DEF, and
INHERIT-INPUT-METHOD, see `completing-read-multiple'."
(ignore initial-input inherit-input-method)
(selectrum-read
prompt (selectrum--normalize-collection table predicate)
:default-candidate (or (car-safe def) def)
:require-match require-match
:history hist
:multiple t))
(let* ((crm-completion-table table)
(coll (all-completions "" #'crm--collection-fn predicate))
(candidates
(lambda (input)
(let ((ninput (or (car (last (split-string input crm-separator)))
"")))
`((input . ,ninput)
(candidates . ,(copy-sequence coll))))))
(res (selectrum-read
(replace-regexp-in-string ": \\'" "[one or more]: " prompt)
candidates
:require-match require-match
:initial-input initial-input
:history hist
:default-candidate def)))
(split-string res crm-separator t)))

;;;###autoload
(defun selectrum-completion-in-region
Expand Down

0 comments on commit b000e57

Please sign in to comment.