aboutsummaryrefslogtreecommitdiff
Commit message (Collapse)AuthorAgeFilesLines
* test: add failing tests for the async generation guard and kill pathCraig Jennings2 days1-0/+184
| | | | | | The tests cover a fresh result being processed, a stale one discarded without touching the replacement child's handle or the failure counter, the watchdog and chime--stop both superseding the generation, and chime--kill-async-process reaping a real child and its buffer. Where a mock can't show the behavior, the tests spawn real processes. async.el's buffer handling and the sentinel silencing are the thing under test.
* fix: guard each event's alert callCraig Jennings2 days1-8/+16
| | | | | | chime--process-notifications maps chime--notify over every due event, and the alert call was unguarded. One dbus error partway through dropped every notification after it, and the caller's condition-case then miscounted the whole thing as a fetch failure, walking the counter toward the persistent-failure warning. Each event's alert now fails on its own and reports to *Messages*.
* test: add failing tests for the per-event alert guardCraig Jennings2 days1-0/+43
| | | | One test asserts that an alert error is reported rather than signalled. The other asserts that a failing event doesn't cost us the notifications after it, driving chime--process-notifications over three events with the middle one raising.
* docs: note that a running Emacs won't see a new ALSA configCraig Jennings2 days1-0/+11
| | | | | | alsa-lib parses its configuration once per process, so an emacs --daemon started before the config landed keeps the old view. play-sound-file keeps failing there while it succeeds in a fresh emacs -Q, which reads as the system fix not having worked. Hit this on my own daemon after adding the pipewire default symlink: nine hours' uptime, still no usable default PCM.
* test: assert on chime's messages, not on Emacs staying silentCraig Jennings2 days1-8/+20
| | | | | | | | Three sound tests mocked message and counted everything it captured. Under make coverage, chime.el loads as instrumented source, so the sentinel lambda compiles on first call and emits "Warning: argument '_event' not left unused" through message. That warning landed in the capture list, the counts came out one high, and the Coverage job failed while all five Emacs versions passed. The tests now filter captured messages to chime's own. What they mean is that chime reported the failure once, not that nothing in Emacs said anything. make test and make test-all never load the instrumented source, so they can't catch this. make coverage reproduces it.
* fix(tests): report failure from test-file and validateCraig Jennings3 days1-5/+9
| | | | | | | | | | Both targets read $? after a pipeline, so they got the exit status of the last command in it rather than of Emacs. test-file piped Emacs through tee, so it printed "All tests passed" over a wall of FAILED lines and exited 0. It now redirects to the log, saves the status, and cats the log back. validate piped Emacs through grep, and grep matched the failure line it was looking for, so a file with unbalanced parens printed its error in green and counted as validated. It now captures the output and the status separately. Verified against a deliberately broken file: before the fix, "All 78 files validated successfully" and exit 0. make test and make test-all were never affected. They shell out to test-unit and test-integration without a pipeline.
* fix: inject the lookahead variables into the async fetch childCraig Jennings3 days2-1/+108
| | | | | | | | The child sizes its agenda span from chime-modeline-lookahead-minutes and chime-tooltip-lookahead-hours, but neither was in chime-default-environment-regex. The child requires chime, so both were bound there at their defaults. Customizing either did nothing past the default eight days, with no error to explain why. The tooltip docstring invites 8760 hours to see distant events, and that setting was inert. I added both names to the injected set. The test that matters walks the child form and fails on any chime defcustom it reads that the regex doesn't cover, so a variable added to the child later can't reintroduce this quietly. Its companions pin the regex's anchoring and the additional-regexes extension point.
* fix: drop nil day counts before taking the minimumCraig Jennings3 days1-14/+24
| | | | | | | | chime--days-until-event maps over every timestamp on an event and keeps a day count only for the all-day ones. A timed timestamp maps to nil. An event carrying both kinds handed -min a list with a nil in it, which signals wrong-type-argument. An event with no all-day timestamp handed it an empty list, which signals too. Both crash on every tick once chime-day-wide-advance-notice is on. The recurring failure walks the async counter up to the persistent-failure warning. The map now runs through -non-nil, and an empty result returns nil, which the docstring already promised. I added a nil branch to chime--day-wide-notification-text so a nil count can't reach the = comparisons. The advance-notice window should already exclude an event with no all-day timestamp, so that branch is a guard rather than a live path.
* test: add failing tests for the days-until-event nil crashCraig Jennings3 days1-0/+131
| | | | | | The tests cover a lone all-day timestamp, the soonest of several, an event mixing timed and all-day timestamps, an event with no all-day timestamp, and an empty timestamp list. A sixth covers the notification text when the day count comes back nil. I built the timestamps against the real current time, not testutil-time's base, which sits 30 days ahead. chime--days-until-event measures against current-time, so the shared helper would have made every expected day count wrong.
* docs: document sound-player selection and the ALSA device failureCraig Jennings3 days2-4/+81
| | | | | | CONFIGURATION.org covers how the player is chosen and when chime-sound-device applies. TROUBLESHOOTING.org names the "No usable sound device driver found" error, how to confirm it outside Emacs with aplay, and the two ways out: name a device that resolves, or repair the system so default routes to PipeWire.
* fix: play the chime through an external player when one is availableCraig Jennings3 days2-11/+128
| | | | | | | | | | | | Emacs' play-sound-file opens an ALSA device directly, so it fails with "No usable sound device driver found" wherever ALSA's default PCM doesn't resolve. That's every PipeWire system where nothing points pcm.!default at the sound server. It also blocks Emacs until the clip finishes, and on macOS it isn't compiled in at all. chime now hands the file to the first of pw-play, paplay, afplay or aplay found on exec-path, spawned asynchronously. I put aplay last because it speaks raw ALSA and shares play-sound-file's failure mode, so falling back to it from a broken default PCM would buy nothing. With no external player installed, play-sound-file still runs, now taking chime-sound-device as its DEVICE argument. Two new defcustoms: chime-sound-player (auto, emacs, or a command name) and chime-sound-device. Both default to today's behavior for anyone whose sound already works. A player that spawns and then exits non-zero is reported through a process sentinel rather than failing silently. The sentinel doesn't fall back to play-sound-file, which would reintroduce the blocking ALSA call this change avoids. I pinned the notify tests to emacs so they mock one function and never spawn a real player.
* test: add failing tests for external sound-player selectionCraig Jennings3 days1-0/+301
| | | | | | The tests cover player selection, asynchronous spawn, the fallback to play-sound-file, DEVICE passthrough, the exit-status sentinel, and both players failing. I mock play-sound-file everywhere, so no test opens an audio device. Two tests spawn true or false as a stand-in player, because neither the returned process nor the sentinel's exit status survives a mock.
* test: add chime-deftest fixture macro and centralize test requiresCraig Jennings2026-06-2453-2413/+1705
| | | | | | | | | | Every test hand-wrote the same scaffolding: call a per-file setup, wrap the body in unwind-protect, call a per-file teardown. That's 419 unwind-protect blocks and 68 near-identical setup/teardown defuns, with no shared fixture because ERT has no native per-test setup. I added a chime-deftest macro in test-bootstrap that creates the test base directory before the body and deletes it afterward, even on failure. I converted the 10 files whose fixture was exactly that base-dir create/delete and whose every test followed the standard shape, dropping their setup/teardown defuns. Files with custom fixtures (modeline state restore, validation reset) keep explicit setup/teardown, since the macro would silently drop their extra logic. I left the 4 tag-bearing integration files alone. I also moved the near-universal testutil-general and testutil-time requires into test-bootstrap, so individual files no longer repeat them. Behavior is unchanged: still 800 tests, full suite green. Converted bodies are copied verbatim, so the change only removes scaffolding, never an assertion.
* refactor: drive chime--sanitize-title delimiters from one alistCraig Jennings2026-06-241-35/+15
| | | | The function matched parens, brackets, and braces with three near-identical cond branches plus a parallel opener-to-closer mapping. That's one balancing algorithm written three times. I replaced it with a single ((open . close) ...) alist driven by assq/rassq. Adding or changing a delimiter pair is now a one-line edit, and there's one code path to reason about. Behavior is unchanged. The existing 30 characterization tests stay green.
* test: restore filter defcustom defaults in blacklist teardownsCraig Jennings2026-06-232-3/+9
| | | | | | test-chime-apply-blacklist and test-chime-whitelist-blacklist-conflicts reset the filter defcustoms with setq in their teardowns. The filters aren't buffer-local, so setq clobbers the global default and leaves it nil for every later test in the same Emacs. test-chime-declined-events-predicate-on-default-exclude-filters reads default-value, so it failed in a combined full-suite run while passing per-file. The teardowns now call custom-reevaluate-setting to restore each filter to its standard value. Every test already let-binds its own filter values, so the global only needs returning to its default.
* feat: add themeable faces to the modeline event displayCraig Jennings2026-06-234-7/+294
| | | | | | The modeline event text inherited the mode-line face with no way to style it. I added four faces (chime-modeline-face, chime-modeline-soon-face, chime-modeline-urgent-face, chime-modeline-no-events-face) that color the display by how soon the next event is. Two thresholds, chime-modeline-soon-threshold-minutes (30) and chime-modeline-urgent-threshold-minutes (5), drive the urgency mapping. The default and idle faces inherit mode-line, so the modeline looks unchanged until you theme it. Soon inherits warning and urgent inherits error, so imminent events stand out across themes without configuration.
* chore: stop tracking local dev toolingCraig Jennings2026-06-239-473/+3
|
* chore: refresh .claude rules and hooks to rulesets canonicalCraig Jennings2026-06-123-15/+67
| | | | The startup language-bundle sync repaired drift in these rulesets-owned files. Committing them at canonical so future syncs stay no-ops.
* docs: reword package summary and keywords for searchabilityCraig Jennings2026-06-122-4/+4
| | | | MELPA and list-packages index the summary line, and the old backronym carried no words anyone would search. I reworded it to plain terms and led the Keywords header with a standard finder keyword so package-lint stays clean. I synced the Eask file to match.
* docs: stack README epigraph lines and reword the lead sentenceCraig Jennings2026-06-121-3/+5
| | | | GitHub's org renderer drops #+begin_verse blocks, so the Fitzgerald lines vanished on the rendered page. Blank-line separation stacks them on both GitHub and Emacs export. Also reword the opening sentence, which had leaned on the removed Douglas Adams "whoosh" line.
* docs: replace README epigraph with Fitzgerald's chime verseCraig Jennings2026-06-121-2/+7
| | | | Swap the Douglas Adams deadlines quote for Edward Fitzgerald's sundial verse, which names the chime directly.
* chore: gitignore editor backup filesCraig Jennings2026-06-111-0/+1
|
* docs: document chime-async-timeout and the frozen-modeline symptomCraig Jennings2026-06-112-0/+36
|
* feat: interrupt async fetches that exceed chime-async-timeoutCraig Jennings2026-06-111-1/+51
| | | | A child that never returns produces no error sexp, so no failure path ever sees it. The failure counter stays at zero and the overlap guard blocks every subsequent check. The watchdog interrupts a fetch older than chime-async-timeout (default 120s, nil disables), records it through chime--record-async-failure, and lets the same check spawn a fresh child.
* fix: skip unavailable agenda files in the async fetch childCraig Jennings2026-06-111-0/+5
| | | | A vanished org-agenda-files entry hit org's interactive "[R]emove from list or [A]bort?" recovery prompt inside the -batch child, which blocked forever. The overlap guard then turned every subsequent check into a silent no-op and the modeline froze on a stale countdown. org-agenda-skip-unavailable-files makes org skip the missing file with a message instead.
* test: add failing tests for the async fetch watchdogCraig Jennings2026-06-112-0/+179
|
* fix: scrub aux-file headers in convert-org-contacts-birthdays.elCraig Jennings2026-05-131-3/+4
| | | | The file was added to Eask's (files ...) list in 675fb68 but kept its standalone Version, Package-Requires, and Keywords headers. package-lint flags those as "Package-Requires outside the main file have no effect" and the lint step fails CI. Match the sibling auxiliary-file pattern (chime-debug.el, chime-org-contacts.el): keep Author + URL, add the convention note, drop the redundant metadata.
* fix: scope validate-el.sh hook to in-project filesCraig Jennings2026-05-131-0/+7
| | | | The PostToolUse hook tried to byte-compile every .el file edited, including ones outside the chime project. Out-of-project files typically require packages that aren't on the hook's -L paths, so validation failed for unrelated reasons. Exit 0 when the edited file isn't under $PROJECT_ROOT.
* test: cover per-event override through the agenda pipelineCraig Jennings2026-05-111-0/+79
| | | | The unit tests call chime--gather-info on a marker built in the test. I added a :slow test that goes one layer up. It puts a SCHEDULED heading with :CHIME_NOTIFY_BEFORE: 30 in a temp .org file, runs org-agenda-list, and gathers events the way chime--retrieve-events does in the async child (split the agenda buffer into lines, pull the org-marker from each, drop nils, map chime--gather-info). The resulting event carries ((30 . medium)). That confirms the override survives a marker that came out of org-agenda-list, not just one built in the test.
* docs: document the per-event :CHIME_NOTIFY_BEFORE: propertyCraig Jennings2026-05-112-1/+23
| | | | The README's migration note said the per-event reminder property had been removed. That's stale now that the property is back. I rewrote the line to point at :CHIME_NOTIFY_BEFORE: and the deprecated :WILD_NOTIFIER_NOTIFY_BEFORE: alias. I also added a "Per-Event Override" section to docs/CONFIGURATION.org covering the syntax, the no-inheritance behavior, malformed-value handling, and the alias's deprecation path.
* feat: add per-event :CHIME_NOTIFY_BEFORE: interval overrideCraig Jennings2026-05-113-57/+152
| | | | | | | | | | Chime's migration from org-wild-notifier dropped the per-event notify-before property, so a heading could no longer override the global chime-alert-intervals. I brought it back. A heading's :CHIME_NOTIFY_BEFORE: N (a non-negative integer) means "notify once, N minutes before, severity medium" and replaces chime-alert-intervals for that event. The org-wild-notifier name :WILD_NOTIFIER_NOTIFY_BEFORE: still works, as a deprecated alias. When it supplies the value, chime emits one per-session warning pointing at the new name. :CHIME_NOTIFY_BEFORE: wins when both are set. A malformed value logs a message naming the heading and falls back to the global. chime--gather-info reads the property in the async child. The deprecation flag rides on the event alist so the parent emits the warning without changing the async return contract. I also touched two test files. test-chime-async-helpers.el's fixtures fed bare symbols where chime--handle-async-success now expects event alists, so they build real events via chime--make-event. And the new test file's message-capture macro had a lexical-scoping bug (the captured list was invisible after the macro returned), so the two affected tests inline the capture and the macro is gone.
* test: add failing tests for per-event interval overrideCraig Jennings2026-05-111-0/+208
| | | | | | I added fifteen tests ahead of the implementation, covering the per-event :CHIME_NOTIFY_BEFORE: property and the deprecated :WILD_NOTIFIER_NOTIFY_BEFORE: alias: value-string parsing (chime--parse-notify-before-value), property lookup with global fallback (chime--intervals-for-marker), the gather path (chime--gather-info honoring the property and flagging the alias on the event), and the once-per-session deprecation warning (chime--maybe-warn-deprecated-properties). They all fail with void-function for the not-yet-defined helpers, plus a length mismatch on the gather-info tests since chime--gather-info still uses the global chime-alert-intervals.
* docs: correct test inventory and org-wild-notifier historyCraig Jennings2026-05-112-19/+6
| | | | | | TESTING.org carried a frozen "645 tests as of 2026-04-04" inventory plus a top-files table that goes stale every time a test file is added. I replaced it with a one-line pointer to `make count`, which is the live source. README's History section said Artem Khramov "deprecated org-wild-notifier in favor of org-alert." He didn't. He archived the repo and stopped responding to issues. The README's "Alternatives" section listed org-alert and org-notify neutrally, never as recommended successors. And the project has since been picked back up under the Emacs Orphanage. I rewrote the paragraph to describe what happened and added a line about the orphanage fork.
* test: close coverage gaps to 99.88% line coverageCraig Jennings2026-05-115-0/+549
| | | | | | Five new test files cover branches the per-function suites missed: the day-wide notification pipeline, the jump-to-event navigation path (including the org-show-entry fallback for Org < 9.6), chime--stop's process-interrupt branch, chime--start's debug log, and the two async error branches in chime--fetch-and-process. The edge-coverage file mops up scattered one-line fallbacks: the day-wide-notification "today" path, the tooltip placeholder pass-through, timestamp-parse's no-context error message, log-silently's mid-line newline insert, the validation :error count, and record-async-failure's chime-debug hook. Line coverage on chime.el goes from 97.1% to 99.88%, 823 of 824 coverable lines. The one remaining line is a pcase _ fallback the preceding regex can't reach.
* feat: make modeline status-message strings customizableCraig Jennings2026-05-113-10/+235
| | | | | | The validation banner, retry-attempt message, async-failure tooltip, and the initial loading tooltip were hardcoded English literals. I added defcustoms for them so the wording can be localized or adjusted. The format-string ones keep their %d/%s directives, with the order spelled out in each docstring. I also dropped the dead :info severity from chime-validate-configuration's docstring. The function only ever emitted :ok, :warning, and :error.
* build: include optional helpers and sounds in packageCraig Jennings2026-05-101-1/+5
|
* feat: tighten chime runtime validation and tooltip behaviorCraig Jennings2026-05-1010-742/+1344
|
* docs: split detailed user docs out of readmeCraig Jennings2026-05-105-1035/+1019
|
* test: harden test dependency and temp-dir setupCraig Jennings2026-05-105-16/+143
|
* chore: symlink claude rules to rulesets canonicalCraig Jennings2026-05-073-385/+3
| | | | | | The .claude/rules/ files (commits.md, testing.md, verification.md) were local copies that drifted from the canonical at ~/code/rulesets. I replaced them with absolute symlinks pointing at the canonical files. This repo now picks up rule updates automatically. The symlinks are absolute. Cloning this repo on a new machine needs ~/code/rulesets at the same path. Otherwise the symlinks dangle.
* refactor!: collapse six filter defcustoms into include/exclude alistsCraig Jennings2026-05-058-246/+228
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Six per-axis filter variables (keyword/tags/predicate × whitelist/blacklist) were carrying parallel structure for what's really one decision: include events that look like X, exclude events that look like Y. I merged them into two alists, `chime-include-filters' and `chime-exclude-filters', each keyed by axis (`keywords', `tags', `predicates'). Default for `chime-exclude-filters' keeps the same out-of-the-box behavior — done items and declined Google Calendar invites stay filtered: ((predicates . (chime-done-keywords-predicate chime-declined-events-predicate))) Implementation: one shared `chime--filter-predicates' helper that walks the alist and emits a marker-taking predicate per non-empty axis. The public callers — now `chime--apply-include-filters' and `chime--apply-exclude-filters' — wrap that helper with `-orfn'-then-`-filter' and `-orfn'-then-`-remove' respectively. The async-environment regex injection list shrank from six names to two, and the debug config dump in chime-debug.el follows. The terminology shift (whitelist/blacklist → include/exclude) drops loaded language for descriptive intent. The internal helpers and the public function names all moved together. Tests: 700-ish lines across five test files (test-chime-apply-whitelist, test-chime-apply-blacklist, test-chime-whitelist-blacklist-conflicts, test-chime-environment-regex, test-chime-declined-events-predicate) were rewritten to bind the new alists. The dedup-conflict tests still exercise the same precedence rule (exclude wins on overlap). README's filtering section was rewritten end-to-end with new examples. Migration: (setq chime-keyword-whitelist '("TODO")) ;; -> (setq chime-include-filters '((keywords . ("TODO")))) (setq chime-predicate-blacklist '(my-pred)) ;; -> (setq chime-exclude-filters '((predicates . (my-pred)))) This brings the consolidation pass to 37 -> 29 defcustoms, the target from .ai/settings-consolidation.org.
* refactor!: collapse three time-left format defcustoms into one alistCraig Jennings2026-05-056-67/+82
| | | | | | | | | | | | | | | | | | | | | | | | I merged `chime-time-left-format-at-event', `chime-time-left-format-short', and `chime-time-left-format-long' into a single alist `chime-time-left-formats' keyed by `at-event' / `short' / `long'. Three knobs for one feature (countdown display) was unnecessary surface area; one alist is the same flexibility with a third the namespace. `chime--time-left' switched from a pcase-on-variable to a pcase-on-regime that picks an alist key, then `alist-get's the format string. Behavior is identical for default settings. Test setup in the four affected files now builds the alist with `(list (cons 'KEY VAL) ...)' instead of `'(...)'. The literal-quote form returns the SAME cons-cell structure on every evaluation, so a previous test mutating it via `setf' on `alist-get' poisoned later tests. `list' + `cons' produces fresh structure per call, which is what the tests actually need. Migration: `(setq chime-time-left-format-short "in %mm")' becomes `(setf (alist-get 'short chime-time-left-formats) "in %mm")', or a full `(setq chime-time-left-formats '((at-event . ...) (short . ...) (long . ...)))' replacement.
* refactor!: demote chime-validation-max-retries to private defvarCraig Jennings2026-05-054-52/+25
| | | | | | | | | | | | | | | | | | | | | This is an internal startup-timing parameter, not a knob real users have reason to tune through `M-x customize'. I demoted it from defcustom to defvar and renamed it to `chime--validation-max-retries' to make the private status explicit. Anyone who was overriding it can keep doing so with `setq' (the variable still exists, just under the new name). The three customize-time validation tests went away with the defcustom — nothing left to validate at customize-time once it stops being a customize-target. The setter helper still applies to the other five numeric defcustoms. Test files that referenced the variable (`test-chime-validation-retry.el', `test-integration-chime-mode.el') were renamed mechanically along with the source. Breaking change: `(setq chime-validation-max-retries N)' becomes `(setq chime--validation-max-retries N)' if you actually had it. Most users won't have touched it.
* refactor!: drop chime-play-sound, use chime-sound-file = nil to disableCraig Jennings2026-05-053-48/+17
| | | | | | | | | | | | | | | | | `chime-play-sound' was redundant with `chime-sound-file' — both had to be truthy for sound to play, and `chime-sound-file' already documented "set to nil to disable sound completely". Two knobs for one decision is a trap. I removed the defcustom and the `(when chime-play-sound ...)' guard in `chime--notify' (it now just checks `chime-sound-file'). Tests, README quick-start, and the troubleshooting checklist all reference the new single-knob form. One redundant test (sound-disabled-via-the-toggle) got dropped because it now duplicates the sound-file-nil case. Breaking change: users with `(setq chime-play-sound nil)' in their config will get a void-variable warning at customize time and lose their disable. Migration: `(setq chime-sound-file nil)'.
* fix: validate numeric defcustoms at customize-timeCraig Jennings2026-05-052-6/+228
| | | | | | | | | | | | | | | | | | | | | | | | | | Six numeric settings are declared as integers but were read straight into arithmetic and timer math. A bad value (string, negative number, nil where nil isn't supported) used to slip past the defcustom and surface as a timer error or `arith-error' deep in a callback, instead of as a configuration problem at the moment the user set it. I added `chime--validate-integer-setting' as a small shared helper and wired a `:set' on each of the affected defcustoms: - `chime-modeline-lookahead-minutes' — integer >= 0 (0 disables) - `chime-tooltip-lookahead-hours' — integer >= 1 - `chime-modeline-tooltip-max-events' — integer >= 1 or nil (show all) - `chime-day-wide-advance-notice' — integer >= 0 or nil (same-day only) - `chime-max-consecutive-failures' — integer >= 0 (0 disables warnings) - `chime-validation-max-retries' — integer >= 0 (0 = fail immediately) The constraints follow each docstring's stated intent. The helper signals `user-error', so `customize-set-variable' surfaces it as a config problem rather than a generic error trace. Tests: 22 cases in `tests/test-chime-numeric-defcustom-setters.el' — five direct on the helper plus each defcustom's accept/reject paths through `customize-set-variable'.
* fix: stop tooltip dedup from hiding distinct events sharing a titleCraig Jennings2026-05-052-14/+76
| | | | | | | | | | | | | | | | | `chime--deduplicate-events-by-title' was keying off the user-facing title alone, so two real "1:1" entries on different days collapsed to one and the second one disappeared from the tooltip. I changed the key to `(marker-file . marker-pos)' — the source heading identity — so distinct headings keep both copies and recurring expansions of one heading still fold to the soonest. When marker info is missing (synthesized test events, edge cases) the key falls back to title, which preserves the older fixtures the function was originally tested against. Three new tests cover the regression paths: two distinct headings sharing a title both survive, one heading expanded into multiple instances still collapses to the soonest, and a mix of sourced and unsourced events behaves correctly under both code paths.
* ci: flip lint job from advisory to requiredCraig Jennings2026-05-051-6/+1
| | | | | | | The lint backlog is now zero — all three checks (package-lint, checkdoc, elisp-lint) are clean. Drop `continue-on-error: true' from each step so a regression actually fails the build instead of quietly turning the job green.
* refactor: clear the rest of the lint backlog and make `make lint' actually workCraig Jennings2026-05-056-183/+61
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Took the package-lint commit's foundation and finished the job. Three groups of changes: 1. **checkdoc** is now clean across all three package files. I worked through every warning: 13 missing-double-space-after-period fixes, 4 message-capitalization fixes, 1 trailing-period-on-error fix, 6 Lisp-symbol-should-be-quoted fixes, and one rephrase from "starts" to the imperative "Log the start of an async check". One `chime-debug.el' docstring also exceeded 80 columns and got split into two lines. 2. **`make lint'** ran elisp-lint but had been silently broken. The shell glob `test-*.el' wasn't expanding (CWD ended up at project root, not tests/), and the noisy validators flagged everything. I rewrote the target to lint package files explicitly via absolute paths, preload chime.el so the byte-compiler sees cross-file symbols when checking chime-debug.el, and disable the validators that conflict with project style or duplicate other lint steps: - `--no-checkdoc' (covered by `eask lint checkdoc') - `--no-package-lint' (covered by `eask lint package'; running it on auxiliary files re-flags them as standalone packages) - `--no-indent-character' (project uses spaces per `.claude/rules/elisp.md'; the validator defaults to tabs) - `--no-fill-column' (project allows up to 80; validator defaults to 70) - `--no-indent' (false-positives on dash threading macros `->'/`->>') The validators-disabled list is documented in the recipe header. 3. **Generated autoload files** (`chime-autoloads.el', `tests/tests-autoloads.el') are now gitignored. `tests/tests-autoloads.el' was tracked from an earlier commit; I removed it from the index. Eask regenerates these on every `eask compile' / `eask install-deps' run, so they don't belong in the tree. Verified: `make compile' clean (with byte-compile-error-on-warn t), `make test-all' green at 677 tests, `eask lint package' clean, `eask lint checkdoc' clean, `make lint' clean. Full lint backlog is now zero across all three checks.
* refactor: clear package-lint warnings for MELPA prepCraig Jennings2026-05-056-59/+73
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | I worked through the package-lint backlog and got it to zero. Five changes: 1. Renamed six interactive debug commands from the private `chime--debug-*' prefix to the public `chime-debug-*' form. They were always M-x targets, so the private prefix was just wrong. The autoload cookies stay because public commands SHOULD be autoloaded. README, docstring references in chime.el, and the matching tests follow the rename. 2. Dropped `Version', `Package-Requires', and `Keywords' headers from chime-org-contacts.el. Auxiliary files in a multi-file package shouldn't carry their own metadata — package-lint flags it as an error because the headers have no effect outside the main file. The main file (chime.el) already declares the chime package's metadata. 3. Dropped `Keywords' from chime-debug.el for the same reason. 4. Dropped the auto-loader for the optional chime-org-contacts integration from chime.el. The old code used `with-eval-after-load 'org-capture' to pull the file in, which package-lint flags as a configuration pattern that doesn't belong in a package. Users who want the integration now require it themselves; the README shows both the plain `with-eval-after-load' pattern and the `use-package :after' form. chime-org-contacts.el's internal `with-eval-after-load' went away too — by the time the user has required the file, they've already gated it on org-capture being loaded, so the inner check is redundant. 5. Dropped the redundant `with-eval-after-load' from chime-org-contacts.el's activation block. The setup function still guards on `(boundp 'org-capture-templates)' so it's safe to require either order. Behavioral note: this is a small breaking change for anyone whose config relied on the auto-load. The README change spells out the migration path.
* test: replace string-search with portable form for Emacs 27.1Craig Jennings2026-05-051-11/+11
| | | | | | | | `string-search' was added in Emacs 28.1. Since chime's package floor is 27.1, the convert-org-contacts-birthdays test file failed on that version in CI. I swapped each `string-search NEEDLE HAYSTACK' for the equivalent `string-match-p (regexp-quote NEEDLE) HAYSTACK', which works on 27.1+ and returns a truthy value the same way.