我已经基于org-mode搭建了一个联系人数据库. 一个联系人记录基本上就是一个带 EMAIL
属性的标题. 像这样: https://julien.danjou.info/projects/emacs-packages#org-contacts.
我想要是能够做到在联系人记录的标题的开头位置处按下 e
就能为该联系人发电子邮件那就好了.
像这种根据标题类型以及speed key来触发不同函数的功能应该是很实用的.
Org-mode已经有了speed key这一功能. 你只需要定义好speed key及其对应的函数,然后提供一个函数来分发这些函数,并把这个分发函数加到 org-speed-command-hook
中就可以了.
下面这段代码能够做到,当你在一个含有 EMAIL
属性的标题开始位置处时:按下 c
就能将电子邮件拷贝到粘贴板中, 按下 e
就能给联系人发电子邮件, 按下 m
就能够拷贝 “name <email?” 这样的字符串到粘贴板中.
按下其他按键则会使用 user-defined speed key(译者注:专指org-speed-commands-user中定义的speed key,而不是泛指所有自定义的speed key) 和 内置的speed key.
此外,为了怕我忘了有哪些speed key可以用,我还定义了 ?
用来为我显示所有的speed key. 这是一个小功能,但是若你经常要用到这些联系人记录,那就显得很实用了,总比不断的执行 M-x some-contacts-command
要好.
(setq org-speed-commands-contacts
'(("c" . (lambda ()
"Copy the email address to the clipboard."
(message (kill-new (org-entry-get (point) "EMAIL")))))
("e" . (lambda ()
"Send an email to the contact."
(let ((email (org-entry-get (point) "EMAIL")))
(compose-mail)
(message-goto-to)
(insert email)
(message-goto-subject))))
("m" . (lambda ()
"Copy \"name <email>\""
(message (kill-new
(format "%s <%s>"
(nth 4 (org-heading-components))
(org-entry-get (point) "EMAIL"))))))
("?" . (lambda ()
"Print contacts speed key help."
(with-output-to-temp-buffer "*Help*"
(princ "Contacts Speed commands\n===========================\n")
(mapc #'org-print-speed-command org-speed-commands-contacts)
(princ "\n")
(princ "User-defined Speed commands\n===========================\n")
(mapc #'org-print-speed-command org-speed-commands-user)
(princ "Built-in Speed commands\n=======================\n")
(mapc #'org-print-speed-command org-speed-commands-default))
(with-current-buffer "*Help*"
(setq truncate-lines t))))))
(defun org-speed-contacts (keys)
(when (and (bolp) (looking-at org-outline-regexp)
(not (null (org-entry-get (point) "EMAIL"))))
(cdr (assoc keys org-speed-commands-contacts))))
(add-hook 'org-speed-command-hook 'org-speed-contacts)