<feed xmlns='http://www.w3.org/2005/Atom'>
<title>dotemacs/modules/org-config.el, branch load-graph-classify-end</title>
<subtitle>My Emacs configuration
</subtitle>
<id>https://git.cjennings.net/dotemacs/atom?h=load-graph-classify-end</id>
<link rel='self' href='https://git.cjennings.net/dotemacs/atom?h=load-graph-classify-end'/>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/'/>
<updated>2026-05-24T21:34:16+00:00</updated>
<entry>
<title>docs(load-graph): classify Org modules</title>
<updated>2026-05-24T21:34:16+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-05-24T21:34:16+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/commit/?id=02baa68063f02cc571789c03b1101c28d139200d'/>
<id>urn:sha1:02baa68063f02cc571789c03b1101c28d139200d</id>
<content type='text'>
Seventh classification batch: the thirteen Org modules — config, agenda, babel, capture, contacts, drill, export, noter, refile, reveal, roam, webclipper, hugo. I annotated each header, added a Batch 7 table to the inventory, and extended the validation allowlist. 65 of 102 modules are now classified.

The daily workflows (config, agenda, capture, refile, roam) keep their eager reason per the spec's Phase 6 target. Babel and contacts move to after-load; export, reveal, drill, noter, webclipper, and hugo become command-loaded. The agenda and refile idle-timer caches are recorded as the side effects the spec already tracks for cache-lifecycle work. No new hidden dependencies.
</content>
</entry>
<entry>
<title>feat(org): label the C-; O org prefix in which-key</title>
<updated>2026-05-24T06:00:59+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-05-24T06:00:59+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/commit/?id=40303246cb1a6d21621d8898a41ed7d4675fc3f3'/>
<id>urn:sha1:40303246cb1a6d21621d8898a41ed7d4675fc3f3</id>
<content type='text'>
The C-; O prefix (cj/org-map) had no which-key labels, so the popup just showed raw command names, and nothing at all for the d (finalize-task) binding. I added labels for the whole prefix, including the r/c table sub-prefixes. The two org-show-all bindings are labeled "cancel sparse tree" (S) and "cancel todo tree" (T) so the popup shows what each one cancels rather than two identical "show all" entries.
</content>
</entry>
<entry>
<title>feat(org-tidy): mark collapsed property drawers with a middle dot</title>
<updated>2026-05-24T05:52:49+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-05-24T05:52:49+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/commit/?id=31dc4b9ed13a6f8e417f82ada8329729997828c9'/>
<id>urn:sha1:31dc4b9ed13a6f8e417f82ada8329729997828c9</id>
<content type='text'>
org-tidy's default inline marker is the music sharp (♯), which reads as a full-size # next to a heading. I set org-tidy-properties-inline-symbol to a middle dot (·) so the collapsed drawer is marked with something far less visually heavy.
</content>
</entry>
<entry>
<title>refactor(org): give org-log-done a single home</title>
<updated>2026-05-23T01:20:25+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-05-23T01:20:25+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/commit/?id=5f8e1bc757fab620f5cf9b5fbc42b6a0030f5e53'/>
<id>urn:sha1:5f8e1bc757fab620f5cf9b5fbc42b6a0030f5e53</id>
<content type='text'>
`org-log-done` was set in two places: `cj/org-todo-settings` in org-config.el set it nil, and org-roam-config.el's `:config` set it to 'time. Whichever module loaded last won, so the effective value was load-order-dependent and fragile.

I set it once in `cj/org-todo-settings` and dropped the org-roam-config setter, leaving a comment at the old site so it doesn't creep back. The value is 'time rather than nil because the dated-completion workflow wants a CLOSED timestamp stamped on every TODO-&gt;DONE.
</content>
</entry>
<entry>
<title>feat(org-config): add cj/org-finalize-task with tests</title>
<updated>2026-05-22T20:01:14+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-05-22T20:01:14+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/commit/?id=082037ad75e21405655adb492d0c85e342f4f771'/>
<id>urn:sha1:082037ad75e21405655adb492d0c85e342f4f771</id>
<content type='text'>
I added a command on C-; O d that finalizes the task at point. It prompts for a finalized keyword from org-done-keywords, so the picker tracks org-todo-keywords automatically. Marking the task done fires the org-roam journal-copy hook, so the completed task lands in today's daily.

Then the heading is reshaped by depth. A sub-task (level 3 or deeper, or a VERIFY at any depth) becomes a dated log entry: the keyword and priority cookie are stripped, a sortable timestamp is prepended, and the tags are kept. A top-level task keeps its keyword and gains a date-only CLOSED line.

The command binds org-inhibit-logging around the org-todo call so it owns the CLOSED line rather than depending on org-log-done, which is set inconsistently across two modules. The journal hook keys off org-state, not org-log-done, so the copy still fires.

Tests run in org temp-buffers with the journal hook bound to nil, exercise the real org primitives, and inject a fixed time so the stamp shape is deterministic.
</content>
</entry>
<entry>
<title>refactor: consolidate runtime state into persist/</title>
<updated>2026-05-16T17:20:44+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-05-16T17:20:44+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/commit/?id=43022b56569717f28fa16284f7092f2bbe0830ad'/>
<id>urn:sha1:43022b56569717f28fa16284f7092f2bbe0830ad</id>
<content type='text'>
Six previously-scattered runtime state files now live under persist/
in user-emacs-directory:

- theme-file (was .emacs-theme)
- pdf-view-restore-filename (was .pdf-view-restore)
- time-zones--city-list-file (was .time-zones.el)
- calendar-sync--state-file (was data/calendar-sync-state.el)
- prescient-save-file (was var/prescient-save.el)
- org-id-locations-file (was .org-id-locations)

The defaults in each module now expand to persist/&lt;name&gt; instead of
the user-emacs-directory root or ad-hoc subdirs.  Existing files
moved into persist/ alongside this change so the next launch picks
up the state without regenerating.

test-ui-theme-default-theme-file-is-emacs-dotfile renamed to
test-ui-theme-default-theme-file-is-under-persist and updated to
assert the new default path.

lsp-session-file is left at the root for now -- prog-lsp.el has no
(require) reference anywhere, so the use-package block that would
carry the redirect never runs.  Tier 3 follow-up: confirm the module
is dead, then delete it or wire it into the load chain.

The var/ directory is now empty and removed.  data/ retains the
calendar agenda content (dcal/gcal/pcal.org) and the .rest API
examples -- content, not state, stays where it is.
</content>
</entry>
<entry>
<title>feat(org-config): hide :PROPERTIES: drawers via org-tidy</title>
<updated>2026-05-16T15:44:14+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-05-16T15:44:14+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/commit/?id=33e0fcb33e7bca6ac69605fc8264a4edb413d75a'/>
<id>urn:sha1:33e0fcb33e7bca6ac69605fc8264a4edb413d75a</id>
<content type='text'>
Adds an org-tidy use-package block hooked into org-mode and sets
org-tidy-properties-style to 'inline so each :PROPERTIES: drawer
collapses to a small marker in the heading line.  The drawer stays
editable through TAB cycling or via M-x org-tidy-mode toggle.

Also sets org-cycle-hide-drawers to 'all in cj/org-general-settings
so drawers fold whenever their parent heading folds -- the native
companion to org-tidy's overlay-based hiding.
</content>
</entry>
<entry>
<title>refactor(org-config): surface narrowing + sparse-tree under C-; O</title>
<updated>2026-05-15T00:05:43+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-05-15T00:05:43+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/commit/?id=1dbf5a4a2d2ce4277dc97a3e9783240324ad5f53'/>
<id>urn:sha1:1dbf5a4a2d2ce4277dc97a3e9783240324ad5f53</id>
<content type='text'>
Narrowing and sparse-tree commands existed in the `:bind' block
on `C-c'-style shortcuts but nothing in `cj/org-map' surfaced
them, so which-key never showed them and discoverability was
poor.

Add direct bindings under `C-; O', flat (no sub-prefixes for
narrow / sparse-tree).  Lowercase creates; capital of the same
letter cancels:

- `n' / `N'  narrow-to-subtree / widen
- `s' / `S'  match-sparse-tree / show-all
- `t' / `T'  show-todo-tree / show-all
- `&gt;' / `&lt;'  forward / backward sibling narrow (kept as-is)
- `R'        reveal-context (no lowercase pair -- `r' is the
             table-row sub-prefix)

Both `S' and `T' resolve to the same `org-show-all' command so
the mental model is just "capital cancels the lowercase I just
ran" without having to recall which letter the cancel actually
lives on.

Free up F2: the old `(&lt;f2&gt; . org-reveal)' binding in the org-mode
`:bind' block is now redundant with `C-; O R'.  Drop it; F2
becomes available for whatever wants it next.

Four new ERT assertions in `test-org-config-keymap-ownership.el'
lock the shape -- the old sparse-tree-submap test was rewritten
for the flat layout and the narrow-submap test became
narrow-bindings (also flat).
</content>
</entry>
<entry>
<title>refactor(org-config): flatten table ops directly under the org menu</title>
<updated>2026-05-14T13:30:47+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-05-14T13:30:47+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/commit/?id=fcdea7f0fcc20b1980ee0ee3fc0ba6159c0cf86e'/>
<id>urn:sha1:fcdea7f0fcc20b1980ee0ee3fc0ba6159c0cf86e</id>
<content type='text'>
Drop the `T' sub-prefix so table operations sit directly under
`C-; O': `O r i' / `O r d' for rows, `O c i' / `O c d' for columns.
Move `cj/org-clear-element-cache' from `c' (which now hosts the
table-column sub-prefix) to capital `C'.  Single-key org commands
under this menu live on capitals from here on so the lowercase
letters stay free for table sub-prefixes.

Drop `cj/org-table-map' entirely -- its bindings now live directly
on `cj/org-map'.  Three tests in `test-org-config-keymap-ownership.el'
updated/added: `C' for clear-cache, plus row and column binding
assertions.
</content>
</entry>
<entry>
<title>refactor(org-config): move org-table-map under the org menu</title>
<updated>2026-05-14T13:21:20+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-05-14T13:21:20+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/commit/?id=623f45f2781ed6c489672dcfb09d877657dbe1da'/>
<id>urn:sha1:623f45f2781ed6c489672dcfb09d877657dbe1da</id>
<content type='text'>
`(keymap-set cj/custom-keymap "T" cj/org-table-map)' at top level
silently collided with `cj/transcribe-map' bound to the same key in
`modules/transcription-config.el'.  Whichever module loaded last won,
the other prefix became unreachable, and which-key still showed both
labels in their respective sections -- so the visible documentation
didn't match what actually fired.

Move the table map under the existing `cj/org-map' (`C-; O') as the
"T" sub-prefix, so `C-; T r i' becomes `C-; O T r i' and friends.
The org menu only had one entry before (clear element cache); table
operations are a natural neighbor.  Frees `C-; T' at the top level
for the transcription menu, which was the only other module fighting
over it.
</content>
</entry>
</feed>
