Use-package: Unable to use a lambda with :bind?

Created on 17 Mar 2016  路  14Comments  路  Source: jwiegley/use-package

I'm finally converting my init file to use use-package. Thanks very much for your work on it (and for taking on maintainership of Emacs!).

I seem to be unable to use :bind to bind keys to lambdas. I've tried several combinations:

(use-package org
  :bind (("<C-f5>" (lambda () (interactive) (org-agenda nil "A")))))

(use-package org
  :bind (("<C-f5>" '(lambda () (interactive) (org-agenda nil "A")))))

(use-package org
  :bind (("<C-f5>" . (lambda () (interactive) (org-agenda nil "A")))))

(use-package org
  :bind (("<C-f5>" . '(lambda () (interactive) (org-agenda nil "A")))))

For all of those I get this error:

mapcar: Wrong type argument: listp, "<C-f5>"

I've searched Google and the issue tracker, but I can't find anything about this problem. I can't even find anyone using lambdas in :bind. But it does work with bind-key:

(bind-key "<C-f5>" (lambda () (interactive) (org-agenda nil "A")))

Thanks for your help.

Most helpful comment

I'll add lambda support to :bind, just as :hook has it now.

All 14 comments

I think :bind only accepts symbols or a strings.

Define the command as a function in your init or config section instead.

It might need to be in :preface, but yes, we do not support lambdas.

Could support for lambdas be added? It seems strange that :bind doesn't support it when global-set-key does. I usually use named functions for as much as I can, but for something as tiny as the one in the example, it seems like a lambda makes sense. :)

If that's not possible, it would be helpful if a note could be added to the docstrings and the guide. I spent probably half an hour trying to figure out why it works in global-set-key but not in :bind, because I thought :bind was supposed to be capable of everything global-set-key and bind-key do.

Thanks.

:bind is a convenience keyword for common patterns. At this time I don't plan to add lambdas, because then I would have to largely disable the error checking that we currently perform on bind patterns. I'll keep thinking about it, though.

Ah, well, that would be quite unfortunate! I have already come to appreciate the error checking use-package does. Oh well. :)

One thing I do wonder is if another syntax could allow this:

:bind (KEY . FUNCTION)

or

:bind (KEY FORM)

Where if FORM is not a lambda form, we automatically turn it into one.

However, this make the possibility of incorrectly diagnosed errors much higher. :(

I guess it's probably not worth it. If someone really wants a lambda that badly, they can do it in :config. Defined functions are probably better for keymaps anyway, because they make it easier to see what your binds do.

I know this is closed, but there are modes where you have a common behaviour that you then want to minimally change depending on the key. An example could be LaTEX. There you have different format macros and you may want to have a key sequence for italics, another for sans-serif, another for bold, etc. etc. Beofre using use-package, I had keymaps with:

(define-key "C-c fb" '(lambda() (interactive) <code for bold font>)
(define-key "C-c fi" '(lambda() (interactive) <code for italics>)
(define-key "C-c fs" '(lambda() (interactive) <code for sans>)

even
(define-key "M-t c" '(lambda() (interactive) <code for citation>)
with all that code refering to a single common function. Clean code, reusability, etc. as I suppose more than one of us has been taught when learning basic programming skills.

Beofre using use-package, I had keymaps with:

Nothing about use-package stops you from using that same code.

I really strongly desire to have lambdas in use-package.
Use-package is a huge convinience tool for cleaning up init files. But by not supporting lambdas, it creates a situation where I end up having to define functions in the global name-space that don't really need to be in the global name space.

This means that the convinence of use-package comes at the cost of name-space clutter.

Since lambdas are really a standard lisp idiom, not supporting them is also counter-intuitive.

I get the desire to have robust error checking. So maybe just have a separate key from :bind? :bind-lambdas maybe? The user then would be explicitely saying "hey -- I KNOW what I'm doing here, this isn't by accident!"

I'll add lambda support to :bind, just as :hook has it now.

I think the documentation needs to be updated?

Could I see an example where a lambda is used? I'm currently trying:

(use-package elisp-mode
  :bind
  (("C-c e s" . '(lambda () (switch-to-buffer "*scratch*"))))
Was this page helpful?
0 / 5 - 0 ratings

Related issues

bymoz089 picture bymoz089  路  5Comments

DamienCassou picture DamienCassou  路  9Comments

sheepduke picture sheepduke  路  3Comments

Yevgnen picture Yevgnen  路  5Comments

xuzhao9 picture xuzhao9  路  7Comments