Denote: Emacs 下的简易笔记系统

1. Intro

用了一段时间 org-roam 插件。但在实际的使用过程中很少用到双链笔记的特性,也很少用到 org-roam-ui。自己更喜欢记录主题笔记。这类笔记内容组织较为集中,放在一个大的 Org 文件中统一管理最方便,而不是像 zs 那样分解成多个原子概念笔记。所以决定放弃使用 org-roam ,尝试用下 denote 这个笔记插件。

Denote 并不预设任何一种记笔记的方式(比如 org-roam 预设了双链笔记的形式),其只是简单的设定了一种简单的笔记文件命名约定。预设这种命名约定也只是为了方便笔记可以用已有的工具进行检索。整个 Denote 的设计即简约又灵活,每个使用者可以根据自己的需求来定制自己喜欢的笔记流程。

下面是 denote 的默认文件名样式:

DATE--TITLE__KEYWORDS.EXTENSION

注意,其中 DATE 项是一个文件或者笔记的唯一标识,不允许更改,不然会使 denote-link 破损。

其官网列出了 denote 的主要设计原则,非常切合我最近对记笔记的思考:

  1. (Predictability):文件名必须遵循一致的描述性命名约定。
  2. (Composability):与其他软件包或内置功能集成,而不是重新发明,做一个 emacs 好公民。
  3. (Portability): 笔记应该为纯文本且保持可移植性。
  4. (Flexibility):不要预设用户对记笔记方式的任何偏好。
  5. (Hackability): denote 的代码保持清晰简洁,方便不同水平的用户理解正在发生的事。

2. Setup

(use-package denote
  :preface (require 'dired)
  :bind (("C-c n c"   . denote)
         ("C-c n n"   . denote-subdirectory)
         ("C-c n j"   . denote-journal-extras-new-entry)
         ("C-c n o"   . denote-open-or-create)
         ("C-c n i"   . denote-link-or-create)
         ("C-c n l"   . denote-find-link)
         ("C-c n C-l" . denote-find-backlink)
         ("C-c n r"   . denote-rename-file-using-front-matter)
         ("C-c n C-r" . denote-rename-file)
         ("C-c n C-f" . denote-org-dblock-insert-links)
         ("C-c n C-b" . denote-org-dblock-insert-backlinks)
         :map dired-mode-map
         ("C-c n r"   . denote-dired-rename-files)
         ("C-c n C-r" . denote-dired-rename-marked-files)
         ("C-c n k"   . denote-dired-rename-marked-files-with-keywords))
  :custom
  (denote-directory org-directory)
  (denote-date-prompt-use-org-read-date t)
  (denote-journal-extras-title-format nil)
  :config
  (denote-rename-buffer-mode 1)
  (add-hook 'dired-mode-hook #'denote-dired-mode-in-directories))

3. Usage

我的日志根据类型分目录存放,在目录的层面上完成一级分类。我把自己的笔记分为几大块,有日记、文献笔记、卡片笔记和博客文章等。所以我常使用 denote-subdirectory 这个命令,每次新建笔记时,其会提示用户选择子目录。在日志中,我会使用 org-mode 的 tag 系统对笔记进行第二级分类。

denote-template 可以用模版来创建笔记,应该会非常有用,其默认实现不会提示选择子目录,可以简单修改适配:

(defun yx/denote-template ()
    "Create note while prompting for a template.
This is equivalent to calling `denote' when `denote-prompts' is
set to \\='(template title keywords subdirectory)."
    (declare (interactive-only t))
    (interactive)
    (let ((denote-prompts '(template title keywords subdirectory)))
      (call-interactively #'denote)))

模版通过参数 denote-templates 来设置,目前的配置中没有模版,等有需要的时候再添加。 denote-open-or-create 命令可以用来创建或打开已有 denote 文件,minibuffer 会提示补全,也是我常用的一个命令。

4. Misc

这下面的内容是其官网文档的一些总结,以及自己使用时的一些心得。

4.1. Add or remove keywords

通过 denote-keywords-adddenote-keywords-remove 这两个命令可以在笔记的 front-matter 添加或删除 keyword,并同时修改文件。

4.2. Renaming files

denote 提供了一些保持文件命名约定和笔记 front-matter 一致的命令

denote-rename-file rename a file and updates existing front matter
denote-dired-rename-marked-files rename marked files in Dired
denote-rename-file-using-front-matter rename a file using front matter
denote-dired-rename-marked-files-using-front-matter  
denote-change-file-type  

文件的 identifier 一般不会改变,其被设计成链接的唯一标识和真实性的唯一来源。所以要注意防止误操作可能引起的日志唯一标识破损的问题。如果不小心删除了front-matter,可以用 denote-add-front-matter 命令来重新生成。

4.3. Linking notes

denote-add-links  
denote-link  
denote-link-dired-marked-notes  
denote-link-after-creating Create new note in the background and link to it directly.
denote-link-or-create  

4.4. 实现 zs 笔记命令

denote-backlinks open the backlinks’ buffer
denote-find-link  
denote-find-backlink  

4.5. Denote 可以结合 Org 动态块来索引已有笔记

动态块可以执行特定函数来获得和更新它的内容,denote 提供了 denote-linksdenote-backlinks 两种动态块,来获得双链的链接信息。

下面是一个denote-links的动态块的示例:

#+BEGIN: denote-links :regexp "_emacs"

#+END:

在其中按 C-c C-c, 就可以收集 keyword 为 emacs 的链接了。每个动态块函数还可以允许带参数,具体看官方文档。


Created with Emacs 29.4 (Org mode 9.6.15) by YangXue
Updated: 2025-01-24 Fri 01:48