Skip to content
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

How to disable prescient in counsel-find-file? #64

Open
arthurcgusmao opened this issue Jun 27, 2020 · 9 comments
Open

How to disable prescient in counsel-find-file? #64

arthurcgusmao opened this issue Jun 27, 2020 · 9 comments
Labels

Comments

@arthurcgusmao
Copy link

arthurcgusmao commented Jun 27, 2020

Hi, for some reason adding find-file or counsel-find-file to a negated list in ivy-prescient-sort-commands has no effect, and the function continues to have its candidates sorted. I can tell it is prescient that is doing this because disabling ivy-prescient-mode automatically disables sorting of find-file. Any ideas on how I can get this to work?
I have configured the variable in the following manner:

(use-package prescient
  :config
  (setq prescient-save-file (concat acg/history-dir "prescient-save.el"))
  (prescient-persist-mode 1))

(use-package ivy-prescient
  :after (prescient ivy)
  :config
  (setq ivy-prescient-sort-commands '(:not swiper swiper-isearch ivy-switch-buffer counsel-find-file counsel-recentf))
  (ivy-prescient-mode 1))

(use-package company-prescient
  :after (prescient company)
  :config (company-prescient-mode 1))
@arthurcgusmao arthurcgusmao changed the title How to disable prescient in find-file? How to disable prescient in counsel-find-file? Jun 27, 2020
@raxod502
Copy link
Member

You could check to make sure the command you expect is being run, with C-h k C-x C-f. Aside from that, however, your configuration looks exactly correct and I would suspect a bug in Ivy.

@arthurcgusmao
Copy link
Author

Thank you @raxod502. The function being run is indeed find-file (or counsel-find-file); both calls result in the same Ivy interface, and adding any or both to ivy-prescient-sort-commands has no effect. I also tried adding the many subfunctions that Counsel leverages to find file (like counsel--find-file-1) with no success.

It must be something with the way counsel-find-file works, but I couldn't figure out exactly what. What is strange is that negating counsel-recentf in ivy-prescient-sort-commands works, but not counsel-find-file.

@raxod502
Copy link
Member

Yeah, I'm afraid I'm not sure what's happening there. It does sure seem like counsel-find-file is getting passed as the CALLER argument to ivy-read. You have probably found a bug in something. See also #65.

@mohkale
Copy link

mohkale commented Dec 29, 2020

Yep. This is almost certainly an edge case. Here

https://github.com/abo-abo/swiper/blob/d2891aab7b816aebf21ebd01ce33933a6ac6244f/ivy.el#L2271-L2317

there's an explicit call to ivy--sorted-files (probably because ivy sorts directories first by default) and it uses (ivy--sort-function #'read-file-name-internal) which evaluates to ivy-prescient--enable-sort-commands. I don't think there's a way to fix this on the ivy side (and I kinda understand why selectrum is a thing now), but we can probs setup a workaround in prescient.

@mohkale
Copy link

mohkale commented Dec 29, 2020

I've managed to get file-name completion back to normal using this:

(add-hook 'ivy-prescient-mode-hook
          (defun ivy-prescient-disable-sort-find-file+ ()
            (when (and (eq (car ivy-prescient-sort-commands) :not)
                       (memq 'counsel-find-file
                             (cdr ivy-prescient-sort-commands)))
              (ivy--alist-set 'ivy-sort-functions-alist
                              #'read-file-name-internal #'ivy-sort-file-function-default))))

but it doesn't disable sorting based on ivy-prescient-sort-commands so it's not really a fix for this issue. It's good enough for my use cases so I'm leaving it here :-).

arthurcgusmao added a commit to arthurcgusmao/acg-emacs that referenced this issue Dec 31, 2020
@unhammer
Copy link

unhammer commented Jan 8, 2021

Is there something similar to disable it for selectrum-prescient.el for certain commands?

@mohkale
Copy link

mohkale commented Jan 13, 2021

@unhammer

There's selectrum-should-sort-p which you can set to nil to disable sorting. However for functions like find-file the sorting already appears to be garbled which makes it kind of useless. If you want ivy like sorting with find-file you can try this:

(defvar selectrum-find-file-keep-prescient-sorting+ nil
  "When true, `selectrum-find-file' keeps sorting based on `prescient-sort' but
still tries to group directories before files..")

(defun selectrum-prescient-preprocess+ (func cands)
  (cond
   ;; Finding file-names should sort directories first.
   ((eq minibuffer-completion-table 'read-file-name-internal)
    (if selectrum-find-file-keep-prescient-sorting+
        ;; WARN: Adapted from ivy, doesn't maintain prescient based sorting
        (cl-loop for cand in (funcall func cands)
                 with dirs  = nil
                 with files = nil
                 do (if (eq (aref cand (- (length cand) 1)) ?/)
                        (setq dirs (cons cand dirs))
                      (setq files (cons cand files)))
                 finally return `(,@(nreverse dirs) ,@(nreverse files)))
      (sort cands
            (lambda (x y)
              (let ((x-dir (eq (aref x (- (length x) 1)) ?/))
                    (y-dir (eq (aref y (- (length y) 1)) ?/)))
                (cond
                 ((and x-dir y-dir)
                  (string< (directory-file-name x) (directory-file-name y)))
                 (x-dir t)
                 (y-dir nil)
                 (t (string< x y))))))))
   (t (funcall func cands))))

(advice-add 'selectrum-prescient--preprocess :around #'selectrum-prescient-preprocess+)

@unhammer
Copy link

Just found selectrum-should-sort-p, seems to work for my uses :-)

@raxod502
Copy link
Member

Is there something similar to disable it for selectrum-prescient.el for certain commands?

See also discussion on the Selectrum side about adding a way to configure completion behavior on a per-command basis: radian-software/selectrum#265

Fair warning, it is nontrivial, assuming that we actually want to do it in a reliable and not-surprising-to-the-user way, rather than as a hack.

@raxod502 raxod502 added the ivy label Feb 22, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Development

No branches or pull requests

4 participants