面向产品经理的Emacs教程:12. 通过Emacs来记笔记

· 3714字 · 8分钟

1 课程回顾 🔗

通过上一节课,我们通过让Emacs记住一些历史信息、对Emacs的撤销和重做进行增强、智能的进行自动保存、crux系统增强等配置,让Emacs的编辑效率进一步得到了提升。

下面,我们来讲一讲如何通过Emacs来记笔记。

2 笔记体系 🔗

笔记当然也有体系,有基于Markdown的体系,也有基于Org mode的体系,甚至有基于txt的体系,不同的体系有不同的特点。

我们既然已经在使用Emacs了,当然要使用基于强大的Org mode的体系。顾名思义,基于Org mode的笔记体系,它的笔记主体都是一个个的org文件,例如我的笔记文件结构大概如下,其中 xxxx.assets 是笔记文件对应存放图片等静态资源的地方(这么命名是因为之前用过 Typora,实在是喜欢Typora的组织结构):

/Users/randolph/org/

20220929T205915--training__training.assets
20220929T205915--training__training.org
20221001T215051--scratch__scratch.assets
20221001T215051--scratch__scratch.org
20221001T215230--report__reading.assets
20221001T215230--report__reading.org
20221001T215555--movies__entertainment.assets
20221001T215555--movies__entertainment.org
20221001T221032--vocabulary__studying.org
20221001T221120--books__reading.assets
20221001T221120--books__reading.org
20221001T221541--linux__studying.assets
20221001T221541--linux__studying.org
20221001T221855--mac__studying.org
20221001T222021--emacs__emacs.assets
20221001T222021--emacs__emacs.org
20221001T222443--software__studying.assets
20221001T222443--software__studying.org
20221001T222847--skill__studying.assets
20221001T222847--skill__studying.org
20221001T223116--dotfiles__notes.org
20221001T223309--music__studying.assets
20221001T223309--music__studying.org
20221001T224050--api__work.org
20221001T224215--python__studying.assets
20221001T224215--python__studying.org
20221001T224858--ai__studying.assets
20221001T224858--ai__studying.org
20221001T225524--product__studying.assets
20221001T225524--product__studying.org
...

3 org-capture快速记录 🔗

首先,先讲讲Org mode的一个非常棒的特性——capture,通过这个特性,我们能够快速将一些内容记录下来。

3.1 org-capture配置 🔗

我们首先进行配置:

(use-package org-capture
  :ensure nil
  :bind ("\e\e c" . (lambda () (interactive) (org-capture)))
  :hook ((org-capture-mode . (lambda ()
                               (setq-local org-complete-tags-always-offer-all-agenda-tags t)))
         (org-capture-mode . delete-other-windows))
  :custom
  (org-capture-use-agenda-date nil)
  ;; define common template
  (org-capture-templates `(("t" "Tasks" entry (file+headline "tasks.org" "Reminders")
                            "* TODO %i%?"
                            :empty-lines-after 1
                            :prepend t)
                           ("n" "Notes" entry (file+headline "capture.org" "Notes")
                            "* %? %^g\n%i\n"
                            :empty-lines-after 1)
                           ;; For EWW
                           ("b" "Bookmarks" entry (file+headline "capture.org" "Bookmarks")
                            "* %:description\n\n%a%?"
                            :empty-lines 1
                            :immediate-finish t)
                           ("d" "Diary")
                           ("dt" "Today's TODO list" entry (file+olp+datetree "diary.org")
                            "* Today's TODO list [/]\n%T\n\n** TODO %?"
                            :empty-lines 1
                            :jump-to-captured t)
                           ("do" "Other stuff" entry (file+olp+datetree "diary.org")
                            "* %?\n%T\n\n%i"
                            :empty-lines 1
                            :jump-to-captured t)
                           ))
  )

这个配置中,最重要的就是 org-capture-templates 这个变量了,这个变量是我们设置快速记录快捷键、初始模板、存放的目的文件等。

3.2 org-capture的演示 🔗

当我们配置完后,我们按下 ESC-ESC c 键后,我们看到如下的快速记录快捷键候选,其中方括号里的快捷键与我们设定的 org-capture-templates 里的快捷键是一致的。

此时,如果我们再按一下 t 键,它会弹出一个 CAPTURE-tasks.org 的缓冲区,按照设定的初始模板,让你继续填充需要记录的内容,填完后,按照提示,按下 C-c C-c 就可以保存这条笔记了,它会自动的把我们记录的内容,按照我们设定的保存文件(即 tasks.org )保存:

我们打开 tasks.org 这个文件夹,可以看到它自动插入到 Reminders 这个标题行下的第一条。

3.3 org-capture模板解释 🔗

我们再回过头来看下我们对于这个模板的定义和每一个配置的含义:

("t"                                             ; 这个是这个快速记录的快捷键设置
 "Tasks"                                         ; 这个是显示在快捷键右边的提示文本
 entry (file+headline "tasks.org" "Reminders")   ; 这个是设置这个快速记录保存到哪个文件的什么位置
 "* TODO %i%?"                                   ; 这个是初始模板
 :empty-lines-after 1                            ; 这个是在这个快速记录后插入一个空行
 :prepend t)                                     ; 这个是插入到最前面的位置,默认是插入到最后一个位置

具体每一个配置项可以参考 org mode官方文档

3.4 org-capture使用场景 🔗

我们配置完org-capture后,可以在如下的场景用到它:

  • 当我们脑海中突然涌现了一个灵感,我们可以通过 ESC-ESC c 来快速记录下灵感
  • 当我们看到网页上的某个有用的知识点,可以通过 capture 快速记录下来先,后续再做统一的整理
  • 当我们要添加一个 TODO 任务时,可以通过快速记录进行任务设置
  • 当我们要记录一个新单词时,我们也可以通过快速记录来记录

下面这个动画是来演示如何通过 capture 进行生词管理(不用担心,后面我会专门写一篇教程讲如何进行生词的管理):


Org capture 是Org mode的一个基础特性,我们后面要用到的很多插件,都会用到这个特性,如 ox-hugo, denote 等等。

4 denote 🔗

基于Org mode的笔记体系,也有很多插件的选择,有 denote, org-roam, zk 等等很多选择,而我使用的是 denote

denote 是一个轻量级的笔记插件,拥有良好的文件名命名模板,选择它是因为它足够简单轻量,刚刚好够使用,当然在自由的Emacs世界,你可以按照自己的喜好来选择。

我们先来安装配置 denote

(use-package denote
  :ensure t
  :hook (dired-mode . denote-dired-mode-in-directories)
  :bind (("C-c d n" . denote)
         ("C-c d d" . denote-date)
         ("C-c d t" . denote-type)
         ("C-c d s" . denote-subdirectory)
         ("C-c d f" . denote-open-or-create)
         ("C-c d r" . denote-dired-rename-file))
  :init
  (with-eval-after-load 'org-capture
    (setq denote-org-capture-specifiers "%l\n%i\n%?")
    (add-to-list 'org-capture-templates
                 '("N" "New note (with denote.el)" plain
                   (file denote-last-path)
                   #'denote-org-capture
                   :no-save t
                   :immediate-finish nil
                   :kill-buffer t
                   :jump-to-captured t)))
  :config
  (setq denote-directory (expand-file-name "~/org/"))
  (setq denote-known-keywords '("emacs" "entertainment" "reading" "studying"))
  (setq denote-infer-keywords t)
  (setq denote-sort-keywords t)
  ;; org is default, set others such as text, markdown-yaml, markdown-toml
  (setq denote-file-type nil)
  (setq denote-prompts '(title keywords))

  ;; We allow multi-word keywords by default.  The author's personal
  ;; preference is for single-word keywords for a more rigid workflow.
  (setq denote-allow-multi-word-keywords t)
  (setq denote-date-format nil)

  ;; If you use Markdown or plain text files (Org renders links as buttons
  ;; right away)
  (add-hook 'find-file-hook #'denote-link-buttonize-buffer)
  (setq denote-dired-rename-expert nil)

  ;; OR if only want it in `denote-dired-directories':
  (add-hook 'dired-mode-hook #'denote-dired-mode-in-directories)
  )

denote 支持以org mode、markdown、txt作为笔记的存储格式,这里我使用的是 org 作为默认的格式。而且,这里我将 denote-directory 设置的和 org-directory 保持一致。

当我们安装完 denote 后,我们就可以使用 M-x denoteC-c d n 来创建一个新的笔记了。它会提示你输入笔记的标题和关键词标签,按照提示输入后,就会生成一个名字类似于 20221001T222021--emacs__emacs.org 的文件,该文件会自动生成一个文件头:

#+title:      emacs
#+date:       [2022-10-01 Sat 22:20]
#+filetags:   :emacs:
#+identifier: 20221001T222021

然后你就可以在这个org文件里愉快的记笔记了,你的所有笔记,就构成了你自己的一张知识网络,长期坚持下去,你会发现,它已经成了你的财富!

5 寻找我们的笔记 🔗

5.1 寻找denote笔记 🔗

我们寻找 denote 笔记,可以使用 denote 自带的一个命令 denote-open-or-create ,我们把这个命令绑定了 C-c d f 快捷键。

你还可以输入关键词标签,或者标题来定位某个笔记,得益于orderless,我们可以不用关心我们输入的关键词的顺序:

5.2 consult-notes寻找笔记插件 🔗

实际上,还有一个更加泛用的插件 consult-notes,它可以让偶我们通过consult快速找到整个org目录下的所有的文件,包括denote笔记。

(use-package consult-notes
  :ensure t
  :commands (consult-notes
             consult-notes-search-in-all-notes)
  :bind (("C-c n f" . consult-notes)
         ("C-c n c" . consult-notes-search-in-all-notes))
  :config
  (setq consult-notes-file-dir-sources
        `(
          ("work"    ?w ,(concat org-directory "/midea/"))
          ("article" ?a ,(concat org-directory "/article/"))
          ("org"     ?o ,(concat org-directory "/"))
          ("hugo"    ?h ,(concat org-directory "/hugo/"))
          ("books"   ?b ,(concat (getenv "HOME") "/Books/"))
          ))

  ;; embark support
  (with-eval-after-load 'embark
    (defun consult-notes-open-dired (cand)
      "Open notes directory dired with point on file CAND."
      (interactive "fNote: ")
      ;; dired-jump is in dired-x.el but is moved to dired in Emacs 28
      (dired-jump nil cand))

    (defun consult-notes-marked (cand)
      "Open a notes file CAND in Marked 2.
Marked 2 is a mac app that renders markdown."
      (interactive "fNote: ")
      (call-process-shell-command (format "open -a \"Marked 2\" \"%s\"" (expand-file-name cand))))

    (defun consult-notes-grep (cand)
      "Run grep in directory of notes file CAND."
      (interactive "fNote: ")
      (consult-grep (file-name-directory cand)))

    (embark-define-keymap consult-notes-map
                          "Keymap for Embark notes actions."
                          :parent embark-file-map
                          ("d" consult-notes-dired)
                          ("g" consult-notes-grep)
                          ("m" consult-notes-marked))

    (add-to-list 'embark-keymap-alist `(,consult-notes-category . consult-notes-map))

    ;; make embark-export use dired for notes
    (setf (alist-get consult-notes-category embark-exporters-alist) #'embark-export-dired)
    )
  )

当我们安装完 consult-notes 后,我们只需要按下 C-c n f 就可以尝试找到整个 consult-notes-file-dir-sources 所定义的所有文件夹下的所有文件,你也可以通过关键词来进行查找和筛选,非常方便:

当你想查找具体某个笔记的内容时,你可以使用 consult-notes-search-in-all-notes 来查找,它会调用 ripgrep 在设定的笔记源目录下去查找该关键词的笔记内容:

当你想查找某个标题行时,你可以调用 my/consult-find-org-headings 函数来查找和筛选所有笔记的标题行:

(defun my/consult-find-org-headings (&optional match)
      "find headngs in all org files."
      (interactive)
      (consult-org-heading match (directory-files org-directory t "^[0-9]\\{8\\}.+\\.org$")))

6 笔记之间的链接 🔗

我们的笔记和笔记之间,甚至标题行和标题行之间,可能会有互相的引用和链接。比如你在读一本书,书里提到了Org mode,而你在另外一个笔记里专门对Org mode的相关功能做了笔记,你就可以把这个笔记的Org mode的标题行链接到你的读书笔记里。

Org mode自带链接功能,你可以轻易的链接任何一个文件的任何一个标题行到当前位置:

  1. 链接当前文件的其他标题行: denote,这个链接的纯文本写法是 [[*denote][denote]] ,星号后面跟着的是当前文件的标题行字符串。
  2. 链接到其他文件的其他标题行: [[file:~/org/进一步提升Emacs效率.org::*crux系统增强][crux系统增强]] ,链接到的是另外一个文件「进一步提升Emacs效率.org」的某个标题行「crux系统增强」。

除了我们使用Org mode自带的链接机制外,我们还可以用一个非常方便的插件 org-super-links ,它除了能设置链接外,还可以自动的设置反向链接,非常方便,下面我们来安装和配置它:

(use-package org-super-links
  :quelpa (org-super-links :fetcher github :repo "toshism/org-super-links")
  :bind (("C-c s s"   . org-super-links-link)
         ("C-c s l"   . org-super-links-store-link)
         ("C-c s C-l" . org-super-links-insert-link)
         ("C-c s d"   . org-super-links-quick-insert-drawer-link)
         ("C-c s i"   . org-super-links-quick-insert-inline-link)
         ("C-c s C-d" . org-super-links-delete-link))
  :config
  (setq org-super-links-related-into-drawer t)
  (setq	org-super-links-link-prefix 'org-super-links-link-prefix-timestamp))

安装完后,我们可以按下 C-s s l 来保存当前所在标题行的链接,然后到目标标题行那里,按下 C-s s C-l 来插入保存的标题行。它在插入源标题行的同时,会创建一个反向链接,这样我们在两个标题行都能看到链接和反向链接的标题行了,非常方便。

7 笔记我们都记些什么呢 🔗

记笔记,当然是一件很有用的事情,因为它有助于帮你形成你自己的独特的知识体系,帮你加强对知识的记忆。之前用纸和笔来记,当然也有好处,可坏处是不太容易检索。

而基于文本,基于电子的笔记,好处就在于可以随时随地的搜索,当我们的记忆有些模糊的时候,我们可以通过强大的搜索和过滤功能快速找到我们想要找到的笔记,然后快速温故知新,长此以往,笔记不单单是你的笔记,它会逐渐成为你的财富。

那我们记笔记,都可以记些什么呢?这个问题说实话,因人而异,对我自己来说:

  1. 学习的内容,如Python、Linux、Emacs等等;
  2. 读书的记录,我会将读的每一本书做一些摘抄和读后感(自从使用Emacs后);
  3. 电影的记录,我会对我看过的每一部电影写一些观后感(自从使用Emacs后);
  4. 工作的记录,我的所有技术文档、产品文档、产品手册都是基于Org mode来写的,广义上也属于笔记的范畴;
  5. 单词的记录,我会把遇到的生词都记录下来,虽然并没有常常温故;
  6. 其他生活的记录,你可以使用Org mode来记录生活的方方面面,点点滴滴。

8 结语 🔗

经过今天的学习,我们了解了如何通过Emacs和Org mode来记笔记,我们可以将我们的学习、工作、生活的方方面面通过强大的Org mode记录下来,形成你自己的知识体系,长此以往,你会发现你越来越「厚重」,这就是厚积薄发的过程!

这节课的配置文件的快照见:emacs-config-l12.org

你也可以在 这里 查看最新的配置文件。