[讨论]你的emacs文献/知识管理方案是什么?

题目中也提到了“知识管理方案”,我提一下我的方案。doom-emacs 自带的module就可以轻松实现的。

  1. org-capture用于记录todo-list和待研究的内容,通过google、wiki或stackoverlfow研究清楚之后从这里搬到正式笔记中。
  2. deft。正式笔记,一个deft笔记对应一个笔记类型。如book/paper/meeting/plan。
  3. org-brain。个人维基,可被deft笔记轻松引用。

至于org-ref等用来管理文献,以前试过,的确不错。现在毕业了,没有这方面的太多需求。能够想到的坑有:

  1. windows上pdf-tool还是不方便,至少标注没那么方便,即使够用也不流畅。
  2. 更新代码的元数据没有那么方便,比不过zotero/mendeley.
  3. 删除item不会删除pdf
  4. 好像也没有基于pdf的全文搜索,这个在zotero/mendely里面都实现得很好
  5. 用会了org-ref之后,完美主义者还会开始折腾用org-mode或latex-mode做ppt,用latex写论文。浪费大量时间,并且有些导师还是要坚持用word改文章。
3 个赞

今天试用了org-ref,问题是强依赖于helm。issue里作者也表示没办法分离。所以就扔了。现在是用ebib来做。对我来说,基本功能足够了。至于所谓的插入这些ivy-bibtex或者helm-bibtex都能做。

贴上两个配置的代码,一是custom.el,一是init.el 文件。谢谢你了。

(custom-set-variables ;; custom-set-variables was added by Custom. ;; If you edit it by hand, you could mess it up, so be careful. ;; Your init file should contain only one such instance. ;; If there is more than one, they won’t work right. '(package-selected-packages (quote (helm-bibtex counsel zop-to-char zenburn-theme which-key volatile-highlights undo-tree super-save smartrep smartparens operate-on-number move-text magit projectile imenu-anywhere hl-todo guru-mode gitignore-mode gitconfig-mode git-timemachine gist flycheck expand-region epl editorconfig easy-kill diminish diff-hl discover-my-major crux browse-kill-ring beacon anzu ace-window)))) (custom-set-faces ;; custom-set-faces was added by Custom. ;; If you edit it by hand, you could mess it up, so be careful. ;; Your init file should contain only one such instance. ;; If there is more than one, they won’t work right. )

(menu-bar-mode 1) (scroll-bar-mode 1) (global-linum-mode t) (global-company-mode t) (setq cursor-type 'bar) (setq ring-bell-function 'ignore)

(defun open-my-custom-file() (interactive) (find-file “~/.emacs.d/personal/custom.el”)) (global-set-key (kbd “”) 'open-my-custom-file)

;; Load path ;; Optimize: Force “lisp”" and “site-lisp” at the head to reduce the startup time. (defun update-load-path (&rest _) “Update `load-path’.” (dolist (dir '(“site-lisp” “lisp”)) (push (expand-file-name dir user-emacs-directory) load-path)))

(defun add-subdirs-to-load-path (&rest _) “Add subdirectories to `load-path’.” (let ((default-directory (expand-file-name “site-lisp” user-emacs-directory))) (normal-top-level-add-subdirs-to-load-path)))

(advice-add #'package-initialize :after #'update-load-path) (advice-add #'package-initialize :after #'add-subdirs-to-load-path)

(update-load-path)

;;; 改五笔输入 ;;(autoload 'chinese-wbim-use-package “chinese-wbim” “Another emacs input method”) ;;(setq chinese-wbim-use-tooltip nil) ;;(register-input-method ;; “chinese-wbim” “euc-cn” 'chinese-wbim-use-package ;; “五笔” “汉字五笔输入法” “wb.txt”) ;;; 用 ; 暂时输入英文

;;(require 'chinese-wbim-extra) ;;(global-set-key “;” 'chinese-wbim-insert-ascii) ;;(setq default-input-method 'chinese-wbim)

;;; settings for ebib ;;(setq ebib-citation-commands ;; (quote ((org-mode ((“cite” “\cite{%K}”))))))

;;(require 'mm-url)

;;(defun ebib-import-bibtex (url) (interactive) ;; ;; (with-temp-buffer ;; (mm-url-insert-file-contents url) (ebib-import)))

;; settings for org-ref (setq reftex-default-bibliography '(“~/Reference/Literature.bib”))

;;see org-ref for use of these variables (setq org-ref-bibliography-notes “~/Reference/ReferenceReadingNotes.org” org-ref-default-bibliography '(“~/Reference/Reference.bib”) org-ref-pdf-directory “G:/学术科研/论文”)

(setq bibtex-completion-bibliography “~/Reference/Literature.bib” bibtex-completion-library-path “G:/学术科研/论文” bibtex-completion-notes-path “~/Reference/Literature-manuscript.org”)

(setq org-ref-completion-library 'org-ref-ivy-cite)

(setq org-ref-insert-link-key “C-c ]”)

(org-ref-define-citation-link “citez” ?z) (defun org-ref-cite-link-format (keyword desc format) (cond ((eq format 'html) (format “(%s)” path)) ((eq format 'latex) (concat “\cite” (when desc (format “[%s]” desc)) “{” (mapconcat (lambda (key) key) (org-ref-split-and-strip-string keyword) “,”) “}”))))

(org-add-link-type “cite” 'org-ref-cite-onclick-minibuffer-menu ;; clicking function 'org-ref-cite-link-format) ;; formatting function

;; Tell org-ref to let helm-bibtex find notes for it (setq org-ref-notes-function (lambda (thekey) (let ((bibtex-completion-bibliography (org-ref-find-bibliography))) (bibtex-completion-edit-notes (list (car (org-ref-get-bibtex-key-and-file thekey)))))))

;; open pdf with system pdf viewer (works on mac) (setq bibtex-completion-pdf-open-function 'org-open-file) (setq org-latex-pdf-process (list “latexmk -shell-escape -bibtex -f -pdf %f”))

(defun my/org-ref-open-pdf-at-point () “Open the pdf for bibtex key under point if it exists.” (interactive) (let* ((results (org-ref-get-bibtex-key-and-file)) (key (car results)) (pdf-file (funcall org-ref-get-pdf-filename-function key))) (if (file-exists-p pdf-file) (find-file pdf-file) (message “No PDF found for %s” key))))

(setq org-ref-open-pdf-function 'my/org-ref-open-pdf-at-point)

(require 'org-ref) (require 'org-id) (require 'doi-utils) (require 'org-ref-wos) (require 'org-ref-scopus) (require 'org-ref-pdf)

;;(use-package helm-bibtex :ensure t ;; :bind (“” . helm-bibtex) ;; :commands (helm-bibtex) ;; :init ;; (add-hook 'bibtex-completion-edit-notes 'org-ref-open-bibtex-notes) ;; (setq bibtex-completion-open-any 'org-ref-open-bibtex-pdf) ;; :config ;; (setq bibtex-completion-bibliography “~/Reference/Reference.bib” ;; bibtex-completion-library-path “G:/学术科研/论文” ;; bibtex-completion-notes-path “~/Reference/ReferenceReadingNotes.org”) ;; (setq bibtex-completion-display-formats ;; '((t . "{=type=:7} {year:4} {=has-pdf=:1}{=has-note=:1} {author:30} {title:72} "))) ;; (setq bibtex-completion-additional-search-fields '(keywords)) ;; (setq bibtex-completion-notes-template-one-file ;; (format “\n** TODO {=key=} - {title}\n :PROPERTIES:\n :Author: {author-or-editor}\n ;;:Journal: {journal}\n :end:\n\n”)) ;; (setq bibtex-completion-display-formats ;; '((t . “{author:20} {year:4} {=has-pdf=:3} {=has-note=:1} {=type=:7} {title:90}”))) ;; (setq bibtex-completion-pdf-field “file”) ;; (setq bibtex-completion-pdf-symbol “PDF”) ;; (setq bibtex-completion-notes-symbol “N”) ;; )

;; (setq bibtex-completion-display-formats ;; '((t . “{author:20} {year:4} {=has-pdf=:3} {=has-note=:1} {=type=:7} {title:90}”))) ;; (defun my/org-ref-notes-function (candidates) ;; (let ((key (helm-marked-candidates))) ;; (funcall org-ref-notes-function (car key))))

;; (helm-delete-action-from-source “Edit notes” helm-source-bibtex) ;;; Note that 7 is a magic number of the index where you want to insert the command. You may need to change yours. ;; (helm-add-action-to-source “Edit notes” 'my/org-ref-notes-function helm-source-bibtex 7) )

;;; init.el — Prelude’s configuration entry point. ;; ;; Copyright (c) 2011-2020 Bozhidar Batsov ;; ;; Author: Bozhidar Batsov [email protected] ;; URL: Redirecting… ;; Version: 1.0.0 ;; Keywords: convenience

;; This file is not part of GNU Emacs.

;;; Commentary:

;; This file simply sets up the default load path and requires ;; the various modules defined within Emacs Prelude.

;;; License:

;; This program is free software; you can redistribute it and/or ;; modify it under the terms of the GNU General Public License ;; as published by the Free Software Foundation; either version 3 ;; of the License, or (at your option) any later version. ;; ;; This program is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; ;; You should have received a copy of the GNU General Public License ;; along with GNU Emacs; see the file COPYING. If not, write to the ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, ;; Boston, MA 02110-1301, USA.

;;; Code:

;; Added by Package.el. This must come before configurations of ;; installed packages. Don’t delete this line. If you don’t want it, ;; just comment it out by adding a semicolon to the start of the line. ;; You may delete these explanatory comments. ;(package-initialize)

(defvar current-user (getenv (if (equal system-type 'windows-nt) “USERNAME” “USER”)))

(message “Prelude is powering up… Be patient, Master %s!” current-user)

(when (version< emacs-version “25.1”) (error “Prelude requires GNU Emacs 25.1 or newer, but you’re running %s” emacs-version))

;; Always load newest byte code (setq load-prefer-newer t)

(defvar prelude-dir (file-name-directory load-file-name) “The root dir of the Emacs Prelude distribution.”) (defvar prelude-core-dir (expand-file-name “core” prelude-dir) “The home of Prelude’s core functionality.”) (defvar prelude-modules-dir (expand-file-name “modules” prelude-dir) “This directory houses all of the built-in Prelude modules.”) (defvar prelude-personal-dir (expand-file-name “personal” prelude-dir) "This directory is for your personal configuration.

Users of Emacs Prelude are encouraged to keep their personal configuration changes in this directory. All Emacs Lisp files there are loaded automatically by Prelude.") (defvar prelude-personal-preload-dir (expand-file-name “preload” prelude-personal-dir) “This directory is for your personal configuration, that you want loaded before Prelude.”) (defvar prelude-vendor-dir (expand-file-name “vendor” prelude-dir) “This directory houses packages that are not yet available in ELPA (or MELPA).”) (defvar prelude-savefile-dir (expand-file-name “savefile” prelude-dir) “This folder stores all the automatically generated save/history-files.”) (defvar prelude-modules-file (expand-file-name “prelude-modules.el” prelude-personal-dir) “This file contains a list of modules that will be loaded by Prelude.”) (defvar prelude-deprecated-modules-file (expand-file-name “prelude-modules.el” prelude-dir) (format "This file may contain a list of Prelude modules.

This is DEPRECATED, use %s instead." prelude-modules-file))

(unless (file-exists-p prelude-savefile-dir) (make-directory prelude-savefile-dir))

(defun prelude-add-subfolders-to-load-path (parent-dir) “Add all level PARENT-DIR subdirs to the `load-path’.” (dolist (f (directory-files parent-dir)) (let ((name (expand-file-name f parent-dir))) (when (and (file-directory-p name) (not (string-prefix-p “.” f))) (add-to-list 'load-path name) (prelude-add-subfolders-to-load-path name)))))

;; add Prelude’s directories to Emacs’s `load-path’ (add-to-list 'load-path prelude-core-dir) (add-to-list 'load-path prelude-modules-dir) (add-to-list 'load-path prelude-vendor-dir) (prelude-add-subfolders-to-load-path prelude-vendor-dir)

;; reduce the frequency of garbage collection by making it happen on ;; each 50MB of allocated data (the default is on every 0.76MB) (setq gc-cons-threshold 50000000)

;; warn when opening files bigger than 100MB (setq large-file-warning-threshold 100000000)

;; preload the personal settings from `prelude-personal-preload-dir’ (when (file-exists-p prelude-personal-preload-dir) (message “Loading personal configuration files in %s…” prelude-personal-preload-dir) (mapc 'load (directory-files prelude-personal-preload-dir 't “^[^#.].*el$”)))

(message “Loading Prelude’s core…”)

;; the core stuff (require 'prelude-packages) (require 'prelude-custom) ;; Needs to be loaded before core, editor and ui (require 'prelude-ui) (require 'prelude-core) (require 'prelude-mode) (require 'prelude-editor) (require 'prelude-global-keybindings)

;; macOS specific settings (when (eq system-type 'darwin) (require 'prelude-macos))

;; Linux specific settings (when (eq system-type 'gnu/linux) (require 'prelude-linux))

(message “Loading Prelude’s modules…”)

;; the modules (if (file-exists-p prelude-modules-file) (progn (load prelude-modules-file) (if (file-exists-p prelude-deprecated-modules-file) (message “Loading new modules configuration, ignoring DEPRECATED prelude-module.el”))) (if (file-exists-p prelude-deprecated-modules-file) (progn (load prelude-deprecated-modules-file) (message (format “The use of %s is DEPRECATED! Use %s instead!” prelude-deprecated-modules-file prelude-modules-file))) (message “Missing modules file %s” prelude-modules-file) (message “You can get started by copying the bundled example file from sample/prelude-modules.el”)))

;; config changes made through the customize UI will be stored here (setq custom-file (expand-file-name “custom.el” prelude-personal-dir))

;; load the personal settings (this includes `custom-file’) (when (file-exists-p prelude-personal-dir) (message “Loading personal configuration files in %s…” prelude-personal-dir)

(mapc 'load (delete prelude-modules-file (directory-files prelude-personal-dir 't “^[^#.].*\.el$”))))

(message “Prelude is ready to do thy bidding, Master %s!” current-user)

;; Patch security vulnerability in Emacs versions older than 25.3 (when (version< emacs-version “25.3”) (with-eval-after-load “enriched” (defun enriched-decode-display-prop (start end &optional param) (list start end))))

(prelude-eval-after-init ;; greet the use with some useful tip (run-at-time 5 nil 'prelude-tip-of-the-day))

;;; init.el ends here

好的,我试试,谢谢!

挖坟回复一下。

感觉你的笔记需求可以部分地用我写的包 xray满足,欢迎尝试 :slight_smile:

支持epub吗?跟org-noter有什么区别?

不支持epub。因为我基本不看epub格式的文档,就没考虑。

xray更像是主题索引(名字就来自kindle的xray功能),可以快速找到同一主题在一个文档或者多个文档中出现的位置,顺带着还可以记笔记。

2 个赞

挖坟回复一下,最近的一些方案更新:

  1. org-ref → org 9.5 自带的 org-cite,主要是 org-ref 太重了,然后我只需要 cite,follow 两项功能(结合 bibtex-action 中的 oc-bibtex-actions)

  2. zotero → ebib,主要是因为我最近发现我实在懒得在 Emacs 整理完笔记之后又出去在 zotero 整理我的论文,而且 better bibtex 自动后台导出 bib 也经常出问题。我宁愿加入 entries 的时候慢点,也想都在 Emacs 中管理。然后 bibtex 可以参照 org-ref 这个 pull request 的方式获取,只要 zotero translator 支持即可

  3. ivy → vertigo 系列,然后 helm-bibtex 或者 ivy-bibtex 这些就换成了 bibtex-action

相关更新可以看我配置最近的几个 commit

4 个赞

原来还有Zotero Translators这种东西,之前没换掉org-ref纯粹是因为doi-utils强制依赖org-ref。。

总算见到一个用ebib的同道。明明ebib很好用,但不知为何用的人不多。而且作者字面意义的几十年如一日维护这个包,简直不能再良心。

唯一我发现不太好用的地方是保存和读取大的bib文件有些卡顿,但这可能是用文本文件储存数据本身存在的问题。我想bib文件要是能储存在sql数据库里面,需要的时候再导出就好了。

这两天在折腾类似的东西,想把 zotero 和 org-roam 整合起来,弄了 org-roam-bibtex 进去

折腾的如何了?有经验分享一下吧 :grinning:

zotero+ebib+consult-bibtex+eaf-pdf-viewer+org-roam+org-roam-bibtex

有办法可以将 zotero 中的笔记(也就是保存到 bibtex 中的笔记)导出到 org 么

请问能把zotero和org-roam整合了吗?

有没有可能出一个小白教程?我看了大虾在知乎的介绍,但是仍然不会配置,多谢!

不会配置的是啥?问题太宽泛无从下手。

感谢!我在知乎中仔细拜读了您写的关于org-roam还有all-in-one的帖子。 在搜索引擎中,我发现您写了很多关于emacs阅读文献,记录笔记的教程。我觉得您的这个流程,正是我所需要的样子。所以非常欣喜,决心照着您的教程学习配置,所以我把您写的所有教程都看了一遍。 但是我仔细多次阅读以后,发现您的教程都是写给Emacs高手的(实际上阅读您所有的教程,都是觉得哇,这个功能真好!但是却无法学会。)。我估计他们看了以后,一定能从中得到启发。 但是因为我是刚入门的小白,我读了以后却是完全无从下手,只知道您用了这个包,但是怎么配置不知道。去您的Github看您的配置,又无法看懂。 我发现您在12月6日又写了一个比较详细的教程: 如何有效利用传统和现代工具进行科研文献的阅读?。非常感谢。

我盼望您在写这个教程时候,能够把读者当成是一个初学的小白。每当介绍一个包时候,都帮忙说明一下,如何安装这个包,有什么需要注意之处。这个包在配置的时候应该怎样配置,如果能简要介绍一下为什么需要这么配置就更好了。另外介绍一下,这个包应该怎么使用,因为语言障碍,很多人可能无法直接阅读理解包内置的说明。 “请看我的配置文件”,我当我读到这句话,我就只能苦笑一下,因为作为一个小白,实在没有能力看懂您的配置文件。

非常感谢您写的这些教程,多谢!

这是我的 org-roam 配置,不需要理解,只需要你安装好 org-roam 和 org-roam-ui,学会开头几行设置的几个快捷键就可以了。

我目前也就用了C-c n f C-c n i C-c n a C-c n t 和 org-roam-ui-open 的 C-c G 五个快捷键。

新手最重要的是先用起来再去理解。安装好插件之后,先抄能把插件功能跑起来的那部分代码。不要把事情搞复杂,想着一次性配置完美。

我短短几个月重新写了两遍配置,理解代码真的很痛苦。

我的建议就是:先用起来,等功能不够了再改配置。

;; org-roam: basic config
;; {{{
(use-package org-roam
  :ensure t
  :defer t ;; autoload
  :bind (
         ("C-c n a" . org-roam-alias-add)
         ("C-c n c" . org-roam-capture)
         ("C-c n f" . org-roam-node-find)
         ("C-c n g" . org-roam-graph)
         ("C-c n i" . org-roam-node-insert)
         ("C-c n j" . org-roam-dailies-capture-today) ;; Dailies
         ("C-c n l" . org-roam-buffer-toggle)
         ("C-c n t" . org-roam-tag-add)
         )
  :config
  (setq org-roam-directory "~/org-roam")
  (setq org-roam-db-location "~/org-roam/org-roam.db")
  (setq org-roam-file-extensions '("org" "md")) ;; enable Org-roam for markdown
  (require 'org-roam-protocol)                  ;; org-roam-protocol
  (org-roam-db-autosync-mode 1) ;; if md-roam installed, move to md-roam config
  )
;; }}}

;; org-roam: backlink count & node hierarchy
;; {{{
;; https://github.com/Jousimies/.emacs.d/blob/master/lisp/init-roam.el
(require 'org)
(require 'org-roam)
;;
(cl-defmethod org-roam-node-directories ((node org-roam-node))
  (if-let ((dirs (file-name-directory (file-relative-name (org-roam-node-file node) org-roam-directory))))
      (format "(%s)" (car (split-string dirs "/")))
    ""))
;;
(cl-defmethod org-roam-node-backlinkscount ((node org-roam-node))
  (let* ((count (caar (org-roam-db-query
                       [:select (funcall count source)
                                :from links
                                :where (= dest $s1)
                                :and (= type "id")]
                       (org-roam-node-id node)))))
    (format "[%d]" count)))
;;
(cl-defmethod org-roam-node-hierarchy ((node org-roam-node))
  (let ((level (org-roam-node-level node)))
    (concat
     (when (> level 0) (concat (org-roam-node-file-title node) " > "))
     (when (> level 1) (concat (string-join (org-roam-node-olp node) " > ") " > "))
     (org-roam-node-title node))))
;;
(setq org-roam-node-display-template
      "${title:50} ${hierarchy:*} ${backlinkscount:6} ${tags:50} ${directories:10}")
;;
;; (setq org-roam-node-display-template (concat
;;                                    "${type:8} ${backlinkscount:3} ${hierarchy:*}"
;;                                   (propertize "${tags:20}" 'face 'org-tag) " "))
;;
;; (setq org-roam-node-display-template "${hierarchy:*} ${tags:20}")
;;
;; (setq org-roam-node-display-template
;;       (concat "${title:*} "
;;               (propertize "${tags:10}" 'face 'org-tag)
;;               ))
;; }}}

;; org-roam: completion
;; {{{
(setq org-roam-completion-everywhere t)
;;roam links support auto-completion via completion-at-point
;; call M-x completion-at-point within a roam link.
;; Where the | character represents the cursor:
;; [[|]] : completes for a file title
;; [[roam:]] : completes for a file title
;; [[*|]] : completes for a headline within this file
;; [[foo*|]] : completes a headline within the file with title “foo”
;; [[roam:foo*|]] completes a headline within the file with title “foo”
;; }}}

;; org-roam: slug (called by org-roam-capture-templates)
;; {{{
;; (cl-defmethod org-roam-node-slug ((node org-roam-node))
;;   "Return the slug of NODE."
;;   (let ((title (org-roam-node-title node))
;;         (slug-trim-chars '(;; Combining Diacritical Marks https://www.unicode.org/charts/PDF/U0300.pdf
;;                            768 ; U+0300 COMBINING GRAVE ACCENT
;;                            769 ; U+0301 COMBINING ACUTE ACCENT
;;                            770 ; U+0302 COMBINING CIRCUMFLEX ACCENT
;;                            771 ; U+0303 COMBINING TILDE
;;                            772 ; U+0304 COMBINING MACRON
;;                            774 ; U+0306 COMBINING BREVE
;;                            775 ; U+0307 COMBINING DOT ABOVE
;;                            776 ; U+0308 COMBINING DIAERESIS
;;                            777 ; U+0309 COMBINING HOOK ABOVE
;;                            778 ; U+030A COMBINING RING ABOVE
;;                            780 ; U+030C COMBINING CARON
;;                            795 ; U+031B COMBINING HORN
;;                            803 ; U+0323 COMBINING DOT BELOW
;;                            804 ; U+0324 COMBINING DIAERESIS BELOW
;;                            805 ; U+0325 COMBINING RING BELOW
;;                            807 ; U+0327 COMBINING CEDILLA
;;                            813 ; U+032D COMBINING CIRCUMFLEX ACCENT BELOW
;;                            814 ; U+032E COMBINING BREVE BELOW
;;                            816 ; U+0330 COMBINING TILDE BELOW
;;                            817 ; U+0331 COMBINING MACRON BELOW
;;                            )))
;;     (cl-flet* ((nonspacing-mark-p (char)
;;                                   (memq char slug-trim-chars))
;;                (strip-nonspacing-marks (s)
;;                                        (ucs-normalize-NFC-string
;;                                         (apply #'string (seq-remove #'nonspacing-mark-p
;;                                                                     (ucs-normalize-NFD-string s)))))
;;                (cl-replace (title pair)
;;                            (replace-regexp-in-string (car pair) (cdr pair) title)))
;;       (let* ((pairs `(("[^[:alnum:][:digit:]]" . "-") ;; convert anything not alphanumeric
;;                       ("--*" . "-")                   ;; remove sequential underscores
;;                       ("^-" . "")                     ;; remove starting underscore
;;                       ("-$" . "")))                   ;; remove ending underscore
;;              (slug (-reduce-from #'cl-replace (strip-nonspacing-marks title) pairs)))
;;         (downcase slug)))))
;; }}}

;; org-roam: filter tags
;; {{{
(defun my/org-roam-filter-by-tag (tag-name)
  (lambda (node)
    (member tag-name (org-roam-node-tags node))))

(defun my/org-roam-list-notes-by-tag (tag-name)
  (mapcar #'org-roam-node-file
          (seq-filter
           (my/org-roam-filter-by-tag tag-name)
           (org-roam-node-list))))
;; }}}

;; org-roam: search tag
;; {{{
(defun my/org-roam-node-find-by-tag ()
  (interactive)
  (let ((chosen-tag
         (completing-read "filter by tag: "
                          (seq-uniq
                           (org-roam-db-query
                            [:select [tag]
                                     :from tags ])))))
    (org-roam-node-find
     nil
     nil
     (lambda (node) (member chosen-tag (org-roam-node-tags node))))))
;; }}}

;; org-roam: template,  id (uuid) timestamps and so on
;; {{{
(setq org-roam-capture-templates
      '(
	;; #+date: %<%Y-%m-%d-%H:%M:%S %Z>\n
	;; #+date: %<%FT%T%z>\n
        ;; a: audio & music
        ;; b: book
        ("b" "图书" plain "%?"
         :target (file+head "图书/${title}.org"
                            "#+title: ${title}\n#+date: %<%FT%T%z>\n#+category:\n#+filetags: \n")
         :immediate-finish t
         :unnarrowed  t)
        ("bz" "Z综合性图书" plain "%?"
         :target (file+head "图书/Z综合性图书/${title}.org"
                            "#+title: ${title}\n#+date: %<%FT%T%z>\n#+category:\n#+filetags: \n")
         :immediate-finish t
         :unnarrowed  t)
        ;; c:
        ("d" "default" plain "%?"
         :target (file+head "${slug}.org"
                            "#+title: ${title}\n#+date: %<%FT%T%z>\n#+category:\n#+filetags:\n")
         :empty-lines 1
         :immediate-finish t
         :unnarrowed  t)
        ("e" "Emacs" plain "%?"
         :target (file+head "Emacs/${slug}.org"
                            "#+title: ${title}\n#+date: %<%FT%T%z>\n#+category:\n#+filetags: \n")
         :immediate-finish t
         :unnarrowed  t)
        ;; f:
        ("f" "Emacs Function" plain "%?"
         :target (file+head "Emacs/function/${slug}.org"
                            "#+title: ${title}\n#+date: %<%FT%T%z>\n#+category:\n#+filetags: \n")
         :immediate-finish t
         :unnarrowed  t)
        ;; g:
        ;; h: human
        ;; i:
        ;; j:
        ;; k:
        ;; l:
        ;; m:
        ;; n:
        ;; o:
        ;; p: project
        ("p" "project" plain "%?"
         :target (file+head "${slug}.org"
                            "#+title: ${title}\n#+date: %<%FT%T%z>\n")
         :immediate-finish t
         :unnarrowed t)
        ("P" "Emacs 包/插件" plain "%?"
         :target (file+head "Emacs/package/${title}.org"
                            "#+title: ${title}\n#+date: %<%FT%T%z>\n#+filetags: :Emacs:\n")
         :immediate-finish t
         :unnarrowed t)
        ;; q:
        ("r" "reference" plain "%?"
         :target (file+head "reference/${title}-%<%FT%T%z>.org"
                            "#+title: ${title}\n#+date: %<%FT%T%z>\n")
         :unnarrowed t)
        ;; s:
        ("s" "软件" plain "%?"
         :target (file+head "software/${slug}.org"
                            "#+title: ${title}\n#+date: %<%FT%T%z>\n")
         :immediate-finish t
         :unnarrowed t)
        ;; t: topic todo
        ("t" "主题" plain "%?"
         :target (file+head "topics/${slug}.org"
                            "#+title: ${title}\n#+date: %<%FT%T%z>\n")
         :immediate-finish t
         :unnarrowed t)
        ;; u:
        ;; v:
        ("v" "Emacs 变量" plain "%?"
         :target (file+head "Emacs/variable/${slug}.org"
                            "#+title: ${title}\n#+date: %<%FT%T%z>\n")
         :immediate-finish t
         :unnarrowed t)
        ;; w:
        ;; x:
        ;; y:
        ;; z:
        ))
;; }}}

;; org-roam: UI
;; {{{
;; (custom-set-faces
;;   '((org-roam-link org-roam-link-current)
;;     :foreground "#e24888" :underline t))
;;
;; (defface my-org-id-link '((t :inherit org-link :slant italic))
;;   "Face for org-id links."
;;   :group 'org-faces)
;; }}}

;; little hack
;; {{{
;; brew install --cask db-browser-for-sqlite
(defun my/org-roam-view-db ()
  (interactive)
  (cond
   ((eq system-type 'darwin)
    (shell-command
     ;; net.sourceforge.sqlitebrowser
     (format "open \"/Applications/DB Browser for SQLite.app\" --args --table nodes %s" org-roam-db-location)))
   (t
    (message "my/org-roam-view-db not yet working on this system-type"))))
;; }}}

;; org-roam-ui
;; {{{
(use-package org-roam-ui
  :after org-roam
  ;; normally we'd recommend hooking orui after org-roam, but since org-roam does not have
  ;; a hookable mode anymore, you're advised to pick something yourself
  ;; if you don't care about startup time, use
  ;; :hook (after-init . org-roam-ui-mode)
  :bind (("C-c G" . org-roam-ui-open)
         )
  :config
  (setq org-roam-ui-sync-theme t
        org-roam-ui-follow t
        org-roam-ui-update-on-save t
        org-roam-ui-open-on-start t)
  )
;; }}}
1 个赞

非常感谢!! :grinning: