From ca6b1468a65e21d2ed5b7dc0d111068076a6d3fe Mon Sep 17 00:00:00 2001 From: bth Date: Tue, 16 Dec 2025 14:22:06 -0800 Subject: [PATCH] um-root-glob um-root-path --- README.md | 8 +++++--- elisp/um.el | 25 ++++++++++++------------- 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index db34dd0..1424e72 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,7 @@ This "database" depends on a few simple ideas: 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. @@ -65,6 +65,8 @@ My config looks like this: (use-package um :after (project embark) + :init (setq um-root-glob ".*/writing/journal") + :config (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" -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: -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. # CLI usage diff --git a/elisp/um.el b/elisp/um.el index 62a128b..d843277 100644 --- a/elisp/um.el +++ b/elisp/um.el @@ -21,7 +21,7 @@ ;; 2. Placing that same id into the file header, so that concatenated files ;; 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. ;; 4. Using the built-in `project' package to organize compositions built from @@ -37,8 +37,8 @@ (require 'project) -(defvar um-journal-path-glob ".*/writing/journal" - "Primary path glob for the journal. This allows various mountpoints.") +(defvar um-root-glob ".*/writing/journal" + "Primary glob for `um-root-path.' This allows various mountpoints.") (defvar um-date-format "%Y-%m-%d" "Format passed to `format-time-string' when creating `um-journal-header'. Defaults to ISO8601.") @@ -63,12 +63,11 @@ ;; find-file-at-point ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; the journal/ serves as content origin, so it must be treated specially. -(defun um-journal-path () +(defun um-root-path () (or (car (seq-filter (lambda (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: (project-known-project-roots))) ;; fallback if not found @@ -84,12 +83,12 @@ ;;;###autoload (defun um-find-file-at-point () - "Return full file path of thing-at-point, falling back first to -`project-root', then to `um-journal-path'." + "Return full file path of thing-at-point, beginning with `default-directory', +falling back to `project-root', then to `um-root-path'." (let ((dirs (list default-directory (project-root (project-current)) - (um-journal-path))) + (um-root-path))) dir 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 (seq-remove (lambda (path) - (or (string-match (um-journal-path) path) + (or (string-match (um-root-path) path) (when (project-current) (string-match (caddr (project-current)) path)) )) @@ -168,7 +167,7 @@ Since journal/ is the origin and other projects shadow it. )) ;; journal path - (let ((default-directory (um-journal-path))) + (let ((default-directory (um-root-path))) (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 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) (let* ( @@ -228,7 +227,7 @@ Assumes the files of interest are returned by `um-journal-path'. (if files (progn (dolist (f files) ;; 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) ) (switch-to-buffer buf)