Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

Already on GitHub? Sign in to your account

dynamically created hydras? #164

Open
benedekfazekas opened this Issue Sep 1, 2015 · 12 comments

Comments

Projects
None yet
5 participants

hi,

this is more like a question than an issue. we decided to use hydras to improve discoverability for clojure refactor see: clojure-emacs/clj-refactor.el#214 (comment). however, would be nice to be able to generate hydras as we have a nice datastructure (and helper functions) which could power that, see: https://github.com/clojure-emacs/clj-refactor.el/blob/new-all-helpers-structure/clj-refactor.el#L293-L373

I have seen the conditional hydra on the wiki but that is not exactly what we need. Any advice how to generate hydra docstring and heads dynamically?

Owner

abo-abo commented Sep 1, 2015

If you want to stick to your data structure, maybe like this:

(eval `(defhydra hydra-foo (:columns 3)
           "cljr"
           ,@(mapcar (lambda (x)
                       (list (car x) (cadr x) (caddr x)))
                     cljr--all-helpers)))
Owner

abo-abo commented Sep 1, 2015

Also look at pandoc-mode. It generates some hydras dynamically.

thx for the help. will give these a try

@benedekfazekas Sorry to barge in here, but as the maintainer of pandoc-mode, I'd be very interested in anything you come up with. There may be better ways to do what I did in pandoc-mode. Would you mind sharing your code when you've come up with something that works? TIA

I have to disappoint you I am afraid. I played a bit with @abo-abo's sample code and then gave up and did not have time to go back. so current hydra code in clj-refactor is pretty hardwired, although i have my helper fns around. Will let you know if I have more 'meaningful' stuff added to clj-refactor.

squiter commented Oct 20, 2016

I don't know if this is a right place to write my doubt but I want to create hydras dynamically by projects.
My first idea is to create launcher with helper links by projects like: ci url, repository, online documentation, etc. There is any way to create hydras like that?

Owner

abo-abo commented Oct 21, 2016

@squiter Just write out the hydra that you need by hand. If you have a few more that fit the same template, use the eval trick above. If you give an example, perhaps I can help you.

squiter commented Oct 21, 2016

@abo-abo thanks for your response!
The eval trick above works fine to me :D

(eval `(defhydra hydra-project-launcher (:column 3)
         "Fast links by projects"
         ,@(mapcar (lambda (x)
                     (list (car x) `(browse-url ,(cadr x)) (caddr x)))
                   (mapcar (lambda (line)
                             (split-string line " - "))
                           (read-lines (concat (projectile-project-root) ".hydra-links"))))))

Thank you again!

stig commented Feb 16, 2017 edited

I'm trying to use the eval trick above, and it works but is not 100% ideal.

This works (auxiliary functions omitted):

(eval `(defhydra sb/hydra-select-themes (:hint nil :color pink)
         "Select Theme"
         ,@(sb/hydra-load-theme-heads (sb/sort-themes (custom-available-themes)))
         ("DEL" (sb/disable-all-themes))
         ("RET" nil "done" :color blue)))

(bind-keys ("C-c w t" . sb/hydra-select-themes/body))

However, that means that if I install a new theme it won't show up in this hydra until I manually re-eval the config snippet, or restart Emacs. That's not ideal. So I wanted to rewrite it to something like this, hoping that the Hydra would be re-created at the point when I invoke it:

(bind-keys ("C-c w t" .
          (eval `(defhydra sb/hydra-select-themes (:hint nil :color pink)
                   "Select Theme"
                   ,@(sb/hydra-load-theme-heads (sb/sort-themes (custom-available-themes)))
                   ("DEL" (sb/disable-all-themes))
                   ("RET" nil "done" :color blue)))))

However, if I try to launch the Hydra now I get the following error:

command-execute: Wrong type argument: commandp, (eval (\` (defhydra sb/hydra-select-themes (:hint nil :color pink) "Select Theme" (\,@ (sb/hydra-load-theme-heads (sb/sort-themes (custom-available-themes)))) ("DEL" (sb/disable-all-themes)) ("RET" nil "done" :color blue))))

Is there a work-around for this? I've tried wrapping the eval in a defun and lambda but neither helped. (Or, I didn't do it correctly: I'm an Emacs-lisp novice.)

Can anyone help with a work-around for this case?

Update: FWIW the complete code is here: https://github.com/stig/dot-files/blob/master/emacs.d/Themes.org#hydra-theme-switching

Update 2: Using #137 (comment) as a reference I finally managed to get it working with the aid of call-interactively:

    (bind-keys ("C-c w t" .
                (lambda ()
                  (interactive)
                  (call-interactively
                   (eval `(defhydra sb/hydra-select-themes (:hint nil :color pink)
                            "Select Theme"
                            ,@(sb/hydra-load-theme-heads (sb/sort-themes (custom-available-themes)))
                            ("DEL" (sb/disable-all-themes))
                            ("RET" nil "done" :color blue)))))))
Owner

abo-abo commented Feb 17, 2017

@stig So now it works for you? Because I don't see why it should not work if custom-available-themes is aware of new themes.

Still, I recommend to simply use counsel-load-theme: it's 2-3 more keys to type but a lot less theme names to read.

stig commented Feb 17, 2017

@abo-abo yeah, it works now.

I don't know what counsel-load-theme is; it doesn't appear to be a function available in my Emacs version (25.1.1)

Owner

abo-abo commented Feb 17, 2017

I don't know what counsel-load-theme is; it doesn't appear to be a function available in my Emacs version (25.1.1)

Available from the counsel package on MELPA.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment