Become deft-free 🎉

This commit is contained in:
Jethro Kuan
2020-02-06 19:26:38 +08:00
parent b8c36133bb
commit 4d825fedde
2 changed files with 85 additions and 73 deletions

View File

@ -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

View File

@ -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: