Preserving sort order of candidates #1294
Comments
Can you give a concrete example? It's not fully clear to me. |
For example: (defconst hledger-jcompletions '("balancesheet"
"daily"
"incomestatement"
"overall"
"stats"
"activity"
"print"
"accounts"
"balance"
"register")
"Commands that can be passed to `hledger-jdo` function defined below.")
(defun hledger-run-command (command)
"Run an hledger COMMAND."
(interactive (list (completing-read "jdo> "
hledger-jcompletions)))
.. With (push '(hledger-run-command) ivy-sort-matches-functions-alist)
(push '(hledger-run-command) ivy-sort-functions-alist) The order of completions isn't kept the same as we have in the list provided. It's modified. @abo-abo |
Can't reproduce with (defconst hledger-jcompletions '("balancesheet"
"daily"
"incomestatement"
"overall"
"stats"
"activity"
"print"
"accounts"
"balance"
"register")
"Commands that can be passed to `hledger-jdo` function defined below.")
(completing-read "jdo> " hledger-jcompletions) The collection is unsorted by default, keeping the same order as the list. |
Here is what I have in my configuration: (use-package ivy
:demand t
:ensure t
:diminish ivy-mode
:preface
(defun ivy--sort-by-len (name candidates)
"Sort CANDIDATES based on similarity of their length with NAME."
(let ((name-len (length name))
(candidates-count (length candidates)))
(if (< 500 candidates-count)
candidates
(seq-sort-by #'length
(lambda (a b)
(< (abs (- name-len a))
(abs (- name-len b))))
candidates))))
:bind (("C-x b" . ivy-switch-buffer)
("C-x B" . ivy-switch-buffer-other-window)
("M-H" . ivy-resume))
:config
(bind-keys :map ivy-minibuffer-map
("C-r" . ivy-previous-line-or-history)
("M-r" . ivy-reverse-i-search))
(setq ivy-initial-inputs-alist nil
ivy-format-function #'ivy-format-function-arrow
ivy-re-builders-alist '((t . ivy--regex-ignore-order))
ivy-use-virtual-buffers t)
;; Change the default sort function to rank matches according to similarity
;; with input text.
(setf (alist-get 't ivy-sort-matches-functions-alist)
#'ivy--sort-by-len)
;; No sorting for `counsel-yank-pop' as candidates are already sorted.
(push '(counsel-yank-pop) ivy-sort-matches-functions-alist)
(push '(hledger-run-command) ivy-sort-matches-functions-alist)
(push '(hledger-run-command) ivy-sort-functions-alist)
(ivy-mode +1)
(use-package ivy-hydra
:bind (:map ivy-minibuffer-map
("M-o" . ivy-dispatching-done-hydra))
:ensure t)
(use-package ivy-rich
:ensure t
:config
(ivy-set-display-transformer 'ivy-switch-buffer
'ivy-rich-switch-buffer-transformer)
(setq ivy-virtual-abbreviate 'full
ivy-rich-switch-buffer-align-virtual-buffer t
ivy-rich-path-style 'abbrev))
(use-package swiper
:ensure t
:bind (("C-. C-s" . swiper))
:commands swiper-from-isearch
:init
(bind-key "C-." #'swiper-from-isearch isearch-mode-map)
:config
(bind-keys :map swiper-map
("M-%" . swiper-query-replace)
("M-h" . swiper-avy)))
(use-package counsel
:ensure t
:bind (("M-x" . counsel-M-x)
("C-x 8 RET" . counsel-unicode-char)
("C-c r" . counsel-recentf)
("C-. C-r" . counsel-ag)
("M-y" . counsel-yank-pop)
:map minibuffer-local-map
("M-r" . counsel-minibuffer-history)
:map ctl-quote-map
("c p" . counsel-linux-app))
:config
(setq counsel-yank-pop-separator
(format "\n%s\n" (make-string 60 ?┅))))
(use-package counsel-osx-app
:doc
"Keep this after `counsel' so that the key binding is
overridden only on OSX."
:ensure t
:if (eq system-type 'darwin)
:bind (:map ctl-quote-map
("c p" . counsel-osx-app)))) Could any of the above be causing it? Thanks for the help! :) |
For some reason, |
I have found the problem. It's happening because |
(defun ivy--sort (name candidates)
"Re-sort candidates by NAME.
All CANDIDATES are assumed to match NAME."
(let ((key (or (ivy-state-caller ivy-last)
(when (functionp (ivy-state-collection ivy-last))
(ivy-state-collection ivy-last))
this-command)) ;;; <------------------------ Added
fun)
(cond ((and ivy--flx-featurep
(eq ivy--regex-function 'ivy--regex-fuzzy))
(ivy--flx-sort name candidates))
((setq fun (cdr (or (assoc key ivy-sort-matches-functions-alist)
(assoc t ivy-sort-matches-functions-alist))))
(funcall fun name candidates))
(t
candidates)))) Making this change achieves what I want. Is there a reason this wasn't made? @abo-abo |
Added |
@abo-abo You are amazing! Thanks :) |
I would like to preserve the order of candidates if I have set
ivy-sort-matching-fns
andivy-sort-funs-alist
(not the exact variable names) tonil
for the specific command. Currently, it doesn't happen. I switched fromhelm
toivy
and in helm that was the default and I think it should be. What are your thoughts? @abo-aboThe text was updated successfully, but these errors were encountered: