um-root-glob um-root-path

This commit is contained in:
bth 2025-12-16 14:22:06 -08:00
commit ca6b1468a6
2 changed files with 17 additions and 16 deletions

View file

@ -39,7 +39,7 @@ This "database" depends on a few simple ideas:
See the `um cat` command for why this matters. See the `um cat` command for why this matters.
3. Using a source "journal/" directory, where source files should first be composed and where we can assume a file exists if not elsewhere. This matters when trying to navigate back to a source file. 3. Using a single "root" project defined by `um-root-glob`, where source files should first be composed and where we can assume a file exists if not elsewhere. This matters when trying to navigate back to a source file.
4. Using the built-in emacs `project` package to organize compositions built from these source files. 4. Using the built-in emacs `project` package to organize compositions built from these source files.
@ -65,6 +65,8 @@ My config looks like this:
(use-package um (use-package um
:after (project embark) :after (project embark)
:init (setq um-root-glob ".*/writing/journal")
:config :config
(advice-add 'embark-target-file-at-point :around 'um-target-file-at-point-advice) (advice-add 'embark-target-file-at-point :around 'um-target-file-at-point-advice)
@ -76,11 +78,11 @@ Note the optional setup of `embark`, which allows us to find files intelligently
# ultralight "database" # ultralight "database"
What I consider the killer feature of `um` is the ability to jump to files from filenames listed in any "child" project back to the "source" project, defined via `um-journal-path-glob`. This means that child projects can be initially defined as simple lists of filenames, which I do to compose larger pieces. A simple filename anywhere can also serve as a "link". What I consider the killer feature of `um` is the ability to jump to files from filenames listed in any "child" project back to the "source" project, defined via `um-root-glob`. This means that child projects can be initially defined as simple lists of filenames, which I do to compose larger pieces. A simple filename anywhere can also serve as a "link".
There are two primary ways this is accessed: There are two primary ways this is accessed:
1. `find-file` and `next-history-element`, which will work as `C-x C-f M-n` out of the box. 1. `find-file` and `next-history-element`, which will work as `C-x C-f M-n` out of the box. See `um-find-file-at-point`.
2. By invoking `emark-dwim` on any filename. Requires `embark` and the `advice-add` shown above. 2. By invoking `emark-dwim` on any filename. Requires `embark` and the `advice-add` shown above.
# CLI usage # CLI usage

View file

@ -21,7 +21,7 @@
;; 2. Placing that same id into the file header, so that concatenated files ;; 2. Placing that same id into the file header, so that concatenated files
;; have reference back to their source. See the `um cat` command. ;; have reference back to their source. See the `um cat` command.
;; 3. Using a source "journal/" directory, where source files should first be ;; 3. Using a source `um-root-glob' directory, where source files should first be
;; composed and where we can assume a file exists if not elsewhere. ;; composed and where we can assume a file exists if not elsewhere.
;; 4. Using the built-in `project' package to organize compositions built from ;; 4. Using the built-in `project' package to organize compositions built from
@ -37,8 +37,8 @@
(require 'project) (require 'project)
(defvar um-journal-path-glob ".*/writing/journal" (defvar um-root-glob ".*/writing/journal"
"Primary path glob for the journal. This allows various mountpoints.") "Primary glob for `um-root-path.' This allows various mountpoints.")
(defvar um-date-format "%Y-%m-%d" (defvar um-date-format "%Y-%m-%d"
"Format passed to `format-time-string' when creating `um-journal-header'. Defaults to ISO8601.") "Format passed to `format-time-string' when creating `um-journal-header'. Defaults to ISO8601.")
@ -63,12 +63,11 @@
;; find-file-at-point ;; find-file-at-point
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; the journal/ serves as content origin, so it must be treated specially. (defun um-root-path ()
(defun um-journal-path ()
(or (car (seq-filter (or (car (seq-filter
(lambda (path) (lambda (path)
;; this way I don't have to hardcode the full path: ;; this way I don't have to hardcode the full path:
(string-match um-journal-path-glob path)) (string-match um-root-glob path))
;; stores all project roots in a list of strings: ;; stores all project roots in a list of strings:
(project-known-project-roots))) (project-known-project-roots)))
;; fallback if not found ;; fallback if not found
@ -84,12 +83,12 @@
;;;###autoload ;;;###autoload
(defun um-find-file-at-point () (defun um-find-file-at-point ()
"Return full file path of thing-at-point, falling back first to "Return full file path of thing-at-point, beginning with `default-directory',
`project-root', then to `um-journal-path'." falling back to `project-root', then to `um-root-path'."
(let ((dirs (list (let ((dirs (list
default-directory default-directory
(project-root (project-current)) (project-root (project-current))
(um-journal-path))) (um-root-path)))
dir dir
file) file)
(while (and dirs (not file)) (while (and dirs (not file))
@ -156,7 +155,7 @@ Since journal/ is the origin and other projects shadow it.
(cl-loop for project-path in (cl-loop for project-path in
(seq-remove (seq-remove
(lambda (path) (lambda (path)
(or (string-match (um-journal-path) path) (or (string-match (um-root-path) path)
(when (project-current) (when (project-current)
(string-match (caddr (project-current)) path)) (string-match (caddr (project-current)) path))
)) ))
@ -168,7 +167,7 @@ Since journal/ is the origin and other projects shadow it.
)) ))
;; journal path ;; journal path
(let ((default-directory (um-journal-path))) (let ((default-directory (um-root-path)))
(funcall origfunc)) (funcall origfunc))
)) ))
@ -208,7 +207,7 @@ NOTE: this searches in the current project root only.
dired-mode, or if marks exist in dired-mode, or the filename at point, and dired-mode, or if marks exist in dired-mode, or the filename at point, and
finally in the current buffer if none of those conditions match. finally in the current buffer if none of those conditions match.
Assumes the files of interest are returned by `um-journal-path'. Assumes the files of interest are returned by `um-root-path'.
" "
(interactive) (interactive)
(let* ( (let* (
@ -228,7 +227,7 @@ Assumes the files of interest are returned by `um-journal-path'.
(if files (progn (dolist (f files) (if files (progn (dolist (f files)
;; TODO: this should use the fallback logic: ;; TODO: this should use the fallback logic:
(find-file (expand-file-name f (um-journal-path))) (find-file (expand-file-name f (um-root-path)))
(um-tag-insert tag) (um-tag-insert tag)
) )
(switch-to-buffer buf) (switch-to-buffer buf)