Simplify org-roam-insert and org-roam-find-file (#62)
* Simplify org-roam-insert and org-roam-find-file See #59. * Add docs for org-roam automatic filenaming * Update installation instructions
This commit is contained in:
parent
a2a448d7d2
commit
791c059200
4 changed files with 107 additions and 85 deletions
51
doc/configuration.md
Normal file
51
doc/configuration.md
Normal file
|
@ -0,0 +1,51 @@
|
|||
To ensure that Org-roam remains manageable, the number of
|
||||
configuration options is deliberately kept small. However, we have
|
||||
attempted to accommodate as many usage styles as possible.
|
||||
|
||||
In this section, we'll go over the main customization options
|
||||
available to Org-Roam. This section is *crucial*. We need to exploit
|
||||
the flexibility of Emacs, and mould our tools exactly to our liking.
|
||||
|
||||
All of Org-roam's customization options can be viewed via `M-x
|
||||
customize-group org-roam`.
|
||||
|
||||
## Org-roam Files
|
||||
|
||||
These customization options revolve around the Org files created and
|
||||
managed by Org-roam.
|
||||
|
||||
### Automatically Creating Files Using Timestamp
|
||||
|
||||
A common hassle is ensuring that files are uniquely named within the
|
||||
Org-roam directory. Org-roam's default workflow utilizes the title of
|
||||
Org files in all of its main commands (`org-roam-insert`,
|
||||
`org-roam-find-file`). Hence, having any unique file name is a decent
|
||||
option, and the default workflow uses the timestamp as the filename.
|
||||
|
||||
The format of the filename is specified by the string
|
||||
`org-roam-file-format`, which defaults to `"%Y%m%d%H%M%S"`. To see
|
||||
valid specifications, see the help (`C-h f`) for `format-time-string`.
|
||||
|
||||
There are several reasons for keeping filenames meaningful. For
|
||||
example, one may wish to publish the Org files, and some publishing
|
||||
methods such as Org-publish use the file names as slugs for the URLs.
|
||||
|
||||
If you wish to maintain manual control of filenames, set
|
||||
`org-roam-use-timestamp-as-filename` to `nil`:
|
||||
|
||||
```emacs-lisp
|
||||
(setq org-roam-use-timestamp-as-filename nil)
|
||||
```
|
||||
|
||||
When this setting is turned off, the user is instead manually prompted
|
||||
for a filename. It is then the user's responsibility to ensure that
|
||||
the file names are unique.
|
||||
|
||||
### Autopopulating Titles
|
||||
|
||||
The default workflow uses the title of the Org file in several
|
||||
commands. The title is specified via the `#+TITLE:` attribute,
|
||||
typically near the top of the file. The option
|
||||
`org-roam-autopopulate-title` defaults to `t`. When true, the title
|
||||
attribute is automatically inserted into the files created via
|
||||
org-roam commands. Setting it to `nil` will disable this behaviour.
|
|
@ -10,7 +10,6 @@ The recommended method is using [use-package][use-package] and
|
|||
:straight (:host github :repo "jethrokuan/org-roam")
|
||||
:custom
|
||||
(org-roam-directory "/path/to/org-files/")
|
||||
(org-roam-link-representation 'title) ;; or keep it as 'id
|
||||
:bind
|
||||
("C-c n l" . org-roam)
|
||||
("C-c n t" . org-roam-today)
|
||||
|
@ -31,5 +30,9 @@ git clone https://github.com/jethrokuan/org-roam/ ~/.emacs.d/elisp/org-roam
|
|||
(require 'org-roam)
|
||||
```
|
||||
|
||||
There are a number of important configuration options, that greatly
|
||||
affect the Roam workflow. Do look through them at the
|
||||
[Configuration](configuration.md) page.
|
||||
|
||||
[use-package]: https://github.com/jwiegley/use-package
|
||||
[straight]: https://github.com/raxod502/straight.el
|
||||
|
|
|
@ -7,6 +7,7 @@ nav:
|
|||
- Home: index.md
|
||||
- A Tour of Org-Roam: tour.md
|
||||
- Installation: installation.md
|
||||
- Configuration: configuration.md
|
||||
- Ecosystem: ecosystem.md
|
||||
- Similar Packages: comparison.md
|
||||
markdown_extensions:
|
||||
|
|
135
org-roam.el
135
org-roam.el
|
@ -33,26 +33,8 @@ Valid values are
|
|||
(const right))
|
||||
:group 'org-roam)
|
||||
|
||||
(defcustom org-roam-link-representation 'id
|
||||
"The value used to represent an org-roam link.
|
||||
|
||||
Valid values are
|
||||
* file,
|
||||
* title."
|
||||
:type '(choice (const id)
|
||||
(const title))
|
||||
:group 'org-roam)
|
||||
|
||||
(defcustom org-roam-timestamped-files nil
|
||||
"Whether to use timestamps to generate unique filenames."
|
||||
:type 'boolean
|
||||
:group 'org-roam)
|
||||
|
||||
(defcustom org-roam-timestamp-format "%Y-%m-%d%H%M%S"
|
||||
"The timestamp format to use filenames.")
|
||||
|
||||
(defcustom org-roam-link-id-format "§%s"
|
||||
"The format string used when inserting org-roam links that use id."
|
||||
(defcustom org-roam-file-format "%Y%m%d%H%M%S"
|
||||
"The timestamp format to use filenames."
|
||||
:type 'string
|
||||
:group 'org-roam)
|
||||
|
||||
|
@ -61,6 +43,9 @@ Valid values are
|
|||
:type 'string
|
||||
:group 'org-roam)
|
||||
|
||||
(defcustom org-roam-use-timestamp-as-filename t
|
||||
"Whether to use timestamp as a file name. If not true, prompt for a file name each time.")
|
||||
|
||||
(defcustom org-roam-autopopulate-title t "Whether to autopopulate the title."
|
||||
:type 'boolean
|
||||
:group 'org-roam)
|
||||
|
@ -133,13 +118,13 @@ If called interactively, then PARENTS is non-nil."
|
|||
(f-child-of-p (file-truename (buffer-file-name (current-buffer)))
|
||||
org-roam-directory)))
|
||||
|
||||
(defun org-roam--get-title (file)
|
||||
"Return title of `FILE'.
|
||||
|
||||
It first tries the cache. If the cache does not contain the file,
|
||||
it will return the title by loading the file."
|
||||
(defun org-roam--get-title-from-cache (file)
|
||||
"Return title of `FILE' from the cache."
|
||||
(or (gethash file org-roam-titles-cache)
|
||||
(org-roam--extract-file-title file)))
|
||||
(progn
|
||||
(unless org-roam-cache-initialized
|
||||
(user-error "The Org-Roam caches aren't built! Please run org-roam--build-cache-async"))
|
||||
nil)))
|
||||
|
||||
(defun org-roam--find-files (dir)
|
||||
"Return all org-roam files in `DIR'."
|
||||
|
@ -177,20 +162,15 @@ If `ABSOLUTE', return the absolute file-path. Else, return the relative file-pat
|
|||
(file-relative-name absolute-file-path
|
||||
(file-truename org-roam-directory)))))
|
||||
|
||||
(defun org-roam--get-id (file-path)
|
||||
"Convert `FILE-PATH' to the org-roam id."
|
||||
(file-name-sans-extension
|
||||
(file-relative-name
|
||||
(file-truename file-path)
|
||||
(file-truename org-roam-directory))))
|
||||
(defun org-roam--get-title-or-slug (file-path)
|
||||
"Convert `FILE-PATH' to the file title, if it exists. Else, return the path."
|
||||
(or (org-roam--get-title-from-cache file-path)
|
||||
(-> file-path
|
||||
(file-relative-name (file-truename org-roam-directory))
|
||||
(file-name-sans-extension))))
|
||||
|
||||
(defun org-roam--get-title-or-id (file-path)
|
||||
"Convert `FILE-PATH' to the file title, if it exists. Else, return the id."
|
||||
(or (org-roam--get-title file-path)
|
||||
(org-roam--get-id file-path)))
|
||||
|
||||
(defun org-roam--title-to-id (title)
|
||||
"Convert TITLE to id."
|
||||
(defun org-roam--title-to-slug (title)
|
||||
"Convert TITLE to a filename-suitable slug."
|
||||
(let* ((s (s-downcase title))
|
||||
(s (replace-regexp-in-string "[^a-zA-Z0-9_ ]" "" s))
|
||||
(s (s-split " " s))
|
||||
|
@ -232,9 +212,20 @@ If not provided, derive the title from the file name."
|
|||
(org-roam--make-file file-path))
|
||||
(find-file file-path)))
|
||||
|
||||
(defun org-roam--get-new-id ()
|
||||
"Return a new ID, generated from the current time."
|
||||
(format-time-string org-roam-timestamp-format (current-time)))
|
||||
(defun org-roam--get-new-id (&optional title)
|
||||
"Return a new ID, generated from the current time.
|
||||
|
||||
Optionally pass it the title, for a smart file name."
|
||||
(if org-roam-use-timestamp-as-filename
|
||||
(format-time-string org-roam-file-format (current-time))
|
||||
(let* ((slug (read-string "Enter ID (without extension): "
|
||||
(if title
|
||||
(org-roam--title-to-slug title)
|
||||
"")))
|
||||
(file-path (org-roam--get-file-path slug t)))
|
||||
(if (file-exists-p file-path)
|
||||
(user-error "There's already a file at %s")
|
||||
slug))))
|
||||
|
||||
(defun org-roam-new-file ()
|
||||
"Quickly create a new file, using the current timestamp."
|
||||
|
@ -243,58 +234,34 @@ If not provided, derive the title from the file name."
|
|||
|
||||
;;; Inserting org-roam links
|
||||
(defun org-roam-insert ()
|
||||
"Insert an org-roam link."
|
||||
"Find an org-roam file, and insert a relative org link to it at point."
|
||||
(interactive)
|
||||
(pcase org-roam-link-representation
|
||||
('id (org-roam--insert-id))
|
||||
('title (org-roam--insert-title))))
|
||||
|
||||
(defun org-roam--insert-title ()
|
||||
"Find `ID', and insert a relative org link to it at point."
|
||||
(let* ((completions (mapcar (lambda (file)
|
||||
(list (org-roam--get-title-or-id file)
|
||||
(org-roam--get-id file)))
|
||||
(list (org-roam--get-title-or-slug file)
|
||||
file))
|
||||
(org-roam--find-all-files)))
|
||||
(title (completing-read "File: " completions))
|
||||
(id (cadr (assoc title completions))))
|
||||
(when (not id)
|
||||
(if org-roam-timestamped-files
|
||||
(setq id (org-roam--get-new-id)))
|
||||
(read-string "Enter new file id: " (org-roam--title-to-id title)))
|
||||
(let ((file-path (org-roam--get-file-path id)))
|
||||
(unless (file-exists-p file-path)
|
||||
(org-roam--make-file file-path title))
|
||||
(insert (format "[[%s][%s]]"
|
||||
(concat "file:" file-path)
|
||||
(format org-roam-link-title-format title))))))
|
||||
|
||||
(defun org-roam--insert-id ()
|
||||
"Find `ID', and insert a relative org link to it at point."
|
||||
(let* ((id (completing-read "File: " (mapcar #'org-roam--get-id (org-roam--find-all-files))))
|
||||
(file-path (org-roam--get-file-path id)))
|
||||
(file-path (or (cadr (assoc title completions))
|
||||
(org-roam--get-new-id title))))
|
||||
(unless (file-exists-p file-path)
|
||||
(org-roam--make-file file-path))
|
||||
(org-roam--make-file file-path title))
|
||||
(insert (format "[[%s][%s]]"
|
||||
(concat "file:" file-path)
|
||||
(format org-roam-link-id-format id)))))
|
||||
(format org-roam-link-title-format title)))))
|
||||
|
||||
;;; Finding org-roam files
|
||||
(defun org-roam-find-file ()
|
||||
"Find and open an org-roam file."
|
||||
(interactive)
|
||||
(let* ((completions (mapcar (lambda (file)
|
||||
(list (org-roam--get-title-or-id file) file))
|
||||
(list (org-roam--get-title-or-slug file) file))
|
||||
(org-roam--find-all-files)))
|
||||
(title-or-id (completing-read "File: " completions))
|
||||
(file-path (cadr (assoc title-or-id completions))))
|
||||
(unless file-path
|
||||
(let ((id (if org-roam-timestamped-files
|
||||
(org-roam--get-new-id)
|
||||
(read-string "Enter new file id: "
|
||||
(org-roam--title-to-id title-or-id)))))
|
||||
(setq file-path (org-roam--get-file-path id t))))
|
||||
(title-or-slug (completing-read "File: " completions))
|
||||
(file-path (or (cadr (assoc title-or-slug completions))
|
||||
(org-roam--get-file-path
|
||||
(org-roam--get-new-id title-or-slug) t))))
|
||||
(unless (file-exists-p file-path)
|
||||
(org-roam--make-file file-path title-or-id))
|
||||
(org-roam--make-file file-path title-or-slug))
|
||||
(find-file file-path)))
|
||||
|
||||
;;; Building the org-roam cache (asynchronously)
|
||||
|
@ -536,7 +503,7 @@ This is equivalent to removing the node from the graph."
|
|||
(defun org-roam-update (file-path)
|
||||
"Show the backlinks for given org file for file at `FILE-PATH'."
|
||||
(org-roam--ensure-cache-built)
|
||||
(let ((buffer-title (org-roam--get-title-or-id file-path)))
|
||||
(let ((buffer-title (org-roam--get-title-or-slug file-path)))
|
||||
(with-current-buffer org-roam-buffer
|
||||
(let ((inhibit-read-only t))
|
||||
(erase-buffer)
|
||||
|
@ -553,7 +520,7 @@ This is equivalent to removing the node from the graph."
|
|||
(maphash (lambda (file-from contents)
|
||||
(insert (format "** [[file:%s][%s]]\n"
|
||||
file-from
|
||||
(org-roam--get-title-or-id file-from)))
|
||||
(org-roam--get-title-or-slug file-from)))
|
||||
(dolist (content contents)
|
||||
(insert (concat (propertize (s-trim (s-replace "\n" " " content))
|
||||
'font-lock-face 'org-block)
|
||||
|
@ -657,15 +624,15 @@ This needs to be quick/infrequent, because this is run at
|
|||
(mapcar (lambda (file)
|
||||
(insert
|
||||
(format " \"%s\" [URL=\"roam://%s\"];\n"
|
||||
(org-roam--get-id file)
|
||||
(org-roam--get-title-or-slug file)
|
||||
file)))
|
||||
(org-roam--find-all-files))
|
||||
(maphash
|
||||
(lambda (from-link to-links)
|
||||
(dolist (to-link to-links)
|
||||
(insert (format " \"%s\" -> \"%s\";\n"
|
||||
(org-roam--get-id from-link)
|
||||
(org-roam--get-id to-link))))
|
||||
(org-roam--get-title-or-slug from-link)
|
||||
(org-roam--get-title-or-slug to-link))))
|
||||
)
|
||||
org-roam-forward-links-cache)
|
||||
(insert "}")
|
||||
|
|
Loading…
Reference in a new issue