Org-roam
概要
Memo
db関連がおかしくなったとき
dbへ書き込みできませんエラーが出たとき。
(org-roam-db-location)
でDBが保存されているパスを調べる。- .dbファイルを削除。
(org-roam-db-clear-all)
でキャッシュ削除。(org-roam-db-sync)
によってdbファイルを再作成。
Selecting deleted buffer
が出るとき。
- ライブラリをすべて削除してインストールし直す
- emacsql-sqliteを保存しているディレクトリに行く。sqliteディレクトリ下でmakeしなおす
- make clean && make emacsql-sqlite
バックエンドの違いを吸収する関数
いわゆるコネクターパターン。接続に使用する関数を返す関数。
https://github.com/kd-collective/org-roam/blob/abe63b436035049923ae96639b9b856697047779/org-roam-db.el#L123-L137
(defun org-roam-db–conn-fn () “Return the function for creating the database connection.” (cl-case org-roam-database-connector (sqlite (progn (require ’emacsql-sqlite) #’emacsql-sqlite)) (libsqlite3 (progn (require ’emacsql-libsqlite3) #’emacsql-libsqlite3)) (sqlite3 (progn (require ’emacsql-sqlite3) #’emacsql-sqlite3))))
References
🖊知的生産のキラーアプリOrg-roamを1年使い倒し学ぶとはなにか考えたポエム(2022) | Futurismo
ZettelkastenやOrg-roamの解説。
Org-roam User Manual
マニュアル。
Org mode 教室 その9: org-roam でアイデアをひねり出す
具体的なワークフローがわかりやすい。
https://blog.jethro.dev/posts/introducing_org_roam/
作者サイトのマニュアル。
https://blog.jethro.dev/posts/org_mode_workflow_preview/
org-modeのワークフロー。
Archives
CLOSE CI, sqliteを入れて試してみる
- search emacsql
Default install sqlite on ubuntu, so does not matter.
DONE 基本的キーバインド
- find(C-c n f)
- バックリンク(C-c n l)
- Roamリンク挿入(C-c n i)補完を有効にすることであまり使わなくなる。
DONE idリンクをpublishできない問題
roamのidがhtmlに変換できないよう。
Unable to resolve link
になる。
(setq org-hugo-base-dir ".") (setq org-export-with-broken-links t)
するとできるが、idリンクを辿れない。 ほかのサイトではidがあってもできてるように見える。 https://hugocisneros.com/blog/my-org-roam-notes-workflow/ orgのバージョンを最新にしたが変わらず。
公式で言及。 https://github.com/org-roam/org-roam/wiki/Hitchhiker's-Rough-Guide-to-Org-roam-V2#export
(setq org-id-link-to-org-use-id t) (setq org-id-extra-files (org-roam--list-files org-roam-directory))
↓で設定していた。これを設定すると成功した。 https://hugocisneros.com/org-config/#configuration
https://gist.github.com/hugcis/1f2d2ad4b98b07ee543f10232ba1b025
(require 'find-lisp) (defun hugcis/publish-note (file) "Publish a note in FILE." (interactive) (with-current-buffer (find-file-noselect file) (projectile-mode -1) (setq org-hugo-section "notes" org-hugo-base-dir "." citeproc-org-org-bib-header "* Bibliography\n<ol class=\"biblio-list\">" citeproc-org-org-bib-footer "</ol>") (let ((org-id-extra-files (find-lisp-find-files org-roam-directory "\.org$"))) (org-hugo-export-wim-to-md))))
find . -name '*.org' | emacs --batch -l ./publish.el --funcall kd/publish
DONE 初期設定
⚠バージョンが上がって設定が変わった。この内容は古い。 roamのデフォルトディレクトリを作成して、そこでファイルが作成されたり、検索対象になる。
(require 'org-roam) (add-hook 'after-init-hook 'org-roam-mode) (make-directory "~/roam" t) (setq org-roam-directory "~/roam")
(setq org-roam-completion-everywhere t) (define-key org-mode-map (kbd "C-M-i") 'completion-at-point)
リンク補完が有効になります。非常に便利。
(define-key org-roam-mode-map (kbd "C-c n l") 'org-roam) (define-key org-roam-mode-map (kbd "C-c n f") 'org-roam-find-file) (define-key org-roam-mode-map (kbd "C-c n g") 'org-roam-graph) (define-key org-mode-map (kbd "C-c n i") 'org-roam-insert) (define-key org-mode-map (kbd "C-c n I") 'org-roam-insert-immediate)
DONE 外部リンクをグラフに表示したくない
org-roam-graph
でファイルリンクだけのつながりを表示したい。
v1ではファイルリンクだけで、外部リンクは出てなくてわかりやすかった。
org-roam-uiを使ってみた。めちゃかっこいい。
org-roam-graph-link-hidden-types でhttp, httpsを指定すると消せた。 これでCIでも出力できるはず。
(setq org-roam-graph-link-hidden-types '("https" "http" "file"))
DONE d3でのグラフ出力
- org-roam-db-syncでdbファイルを生成する
- dbファイルをグラフとしてjsonに変換する
- JavaScriptのd3ライブラリでjsonを読み込む
- ブラウザ描画
CLOSE Selecting deleted bufferエラー
新しく構築した環境にて、 (org-roam-db-sync)
をやると Selecting deleted buffer
がエラーが出る。
依存しているemacs-sqlite関係でなにかおかしくなっているよう。同じくemacs-sqliteに依存しているmagit-forgeも動かない。
メインマシン、GitHub Actions環境ではうまくいっているので、sqlite関係か、.emacs.dで何か起きている。 うまくいくようになった。関連ライブラリが修正されたよう。
DONE dbを使って何をしているのか DontKnow
デフォルトではsqliteを利用しているのは知っているが、実際何をしているのだろうか。結論: ファイルの変更をdbに同期し、再利用しやすいようにしている。
まずorg-roam-db.elを見てみる。
https://github.com/kd-collective/org-roam/blob/abe63b436035049923ae96639b9b856697047779/org-roam-db.el#L279-L288
;;; Database API ;;;; Clearing (defun org-roam-db-clear-all () “Clears all entries in the Org-roam cache.” (interactive) (when (file-exists-p org-roam-db-location) (dolist (table (mapcar #’car org-roam-db–table-schemata)) (org-roam-db-query `[:delete :from ,table]))))
(defun org-roam-db-clear-file (&optional file)
https://github.com/kd-collective/org-roam/blob/abe63b436035049923ae96639b9b856697047779/org-roam-db.el#L309-L323
(defun org-roam-db-insert-file () “Update the files table for the current buffer. If UPDATE-P is non-nil, first remove the file in the database.” (let* ((file (buffer-file-name)) (file-title (org-roam-db–file-title)) (attr (file-attributes file)) (atime (file-attribute-access-time attr)) (mtime (file-attribute-modification-time attr)) (hash (org-roam-db–file-hash))) (org-roam-db-query [:insert :into files :values $v1] (list (vector file file-title hash atime mtime)))))
(defun org-roam-db-get-scheduled-time ()
org-roam-db-insert-fileが呼ばれることによって、orgファイルの追加をdbと同期する。こういった感じで1ファイルの追加、削除、変更に対応する同期関数がある。
↑のみでは1ファイルのみなので、org-roamファイル全体に大して同期をかける関数がある。org-roam-db-sync。変更のタイプを判定して、各関数で処理し、orgファイルとdbの内容を同期する。なるほど。
https://github.com/kd-collective/org-roam/blob/abe63b436035049923ae96639b9b856697047779/org-roam-db.el#L611-L643
(defun org-roam-db-sync (&optional force) “Synchronize the cache state with the current Org files on-disk. If FORCE, force a rebuild of the cache from scratch.” (interactive “P”) (org-roam-db–close) ;; Force a reconnect (when force (delete-file org-roam-db-location)) (org-roam-db) ;; To initialize the database, no-op if already initialized (org-roam-require ’(org-ref oc)) (let* ((gc-cons-threshold org-roam-db-gc-threshold) (org-agenda-files nil) (org-roam-files (org-roam-list-files)) (current-files (org-roam-db–get-current-files)) (modified-files nil)) (dolist (file org-roam-files) (let ((contents-hash (org-roam-db–file-hash file))) (unless (string= (gethash file current-files) contents-hash) (push file modified-files))) (remhash file current-files)) (emacsql-with-transaction (org-roam-db) (org-roam-dolist-with-progress (file (hash-table-keys current-files)) “Clearing removed files…” (org-roam-db-clear-file file)) (org-roam-dolist-with-progress (file modified-files) “Processing modified files…” (condition-case err (org-roam-db-update-file file ’no-require) (error (org-roam-db-clear-file file) (lwarn ’org-roam :error “Failed to process %s with error %s, skipping…” file (error-message-string err))))))))
;;;###autoload
直にdbに追加する関数を呼ぶことはなく、ファイルの変更をもとに同期関数経由でdbに追加されるようだ。ファイルの方が先に存在していて、後でdbと同期する。
https://github.com/kd-collective/org-roam/blob/abe63b436035049923ae96639b9b856697047779/org-roam-node.el#L461-L477
;;;###autoload (cl-defun org-roam-node-find (&optional other-window initial-input filter-fn &key templates) “Find and open an Org-roam node by its title or alias. INITIAL-INPUT is the initial input for the prompt. FILTER-FN is a function to filter out nodes: it takes an `org-roam-node’, and when nil is returned the node will be filtered out. If OTHER-WINDOW, visit the NODE in another window. The TEMPLATES, if provided, override the list of capture templates (see `org-roam-capture-’.)” (interactive current-prefix-arg) (let ((node (org-roam-node-read initial-input filter-fn))) (if (org-roam-node-file node) (org-roam-node-visit node other-window) (org-roam-capture- :node node :templates templates :props ’(:finalize find-file)))))
- ファイルがあれば、visitを呼び出す
- ファイルがなければ、作成するためにcaptureを呼び出す。dbと関係することは同期時にやるので、ここでは一切考えなくてよく、責務分離できている
dbへの同期をみた。利用はどうしているのだろうか。
探す系は、org-roam-node.elに含まれている。
https://github.com/kd-collective/org-roam/blob/abe63b436035049923ae96639b9b856697047779/org-roam-node.el#L461-L477
;;;###autoload (cl-defun org-roam-node-find (&optional other-window initial-input filter-fn &key templates) “Find and open an Org-roam node by its title or alias. INITIAL-INPUT is the initial input for the prompt. FILTER-FN is a function to filter out nodes: it takes an `org-roam-node’, and when nil is returned the node will be filtered out. If OTHER-WINDOW, visit the NODE in another window. The TEMPLATES, if provided, override the list of capture templates (see `org-roam-capture-’.)” (interactive current-prefix-arg) (let ((node (org-roam-node-read initial-input filter-fn))) (if (org-roam-node-file node) (org-roam-node-visit node other-window) (org-roam-capture- :node node :templates templates :props ’(:finalize find-file)))))
- nodeが存在していればファイルを開く。そうでなければorg-roam-captureでテンプレート画面を開く
- 開くときもdbに接続して情報を取ってくるはずだが、コードのどの箇所かわからなかった
DONE メモのとり方について再考
- denoteとroamの使い分けが微妙
- 1つの見出しが1つのファイルに属するとは限らない
- 文章としてあまり読みやすいものではない
Footnotes:
https://roamresearch.com/ Webでのアウトラインツール。