Open14

SpacemacsとObsidianの融合

雪下雪下

用語

Spacemacs: スペースキーを中心とした、記憶しやすく検索性が高く一貫性のあるキーバインドを特徴とするEmacsディストリビューション。

PKM: Personal Knowledge Management. 個人が得た情報、知識、経験を整理し次の知的生産に使えるようにしておくこと。ツールとして、Roam Research, Obsidian, Notionなどがある。

目的

このスクラップでは「Spacemacs上にObsidianを再現する」ことを目標に環境構築を進めていきます。

要件

  • EmacsでもObsidianでも編集でき、一方で編集したことが他方にも反映される
  • どちらでも同じbacklinkが追える、同じグラフビューが見られる

動機

スクラップ主はObsidianを気に入り、勉強に使っていました。<iframe>を使うことでYouTubeを見ることもできました。しかし人間は欲張りなもので、Obsidianだとターミナルが使えない、ブラウザが見られない、プログラミングできない、といったことが気になるようになりました。
Emacsならそれらが全て解決できます。ターミナルもあるしブラウザもあるしプログラミングもできます。Obsidianと同じことがEmacs上で再現できればいよいよ永住可能な最強PKM環境ができるのです。
幸い、org-roamを用いることで実現できそうでした。しかしこれはorg-modeの拡張機能であり、orgファイルを前提としています。そうすると折角整理した情報にスマホからアクセスするのは難しくなってしまいます。Obsidianは近々モバイル版が出るはずなので、Obsidianならスマホでも見られるようになります。
求めているのはPCでの快適な編集とモバイルからの参照。org-roamではPCでの編集は理想的でもモバイルから見にくいです。一方のObsidianはモバイル版が出てもPCでの永住環境は作れません。これを解決するのがmd-roamというorg-roamの機能をmarkdownにまで拡張するEmacs拡張機能です。
org-roam, md-roamとの出会いを経て、EmacsとObsidianの融合という夢を実現する道筋が見えてきました。

使用予定のEmacs拡張機能

備考

なお、環境はMac OS前提です。Windowsで同じことをできた方がいらっしゃればやり方を投稿してくださると幸いです。

雪下雪下

ブラウザ付きSpacemacs環境構築

手順

  1. Homebrewでemacs-plus@28を入れる
  2. spacemacsを導入
  3. .spacemacsを編集

Homebrewでemacs-plus@28を入れる

d12frosted/homebrew-emacs-plus

を使う。

brew tap d12frosted/emacs-plus
brew install emacs-plus@28 --with-xwidgets --with-modern-black-dragon-icon
ln -s /usr/local/opt/emacs-plus@28/Emacs.app /Applications

—with-xwidgetsがブラウザを入れるのに必要。iconは好きなものにするといい。

3行目はEmacsをMacのアプリとしてTerminalと独立に起動するため。

※ブラウザが必要ない場合は

railwaycat/homebrew-emacsmacport

がMacのアプリとして使いやすいようEmacsを設定してくれる。xwidgets入りのビルドがまだできないようなので、今後対応されることに期待。

Spacemacsの導入

Spacemacs: Emacs advanced Kit focused on Evil

ホームディレクトリで以下のコマンドを実行。

git clone https://github.com/syl20bnr/spacemacs ~/.emacs.d

emacsを開き、初期設定。Vim→Spacemacsで。

.spacemacsの編集

初期設定が終わり、.spacemacsが作成されているのでこれを編集していく。

雪下雪下

以下は同じファイル群のネットワークをグラフ化したものである(PDFなどのファイルが含まれるかどうかで少し違っている)。
ObsidianでもGroupを用いることで色は付けられるようだ。

org-roam serverでのグラフ

Obsidianでのグラフ

雪下雪下

.spacemacsの編集

layer

dotspacemacs-configuration-layersにorg-layerの設定を追記。org-enable-roam-supportをt (true)にする。

dotspacemacs-configuration-layers
'(
  (org :variables
    org-enable-roam-support t)
)

additional packages

dotspacemacs-additional-packagesにorg-roam-serverを追記。

dotspacemacs-additional-packages
'(
     org-roam-server
)

dotspacemacs/user-init()

md-roamのGitHubからmd-roam.elを落としてきて、user-init()に加える。

(defun dotspacemacs/user-init ()
  "Initialization for user code:
This function is called immediately after `dotspacemacs/init', before layer
configuration.
It is mostly for variables that should be set before packages are loaded.
If you are unsure, try setting them in `dotspacemacs/user-config' first."
  ;; md-roam
  (add-to-list 'load-path "~/.emacs.d/md-roam/") ;Modify with your own path
  (require 'md-roam) ;this must be before org-roam
  )

dotspacemacs/user-config()

(defun dotspacemacs/user-config ()
  "Configuration for user code:
This function is called at the very end of Spacemacs startup, after layer
configuration.
Put your configuration code here, except for variables that should be set
before packages are loaded."

  ;; orgまわり
  ;; 全体のディレクトリ指定
  (setq org-directory "/Users/ユーザー名/Library/Mobile Documents/com~apple~CloudDocs/org-mode")

  ;; リンクを同じウインドウで開く
  (setq org-link-frame-setup '((file . find-file)))

  ;; org-downloadの保存先
  (setq org-download-image-dir "/Users/ユーザー名/Library/Mobile Documents/com~apple~CloudDocs/org-mode/images")

  ;; 画像サイズ
  (setq org-image-actual-width '(400))

  ;; org-agendaとcapture see https://maskaw.hatenablog.com/entry/2018/09/21/205910
  (setq org-todo-keywords
        '((sequence "TODO(t)" "WAIT(w)" "REMIND(r)" "|" "DONE(d)" "SOMEDAY(s)" "CANCEL(c)")))
  (setq org-log-done 'time)
  (setq org-agenda-files '(
                           "/Users/ユーザー名/Library/Mobile Documents/com~apple~CloudDocs/org-mode/roam/task/"
                           "/Users/ユーザー名/Library/Mobile Documents/com~apple~CloudDocs/org-mode/roam/daily/"
                           "/Users/ユーザー名/Library/Mobile Documents/com~apple~CloudDocs/org-mode/remind.org"
                           "/Users/ユーザー名/Library/Mobile Documents/com~apple~CloudDocs/org-mode/knowledge.org"))
  (setq org-capture-templates
        '(("t" "Todo" entry (file+headline "/Users/ユーザー名/Library/Mobile Documents/com~apple~CloudDocs/org-mode/remind.org" "★Capture") "* REMIND %? (wrote on %U)")
          ("k" "Knowledge" entry (file+headline "/Users/ユーザー名/Library/Mobile Documents/com~apple~CloudDocs/org-mode/knowledge.org" "TOP") "* %?\n # Wrote on %U")))

  ;; org-roam
  (setq org-roam-db-update-method 'immediate)
  (setq org-roam-db-location "~/.emacs.d/org-roam.db")
  (setq org-roam-directory "/Users/ユーザー名/Library/Mobile Documents/com~apple~CloudDocs/org-mode/roam/")
  (setq org-roam-index-file "/Users/ユーザー名/Library/Mobile Documents/com~apple~CloudDocs/org-mode/roam/Index.org")
  (setq org-roam-dailies-directory "/Users/ユーザー名/Library/Mobile Documents/com~apple~CloudDocs/org-mode/roam/daily/")
  ;; init時にdbを更新
  (add-hook 'emacs-startup-hook 'org-roam-mode)
  (add-hook 'after-init-hook 'org-roam-db-build-cache)

    ;; md-roam
  (setq md-roam-file-extension-single "md")
  (setq org-roam-title-sources '((mdtitle title mdheadline headline) (mdalias alias)))
  (setq org-roam-file-extensions '("org" "md"))
  ;; tag support
  (setq org-roam-tag-sources '(md-frontmatter))
  ;; Disable Org-roam file link for Markdown files for performance.
  (setq md-roam-use-org-file-links nil) ; default is t
  ;; Enable backlinks with using Markdown link syntax [description](path/to/file.ext)
  (setq md-roam-use-markdown-file-links t) ; default is nil
  ;; (setq org-roam-link-auto-replace nil)

    ;; org-roam-server
  (setq org-roam-server-host "127.0.0.1"
        org-roam-server-port 8080
        org-roam-server-authenticate nil
        org-roam-server-export-inline-images t
        org-roam-server-serve-files nil
        org-roam-server-served-file-extensions '("pdf" "mp4" "ogv")
        org-roam-server-network-poll t
        org-roam-server-network-arrows nil
        org-roam-server-network-label-truncate t
        org-roam-server-network-label-truncate-length 60
        org-roam-server-network-label-wrap-length 20)
  ;; org終わり
雪下雪下

user-config()の追記。
markdownの時もサイズ調整をした方がよい。

(setq markdown-max-image-size '(400 . 800))

などとする。

雪下雪下

org-roam-serverがSpacemacsのOrg Layerに反映されたので、additional packagesではなくlayerのところを

dotspacemacs-configuration-layers
'(
  (org :variables
    org-enable-roam-support t
    org-enable-roam-server t
)
)

にする。

雪下雪下

MobileOrg
PCのorg-fileをスマホから参照したりメモを追加することができる。
org-roamを使う場合ファイル数が多くなるがしっかり動くだろうか。

Cj BC_SDCj BC_SD

もしもiPhone/iPadであれば、beorgというサードパーティ製のアプリケーションもあります
MobileOrgは公式の機能ですが特殊なフォーマットに書き出す必要があり、それに対してbeorgはorg文書のまま扱えるので個人的には使いやすさを感じています
私は最初からbeorgにしていたのでmobileOrgとの比較はできませんが、UIも機能も豊富なのでおすすめです!(schemeで色々カスタマイズもできます)

雪下雪下

ObsidianがMobile対応しているので

  1. Emacsでノートテイキングをしたい
  2. スマートフォンからも見たい
  3. org形式にはこだわらない

という人にはかなりおすすめかも