<feed xmlns='http://www.w3.org/2005/Atom'>
<title>dotemacs/modules/org-capture-config.el, branch load-graph-classify-start</title>
<subtitle>My Emacs configuration
</subtitle>
<id>https://git.cjennings.net/dotemacs/atom?h=load-graph-classify-start</id>
<link rel='self' href='https://git.cjennings.net/dotemacs/atom?h=load-graph-classify-start'/>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/'/>
<updated>2026-05-24T09:25:24+00:00</updated>
<entry>
<title>refactor(org-drill): share one validated drill-file selector</title>
<updated>2026-05-24T09:25:24+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-05-24T09:25:24+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/commit/?id=49038c418ead0adc83ffc8fce43c0cb6da9813df'/>
<id>urn:sha1:49038c418ead0adc83ffc8fce43c0cb6da9813df</id>
<content type='text'>
org-capture-config.el and org-drill-config.el each scanned drill-dir with an inline directory-files call, so a missing, empty, or unreadable drill-dir surfaced as a low-level directory-files error or an empty completing-read, depending on which command ran. Added cj/--drill-files-or-error, the single validated entry point: it signals a clear user-error when the directory is missing, unreadable, or has no drill files, and otherwise returns the list. cj/--drill-pick-file and both drill capture templates now route through it. The pure cj/--drill-files-in primitive and its tests are unchanged. Tests cover missing dir, empty dir, a non-org-only dir, and a normal listing.
</content>
</entry>
<entry>
<title>fix(org-capture): single-source the file+headline cache key</title>
<updated>2026-05-11T23:17:22+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-05-11T23:17:22+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/commit/?id=fc94e5b7101f6677950c414c2822b451351ccc56'/>
<id>urn:sha1:fc94e5b7101f6677950c414c2822b451351ccc56</id>
<content type='text'>
`cj/org-capture--goto-file-headline' stored the marker under `(list (expand-file-name (buffer-file-name)) headline)' while the lookup helper `cj/org-capture--file-headline-cache-key' uses `(list (org-capture-expand-file path) headline)'. They agree for plain absolute paths, but a symlinked target (`expand-file-name' doesn't follow symlinks, `find-file' canonicalizes the buffer name) or a capture path that needs `org-capture-expand-file's special handling would make the put-key and get-key diverge, so the cache would silently never hit. Production now goes through the helper too, so the key is built one way.
</content>
</entry>
<entry>
<title>perf(org-capture): cache file+headline target markers</title>
<updated>2026-05-11T22:17:53+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-05-11T22:17:53+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/commit/?id=96ee689709ca45866e985fff2179c0e6797ec697'/>
<id>urn:sha1:96ee689709ca45866e985fff2179c0e6797ec697</id>
<content type='text'>
A task capture took 15-20 seconds: Org resolves a `(file+headline FILE "Headline")' target by opening the file, widening, and regex-scanning from the top for the headline, and the inbox template captures to `(file+headline inbox-file "Inbox")' over and over. An `:around' advice on `org-capture-set-target-location' caches a marker per resolved file/headline. On the next capture it validates the marker (still live, still in an Org buffer, still at a heading, headline text still matches) and jumps straight there. On any mismatch it falls back to the normal scan/create and refreshes the cache. `M-x cj/org-capture-clear-target-cache' resets it. Tests cover the cache hit, marker invalidation after the headline text changes, and creating a missing headline.
</content>
</entry>
<entry>
<title>fix: close drill capture template source link</title>
<updated>2026-05-04T00:28:36+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-05-04T00:28:36+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/commit/?id=6a2539951416fd1ee2ad744090faf255031b71e7'/>
<id>urn:sha1:6a2539951416fd1ee2ad744090faf255031b71e7</id>
<content type='text'>
The "d" drill capture template had a malformed source link with only one closing bracket and a literal `n` where a newline should have been:

    Source: [[%:link][%:description]
    nCaptured On: %U

So new drill captures wrote a broken link and `nCaptured On:` instead of a clean `Captured On:` line on the next row.

I closed the link with the missing `]`, and removed the stray `n` so the line break before "Captured On" is just a real newline. The "f" (PDF drill) template was already correct, so I left it alone.

I added `tests/test-org-capture-config-drill-template.el`. It loads the module, picks up the "d" template, and asserts both the closed link and the `\nCaptured On: %U` form, plus negative assertions against the broken pre-fix shapes.
</content>
</entry>
<entry>
<title>test: add 86 new tests, fix 3 production bugs, fix 8 stale tests</title>
<updated>2026-02-16T01:58:15+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-02-16T01:58:15+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/commit/?id=a6233bb665a68732fb7e13f0b3581bab61de4938'/>
<id>urn:sha1:a6233bb665a68732fb7e13f0b3581bab61de4938</id>
<content type='text'>
New test coverage (86 tests across 7 files):
- custom-case: 43 tests (title-case-region, upcase-dwim, downcase-dwim)
- custom-datetime: 10 tests (all insert methods with mocked time)
- config-utilities: 11 tests (format-build-time type branching)
- org-capture-config: 22 tests (date-prefix + event-content)

Production bugs found and fixed:
- custom-case: title-case-region crashes on whitespace/punctuation-only input
  (char-after returns nil when no word chars found)
- org-capture-config: browser branch missing empty-string guard on :initial
  plist value, producing stray newline in capture output
- mousetrap-mode: keymap never registered in minor-mode-map-alist, so mode
  was silently not blocking any mouse events. Now pushes/removes on toggle.

Additional fixes:
- local-repository: fix cons cell syntax bug in localrepo-initialize
  (was calling vars as functions instead of using cons)
- dupre-theme tests: update rainbow-delimiter color expectations
- mousetrap tests: update dashboard profile (primary-click → scroll+primary)
- music completion test: bind completion-ignore-case to prevent pollution
- Delete redundant interactive recording test (duplicate of ERT version)

Refactoring:
- org-capture-config: extract cj/org-capture--date-prefix pure function
  from cj/org-capture-format-event-headline for testability

Test checklist: todo.org updated to [11/25], removed untestable modules
</content>
</entry>
<entry>
<title>feat(calendar-sync): Add automatic timezone detection and chronological sorting</title>
<updated>2025-11-17T00:09:17+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2025-11-17T00:09:17+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/commit/?id=d842e08de5600c90c2f9de93ca81aea32be9775a'/>
<id>urn:sha1:d842e08de5600c90c2f9de93ca81aea32be9775a</id>
<content type='text'>
Implemented calendar-sync.el as a complete replacement for org-gcal, featuring:

**Core Functionality:**
- One-way sync from Google Calendar to Org (via .ics URL)
- UTC to local timezone conversion for all event timestamps
- Chronological event sorting (past → present → future)
- Non-blocking sync using curl (works reliably in daemon mode)

**Automatic Timezone Detection:**
- Detects timezone changes when traveling between timezones
- Tracks timezone offset in seconds (-21600 for CST, -28800 for PST, etc.)
- Triggers automatic re-sync when timezone changes detected
- Shows informative messages: "Timezone change detected (UTC-6 → UTC-8)"

**State Persistence:**
- Saves sync state to ~/.emacs.d/data/calendar-sync-state.el
- Persists timezone and last sync time across Emacs sessions
- Enables detection even after closing Emacs before traveling

**User Features:**
- Interactive commands: calendar-sync-now, calendar-sync-start/stop
- Keybindings: C-; g s (sync), C-; g a (start auto-sync), C-; g x (stop)
- Optional auto-sync every 15 minutes (disabled by default)
- Clear status messages for all operations

**Code Quality:**
- Comprehensive test coverage: 51 ERT tests (100% passing)
- Refactored UTC conversion into separate function
- Clean separation of concerns (parsing, conversion, formatting, sorting)
- Well-documented with timezone behavior guide and changelog

**Migration:**
- Removed org-gcal-config.el (archived in modules/archived/)
- Updated init.el to use calendar-sync
- Moved gcal.org to .emacs.d/data/ for machine-independent syncing
- Removed org-gcal appointment capture template

Files modified: modules/calendar-sync.el:442, tests/test-calendar-sync.el:577
Files created: data/calendar-sync-state.el, tests/testutil-calendar-sync.el
Documentation: docs/calendar-sync-timezones.md, docs/calendar-sync-changelog.md
</content>
</entry>
<entry>
<title>refactor:org-modules: Improve org-mode configuration</title>
<updated>2025-10-23T05:12:41+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2025-10-23T05:12:41+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/commit/?id=f499ea3bf76fa552bccefbacf2644331f655fb29'/>
<id>urn:sha1:f499ea3bf76fa552bccefbacf2644331f655fb29</id>
<content type='text'>
Remove redundant declarations and reorganize settings for clarity.
Centralize org-mode customizations and use `use-package` for
streamlined loading and configuration. Remove backward-compatible
safeguards and reduce inline comments for cleaner code. Optimize key
mappings and simplify the setup of org-related packages.
</content>
</entry>
<entry>
<title>refactor: org-capture: Simplify and restructure capture config</title>
<updated>2025-10-20T18:16:51+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2025-10-20T18:16:51+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/commit/?id=03627ac73eefb582e8680afcd64c40a0be728ed7'/>
<id>urn:sha1:03627ac73eefb582e8680afcd64c40a0be728ed7</id>
<content type='text'>
Streamlined org-capture-config.el by removing redundant comments,
unused functions, and obsolete declarations. Consolidated the
capture helper functions within use-package configuration for better
readability and maintenance.
</content>
</entry>
<entry>
<title>feat: org-capture: Add drill capture helpers and templates</title>
<updated>2025-10-20T17:56:32+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2025-10-20T17:56:32+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/commit/?id=92f8c8e9c773bfafc06c47a4e7d8aaaae7b83c3c'/>
<id>urn:sha1:92f8c8e9c773bfafc06c47a4e7d8aaaae7b83c3c</id>
<content type='text'>
Introduce functions `cj/drill-source-link` and
`cj/drill-answer-content` for generating source links and content in
org-drill captures. Expand org-capture-templates with new entries
for drill questions and PDF captures. Adjust key mappings with
`keymap-global-set` for task capture.

Enhance the org-drill configuration with new keybindings using
`keymap-set`. Remove old capture template setup and update
initialization sequences.
</content>
</entry>
<entry>
<title>fix: org-capture: appt replaces event, selections auto-finish</title>
<updated>2025-10-18T05:23:29+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2025-10-18T05:23:29+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/commit/?id=1fe816e59f922f9c81dfbb902469f9bda9ded4df'/>
<id>urn:sha1:1fe816e59f922f9c81dfbb902469f9bda9ded4df</id>
<content type='text'>
- moving away from two org files to manage events in favor of simply using gcal integration with org-gcal. disabled capture template for schedule-file.
- text with selection should auto-finish at capture
</content>
</entry>
</feed>
