本来非代码的部分一般放到注释中的,不过用 use-package
的关键词组织起来感觉似乎不错:
(use-package magit
:ensure t
:homepage https://github.com/magit/magit
:info (info "(magit) Top")
:tips
- To launch from shell, use $ emacsclient -e '(magit-status)'
- Here is another tip
- ...
:bind ("C-x C-g" . magit-status)
:config (setq magit-save-repository-buffers 'dontask))
上面添加了三个新的关键词: homepage
, info
和 tips
,不像其它的关键词,这三个关键词完全没用,不对原来的 (use-packag ...)
造成任何影响。
(add-to-list 'use-package-keywords :homepage t)
(defun use-package-normalize/:homepage (&rest _))
(defun use-package-handler/:homepage (&rest _))
(add-to-list 'use-package-keywords :info t)
(defun use-package-normalize/:info (&rest _))
(defun use-package-handler/:info (&rest _))
(add-to-list 'use-package-keywords :tips t)
(defun use-package-normalize/:tips (&rest _))
(defun use-package-handler/:tips (&rest _))
Extending use-package with new or modified keywords
1 个赞
可以用 String,只要 Lisp Reader 能处理就行。
说到这种关键词我想起了 plist 的问题, 其实冒号也不是必须的:
(plist-get '(:foo 1 bar 2) :foo) ;; => 1
(plist-get '(:foo 1 bar 2) 'bar) ;; => 2
另一个问题是:如何像 use-package 那样,一个 keyword 对应多个值呢?
(plist-get '(:foo 1 2 3 :bar 4) :foo) ;; => 1
(plist-member '(:foo 1 2 3 :bar 4) :foo) ;; => (:foo 1 2 3 :bar 4)
(plist-member '(:foo 1 2 3 :bar 4) :bar) ;; => (:bar 4)
plist-memmber
返回的是剩下所有元素,这个特性可以拿来用:
(setq my-keywords '(:foo t :bar t))
(defun my-plist-get (plst key)
(let (vals)
(catch 'break
(mapc (lambda (val)
(if (plist-get my-keywords val)
(throw 'break vals)
(setq vals (append vals `(,val)))))
(cdr (plist-member plst key))))))
(my-plist-get '(:foo 1 2 3 :bar 4) :foo)
;; => (1 2 3)
(defun my-plist-get (plst key)
(let (vals)
(catch 'break
(mapc (lambda (val)
(if (keywordp val)
(throw 'break vals)
(setq vals (append vals `(,val)))))
(cdr (plist-member plst key))))))
(my-plist-get '(:foo 1 2 3 :bar 4) :foo)
;; => (1 2 3)
一个属性对应多个值就不适合继续叫做 plist 了。
use-package 把这种叫做 pseudo-plist,使用之前转换成 plist:
(use-package-normalize-plist ":init" '(:init (foo) (bar)))
;; => (:init ((foo) (bar)))
https://github.com/jwiegley/use-package/blob/1928d80/use-package.el#L513