<feed xmlns='http://www.w3.org/2005/Atom'>
<title>dotemacs/modules/org-agenda-config.el, branch performance</title>
<subtitle>My Emacs configuration
</subtitle>
<id>https://git.cjennings.net/dotemacs/atom?h=performance</id>
<link rel='self' href='https://git.cjennings.net/dotemacs/atom?h=performance'/>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/'/>
<updated>2025-11-12T00:51:33+00:00</updated>
<entry>
<title>perf: Cache org-agenda files to improve view performance</title>
<updated>2025-11-12T00:51:33+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2025-11-12T00:51:33+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/commit/?id=1d2ba0456e169b977bfd4389f2100e02cc10c5f5'/>
<id>urn:sha1:1d2ba0456e169b977bfd4389f2100e02cc10c5f5</id>
<content type='text'>
Applied same caching strategy as org-refile to org-agenda file building.

Root Cause:
- cj/build-org-agenda-list scanned projects-dir recursively
- Called on EVERY agenda view (F8, C-f8)
- directory-files-recursively scans 3,959 files to find 7 todo.org files
- Contributes to 30+ second agenda view time

Solution Implemented:
1. Cache layer with 1-hour TTL
   - First view: builds and caches file list (one-time cost)
   - Subsequent views: use cache (instant)
   - Auto-refresh after 1 hour or Emacs restart

2. Async cache building
   - Runs 10 seconds after Emacs idle (non-blocking)
   - Zero startup impact
   - Cache ready before first agenda view in typical workflow

3. Manual refresh available
   - M-x cj/org-agenda-refresh-files
   - Use after adding new projects/todo.org files
   - Force rebuild bypasses cache

4. Robust error handling
   - Building flag prevents concurrent builds
   - unwind-protect ensures flag always clears
   - Graceful handling if user views agenda before async build completes

Changes (modules/org-agenda-config.el):
- Added cache variables (lines 85-97)
- Modified cj/build-org-agenda-list for caching (lines 116-161)
- Added cj/org-agenda-refresh-files for manual refresh (lines 171-177)
- Async build via run-with-idle-timer (lines 163-169)
- Enhanced commentary documenting performance (lines 6-12)
- Removed emacs-startup-hook (now using idle timer)

Expected Impact:
- Reduces one component of 30+ second agenda view delay
- File list building: several seconds → instant (cached)
- Combined with org-refile optimization: significant daily time savings
</content>
</entry>
<entry>
<title>config: Increase chime modeline lookahead and tooltip display</title>
<updated>2025-11-11T03:02:48+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2025-11-11T03:02:48+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/commit/?id=b18122731e88b7c77c9b4c3f9c6fcd961d85c112'/>
<id>urn:sha1:b18122731e88b7c77c9b4c3f9c6fcd961d85c112</id>
<content type='text'>
Expanded chime modeline settings for better event visibility:
- Lookahead window: 3 hours → 6 hours
- Tooltip max events: 10 → 20
- Tooltip lookahead: 6 days → 7 days (full week)

Provides more advance notice of upcoming events and better weekly overview.
</content>
</entry>
<entry>
<title>feat:chime: Add calendar URL configuration</title>
<updated>2025-11-09T21:34:51+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2025-11-09T21:34:51+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/commit/?id=f85d96473de7587fe6ab3d8a9396ae5897d2cd40'/>
<id>urn:sha1:f85d96473de7587fe6ab3d8a9396ae5897d2cd40</id>
<content type='text'>
Set the calendar URL in chime configuration for better integration
with Google Calendar. Debug mode remains available but disabled by
default.
</content>
</entry>
<entry>
<title>feat: Fix modeline lag and add org multi-level sort with comprehensive tests</title>
<updated>2025-11-08T22:11:58+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2025-11-08T22:11:58+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/commit/?id=513dfd2a1d497da8bd9d5261458cf4140dce7ad6'/>
<id>urn:sha1:513dfd2a1d497da8bd9d5261458cf4140dce7ad6</id>
<content type='text'>
Performance improvement and new feature with full test coverage.

## Changes

### 1. Fix modeline line/column position lag (#A priority)
- Replace expensive line-number-at-pos with cached %l/%c format specifiers
- Enable line-number-mode explicitly for caching
- Result: Instant modeline updates, zero performance overhead
- Files: modules/modeline-config.el:81-83, modules/ui-config.el:53

### 2. Implement multi-level org sorting
- New function: cj/org-sort-by-todo-and-priority
- Sorts by TODO status (TODO before DONE) AND priority (A→B→C→D)
- Uses stable sorting: priority first, then TODO state
- Gracefully handles empty sections (no error)
- Bound to C-; o o (ordering → org sort)
- Files: modules/org-config.el:278-299, modules/custom-ordering.el:253,267

### 3. Comprehensive ERT test suite (12/12 passing)
- Normal cases: Mixed TODO/DONE, multiple of same type, same priority
- Boundary cases: Empty sections, single entries, no priorities
- Error cases: Non-org-mode buffer
- Test file: tests/test-org-sort-by-todo-and-priority.el

### 4. Testing improvements discovered
- Disable org-mode hooks to avoid package dependencies in batch mode
- org-sort-entries must be called from parent heading
- Preserve priority cookie in org-get-heading (t t nil t)
- Add condition-case to handle "Nothing to sort" gracefully

### 5. Minor cleanup
- Comment out chime-debug setting (org-agenda-config.el:267)
- Mark modeline lag task as DONE in todo.org

## Technical Details

Modeline optimization:
- line-number-at-pos is O(n) where n = current line
- %l and %c are O(1) lookups from cached values

Org sorting algorithm uses stable sort:
1. Sort by priority (A, B, C, D, unprioritized)
2. Sort by TODO status (preserves priority order within groups)
Result: TODO [#A], TODO [#B], DONE [#A], DONE [#B], etc.
</content>
</entry>
<entry>
<title>config: Update chime.el to use new alert-intervals format</title>
<updated>2025-11-03T07:09:51+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2025-11-03T07:09:51+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/commit/?id=8e23ac955e126cf335d6b565704f562bff0f5071'/>
<id>urn:sha1:8e23ac955e126cf335d6b565704f562bff0f5071</id>
<content type='text'>
Updated chime configuration for severity refactor:
- Replaced chime-alert-time and chime-alert-severity with
  chime-alert-intervals '((5 . medium) (0 . medium))
- Changed polling interval from 60s to 30s for faster response
- Added chime-day-wide-time "09:00" for all-day event notifications
- Removed settings that match defaults (play-sound, keyword filters, etc.)
- Changed chime-debug from t to nil

All notifications now use medium urgency.
</content>
</entry>
<entry>
<title>feat: Add chime-debug nil setting to config</title>
<updated>2025-11-02T00:03:05+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2025-11-02T00:03:05+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/commit/?id=fac92e65ebafd026dc5c4fd6ffc295ef60061932'/>
<id>urn:sha1:fac92e65ebafd026dc5c4fd6ffc295ef60061932</id>
<content type='text'>
Explicitly set chime-debug to nil in :init section.
Matches new chime.el default (changed from t to nil in recent commit).

Clean production setup - debug mode available by changing to t when needed.
</content>
</entry>
<entry>
<title>fix(org-agenda): improve chime startup integration</title>
<updated>2025-10-30T05:18:03+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2025-10-30T05:18:03+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/commit/?id=6d54c19b9bf77ba07c175f863e172fddd4cb9c1d'/>
<id>urn:sha1:6d54c19b9bf77ba07c175f863e172fddd4cb9c1d</id>
<content type='text'>
This commit fixes timing issues with chime.el startup and simplifies
configuration after chime.el's validation improvements.

## Changes

**1. Fixed org-agenda lazy loading issue**
- Added `:demand t` to org-agenda use-package
- Ensures org-agenda loads before chime tries to use it
- Prevents "org-agenda not available" errors

**2. Cleaned up duplicate rebuild hooks**
- Removed duplicate emacs-startup-hook with idle-timer
- Kept single emacs-startup-hook for rebuild
- Simpler, more maintainable configuration

**3. Simplified chime configuration**
- Restored `(chime-mode 1)` in use-package :config
- Removed conditional fboundp check (no longer needed)
- Works with chime.el's new deferred validation
- Fixed `:after` clause (removed org-agenda dependency)

**4. Fixed formatting issues**
- Removed stray 's' character in add-hook indentation
- Consistent indentation throughout

## Integration with chime.el v0.6.0

This commit pairs with chime.el's new features:
- chime-startup-delay (default 10 sec) gives rebuild hook time to run
- Validation moved to first check (no startup blocking)
- Clean user experience with no false warnings

## Timeline
```
Time 0s:   Emacs starts
Time 0s:   org-agenda loads (:demand t)
Time 0s:   chime-mode 1 (starts timer, no validation)
Time 0.1s: emacs-startup-hook → rebuild org-agenda-files
Time 10s:  First chime-check → validates, finds events
Time 24s:  Modeline populated with events
```

**Result:** 24 second startup (vs previous 463 seconds - 95% improvement)
</content>
</entry>
<entry>
<title>feat: add debug infrastructure for config modules</title>
<updated>2025-10-29T14:38:53+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2025-10-29T14:38:53+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/commit/?id=2979be13b55ae52b795a39db652ca69ee18424e5'/>
<id>urn:sha1:2979be13b55ae52b795a39db652ca69ee18424e5</id>
<content type='text'>
This commit establishes a pattern for organizing debug code in separate
files that can be enabled/disabled via a central toggle.

## Changes

**1. Added debug toggle to user-constants.el**

New variable `cj/debug-modules` controls which modules load debug functions:
- Set to nil (default): No debug functions loaded
- Set to list of symbols: Load debug for specific modules
  Example: (setq cj/debug-modules '(org-agenda mail))
- Set to t: Load all debug modules
  Example: (setq cj/debug-modules t)

Placed early in user-constants.el so it's available before other modules load.

**2. Created org-agenda-config-debug.el**

New debug file contains:
- `cj/org-agenda-debug-dump-files` - Shows all org-agenda-files with status,
  file sizes, and modification times
- `cj/org-agenda-debug-rebuild-timing` - Measures rebuild performance and
  reports detailed timing statistics
- `cj/log-silently` - Helper function to write to *Messages* without echo

All functions use ;;;###autoload for easy invocation before explicit loading.

**3. Added conditional require to org-agenda-config.el**

Checks `cj/debug-modules` and conditionally loads org-agenda-config-debug.el:
```elisp
(when (or (eq cj/debug-modules t)
          (memq 'org-agenda cj/debug-modules))
  (require 'org-agenda-config-debug ...))
```

## Benefits

**Cleaner separation of concerns:**
- Production code stays in main config files
- Debug code isolated in *-debug.el files
- Easy to enable/disable debugging per module

**Reusable pattern:**
- Can be applied to any config module (mail, chime, etc.)
- Consistent naming: &lt;module&gt;-debug.el
- Consistent namespace: cj/&lt;module&gt;-debug-*

**Zero overhead when disabled:**
- Debug files not loaded unless explicitly enabled
- No performance impact on normal usage

## Usage

To enable org-agenda debug functions:
```elisp
;; In user-constants.el or early-init.el
(setq cj/debug-modules '(org-agenda))
```

Then restart Emacs and run:
- M-x cj/org-agenda-debug-dump-files
- M-x cj/org-agenda-debug-rebuild-timing
</content>
</entry>
<entry>
<title>fix: update chime variable names after breaking changes</title>
<updated>2025-10-29T14:21:06+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2025-10-29T14:21:06+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/commit/?id=a002b7546d7548976e400e15e18143643c6d57d5'/>
<id>urn:sha1:a002b7546d7548976e400e15e18143643c6d57d5</id>
<content type='text'>
Update configuration to use renamed chime variables:
- chime-modeline-lookahead → chime-modeline-lookahead-minutes
- Update comment referencing chime-tooltip-lookahead-hours

These variables were renamed in chime.el commit 2a89893
(feat: comprehensive test improvements and lookahead refactoring).

Fixes issue where modeline wasn't displaying after Emacs restart
because the old variable name had no effect.
</content>
</entry>
<entry>
<title>refactor:org-agenda-config: Update chime package</title>
<updated>2025-10-29T13:58:57+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2025-10-29T13:58:57+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/dotemacs/commit/?id=c14d21649fd45d7154fa90025f6ec4db06d16f30'/>
<id>urn:sha1:c14d21649fd45d7154fa90025f6ec4db06d16f30</id>
<content type='text'>
Remove unnecessary blank lines in function docstrings to enhance
readability. Update chime package settings to use a local version
instead of the latest from GitHub, and adjust modeline lookahead and
tooltip settings for better event visibility.
</content>
</entry>
</feed>
