27

When I run #'helm-find-files, and move point to a directory, pressing <ret> results in opening that directory in dired mode. One has to press C-j to enter that directory in Helm.

I'd like to have <RET> act as C-j does here, but not necessarily everywhere else. I checked, and C-j is bound to #'helm-maybe-exit-minibuffer, whereas <RET> is bound to #'helm-execute-persistent-action. Binding <RET> to #'helm-maybe-exit-minibuffer works for this case, but breaks other cases: for example, the helm autocomplete in describe-function.

So, when using Helm to find a file, how can I make pressing <RET> open that directory in Helm?

programking
  • 7,064
  • 9
  • 41
  • 62
zck
  • 8,984
  • 2
  • 31
  • 65
  • What's wrong with binding `` to execute persistent action, and whenever you want to enter a directory, just press TAB. I think it's more suitable than ``, since `` is expected to execute something in most applications, not just Emacs anyway. – Tu Do Nov 22 '14 at 15:53
  • 1
    @TuDo I'm used to `ido-mode`, where pressing `` selects the folder to find files inside it. I think this is the most consistent behavior when trying to find a file -- what you want to do when you've found the file is open it; what you want to do when you've found a folder is go inside it so you can find the file. – zck Nov 22 '14 at 16:15
  • What you said belongs to Ido only. Many application use `` to enter a director and `` for completion to navigate file system. For example, all the shells (bash, zsh, fish...), stock `find-file` (no Ido) does it this way. I think Ido is inconsistent: it uses two key bindings to complete different objects: `` for directory, `` for file. You can only "enter" a directory by falling back to stock `find-file` or press `C-d`, yet another key binding. Isn't it simpler to have `` for comoplete and `` for everything else? – Tu Do Nov 22 '14 at 16:51
  • 2
    Helm has the opposite behavior -- when on a file, `` both autocompletes *and* selects. You don't have to hit `` to finish completing the filename. But we're arguing over preferences -- I just want "enter" to mean "select the thing at point". And for me, that doesn't mean "open dired". If I was in a shell, I expect different behavior. – zck Nov 22 '14 at 16:59
  • 4
    I'm with zck here, the muscle memory is there after years of using ido (and the most expected action there is drilling down) and this was the main pain point while getting used to helm. I have since switched to using the right arrow key to drill down (took about a week to get used to) – ustun Dec 04 '14 at 16:46
  • See https://groups.google.com/forum/m/#!topic/emacs-helm/cVK3rFBmvq0 – ustun Dec 04 '14 at 16:48
  • 1
    I'm also with zck. Navigating in ido is a lot more intuitive than the helm standard behaviour. Especially the backspace key. It deletes a char from the search or jumps back on folder if nothing is inserted. Is there a way to rewire the keys to get this functionallity? – f00860 Feb 01 '15 at 21:34
  • [This blog post](http://jixiuf.github.io/blog/00011-emacs-make-helm-like-ido.html/) may be helpful. It will rebind `C-j RET` and `C-d`. – jixiuf Mar 13 '17 at 09:11
  • 1
    As of [Helm 2.6.1](https://github.com/emacs-helm/helm/releases/tag/v2.6.1) the behavior you want is the default. – amitp Sep 06 '17 at 20:59

3 Answers3

20

I've also used ido-mode a lot and trained my muscle memory :) I think the ido style is more intuitive than the helm approach. I search for stuff (typing in some characters) and commit to the find (hit RET), just like the search/address bar of my web browser. If the selection is a directory, I enter this directory and start searching again in this directory. This seems natural for me, so I've written a small advice around helm-execute-persistent-action to force this mechanic.

(require 'helm)
(defun fu/helm-find-files-navigate-forward (orig-fun &rest args)
  (if (and (equal "Find Files" (assoc-default 'name (helm-get-current-source)))
           (equal args nil)
           (stringp (helm-get-selection))
           (not (file-directory-p (helm-get-selection))))
      (helm-maybe-exit-minibuffer)
    (apply orig-fun args)))
(advice-add 'helm-execute-persistent-action :around #'fu/helm-find-files-navigate-forward)
(define-key helm-find-files-map (kbd "<return>") 'helm-execute-persistent-action)

I've also optimize the backspace key slightly. If I type something and want to do a correction, I hit backspace. This will delete one character. If I am on the beginning of the directory and hit backspace again, I navigate one level up. This speeds up the navigation dramatically!

(defun fu/helm-find-files-navigate-back (orig-fun &rest args)
  (if (= (length helm-pattern) (length (helm-find-files-initial-input)))
      (helm-find-files-up-one-level 1)
    (apply orig-fun args)))
(advice-add 'helm-ff-delete-char-backward :around #'fu/helm-find-files-navigate-back)

To remove the useless . and .. at the very beginning, you can add it to the helm-boring-file-regexp-list configuration variable.

f00860
  • 315
  • 3
  • 7
  • 2
    The Helm approach is consistent with stock `find-file` though. And the `.` and `..` is not really useless when you suddent want to open Dired in current or parent directory. And I find that `C-l` is faster than pressing `backspace`. – Tu Do Feb 24 '15 at 14:17
  • I'm circling back to customize this behavior a little bit more -- is there a reason you use advice here, and not bind fu/helm-find-files-navigate-forward directly to `(kbd "")`? It seems a little cleaner to just call helm-execute-persistent-action directly inside the new function. – zck Apr 16 '15 at 06:40
  • 1
    Unfortunately, this doesn't work for me. First of all, I get `Symbol's value as variable is void: helm-find-files-map`. When I put `(helm-mode 1)` after `(require 'helm)`, I get no such error, but it doesn't work either. Any Idea what I might be missing? Here's my complete init.el: http://pastebin.com/drFZsDxW Emacs version is 24.4.1 (i686-pc-mingw32) – Geier Apr 20 '15 at 17:00
  • Didn't work for me. Even with the `define-key`, if I try `C-h k RET` on teh find-file minibuffer it still shows `helm-confirm-and-exit-minibuffer` as bound. – Rafael Ibraim Apr 23 '15 at 13:53
  • @RafaelIbraim try use (kbd "RET") – netawater Apr 29 '15 at 06:23
  • @T. Verron add "\\.$" to helm-boring-file-regexp-list is not OK for me, could you help? – netawater Apr 29 '15 at 07:45
  • @netawater In recent helm versions you can not use this anymore: [see here for more info](https://github.com/emacs-helm/helm/issues/924). There is a workaround for this that some people [use](https://github.com/search?q=defun+no-dots&type=Code&utf8=%E2%9C%93). – clemera Feb 14 '16 at 16:06
  • I like your solution however it breaks grep for me. When using projectile grep and wanted to quickly visit the file, I usually hit the right key for a preview. With your code now I would visit the file and discard the grep results window. Could you fix it? – SFbay007 Jan 22 '17 at 02:36
  • I also added the binding to `helm-read-file-map` to catch `insert-file`. – Michaël Apr 20 '18 at 11:38
-1

I can't comment on Fu86's answer due to rep but I'm piggy backing off it (sorry if this isn't normal protocol). I got a void function using his answer due to "helm-find-files-map". It worked for me to use the "helm-map" key map instead. No conflicts so far and it is the behavior I was looking for.

... (define-key helm-map (kbd "<return>") 'helm-execute-persistent-action) ...

Iceback
  • 1
  • 1
-1

I could not get @Fu86's answer to work but the following worked for me:

(defun jkf/helm-find-files-navigate-forward (orig-fun &rest args)
  (if (file-directory-p (helm-get-selection)) 
      (helm-execute-persistent-action)
    (apply orig-fun args)))
(advice-add 'helm-confirm-and-exit-minibuffer 
   :around #'jkf/helm-find-files-navigate-forward)

see also: https://stackoverflow.com/questions/27652371/how-can-i-change-emacs-helm-find-file-default-action-on-directory-to-be-go-insid

Edit

My solution works in helm-20141112.946 but in helm-20160211.934 it does not work and @Fu86 answer is the solution