-
-
Notifications
You must be signed in to change notification settings - Fork 338
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
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: