wenno
2020 年3 月 28 日 06:54
1
已解决,见21楼,感谢各位的帮助和指点
需求: lazy load emms(从而提高启动速度),在我按下 s-c m 后加载 emms ( s-c 是我 hydra 的前缀)
目前代码:
emms,我的理解是:
init 是 emacs 启动时就会运行的,因此会定义 hydra-media-player/body
当 hydra-media-player/body 这个 command 被调用时,运行 config 的内容,加载 emms-setup 等
(use-package emms
:commands (hydra-media-player/body)
:init
(defhydra hydra-media-player ()
"emms"
("p" emms-pause "pause/resume")
("l" emms-play-playlist "playlist")
("f" emms-play-file "song")
("d" emms-play-directory-tree "directory")
(">" emms-next "next")
("<" emms-previous "previous")
("s" emms-stop "stop")
("q" nil "quit"))
:config
(require 'emms-setup)
(emms-standard)
(emms-default-players)
)
hydra:
(defhydra hydra-wenshan-emacs ()
"Hydra"
("m" hydra-media-player/body "media player" :exit t)
("s" aweshell-new "eshell" :exit t)
("c" compile "compile" :exit t)
("r" recompile "re-compile" :exit t)
("q" nil "quit"))
(global-set-key (kbd "s-c") 'hydra-wenshan-emacs/body)
问题: s-c m 后能看到 hydra-media-player 的那些选项,但按任意选项,都会出现类似 “Wrong type argument: commandp, emms-play-directory-tree” 的错误,求指点
wenno
2020 年3 月 28 日 07:00
2
一种办法是把 hydra-media-player 里面用到的命令都加到 commands 里:
(use-package emms
:commands (emms-play-directory-tree)
:init
(defhydra hydra-media-player ()
"emms"
("p" emms-pause "pause/resume")
("l" emms-play-playlist "playlist")
("f" emms-play-file "song")
("d" emms-play-directory-tree "directory")
(">" emms-next "next")
("<" emms-previous "previous")
("s" emms-stop "stop")
("q" nil "quit"))
:config
(require 'emms-setup)
(emms-standard)
(emms-default-players)
)
但这样代码有重复,请问有更简洁的写法吗?
wsug
2020 年3 月 28 日 07:49
5
问下s-c这个绑定的是什么 (global-set-key (kbd "s-c") 'hydra-wenshan-emacs/body)
,C-c是ctrl+c,M-c是alt+c,“s-c”还以为是shift+c,一试发现不对,shift+…也是我的hydra前缀
wsug
2020 年3 月 28 日 07:55
7
原来是这样,我还以为终于遇到有人用shift开头的快捷键了
总之,问题原因就是 xxx/body
调用之时,emms-*
函数必须就绪。
你可以简单地再写一个函数绑定 “m” 键,在这个函数里面 (require 'emms) (xxx/body)
。
xiyang
2020 年3 月 28 日 09:15
10
或许你可以使用
(defhydra hydra-media-player (:body-pre
(progn
(require 'emms-setup)
(emms-standard)
(emms-default-players)))
...)
或者直接使用(advice-add 'hydra-media-player/body :before ...)
1 个赞
它的subroutine pretty-hydra 更通用, 局限性质更小,而且可以在其之上建立更加强大的use-package 的key。
这个错误一般都是函数不是 interactive
的。我没有使用 emms,用下面这个简单测试了下是没有问题的。
(defhydra hydra-test2 ()
"test2"
("l" counsel-load-theme "load theme")
("q" nil "quit"))
(defhydra hydra-test ()
"Hydra"
("m" hydra-test2/body "test" :exit t)
("q" nil "quit"))
(global-set-key (kbd "s-c") 'hydra-test/body)
wenno
2020 年3 月 28 日 21:11
14
多谢推荐,浏览了一下 README,好像不太能达到我想要的效果诶
wenno
2020 年3 月 28 日 21:33
16
对,我的理解好像是有问题。
根据 use-package 的 README:
When you use the :commands
keyword, it creates autoloads for those commands and defers loading of the module until they are used.
=> 所以 :commands (hydra-media-player/body)
使得:当 hydra-media-player/body 被调用时,加载 emms 这个 module
Similarly, :config
can be used to execute code after a package is loaded. In cases where loading is done lazily (see more about autoloading below), this execution is deferred until after the autoload occurs
=> 所以当 emms 加载完后,会运行 config 里面的内容
合起来,我的理解是:当 hydra-media-player/body 被调用 → 加载 emms 这个 module → 运行 config 里面的内容
而 config 里面的内容会使得 emms-play-directory-tree 变成可用的
(require 'emms-setup)
(emms-standard)
(emms-default-players)
但不知道这个理解是在哪错了。
wenno
2020 年3 月 28 日 21:42
17
嗯,确实是这个原因
你的意思是类似于这样吗?
(defhydra hydra-wenshan-emacs ()
"Hydra"
("m" (lambda ()
(interactive)
(require 'emms-setup)
(emms-standard)
(emms-default-players)
(hydra-media-player/body)) "media player" :exit t)
("p" hydra-projectile/body "project interaction" :exit t)
("s" aweshell-new "eshell" :exit t)
("c" compile "compile" :exit t)
("r" recompile "re-compile" :exit t)
("q" nil "quit"))
这样确实可以,但会导致每次按 m 都运行一遍 (require 'emms-setup)...
那段代码
wenno
2020 年3 月 28 日 21:44
18
嗯,这样做是没问题的,我的问题似乎是个 use-package 有关,即 hydra-media-player/body 被调用时,emms-setup 那段代码没有被运行,从而导致 emms-play… 这些 commands 没有加载
wenno
2020 年3 月 28 日 21:47
19
挺好的,多谢周冲兄关心啊,你可还好?
澳洲也慢慢 lock down 了,最近都是在家工作。
这边还行,现在除了餐饮业之外,其他行业都渐渐恢复了