aboutsummaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
Diffstat (limited to 'modules')
-rw-r--r--modules/calendar-sync.el44
-rw-r--r--modules/dirvish-config.el21
-rw-r--r--modules/org-contacts-config.el48
-rw-r--r--modules/org-noter-config.el23
-rw-r--r--modules/vc-config.el21
5 files changed, 133 insertions, 24 deletions
diff --git a/modules/calendar-sync.el b/modules/calendar-sync.el
index 2ff535668..8d7552d3e 100644
--- a/modules/calendar-sync.el
+++ b/modules/calendar-sync.el
@@ -223,7 +223,7 @@ Example: -21600 for CST (UTC-6), -28800 for PST (UTC-8)."
(defun calendar-sync--format-timezone-offset (offset)
"Format timezone OFFSET (in seconds) as human-readable string.
-Example: -21600 → 'UTC-6' or 'UTC-6:00'."
+Example: -21600 → `UTC-6' or `UTC-6:00'."
(if (null offset)
"unknown"
(let* ((hours (/ offset 3600))
@@ -289,7 +289,7 @@ Example: -21600 → 'UTC-6' or 'UTC-6:00'."
"Normalize line endings in CONTENT to Unix format (LF only).
Removes all carriage return characters (\\r) from CONTENT.
The iCalendar format (RFC 5545) uses CRLF line endings, but Emacs
-and 'org-mode' expect LF only. This function ensures consistent line
+and `org-mode' expect LF only. This function ensures consistent line
endings throughout the parsing pipeline.
Returns CONTENT with all \\r characters removed."
@@ -423,14 +423,16 @@ Handles both simple values and values with parameters like TZID."
(defun calendar-sync--get-recurrence-id-line (event-str)
"Extract full RECURRENCE-ID line from EVENT-STR, including parameters.
-Returns the complete line like 'RECURRENCE-ID;TZID=Europe/Tallinn:20260203T170000'.
+Returns the complete line like
+`RECURRENCE-ID;TZID=Europe/Tallinn:20260203T170000'.
Returns nil if not found."
(when (and event-str (stringp event-str))
(calendar-sync--get-property-line event-str "RECURRENCE-ID")))
(defun calendar-sync--parse-ics-datetime (value)
"Parse iCal datetime VALUE into (year month day hour minute) list.
-Returns nil for invalid input. For date-only values, returns (year month day nil nil).
+Returns nil for invalid input. For date-only values, returns
+(year month day nil nil).
Handles formats: 20260203T090000Z, 20260203T090000, 20260203."
(when (and value
(stringp value)
@@ -493,7 +495,8 @@ start time fail to parse. The plist holds :recurrence-id (localized),
(defun calendar-sync--collect-recurrence-exceptions (ics-content)
"Collect all RECURRENCE-ID events from ICS-CONTENT.
Returns hash table mapping UID to list of exception event plists.
-Each exception plist contains :recurrence-id (parsed), :start, :end, :summary, etc."
+Each exception plist contains :recurrence-id (parsed), :start, :end,
+:summary, etc."
(let ((exceptions (make-hash-table :test 'equal)))
(when (and ics-content (stringp ics-content))
(dolist (event-str (calendar-sync--split-events ics-content))
@@ -571,7 +574,8 @@ Returns new list with matching occurrences replaced by exception times."
(defun calendar-sync--get-exdates (event-str)
"Extract all EXDATE values from EVENT-STR.
-Returns list of datetime strings (without TZID parameters), or nil if none found.
+Returns list of datetime strings (without TZID parameters), or nil if
+none found.
Handles both simple values and values with parameters like TZID."
(when (and event-str (stringp event-str) (not (string-empty-p event-str)))
(let ((exdates '())
@@ -584,7 +588,8 @@ Handles both simple values and values with parameters like TZID."
(defun calendar-sync--get-exdate-line (event-str exdate-value)
"Find the full EXDATE line containing EXDATE-VALUE from EVENT-STR.
-Returns the complete line like 'EXDATE;TZID=America/New_York:20260210T130000'.
+Returns the complete line like
+`EXDATE;TZID=America/New_York:20260210T130000'.
Returns nil if not found."
(when (and event-str (stringp event-str) exdate-value)
(let ((pattern (format "^\\(EXDATE[^:]*:%s\\)" (regexp-quote exdate-value))))
@@ -618,7 +623,8 @@ Converts TZID-qualified and UTC times to local time."
(defun calendar-sync--exdate-matches-p (occurrence-start exdate)
"Check if OCCURRENCE-START matches EXDATE.
OCCURRENCE-START is (year month day hour minute).
-EXDATE is (year month day hour minute) or (year month day nil nil) for date-only.
+EXDATE is (year month day hour minute) or (year month day nil nil) for
+date-only.
Date-only EXDATE matches any time on that day."
(and occurrence-start exdate
(= (nth 0 occurrence-start) (nth 0 exdate)) ; year
@@ -682,7 +688,8 @@ Returns nil if property not found."
(defun calendar-sync--get-property-line (event property)
"Extract full PROPERTY line from EVENT string, including parameters.
-Returns the complete line like 'DTSTART;TZID=Europe/Lisbon:20260202T190000'.
+Returns the complete line like
+`DTSTART;TZID=Europe/Lisbon:20260202T190000'.
Returns nil if property not found."
(when (string-match (format "^\\(%s[^\n]*\\)$" (regexp-quote property)) event)
(match-string 1 event)))
@@ -790,8 +797,8 @@ Returns URL string or nil."
(defun calendar-sync--extract-tzid (property-line)
"Extract TZID parameter value from PROPERTY-LINE.
-PROPERTY-LINE is like 'DTSTART;TZID=Europe/Lisbon:20260202T190000'.
-Returns timezone string like 'Europe/Lisbon', or nil if no TZID.
+PROPERTY-LINE is like `DTSTART;TZID=Europe/Lisbon:20260202T190000'.
+Returns timezone string like `Europe/Lisbon', or nil if no TZID.
Returns nil for malformed lines (missing colon separator)."
(when (and property-line
(stringp property-line)
@@ -813,7 +820,7 @@ Returns list (year month day hour minute) in local timezone."
(defun calendar-sync--convert-tz-to-local (year month day hour minute source-tz)
"Convert datetime from SOURCE-TZ timezone to local time.
-SOURCE-TZ is a timezone name like 'Europe/Lisbon' or 'Asia/Yerevan'.
+SOURCE-TZ is a timezone name like `Europe/Lisbon' or `Asia/Yerevan'.
Returns list (year month day hour minute) in local timezone, or nil on error.
Uses Emacs built-in timezone support (encode-time/decode-time with ZONE
@@ -837,8 +844,10 @@ TZ database as the `date' command."
"Convert PARSED datetime to local time using timezone info.
PARSED is (year month day hour minute) or (year month day nil nil).
IS-UTC non-nil means the value had a Z suffix.
+
TZID is a timezone string like \"Europe/Lisbon\", or nil.
-Returns PARSED converted to local time, or PARSED unchanged if no conversion needed."
+Returns PARSED converted to local time, or PARSED unchanged if no
+conversion needed."
(cond
(is-utc
(calendar-sync--convert-utc-to-local
@@ -856,7 +865,8 @@ Returns PARSED converted to local time, or PARSED unchanged if no conversion nee
"Parse iCal timestamp string TIMESTAMP-STR.
Returns (year month day hour minute) or (year month day) for all-day events.
Converts UTC times (ending in Z) to local time.
-If TZID is provided (e.g., 'Europe/Lisbon'), converts from that timezone to local.
+If TZID is provided (e.g., `Europe/Lisbon'), converts from that timezone
+to local.
Returns nil if parsing fails."
(cond
;; DateTime format: 20251116T140000Z or 20251116T140000
@@ -913,7 +923,8 @@ Returns string like '<2025-11-16 Sun 14:00-15:00>' or '<2025-11-16 Sun>'."
(defun calendar-sync--date-to-time (date)
"Convert DATE to time value for comparison.
DATE should be a list starting with (year month day ...).
-Only the first three elements are used; extra elements (hour, minute) are ignored."
+Only the first three elements are used; extra elements (hour, minute) are
+ignored."
(let ((day (nth 2 date))
(month (nth 1 date))
(year (nth 0 date)))
@@ -1082,7 +1093,8 @@ Returns nil if event lacks required fields (DTSTART, SUMMARY).
Skips events with RECURRENCE-ID (individual instances of recurring events
are handled separately via exception collection).
Handles TZID-qualified timestamps by converting to local time.
-Cleans text fields (description, location, summary) via `calendar-sync--clean-text'."
+Cleans text fields (description, location, summary) via
+`calendar-sync--clean-text'."
;; Skip individual instances of recurring events (they're collected as exceptions)
(unless (calendar-sync--get-property event-str "RECURRENCE-ID")
(let* ((uid (calendar-sync--get-property event-str "UID"))
diff --git a/modules/dirvish-config.el b/modules/dirvish-config.el
index 04f9ce20e..f33e8cf74 100644
--- a/modules/dirvish-config.el
+++ b/modules/dirvish-config.el
@@ -41,6 +41,24 @@
(declare-function cj/drill-this-file "org-drill-config")
+;; Dirvish/Dired functions called from lazy-loaded packages.
+(declare-function dirvish-peek-mode "dirvish")
+(declare-function dirvish-side-follow-mode "dirvish")
+(declare-function dirvish-quit "dirvish")
+(declare-function dired-get-marked-files "dired")
+(declare-function dired-dwim-target-directory "dired-aux")
+(declare-function dired-get-file-for-visit "dired")
+(declare-function dired-get-filename "dired")
+(declare-function dired-mark "dired")
+(declare-function dired-current-directory "dired")
+(declare-function dired-file-name-at-point "dired-x")
+(declare-function dired-find-file "dired")
+(declare-function project-roots "project")
+
+;; External package variables referenced before their package loads.
+(defvar ediff-after-quit-hook-internal)
+(defvar dirvish-side-attributes)
+
;; mark files in dirvish, attach in mu4e
(add-hook 'dired-mode-hook 'turn-on-gnus-dired-mode)
@@ -349,7 +367,8 @@ Shadows dired's `P' (`dired-do-print') with this type-aware version."
(defun cj/dirvish-drill-file ()
"Open the Org file at point and start an `org-drill' session on it.
-Bound to `S' (\"study\") in `dirvish-mode-map'; refuses anything but a `.org' file."
+Bound to `S' (\"study\") in `dirvish-mode-map'; refuses anything but
+a `.org' file."
(interactive)
(let ((file (dired-get-filename nil t)))
(unless (and file (not (file-directory-p file)) (string-suffix-p ".org" file t))
diff --git a/modules/org-contacts-config.el b/modules/org-contacts-config.el
index 556530eb2..64abb9fb5 100644
--- a/modules/org-contacts-config.el
+++ b/modules/org-contacts-config.el
@@ -22,6 +22,36 @@
(require 'user-constants)
+;; Function declarations -- these live in lazily-loaded packages, so the
+;; byte-compiler can't see their definitions when this module compiles
+;; standalone.
+(declare-function org-contacts-db "org-contacts")
+(declare-function org-contacts-anniversaries "org-contacts")
+(declare-function org-contacts-files "org-contacts")
+(declare-function org-columns "org-colview")
+(declare-function org-reveal "org")
+(declare-function org-fold-show-entry "org-fold")
+(declare-function org-heading-components "org")
+(declare-function org-map-entries "org")
+(declare-function org-entry-get "org")
+(declare-function outline-next-heading "outline")
+(declare-function calendar-current-date "calendar")
+(declare-function mu4e-message-at-point "mu4e-message")
+(declare-function mu4e-message-field "mu4e-message")
+(declare-function which-key-add-key-based-replacements "which-key")
+
+;; External package variables referenced below; declared so the compiler
+;; treats them as special rather than free.
+(defvar org-capture-plist)
+(defvar org-capture-templates)
+(defvar mu4e~view-message)
+(defvar org-agenda-include-diary)
+(defvar org-agenda-custom-commands)
+(defvar mu4e-org-contacts-file)
+(defvar mu4e-headers-actions)
+(defvar mu4e-view-actions)
+(defvar mu4e-compose-complete-addresses)
+
;; Set `org-contacts-files' eagerly at require time. Setting it in the
;; `use-package' form below would only apply when org-contacts loads, which is
;; deferred behind `:after (org mu4e)' -- later than the first
@@ -42,10 +72,13 @@
(defun cj/org-contacts-anniversaries-safe ()
"Safely call org-contacts-anniversaries with required bindings."
(require 'diary-lib)
- ;; These need to be dynamically bound for diary functions
- (defvar date)
- (defvar entry)
- (defvar original-date)
+ ;; `date', `entry', and `original-date' are diary special vars that the
+ ;; diary functions read dynamically. Declare them special locally; the
+ ;; suppressed warning is the unprefixed-name lint on these calendar names.
+ (with-suppressed-warnings ((lexical date entry original-date))
+ (defvar date)
+ (defvar entry)
+ (defvar original-date))
(let ((date (calendar-current-date))
(entry "")
(original-date (calendar-current-date)))
@@ -186,9 +219,10 @@ Added: %U"
(defun cj/--parse-email-string (name email-string)
"Parse EMAIL-STRING and return formatted entries for NAME.
-EMAIL-STRING may contain multiple emails separated by commas, semicolons, or spaces.
-Returns a list of strings formatted as 'Name <email>'.
-Returns nil if EMAIL-STRING is nil or contains only whitespace."
+EMAIL-STRING may contain multiple emails separated by commas,
+semicolons, or spaces. Returns a list of strings formatted as
+\"Name <email>\". Returns nil if EMAIL-STRING is nil or contains only
+whitespace."
(when (and email-string (string-match-p "[^[:space:]]" email-string))
(let ((emails (split-string email-string "[,;[:space:]]+" t)))
(mapcar (lambda (email)
diff --git a/modules/org-noter-config.el b/modules/org-noter-config.el
index 4e5bd1778..b9b7bbff2 100644
--- a/modules/org-noter-config.el
+++ b/modules/org-noter-config.el
@@ -39,9 +39,32 @@
;; Forward declarations
(declare-function org-id-uuid "org-id")
+(declare-function org-entry-get "org")
(declare-function nov-mode "ext:nov")
(declare-function pdf-view-mode "ext:pdf-view")
+;; pdf-tools fit commands (lazily loaded with pdf-tools)
+(declare-function pdf-view-fit-width-to-window "pdf-view")
+(declare-function pdf-view-fit-height-to-window "pdf-view")
+(declare-function pdf-view-fit-page-to-window "pdf-view")
+;; face-remap is built in but loaded lazily
+(declare-function face-remap-remove-relative "face-remap")
+;; org-noter session/sync/skeleton commands (lazily loaded with org-noter)
+(declare-function org-noter--get-notes-window "org-noter")
+(declare-function org-noter--get-doc-window "org-noter")
+(declare-function org-noter-insert-note "org-noter")
+(declare-function org-noter-enable-org-roam-integration "org-noter")
+(declare-function org-noter-sync-next-note "org-noter")
+(declare-function org-noter-sync-prev-note "org-noter")
+(declare-function org-noter-sync-current-note "org-noter")
+(declare-function org-noter-create-skeleton "org-noter")
+(declare-function org-noter-kill-session "org-noter")
+(declare-function org-noter-toggle-notes-window-location "org-noter")
(defvar nov-file-name)
+;; org-noter package variables assigned at session start / config time
+(defvar org-noter-notes-window-location)
+(defvar org-noter-use-pdftools-link-location)
+(defvar org-noter-use-org-id)
+(defvar org-noter-use-unique-org-id)
;;; Configuration Variables
(defvar cj/org-noter-notes-directory roam-dir
diff --git a/modules/vc-config.el b/modules/vc-config.el
index 654116c59..fcca7e07b 100644
--- a/modules/vc-config.el
+++ b/modules/vc-config.el
@@ -27,6 +27,27 @@
(require 'user-constants) ;; provides code-dir
(require 'keybindings) ;; provides cj/custom-keymap
+;; Forward declaration: cj/vc-map is defined later in this file (see
+;; `defvar-keymap' below) but referenced earlier in a use-package :bind form.
+(defvar cj/vc-map)
+
+;; External package variables (assigned in :config blocks of lazily-loaded
+;; packages, so not loaded at byte-compile time).
+(defvar forge-pull-notifications)
+(defvar forge-topic-list-limit)
+
+;; External package functions (from lazily-loaded packages).
+(declare-function git-gutter:next-hunk "git-gutter")
+(declare-function git-gutter:previous-hunk "git-gutter")
+(declare-function git-timemachine--start "git-timemachine")
+(declare-function git-timemachine--revisions "git-timemachine")
+(declare-function git-timemachine-show-revision "git-timemachine")
+(declare-function forge-current-repository "forge")
+(declare-function forge-create-issue "forge")
+
+;; Defined later in this file; referenced earlier in `cj/git-timemachine'.
+(declare-function cj/git-timemachine-show-selected-revision "vc-config")
+
;; ---------------------------- Magit Configuration ----------------------------
(use-package magit