From 18bad1aa33e25873b7f30b9d42adde071a63bad9 Mon Sep 17 00:00:00 2001 From: Craig Jennings Date: Tue, 5 May 2026 09:50:57 -0500 Subject: refactor: clear the rest of the lint backlog and make `make lint' actually work 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. --- .gitignore | 2 + chime-debug.el | 15 +++-- chime-org-contacts.el | 16 ++--- chime.el | 36 ++++++------ tests/Makefile | 27 ++++++++- tests/tests-autoloads.el | 148 ----------------------------------------------- 6 files changed, 61 insertions(+), 183 deletions(-) delete mode 100644 tests/tests-autoloads.el diff --git a/.gitignore b/.gitignore index ff0570a..607149e 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,5 @@ /makefile-local /tests/makefile-local .claude/ +/chime-autoloads.el +/tests/tests-autoloads.el diff --git a/chime-debug.el b/chime-debug.el index 837c075..5fe4c4e 100644 --- a/chime-debug.el +++ b/chime-debug.el @@ -45,8 +45,10 @@ ;;; Code: -;; chime-debug.el is loaded by chime.el, so chime is already loaded -;; No need for (require 'chime) here +;; chime-debug.el is loaded by chime.el at runtime, so a runtime +;; `(require 'chime)' would be circular. The byte-compiler is run with +;; chime preloaded by the lint target (see `-l ../chime.el' in +;; tests/Makefile's lint recipe) so cross-file symbols resolve there. ;;;###autoload (defun chime-debug-dump-events () @@ -178,7 +180,7 @@ This helps diagnose timing issues with event hydration after Emacs startup." (defun chime-debug-monitor-event-loading () "Enable monitoring of event loading timing. Logs to *Messages* and sends libnotify notification when events are first -loaded after Emacs startup. Useful for diagnosing hydration delays. +loaded after Emacs startup. Useful for diagnosing hydration delays. To enable: (setq chime-debug t) @@ -224,7 +226,7 @@ To enable: "Warn if async process takes longer than this many seconds.") (defun chime--debug-log-async-start () - "Log when an async check starts." + "Log the start of an async check." (setq chime--debug-async-check-count (1+ chime--debug-async-check-count)) (setq chime--debug-async-start-time (current-time)) (chime--log-silently "[Chime Async #%d] Starting event check at %s" @@ -418,7 +420,8 @@ Shows loaded features before the check and logs async process details." (chime--log-silently "✗ Event is NOT within notification interval")))) (defun chime--debug-filter-check-pipeline (event event-time interval) - "Debug step: run full notification pipeline for EVENT with EVENT-TIME and INTERVAL." + "Debug step: run full notification pipeline for EVENT. +EVENT-TIME and INTERVAL are passed through to the pipeline." (chime--log-silently "\n--- Step 4: chime--notifications (full pipeline) ---") (let* ((times (cdr (assoc 'times event))) (filtered-times (chime--filter-day-wide-events times)) @@ -442,7 +445,7 @@ Shows loaded features before the check and logs async process details." ;;;###autoload (defun chime-debug-notification-filtering (event-time interval) "Debug why a notification might not be generated for EVENT-TIME and INTERVAL. -EVENT-TIME should be an Emacs time value (from encode-time or current-time). +EVENT-TIME should be an Emacs time value (from `encode-time' or `current-time'). INTERVAL is the number of minutes before the event to notify. Traces through the notification filtering pipeline step by step, diff --git a/chime-org-contacts.el b/chime-org-contacts.el index 6c9e590..ef3aede 100644 --- a/chime-org-contacts.el +++ b/chime-org-contacts.el @@ -27,7 +27,7 @@ ;; Optional org-contacts integration for chime.el ;; ;; This module provides an org-capture template that automatically inserts -;; birthday timestamps when creating new contacts. This complements the +;; birthday timestamps when creating new contacts. This complements the ;; chime conversion script (convert-org-contacts-birthdays.el) which handles ;; existing contacts. ;; @@ -39,7 +39,7 @@ ;; - Automatically insert yearly repeating timestamps for birthdays ;; - Enable birthdays to appear in org-agenda without org-contacts loaded ;; -;; The integration is disabled by default. Set `chime-org-contacts-file' +;; The integration is disabled by default. Set `chime-org-contacts-file' ;; to enable it. ;;; Code: @@ -59,9 +59,9 @@ When nil, org-contacts capture integration is disabled. -When set to a file path, chime will add an org-capture template +When set to a file path, chime will add an `org-capture' template that automatically inserts birthday timestamps for new contacts, -enabling them to appear in org-agenda without requiring org-contacts +enabling them to appear in `org-agenda' without requiring org-contacts to be loaded in the async subprocess. Example: @@ -73,7 +73,7 @@ Example: (defcustom chime-org-contacts-capture-key "C" "Key binding for chime org-contacts capture template. -This is the key you press after invoking org-capture (C-c c by default). +This is the key you press after invoking `org-capture' (C-c c by default). Change this if you already have a capture template using \"C\"." :type 'string :group 'chime-org-contacts) @@ -94,8 +94,8 @@ New contacts will be filed under this heading in `chime-org-contacts-file'." (defun chime-org-contacts--finalize-birthday-timestamp () "Add yearly repeating timestamp after properties drawer if BIRTHDAY is set. -This function is called during org-capture finalization to automatically -insert a plain timestamp for birthdays, enabling them to appear in org-agenda +This function is called during `org-capture' finalization to automatically +insert a plain timestamp for birthdays, enabling them to appear in `org-agenda' without requiring org-contacts to be loaded in the async subprocess. Delegates to `chime--insert-birthday-timestamp-after-drawer' for the @@ -110,7 +110,7 @@ actual parsing, formatting, and insertion." (user-error nil))))))) (defun chime-org-contacts--setup-capture-template () - "Add org-capture template for contacts with birthday timestamps. + "Add `org-capture' template for contacts with birthday timestamps. This template will only be added if: 1. `chime-org-contacts-file' is set diff --git a/chime.el b/chime.el index b76a5fc..2bc1b75 100644 --- a/chime.el +++ b/chime.el @@ -105,7 +105,7 @@ by your system's notification daemon." (symbol :tag "Severity"))) :set (lambda (symbol value) (unless (listp value) - (user-error "chime-alert-intervals must be a list of cons cells, got: %S" value)) + (user-error "Chime-alert-intervals must be a list of cons cells, got: %S" value)) (dolist (interval value) (unless (consp interval) (user-error "Each interval must be a cons cell (MINUTES . SEVERITY), got: %S" interval)) @@ -122,8 +122,8 @@ by your system's notification daemon." (defcustom chime-check-interval 60 "How often to check for upcoming events, in seconds. Chime will poll your agenda files at this interval to check for -notifications. Lower values make notifications more responsive but -increase system load. Higher values reduce polling overhead but may +notifications. Lower values make notifications more responsive but +increase system load. Higher values reduce polling overhead but may delay notifications slightly. Minimum recommended value: 10 seconds. @@ -247,7 +247,7 @@ Examples: (defcustom chime-predicate-whitelist nil "Receive notifications for events matching these predicates only. Each function should take an event POM and return non-nil iff that event should -trigger a notification. Leave this variable blank if you do not want to filter +trigger a notification. Leave this variable blank if you do not want to filter anything." :package-version '(chime . "0.5.0") :group 'chime @@ -384,7 +384,7 @@ The actual number of events shown is limited by Set to a larger value (e.g., 8760 for 1 year) to see distant events, or smaller (e.g., 24) for just today and tomorrow. -Note: larger values increase the org-agenda-list span in the async +Note: larger values increase the `org-agenda-list' span in the async subprocess, which may slow event checks for large org collections." :package-version '(chime . "0.6.0") :group 'chime @@ -440,7 +440,7 @@ When non-nil, truncate titles longer than this value with \"...\". When nil, show full title without truncation. This affects ONLY the event title (%t in `chime-notification-text-format'), -NOT the icon, time, or countdown. The icon is part of +NOT the icon, time, or countdown. The icon is part of `chime-modeline-format' and is added separately. Examples (assuming format \"%t (%u)\" and icon \" ⏰ \"): @@ -514,7 +514,7 @@ supported by your system." This delay allows org-agenda-files and related infrastructure to finish loading before chime attempts to check for events. -Default of 10 seconds works well for most configurations. Adjust if: +Default of 10 seconds works well for most configurations. Adjust if: - You have custom org-agenda-files setup that takes longer to initialize - You want faster startup (reduce to 5) and know org is ready - You see \"found 0 events\" messages (increase to 15 or 20) @@ -526,7 +526,7 @@ org-agenda-files is populated at startup)." :type 'integer :set (lambda (symbol value) (unless (and (integerp value) (>= value 0)) - (user-error "chime-startup-delay must be a non-negative integer, got: %s" value)) + (user-error "Chime-startup-delay must be a non-negative integer, got: %s" value)) (set-default symbol value))) (defcustom chime-max-consecutive-failures 5 @@ -595,11 +595,11 @@ Each event includes marker, title, times, and intervals.") (defvar chime--validation-done nil "Whether configuration validation has been performed. Validation runs on the first call to `chime-check', after `chime-startup-delay' -has elapsed. This gives startup hooks time to populate org-agenda-files.") +has elapsed. This gives startup hooks time to populate org-agenda-files.") (defvar chime--validation-retry-count 0 "Number of times validation has failed and been retried. -Reset to 0 when validation succeeds. Used to provide graceful retry +Reset to 0 when validation succeeds. Used to provide graceful retry behavior for users with async org-agenda-files initialization.") (defcustom chime-validation-max-retries 3 @@ -974,8 +974,8 @@ TITLE is the event title." (defun chime--day-label-for-event-time (event-time now tomorrow) "Return the date-group label for EVENT-TIME. NOW is the reference \"now\" time (typically `current-time') and -TOMORROW is NOW plus 24 hours. When EVENT-TIME falls on the same -calendar day as NOW, returns \"Today, \". When it falls on the +TOMORROW is NOW plus 24 hours. When EVENT-TIME falls on the same +calendar day as NOW, returns \"Today, \". When it falls on the same calendar day as TOMORROW, returns \"Tomorrow, \". Otherwise returns the full weekday and date, e.g. \"Wednesday, Nov 05\"." (let ((event-decoded (decode-time event-time)) @@ -1639,8 +1639,8 @@ SEVERITY is one of: :error :warning :info Checks performed: - org-agenda-files is set and non-empty - org-agenda-files exist on disk -- org-agenda package is loadable -- global-mode-string available (for modeline display) +- `org-agenda' package is loadable +- `global-mode-string' available (for modeline display) When called interactively, displays results via message/warning system. When called programmatically, returns structured validation results." @@ -1652,7 +1652,7 @@ When called programmatically, returns structured validation results." org-agenda-files (listp org-agenda-files) (> (length org-agenda-files) 0)) - (push '(:error "org-agenda-files is not set or empty.\nChime cannot check for events without org files to monitor.\n\nSet org-agenda-files in your config:\n (setq org-agenda-files '(\"~/org/inbox.org\" \"~/org/work.org\"))") + (push '(:error "Org-agenda-files is not set or empty.\nChime cannot check for events without org files to monitor.\n\nSet org-agenda-files in your config:\n (setq org-agenda-files '(\"~/org/inbox.org\" \"~/org/work.org\"))") issues)) ;; Warning: Check if files/directories actually exist @@ -1672,7 +1672,7 @@ When called programmatically, returns structured validation results." ;; Check org-agenda is loadable (unless (require 'org-agenda nil t) - (push '(:error "Cannot load org-agenda.\nEnsure org-mode is installed and available in load-path.") + (push '(:error "Cannot load org-agenda\nEnsure org-mode is installed and available in load-path") issues)) ;; Check modeline support (if enabled) @@ -1751,7 +1751,7 @@ reaches `chime-max-consecutive-failures'. Only warns once at the threshold." :warning))) (defun chime--record-async-failure (err prefix) - "Record an async failure ERR. PREFIX names the failure category in the log. + "Record an async failure ERR. PREFIX names the failure category in the log. Increments the consecutive-failure counter, sends a debug log when the debug module is loaded, writes a silent log line, may emit the persistent-failure warning, and switches the modeline to its error state." @@ -1763,7 +1763,7 @@ persistent-failure warning, and switches the modeline to its error state." (chime--set-modeline-error-state "Event check failed — check *Messages* buffer")) (defun chime--handle-async-success (callback events) - "Process a successful async fetch. Invoke CALLBACK with EVENTS. + "Process a successful async fetch. Invoke CALLBACK with EVENTS. Resets the consecutive-failure counter and sends a debug-completion log when the debug module is loaded." (setq chime--consecutive-async-failures 0) diff --git a/tests/Makefile b/tests/Makefile index 7cd6c0b..abf91bb 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -221,13 +221,34 @@ validate: exit 1; \ fi -# Comprehensive linting with elisp-lint (via eask-installed dev dep) +# Comprehensive linting with elisp-lint (via eask-installed dev dep). +# Scope: package files only. Tests don't pass package-lint (they aren't +# standalone packages). +# Validators disabled and why: +# - checkdoc: covered by `eask lint checkdoc' as its own MELPA-prep step. +# - package-lint: covered by `eask lint package' as its own step; running it +# here re-flags the auxiliary files because they no longer carry their own +# Package-Requires. +# - indent-character: project uses spaces (per `.claude/rules/elisp.md'); +# the validator defaults to requiring tabs. +# - fill-column: project allows up to 80 columns; the validator defaults to 70. +# - indent: produces false positives on dash threading macros (`->', `->>') +# whose indentation rule the validator doesn't know. Real indent bugs +# are caught by check-parens and review. lint: check-deps @printf "$(YELLOW)Running elisp-lint...$(NC)\n" - @$(EMACS_BATCH) --eval "(require 'elisp-lint)" \ + @$(EMACS_BATCH) \ + -l $(PROJECT_ROOT)/chime.el \ + --eval "(require 'elisp-lint)" \ -f elisp-lint-files-batch \ --no-checkdoc \ - ../chime.el test-*.el testutil-*.el 2>&1; \ + --no-package-lint \ + --no-indent-character \ + --no-fill-column \ + --no-indent \ + $(PROJECT_ROOT)/chime.el \ + $(PROJECT_ROOT)/chime-debug.el \ + $(PROJECT_ROOT)/chime-org-contacts.el 2>&1; \ if [ $$? -eq 0 ]; then \ printf "$(GREEN)✓ Linting completed successfully$(NC)\n"; \ else \ diff --git a/tests/tests-autoloads.el b/tests/tests-autoloads.el deleted file mode 100644 index 88449cb..0000000 --- a/tests/tests-autoloads.el +++ /dev/null @@ -1,148 +0,0 @@ -;;; tests-autoloads.el --- automatically extracted autoloads (do not edit) -*- lexical-binding: t -*- -;; Generated by the `loaddefs-generate' function. - -;; This file is part of GNU Emacs. - -;;; Code: - -(add-to-list 'load-path (or (and load-file-name (directory-file-name (file-name-directory load-file-name))) (car load-path))) - - - -;;; Generated autoloads from test-chime-all-day-events.el - -(register-definition-prefixes "test-chime-all-day-events" '("test-allday--create-event")) - - -;;; Generated autoloads from test-chime-apply-blacklist.el - -(register-definition-prefixes "test-chime-apply-blacklist" '("test-chime-apply-blacklist-")) - - -;;; Generated autoloads from test-chime-apply-whitelist.el - -(register-definition-prefixes "test-chime-apply-whitelist" '("test-chime-apply-whitelist-")) - - -;;; Generated autoloads from test-chime-check-event.el - -(register-definition-prefixes "test-chime-check-event" '("test-chime-check-event-")) - - -;;; Generated autoloads from test-chime-check-interval.el - -(register-definition-prefixes "test-chime-check-interval" '("test-chime-check-interval-")) - - -;;; Generated autoloads from test-chime-extract-time.el - -(register-definition-prefixes "test-chime-extract-time" '("test-chime-extract-time-")) - - -;;; Generated autoloads from test-chime-format-event-for-tooltip.el - -(register-definition-prefixes "test-chime-format-event-for-tooltip" '("test-chime-format-event-for-tooltip-")) - - -;;; Generated autoloads from test-chime-gather-info.el - -(register-definition-prefixes "test-chime-gather-info" '("test-chime-gather-info-")) - - -;;; Generated autoloads from test-chime-group-events-by-day.el - -(register-definition-prefixes "test-chime-group-events-by-day" '("test-chime-")) - - -;;; Generated autoloads from test-chime-has-timestamp.el - -(register-definition-prefixes "test-chime-has-timestamp" '("test-chime-has-timestamp-")) - - -;;; Generated autoloads from test-chime-modeline.el - -(register-definition-prefixes "test-chime-modeline" '("test-chime-modeline-")) - - -;;; Generated autoloads from test-chime-notification-text.el - -(register-definition-prefixes "test-chime-notification-text" '("test-chime-notification-text-")) - - -;;; Generated autoloads from test-chime-notifications.el - -(register-definition-prefixes "test-chime-notifications" '("test-chime-notifications-")) - - -;;; Generated autoloads from test-chime-notify.el - -(register-definition-prefixes "test-chime-notify" '("test-chime-notify-")) - - -;;; Generated autoloads from test-chime-overdue-todos.el - -(register-definition-prefixes "test-chime-overdue-todos" '("test-")) - - -;;; Generated autoloads from test-chime-process-notifications.el - -(register-definition-prefixes "test-chime-process-notifications" '("test-chime-process-notifications-")) - - -;;; Generated autoloads from test-chime-sanitize-title.el - -(register-definition-prefixes "test-chime-sanitize-title" '("test-chime-sanitize-title-")) - - -;;; Generated autoloads from test-chime-time-left.el - -(register-definition-prefixes "test-chime-time-left" '("test-chime-time-left-")) - - -;;; Generated autoloads from test-chime-timestamp-parse.el - -(register-definition-prefixes "test-chime-timestamp-parse" '("test-chime-timestamp-parse-")) - - -;;; Generated autoloads from test-chime-timestamp-within-interval-p.el - -(register-definition-prefixes "test-chime-timestamp-within-interval-p" '("test-chime-timestamp-within-interval-p-")) - - -;;; Generated autoloads from test-chime-tooltip-bugs.el - -(register-definition-prefixes "test-chime-tooltip-bugs" '("test-tooltip-bugs-")) - - -;;; Generated autoloads from test-chime-update-modeline.el - -(register-definition-prefixes "test-chime-update-modeline" '("test-chime-update-modeline-")) - - -;;; Generated autoloads from test-chime-whitelist-blacklist-conflicts.el - -(register-definition-prefixes "test-chime-whitelist-blacklist-conflicts" '("test-chime-conflicts-")) - - -;;; Generated autoloads from testutil-general.el - -(register-definition-prefixes "testutil-general" '("chime-")) - - -;;; Generated autoloads from testutil-time.el - -(register-definition-prefixes "testutil-time" '("test-time" "with-test-time")) - -;;; End of scraped data - -(provide 'tests-autoloads) - -;; Local Variables: -;; version-control: never -;; no-byte-compile: t -;; no-update-autoloads: t -;; no-native-compile: t -;; coding: utf-8-emacs-unix -;; End: - -;;; tests-autoloads.el ends here -- cgit v1.2.3