Using helm for file-selection commands

96 views
Skip to first unread message

Tassilo Horn

unread,
Mar 5, 2015, 7:52:33 AM3/5/15
to emacs...@googlegroups.com
Hi!

Is there a way to start helm for the current file selection?  For example I want to attach some file to an email message I'm writing with Gnus.  I get the standard file selection prompt but then I decide that helm's locate source would do the job better.  How can I activate that now?

Basically, the existing minibuffer binding `C-r' which invokes `helm-minibuffer-history' which uses a recursive minibuffer is exactly what I want just that I don't want to have the minibuffer history as the only source but I want to use any of my preferred file sources (locate, recentf, etc.).  The behavior of `helm-minibuffer-history' is that hitting RET on some history entry simply inserts that entry into the minibuffer with recursion level one less than the minibuffer which read the helm pattern.  In contrast, when I invoke `helm-for-files' from an existing minibuffer prompting for a file and select a file with RET, it'll be opened and the previous minibuffer is still prompting.  Hitting TAB also doesn't reveal some "Exit minibuffer and insert path to file" action.

So I think I want some kind of wrapper around `helm-for-files' which enables recursive minibuffers and where selecting a file with RET exists the current minibuffer and inserts the selected file's path at the previous minibuffer prompt just like `helm-minibuffer-history' does.

Is that feasible?

Bye,
Tassilo

Thierry Volpiatto

unread,
Mar 5, 2015, 9:01:18 AM3/5/15
to emacs...@googlegroups.com

Tassilo Horn <ts...@gnu.org> writes:

> Hi!
>
> Is there a way to start helm for the current file selection?

Not sure to understand here what you want.

> For example I want to attach some file to an email message I'm writing
> with Gnus.

1) M-x helm-find-files => navigate to your file and C-c C-a
Or
2) with helm-mode enabled, C-c C-a from your mail buffer.

> I get the standard file selection prompt

I assume you got this prompt from 2)

> but then I decide that helm's locate source would do the job better.
> How can I activate that now?

C-x C-f C-x-C-f => search you file with locate and then C-x C-f C-c C-a.

Probably you should use 1) directly in such cases.

I could add C-c C-a to files commands like locate if you want.

> Basically, the existing minibuffer binding `C-r' which invokes
> `helm-minibuffer-history' which uses a recursive minibuffer is exactly
> what I want just that I don't want to have the minibuffer history as
> the only source but I want to use any of my preferred file sources
> (locate, recentf, etc.). The behavior of `helm-minibuffer-history' is
> that hitting RET on some history entry simply inserts that entry into
> the minibuffer with recursion level one less than the minibuffer which
> read the helm pattern. In contrast, when I invoke `helm-for-files'
> from an existing minibuffer prompting for a file and select a file
> with RET, it'll be opened and the previous minibuffer is still
> prompting. Hitting TAB also doesn't reveal some "Exit minibuffer and
> insert path to file" action.
>
> So I think I want some kind of wrapper around `helm-for-files' which
> enables recursive minibuffers and where selecting a file with RET
> exists the current minibuffer and inserts the selected file's path at
> the previous minibuffer prompt just like `helm-minibuffer-history'
> does.
>
> Is that feasible?

Not sure to understand where you start helm-for-files and what
you want to do exactly.

BTW you should use now helm-multifiles which doesn't launch locate
unless you ask it with C-c p. (IOW helm-for-files is deprecated).

--
Thierry
Get my Gnupg key:
gpg --keyserver pgp.mit.edu --recv-keys 59F29997

Thierry Volpiatto

unread,
Mar 5, 2015, 11:23:48 AM3/5/15
to Tassilo Horn, emacs...@googlegroups.com

Tassilo Horn <tsd...@gmail.com> writes:

> Thierry Volpiatto <thierry....@gmail.com> writes:
>
> Hi Thierry,
>
>>> For example I want to attach some file to an email message I'm
>>> writing with Gnus.
>>
>> 1) M-x helm-find-files => navigate to your file and C-c C-a
>
> This gives
>
> Debugger entered--Lisp error: (void-function gnus-dired-attach)
>
> (require 'gnus-dired) fixes that. IMO `helm-ff-run-gnus-attach-files'
> should do that instead of requiring the user to have that done
> beforehand.

Right, thanks I will fix this (I have '(require 'gnus-dired)' since ages
in my init file so I never notice this)

> Anyway, that works now. :-)
>
>> 2) with helm-mode enabled, C-c C-a from your mail buffer.
>
> I tried it and it does work but most of the time I prefer the less
> obtrusive standard buffer/file/command promts.

Ok, me too.

>>> I get the standard file selection prompt
>>
>> I assume you got this prompt from 2)
>
> No, helm-mode is not activated.
>
>>> but then I decide that helm's locate source would do the job better.
>>> How can I activate that now?
>>
>> C-x C-f C-x-C-f => search you file with locate and then C-x C-f C-c C-a.
>
> Ah, so with repeated C-x C-f and helm-mode activated I can cycle through
> the helm backends.
>
>> Probably you should use 1) directly in such cases.
>
> Yes, of course. But let's assume there is some command that wants to
> read a file name from the minibuffer which you didn't already cover with
> an action in helm. :-)

C-x C-f => navigate => C-c i
This is also completing the filename already entered in minibuffer or
anywhere else.

>> Not sure to understand where you start helm-for-files and what you
>> want to do exactly.
>
> What I'm looking for is a way to switch to the helm version of selecting
> a file/buffer/whatever when there's already a "normal" prompt for
> reading that in.

So yes, use C-x C-f + C-c i.

> (1) That can either mean an actual switch, e.g., like in ido where `C-x
> C-f'/`C-x b' while an active ido prompt falls back to the standard
> prompts and completion.
>
> (2) It may also mean having a helm action which quits helm and inserts
> the currently selected item wherever I invoked helm from.
>
> I think (1) is pretty hairy to implement but (2) should be easy. I
> think I just need to bind some key to a command which does (2). I've
> tried
>
> --8<---------------cut here---------------start------------->8---
> (defun th/helm-insert-selection ()
> (interactive)
> (when-let ((item (helm-get-selection)))
> (helm-quit-and-execute-action (lambda (&rest _ignore)
> (insert item)))))
>
> (define-key helm-map (kbd "M-SPC") #'th/helm-insert-selection)
> --8<---------------cut here---------------end--------------->8---
>
> and basically that does the trick. I'd welcome if you could tell me if
> that's the intended way.

No, just use C-x C-f as said above.

You can also insert from any helm command with C-c C-i and it is
persistent, it works in minibuffer too (It is not a completion command,
it is just inserting at point).
It works also with marked candidates (i.e you can mark many candidates
and hit C-c C-i to insert them in current-buffer)

Thierry Volpiatto

unread,
Mar 5, 2015, 3:16:08 PM3/5/15
to Tassilo Horn, emacs...@googlegroups.com

Tassilo Horn <tsd...@gmail.com> writes:

> Thierry Volpiatto <thierry....@gmail.com> writes:
>
>>> Yes, of course. But let's assume there is some command that wants to
>>> read a file name from the minibuffer which you didn't already cover with
>>> an action in helm. :-)
>>
>> C-x C-f => navigate => C-c i
>> This is also completing the filename already entered in minibuffer or
>> anywhere else.
>
> C-c i is undefined.

It seems you use find-file helmized by helm-mode, please bind C-x C-f to
helm-find-files, you will have C-c i and many others features you don't
have in find-file (helmized).

> Do you mean C-c C-i (helm-copy-to-buffer)?

No.

C-c C-i is something different, use it preferably to insert more than
one candidate in a buffer.

Tassilo Horn

unread,
Mar 6, 2015, 1:10:52 AM3/6/15
to Thierry Volpiatto, emacs...@googlegroups.com
Thierry Volpiatto <thierry....@gmail.com> writes:

Hi Thierry,

>> For example I want to attach some file to an email message I'm
>> writing with Gnus.
>
> 1) M-x helm-find-files => navigate to your file and C-c C-a

This gives

Debugger entered--Lisp error: (void-function gnus-dired-attach)

(require 'gnus-dired) fixes that. IMO `helm-ff-run-gnus-attach-files'
should do that instead of requiring the user to have that done
beforehand.

Anyway, that works now. :-)

> 2) with helm-mode enabled, C-c C-a from your mail buffer.

I tried it and it does work but most of the time I prefer the less
obtrusive standard buffer/file/command promts.

>> I get the standard file selection prompt
>
> I assume you got this prompt from 2)

No, helm-mode is not activated.

>> but then I decide that helm's locate source would do the job better.
>> How can I activate that now?
>
> C-x C-f C-x-C-f => search you file with locate and then C-x C-f C-c C-a.

Ah, so with repeated C-x C-f and helm-mode activated I can cycle through
the helm backends.

> Probably you should use 1) directly in such cases.

Yes, of course. But let's assume there is some command that wants to
read a file name from the minibuffer which you didn't already cover with
an action in helm. :-)

> Not sure to understand where you start helm-for-files and what you
> want to do exactly.

What I'm looking for is a way to switch to the helm version of selecting
a file/buffer/whatever when there's already a "normal" prompt for
reading that in.

(1) That can either mean an actual switch, e.g., like in ido where `C-x
C-f'/`C-x b' while an active ido prompt falls back to the standard
prompts and completion.

(2) It may also mean having a helm action which quits helm and inserts
the currently selected item wherever I invoked helm from.

I think (1) is pretty hairy to implement but (2) should be easy. I
think I just need to bind some key to a command which does (2). I've
tried

--8<---------------cut here---------------start------------->8---
(defun th/helm-insert-selection ()
(interactive)
(when-let ((item (helm-get-selection)))
(helm-quit-and-execute-action (lambda (&rest _ignore)
(insert item)))))

(define-key helm-map (kbd "M-SPC") #'th/helm-insert-selection)
--8<---------------cut here---------------end--------------->8---

and basically that does the trick. I'd welcome if you could tell me if
that's the intended way.

> BTW you should use now helm-multifiles which doesn't launch locate
> unless you ask it with C-c p. (IOW helm-for-files is deprecated).

I always want to have locate enabled but it seems it's hard-coded as
disabled with `helm-multi-files'. But I use my own version of
helm-for-files anyway which adds some more sources like helm-projectile.

Bye,
Tassilo

Tassilo Horn

unread,
Mar 6, 2015, 1:10:54 AM3/6/15
to Thierry Volpiatto, emacs...@googlegroups.com
Thierry Volpiatto <thierry....@gmail.com> writes:

>> Yes, of course. But let's assume there is some command that wants to
>> read a file name from the minibuffer which you didn't already cover with
>> an action in helm. :-)
>
> C-x C-f => navigate => C-c i
> This is also completing the filename already entered in minibuffer or
> anywhere else.

C-c i is undefined. Do you mean C-c C-i (helm-copy-to-buffer)?

>> --8<---------------cut here---------------start------------->8---
>> (defun th/helm-insert-selection ()
>> (interactive)
>> (when-let ((item (helm-get-selection)))
>> (helm-quit-and-execute-action (lambda (&rest _ignore)
>> (insert item)))))
>>
>> (define-key helm-map (kbd "M-SPC") #'th/helm-insert-selection)
>> --8<---------------cut here---------------end--------------->8---
>>
>> and basically that does the trick. I'd welcome if you could tell me if
>> that's the intended way.
>
> No, just use C-x C-f as said above.

Now I use this because I didn't like that `helm-copy-to-buffer' inserts
a newline after the last element in the selection especially when it's
copied to a find-file prompt, and I wanted to have a variant which exits
helm, too.

--8<---------------cut here---------------start------------->8---
(defun th/helm-copy-to-buffer ()
"Copy selection or marked candidates to `helm-current-buffer'.
If that's the minibuffer, delete its editable contents before,
i.e., replace it with whatever is copied from helm."
(interactive)
(with-helm-buffer
(let ((candidates (helm-marked-candidates)))
(with-helm-current-buffer
(when (minibufferp) (delete-minibuffer-contents))
(while candidates
(insert (car candidates))
(setq candidates (cdr candidates))
(when candidates
(insert "\n")))))))

(defun th/helm-copy-to-buffer-and-exit ()
(interactive)
(helm-quit-and-execute-action
(lambda (_ignore)
(th/helm-copy-to-buffer))))

(define-key helm-map (kbd "M-SPC") #'th/helm-copy-to-buffer-and-exit)
(define-key helm-map (kbd "C-c C-i") #'th/helm-copy-to-buffer)
--8<---------------cut here---------------end--------------->8---

> You can also insert from any helm command with C-c C-i and it is
> persistent, it works in minibuffer too (It is not a completion
> command, it is just inserting at point).

That's what I am using now (or a variant of that). So I guess your C-c
i above wasn't just a typo but some similar command. Is it possible
that this is just a binding you do locally? What's the command?

Bye,
Tassilo

Tassilo Horn

unread,
Mar 10, 2015, 1:15:54 AM3/10/15
to Thierry Volpiatto, emacs...@googlegroups.com
Thierry Volpiatto <thierry....@gmail.com> writes:

>>> C-x C-f => navigate => C-c i
>>> This is also completing the filename already entered in minibuffer or
>>> anywhere else.
>>
>> C-c i is undefined.
>
> It seems you use find-file helmized by helm-mode, please bind C-x C-f
> to helm-find-files, you will have C-c i and many others features you
> don't have in find-file (helmized).

No, I use vanilla `find-file' (with icomplete), and the point of the
whole story is that I like that and usually don't want to use
`helm-find-files' (or `helm-for-files'). Just in some cases, namely
where I suddenly feel that a locate search for picking a file name would
be better, I want to refrain to helm.

> C-c C-i is something different, use it preferably to insert more than
> one candidate in a buffer.

Yeah, my variant now does exactly what I want. Now I can

<command> ;=> command openes the vanilla file selection prompt
; now I see that default-directory and the file I wanna pick are
; far away from each other, thus a locate would do better
C-c a ;=> fires up my variant of helm-for-files in a recursive
; minibuffer
; I select the file I want to pick from the locate source (or some
; other source)
C-c C-i ; My th/helm-copy-to-buffer-and-exit command clears the
; current minibuffer input and inserts the helm selection(s)
; without a trailing \n as helm-copy-to-buffer does

So I'm completely satisfied now. Thanks for pointing me in the right
direction!

Bye,
Tassilo
Reply all
Reply to author
Forward
0 new messages