mirror of
https://github.com/org-roam/org-roam
synced 2025-08-01 12:17:21 -05:00
Become deft-free 🎉
This commit is contained in:
29
README.md
29
README.md
@ -34,31 +34,14 @@ used to navigate to the respective files.
|
|||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
You should first have [deft](https://jblevins.org/projects/deft/)
|
The recommended method is using
|
||||||
setup properly. This is only necessary now, and I intend to move away
|
[use-package](https://github.com/jwiegley/use-package) and
|
||||||
from it once it becomes clearer what org-roam should be presenting.
|
|
||||||
|
|
||||||
```
|
|
||||||
(use-package deft
|
|
||||||
:after org
|
|
||||||
:bind
|
|
||||||
("C-c n d" . deft)
|
|
||||||
:custom
|
|
||||||
(deft-recursive t)
|
|
||||||
(deft-use-filter-string-for-filename t)
|
|
||||||
(deft-default-extension "org")
|
|
||||||
(deft-directory "~/org-files/")
|
|
||||||
(deft-use-filename-as-title t))
|
|
||||||
```
|
|
||||||
|
|
||||||
You can then setup org-roam as follows. The recommended method is
|
|
||||||
using [use-package](https://github.com/jwiegley/use-package) and
|
|
||||||
[straight](https://github.com/raxod502/straight.el), or a similar
|
[straight](https://github.com/raxod502/straight.el), or a similar
|
||||||
package manager.
|
package manager.
|
||||||
|
|
||||||
```
|
```
|
||||||
(use-package org-roam
|
(use-package org-roam
|
||||||
:after deft org
|
:after org
|
||||||
:hook (org-mode . org-roam-mode)
|
:hook (org-mode . org-roam-mode)
|
||||||
:straight (:host github :repo "jethrokuan/org-roam")
|
:straight (:host github :repo "jethrokuan/org-roam")
|
||||||
:bind
|
:bind
|
||||||
@ -85,15 +68,15 @@ git clone https://github.com/jethrokuan/org-roam/ ~/.emacs.d/elisp/org-roam
|
|||||||
|
|
||||||
Suppose you want to keep track of all the cool-facts you come across.
|
Suppose you want to keep track of all the cool-facts you come across.
|
||||||
|
|
||||||
1. Open a deft file and start writing about anything. You can choose
|
1. Open a org-roam file and start writing about anything. You can choose
|
||||||
to jot it in your daily file with `org-roam-today`, or pick a file
|
to jot it in your daily file with `org-roam-today`, or pick a file
|
||||||
using the deft interface. Anywhere near your cool fact, run `M-x
|
using `org-roam-find-file`. Anywhere near your cool fact, run `M-x
|
||||||
org-roam-insert` and choose the filename `cool-facts` and then keep
|
org-roam-insert` and choose the filename `cool-facts` and then keep
|
||||||
on writing whatever you want. You can choose to create existing
|
on writing whatever you want. You can choose to create existing
|
||||||
files, or create a new file if necessary.
|
files, or create a new file if necessary.
|
||||||
2. When you open `cool-facts.org` and call `org-roam` you will
|
2. When you open `cool-facts.org` and call `org-roam` you will
|
||||||
see all the places you have referenced this file. So all the
|
see all the places you have referenced this file. So all the
|
||||||
cool-facts you have writen anywhere in your deft database are
|
cool-facts you have writen anywhere in your database are
|
||||||
easily accessible from here.
|
easily accessible from here.
|
||||||
3. Note that `cool-facts.org` doesn't even have to contain any
|
3. Note that `cool-facts.org` doesn't even have to contain any
|
||||||
content: it can just be used as an index page for referencing all
|
content: it can just be used as an index page for referencing all
|
||||||
|
129
org-roam.el
129
org-roam.el
@ -1,26 +1,30 @@
|
|||||||
;;; org-roam.el --- Roam Research replica with Org-mode and Deft
|
;;; org-roam.el --- Roam Research replica with Org-mode
|
||||||
|
|
||||||
;;; Commentary:
|
;;; Commentary:
|
||||||
;;
|
;;
|
||||||
|
|
||||||
;;; Code:
|
;;; Code:
|
||||||
(require 'deft)
|
|
||||||
(require 'org-roam-polyfill)
|
(require 'org-roam-polyfill)
|
||||||
(require 'org-element)
|
(require 'org-element)
|
||||||
(require 'async)
|
(require 'async)
|
||||||
(require 'subr-x)
|
(require 'subr-x)
|
||||||
(require 's)
|
(require 's)
|
||||||
|
|
||||||
|
;;; Customizations
|
||||||
(defgroup org-roam nil
|
(defgroup org-roam nil
|
||||||
"Roam Research replica in Org-mode."
|
"Roam Research replica in Org-mode."
|
||||||
:group 'org
|
:group 'org
|
||||||
:prefix "org-roam-")
|
:prefix "org-roam-")
|
||||||
|
|
||||||
(defvar org-roam-directory deft-directory
|
(defcustom org-roam-directory (expand-file-name "~/org-roam/")
|
||||||
"Org roam directory.")
|
"Org-roam directory."
|
||||||
|
:type 'directory
|
||||||
|
:group 'org-roam)
|
||||||
|
|
||||||
(defcustom org-roam-zettel-indicator "§"
|
(defcustom org-roam-zettel-indicator "§"
|
||||||
"Indicator in front of a zettel.")
|
"Indicator in front of a zettel."
|
||||||
|
:type 'string
|
||||||
|
:group 'org-roam)
|
||||||
|
|
||||||
(defcustom org-roam-position 'right
|
(defcustom org-roam-position 'right
|
||||||
"Position of `org-roam' buffer.
|
"Position of `org-roam' buffer.
|
||||||
@ -32,11 +36,34 @@ Valid values are
|
|||||||
(const right))
|
(const right))
|
||||||
:group 'org-roam)
|
:group 'org-roam)
|
||||||
|
|
||||||
(defvar org-roam-buffer "*org-roam*"
|
(defcustom org-roam-buffer "*org-roam*"
|
||||||
"Org-roam buffer name.")
|
"Org-roam buffer name."
|
||||||
|
:type 'string
|
||||||
|
:group 'org-roam)
|
||||||
|
|
||||||
(defvar org-roam-preview-content-delimiter "------"
|
(defcustom org-roam-preview-content-delimiter "------"
|
||||||
"Delimiter for preview content.")
|
"Delimiter for preview content."
|
||||||
|
:type 'string
|
||||||
|
:group 'org-roam)
|
||||||
|
|
||||||
|
(defcustom org-roam-update-interval 5
|
||||||
|
"Number of minutes to run asynchronous update of backlinks."
|
||||||
|
:type 'number
|
||||||
|
:group 'org-roam)
|
||||||
|
|
||||||
|
(defcustom org-roam-graph-viewer (executable-find "firefox")
|
||||||
|
"Path to executable for viewing SVG."
|
||||||
|
:type 'string
|
||||||
|
:group 'org-roam)
|
||||||
|
|
||||||
|
(defcustom org-roam-graphviz-executable (executable-find "dot")
|
||||||
|
"Path to graphviz executable."
|
||||||
|
:type 'string
|
||||||
|
:group 'org-roam)
|
||||||
|
|
||||||
|
;;; Dynamic variables
|
||||||
|
(defvar org-roam-update-timer nil
|
||||||
|
"Variable containing the timer that periodically updates the buffer.")
|
||||||
|
|
||||||
(defvar org-roam-cache nil
|
(defvar org-roam-cache nil
|
||||||
"Cache containing backlinks for `org-roam' buffers.")
|
"Cache containing backlinks for `org-roam' buffers.")
|
||||||
@ -44,28 +71,7 @@ Valid values are
|
|||||||
(defvar org-roam-current-file-id nil
|
(defvar org-roam-current-file-id nil
|
||||||
"Currently displayed file in `org-roam' buffer.")
|
"Currently displayed file in `org-roam' buffer.")
|
||||||
|
|
||||||
(defvar org-roam-update-interval 5
|
;;; Utilities
|
||||||
"Number of minutes to run asynchronous update of backlinks.")
|
|
||||||
|
|
||||||
(defvar org-roam-update-timer nil
|
|
||||||
"Variable containing the timer that periodically updates the buffer.")
|
|
||||||
|
|
||||||
(defvar org-roam-graph-viewer (executable-find "firefox")
|
|
||||||
"Path to executable for viewing SVG.")
|
|
||||||
|
|
||||||
(defvar org-roam-graphviz-executable (executable-find "dot")
|
|
||||||
"Path to graphviz executable.")
|
|
||||||
|
|
||||||
(define-inline org-roam-current-visibility ()
|
|
||||||
"Return whether the current visibility state of the org-roam buffer.
|
|
||||||
Valid states are 'visible, 'exists and 'none."
|
|
||||||
(declare (side-effect-free t))
|
|
||||||
(inline-quote
|
|
||||||
(cond
|
|
||||||
((get-buffer-window org-roam-buffer) 'visible)
|
|
||||||
((get-buffer org-roam-buffer) 'exists)
|
|
||||||
(t 'none))))
|
|
||||||
|
|
||||||
(defun org-roam--find-files (dir)
|
(defun org-roam--find-files (dir)
|
||||||
(if (file-exists-p dir)
|
(if (file-exists-p dir)
|
||||||
(let ((files (directory-files dir t "." t))
|
(let ((files (directory-files dir t "." t))
|
||||||
@ -103,6 +109,7 @@ Valid states are 'visible, 'exists and 'none."
|
|||||||
(file-truename file-path)
|
(file-truename file-path)
|
||||||
(file-truename org-roam-directory))))
|
(file-truename org-roam-directory))))
|
||||||
|
|
||||||
|
;;; Inserting org-roam links
|
||||||
(defun org-roam-insert (id)
|
(defun org-roam-insert (id)
|
||||||
"Find `ID', and insert a relative org link to it at point."
|
"Find `ID', and insert a relative org link to it at point."
|
||||||
(interactive (list (completing-read "File: "
|
(interactive (list (completing-read "File: "
|
||||||
@ -115,6 +122,7 @@ Valid states are 'visible, 'exists and 'none."
|
|||||||
(concat "file:" file-path)
|
(concat "file:" file-path)
|
||||||
(concat org-roam-zettel-indicator id)))))
|
(concat org-roam-zettel-indicator id)))))
|
||||||
|
|
||||||
|
;;; Finding org-roam files
|
||||||
(defun org-roam-find-file (id)
|
(defun org-roam-find-file (id)
|
||||||
"Find and open file with id `ID'."
|
"Find and open file with id `ID'."
|
||||||
(interactive (list (completing-read "File: "
|
(interactive (list (completing-read "File: "
|
||||||
@ -125,11 +133,11 @@ Valid states are 'visible, 'exists and 'none."
|
|||||||
(make-empty-file file-path))
|
(make-empty-file file-path))
|
||||||
(find-file file-path)))
|
(find-file file-path)))
|
||||||
|
|
||||||
|
;;; Building the org-roam cache (asynchronously)
|
||||||
(defun org-roam--build-cache-async ()
|
(defun org-roam--build-cache-async ()
|
||||||
"Builds the cache asychronously, saving it into `org-roam-cache'."
|
"Builds the cache asychronously, saving it into `org-roam-cache'."
|
||||||
(interactive)
|
(interactive)
|
||||||
(setq org-roam-files (org-roam--find-all-files))
|
(setq org-roam-files (org-roam--find-all-files))
|
||||||
(setq org-roam-directory deft-directory)
|
|
||||||
(async-start
|
(async-start
|
||||||
`(lambda ()
|
`(lambda ()
|
||||||
(require 'org)
|
(require 'org)
|
||||||
@ -188,7 +196,9 @@ Valid states are 'visible, 'exists and 'none."
|
|||||||
backlinks)))
|
backlinks)))
|
||||||
(org-roam--maybe-update-buffer))))
|
(org-roam--maybe-update-buffer))))
|
||||||
|
|
||||||
(defun org-roam-new-file-named (slug)
|
|
||||||
|
;;; Org-roam daily notes
|
||||||
|
(defun org-roam--new-file-named (slug)
|
||||||
"Create a new file named `SLUG'.
|
"Create a new file named `SLUG'.
|
||||||
`SLUG' is the short file name, without a path or a file extension."
|
`SLUG' is the short file name, without a path or a file extension."
|
||||||
(interactive "sNew filename (without extension): ")
|
(interactive "sNew filename (without extension): ")
|
||||||
@ -197,8 +207,10 @@ Valid states are 'visible, 'exists and 'none."
|
|||||||
(defun org-roam-today ()
|
(defun org-roam-today ()
|
||||||
"Create the file for today."
|
"Create the file for today."
|
||||||
(interactive)
|
(interactive)
|
||||||
(org-roam-new-file-named (format-time-string "%Y-%m-%d" (current-time))))
|
(org-roam--new-file-named (format-time-string "%Y-%m-%d" (current-time))))
|
||||||
|
|
||||||
|
|
||||||
|
;;; Org-roam buffer updates
|
||||||
(defun org-global-props (&optional property buffer)
|
(defun org-global-props (&optional property buffer)
|
||||||
"Get the plists of global org properties of current buffer."
|
"Get the plists of global org properties of current buffer."
|
||||||
(unless property (setq property "PROPERTY"))
|
(unless property (setq property "PROPERTY"))
|
||||||
@ -231,17 +243,35 @@ Valid states are 'visible, 'exists and 'none."
|
|||||||
(read-only-mode 1)))
|
(read-only-mode 1)))
|
||||||
(setq org-roam-current-file-id link-id)))
|
(setq org-roam-current-file-id link-id)))
|
||||||
|
|
||||||
|
;;; Show/hide the org-roam buffer
|
||||||
|
(define-inline org-roam--current-visibility ()
|
||||||
|
"Return whether the current visibility state of the org-roam buffer.
|
||||||
|
Valid states are 'visible, 'exists and 'none."
|
||||||
|
(declare (side-effect-free t))
|
||||||
|
(inline-quote
|
||||||
|
(cond
|
||||||
|
((get-buffer-window org-roam-buffer) 'visible)
|
||||||
|
((get-buffer org-roam-buffer) 'exists)
|
||||||
|
(t 'none))))
|
||||||
|
|
||||||
|
(defun org-roam--setup-buffer ()
|
||||||
|
"Setup the `org-roam' buffer at the `org-roam-position'."
|
||||||
|
(display-buffer-in-side-window
|
||||||
|
(get-buffer-create org-roam-buffer)
|
||||||
|
`((side . ,org-roam-position))))
|
||||||
|
|
||||||
(defun org-roam ()
|
(defun org-roam ()
|
||||||
"Initialize `org-roam'.
|
"Initialize `org-roam'.
|
||||||
1. Setup to auto-update `org-roam-buffer' with the correct information.
|
1. Setup to auto-update `org-roam-buffer' with the correct information.
|
||||||
2. Starts the timer to asynchronously build backlinks.
|
2. Starts the timer to asynchronously build backlinks.
|
||||||
3. Pops up the window `org-roam-buffer' accordingly."
|
3. Pops up the window `org-roam-buffer' accordingly."
|
||||||
(interactive)
|
(interactive)
|
||||||
(pcase (org-roam-current-visibility)
|
(pcase (org-roam--current-visibility)
|
||||||
('visible (delete-window (get-buffer-window org-roam-buffer)))
|
('visible (delete-window (get-buffer-window org-roam-buffer)))
|
||||||
('exists (org-roam--setup-buffer))
|
('exists (org-roam--setup-buffer))
|
||||||
('none (org-roam--setup-buffer))))
|
('none (org-roam--setup-buffer))))
|
||||||
|
|
||||||
|
;;; The minor mode definition that updates the buffer
|
||||||
(defun org-roam--enable ()
|
(defun org-roam--enable ()
|
||||||
(add-hook 'post-command-hook #'org-roam--maybe-update-buffer -100 t)
|
(add-hook 'post-command-hook #'org-roam--maybe-update-buffer -100 t)
|
||||||
(unless org-roam-update-timer
|
(unless org-roam-update-timer
|
||||||
@ -255,18 +285,10 @@ Valid states are 'visible, 'exists and 'none."
|
|||||||
(cancel-timer org-roam-update-timer)
|
(cancel-timer org-roam-update-timer)
|
||||||
(setq org-roam-update-timer nil)))
|
(setq org-roam-update-timer nil)))
|
||||||
|
|
||||||
(defun org-roam--setup-buffer ()
|
|
||||||
"Setup the `org-roam' buffer at the `org-roam-position'."
|
|
||||||
(display-buffer-in-side-window
|
|
||||||
(get-buffer-create org-roam-buffer)
|
|
||||||
`((side . ,org-roam-position))))
|
|
||||||
|
|
||||||
(defun org-roam--maybe-update-buffer ()
|
(defun org-roam--maybe-update-buffer ()
|
||||||
"Update `org-roam-buffer' with the necessary information.
|
"Update `org-roam-buffer' with the necessary information.
|
||||||
This needs to be quick/infrequent, because this is run at
|
This needs to be quick/infrequent, because this is run at
|
||||||
`post-command-hook'. This is achieved by only checking Org files
|
`post-command-hook'."
|
||||||
that are amongst deft files, and `org-roam' not already
|
|
||||||
displaying information for the correct file."
|
|
||||||
(with-current-buffer (window-buffer)
|
(with-current-buffer (window-buffer)
|
||||||
(when (and (eq major-mode 'org-mode)
|
(when (and (eq major-mode 'org-mode)
|
||||||
(get-buffer org-roam-buffer)
|
(get-buffer org-roam-buffer)
|
||||||
@ -275,6 +297,14 @@ displaying information for the correct file."
|
|||||||
(member (file-truename (buffer-file-name (window-buffer))) (org-roam--find-all-files)))
|
(member (file-truename (buffer-file-name (window-buffer))) (org-roam--find-all-files)))
|
||||||
(org-roam-update (org-roam--get-id (buffer-file-name (window-buffer)))))))
|
(org-roam-update (org-roam--get-id (buffer-file-name (window-buffer)))))))
|
||||||
|
|
||||||
|
(define-minor-mode org-roam-mode
|
||||||
|
"Global minor mode to automatically update the org-roam buffer."
|
||||||
|
:require 'org-roam
|
||||||
|
(if org-roam-mode
|
||||||
|
(org-roam--enable)
|
||||||
|
(org-roam--disable)))
|
||||||
|
|
||||||
|
;;; Building the Graphviz graph
|
||||||
(defun org-roam-build-graph ()
|
(defun org-roam-build-graph ()
|
||||||
"Build graphviz graph output."
|
"Build graphviz graph output."
|
||||||
(with-temp-buffer
|
(with-temp-buffer
|
||||||
@ -310,13 +340,12 @@ displaying information for the correct file."
|
|||||||
(call-process org-roam-graphviz-executable nil 0 nil temp-dot "-Tsvg" "-o" temp-graph)
|
(call-process org-roam-graphviz-executable nil 0 nil temp-dot "-Tsvg" "-o" temp-graph)
|
||||||
(call-process org-roam-graph-viewer nil 0 nil temp-graph)))
|
(call-process org-roam-graph-viewer nil 0 nil temp-graph)))
|
||||||
|
|
||||||
(define-minor-mode org-roam-mode
|
|
||||||
"Global minor mode to automatically update the org-roam buffer."
|
|
||||||
:require 'org-roam
|
|
||||||
(if org-roam-mode
|
|
||||||
(org-roam--enable)
|
|
||||||
(org-roam--disable)))
|
|
||||||
|
|
||||||
(provide 'org-roam)
|
(provide 'org-roam)
|
||||||
|
|
||||||
;;; org-roam.el ends here
|
;;; org-roam.el ends here
|
||||||
|
|
||||||
|
;; Local Variables:
|
||||||
|
;; outline-regexp: ";;;+ "
|
||||||
|
;; End:
|
||||||
|
Reference in New Issue
Block a user