EMACS-DOCUMENT

=============>集思广益

org-mode中定义与上下文相关的speed-keys

我已经基于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)