minad / vertico

:dizzy: vertico.el - VERTical Interactive COmpletion
GNU General Public License v3.0
1.44k stars 58 forks source link

Emulation of the "default selection" in ido-find-file #242

Closed mlemerre closed 2 years ago

mlemerre commented 2 years ago

Hi,

I really like vertico and I think it could be the first "new" completion UI that could make me switch from ido. There is however one feature that I miss in ido, which is that whe ido-find-file enters a new directory, it preselects as the next selection candidate the last opened file or directory. This is a very useful preset and allows to navigate long nested directories using just RET, instead of having to retype the directory name. vertico-directory is nice but does not explain how we can recover this behavior, so I wonder if it would be easy to emulate using vertico? If so, it would be useful to add this to vertico-directory.

Thank your for vertico!

mlemerre commented 2 years ago

I wondered if vertico-sort-function would help, but it seems that the options that it provides, such as vertico-sort-history-length-alpha, are not functions that are provided in the vertico package

minad commented 2 years ago

Vertico should already do what you are asking for by default. The sort function vertico-sort-history-length-alpha is provided by Vertico and used by default. It will sort recent elements to the top. The topmost element will be preselected. The entries are taken from the file-name-history variable. See also savehist-mode to persist the minibuffer history variables.

minad commented 2 years ago

However when navigating long directory hierarchies the intermediate paths are not actually opened, only inserted during completion. Therefore they are not recorded in the history. However it should be easy to add them too by advising vertico-insert. Then one should call add-to-history there. Maybe I should add this behavior to vertico-directory-enter by default. The only downside is that this will more quickly flood the history variable which is usually fairly short by default.

(As an alternative for navigating deep hierarchies you may also consider a directory jumper like consult-dir, which gives you a list of recent directories and let's you jump in a single step. After that you select the desired file.)

mlemerre commented 2 years ago

I really think the function is not present in today's master branch, as I grepped it in a fresh checkout and the result was:


./README.org:    (setq files (vertico-sort-history-length-alpha files))
./vertico.el:(defcustom vertico-sort-function #'vertico-sort-history-length-alpha
./vertico.el:          (const :tag "By history, length and alpha" ,#'vertico-sort-history-length-alpha)
./vertico.el:          (const :tag "By history and alpha" ,#'vertico-sort-history-alpha)```

Or is there some trickery I didn't get?
minad commented 2 years ago

Or is there some trickery I didn't get?

Elisp has macros. Take a closer look. But I wouldn't call macros trickery :)

mlemerre commented 2 years ago

Thanks, I understand it now. If you fear that remembering about intermediate history steps would flood file-name-history, maybe it would be possible to use another history variable for these intermediate opened values?

I tried to look at how ido does it; it seems to me that it uses file-name-history to just find if in the current history, we could reuse a common prefix compared to the current directory. So it does not need another variable.

minad commented 2 years ago

I tried to look at how ido does it; it seems to me that it uses file-name-history to just find if in the current history, we could reuse a common prefix compared to the current directory. So it does not need another variable.

Yes, we could do that. I've considered to implement this before. It requires special casing file name handling, which I've avoided so far. But this only matters for files and it is a simple change, so I will take another look at this.

The underlying problem is that the completion boundaries are reported insufficiently - only the start position is available, not the end position (we have to look for slash for files). This is a problem of the completion-all-completions API which hopefully gets sorted out at some point.

minad commented 2 years ago

I improved the history handling as we discussed. However Vertico does not preselect the first file by default. Instead it preselects the prompt if the prompt is a valid completion. See

https://github.com/minad/vertico/blob/0bc58baba1904cefefccc1cd5510d2e942c181f1/vertico.el#L437-L450

If you want to override this behavior you could advise vertico--update-candidates and always preselect the first candidate. An alternative would be to add an option to configure the preselection behavior, but I am not convinced that preselecting the first candidate always is a good idea.