In find-file, when typing RET on a directory, it's opened in dired. I personally never use dired, and I expect it to work as TAB in this situation.
I didn't find a way to do this in a single selectrum completing session. Here's what I'm using now:
(defun my-find-file (&optional default-dir)
"An alternative for `find-file'.
This completes the directory when pressing `RET', rather than
open it in dired.
DEFAULT-DIR is used to specify the starting directory."
(interactive)
(let* ((file (read-file-name "Find file: " default-dir nil
(confirm-nonexistent-file-or-buffer))))
(if (directory-name-p file)
(my-find-file file)
(pop-to-buffer-same-window (find-file-noselect file)))))
But there are 2 problems:
RET on a directory.Do you have any idea for a better implementation?
See #216, this seems to be a common demand, so it's worth thinking about providing a better interface for these things and then mentioning it in the README/wiki
The solution you gave in #216 works, but breaks read-directory-name. I'll try to make this work only for find-file.
Thanks! Here is an alternate version skipping this behaviour in this case:
(add-hook 'minibuffer-setup-hook
(defun selectrum-setup+ ()
(when (and selectrum-active-p
minibuffer-completing-file-name)
(let ((map (copy-keymap (current-local-map))))
(define-key map (kbd "RET") 'selectrum-select-current-candidate+)
(use-local-map map)))))
(defun selectrum-select-current-candidate+ (&optional arg)
(interactive "P")
(let* ((index (selectrum--index-for-arg arg))
(candidate (selectrum--get-candidate index))
(path (selectrum--get-full candidate)))
(call-interactively
(if (and (file-directory-p path)
(not (eq minibuffer-completion-predicate
'file-directory-p)))
'selectrum-insert-current-candidate
'selectrum-select-current-candidate))))
How about this:
(defun selectrum-select-current-candidate+ (&optional arg)
(interactive "P")
(let* ((index (selectrum--index-for-arg arg))
(candidate (selectrum--get-candidate index))
(path (selectrum--get-full candidate)))
(call-interactively
(if (file-directory-p path)
'selectrum-insert-current-candidate
'selectrum-select-current-candidate))))
(defmacro selectrum-complete-dir-by-ret (&rest body)
`(minibuffer-with-setup-hook
(defun selectrum-setup+ ()
(when (and selectrum-active-p
minibuffer-completing-file-name)
(let ((map (copy-keymap (current-local-map))))
(define-key map (kbd "RET") 'selectrum-select-current-candidate+)
(use-local-map map))))
,@body))
(defun toki-find-file ()
"An alternative for `find-file'.
This completes the directory when pressing `RET', rather than
open it in dired."
(interactive)
(selectrum-complete-dir-by-ret
(call-interactively #'find-file)))
The user could wrap (or advise) commands by selectrum-complete-dir-by-ret on their own needs.
providing a better interface for these things and then mentioning it in the README/wiki
Yeah, I think this would be a great improvement! Ideally, the user doesn't need to do things with minibuffer-with-setup-hook; I don't think very many people are familiar with it other than in the Selectrum issue tracker ;)
The user could wrap (or advise) commands by selectrum-complete-dir-by-ret on their own needs.
This use case may be common enough to make it worth adding a selectrum-minibuffer-file-map similar to minibuffer-local-filename-completion-map. This would make it easy enough for anyone to customize bindings for file completions. We could include some common commands like the one discussed here which we bind to unused keys and users can rebind those to other keys in case they want.
The macro is also a good idea, maybe we could generalize it to something like selectrum-with-keymap so one can easily instantiate a custom keymap for a single session.
To add to that, I think it would be nice when the macro would be a generic wrapper around completing-read which also works when not using selectrum.
This use case may be common enough to make it worth adding a
selectrum-minibuffer-file-mapsimilar tominibuffer-local-filename-completion-map.
A good thing about the above code is the keymap is generated on the fly, so any customization on selectrum-minibuffer-map is keeped. If we offer multiple maps, the user is likely to have to customize all of them.
Or maybe we can offer selectrum-with-keymap, which merges the keymap provided with selectrum-minibuffer-map, so only the differences are needed to be defined in selectrum-minibuffer-file-map.
Yeah, I thought we can set selectrum-minibuffer-map as the parent of selectrum-minibuffer-file-map and the macro would be used to force some bindings for a specific session.
I think it would be better to offer alternative commands similar to icomplete-fido-ret, icomplete-fido-delete-char and icomplete-fido-backward-updir. They check the current context, if it's a file name completion, do their special thing, and otherwise do the "normal" thing.
The users will be able to put them on the keymap manually, or maybe enable some special selectrum-ido-emulation-mode.
Thanks, that would be convenient for users coming from ido/fido. We try to avoid including such workflow customizations usually, I think I would prefer when this selectrum-ido-emulation mode would live in its own package.
I'll wait for someone to create it.
I have included a reference to that in the issue name so users which have interest in such a package can find it easily and see that there is demand for it.
@dgutov
I don't use ido/fido myself, I hope this helps as long there doesn't exists a potentially more featured ido-emulation-mode.
Thanks, these seem to work.
And selectrum--get-meta is a private function. So it doesn't seem like a third party package should call it.
Thanks, if a third party package will get created it can also use the following instead:
(completion-metadata-get
(completion-metadata (minibuffer-contents)
minibuffer-completion-table
minibuffer-completion-predicate)
'category)
Closing this since no action will be taken and the answer how to get this and other ido behavior was added to the wiki
Most helpful comment
Thanks, if a third party package will get created it can also use the following instead: