;;; wttrin-debug.el --- Debug functions for wttrin.el -*- lexical-binding: t; -*- ;; Copyright (C) 2025-2026 Craig Jennings ;; Author: Craig Jennings ;; Keywords: debug weather wttrin ;; SPDX-License-Identifier: GPL-3.0-or-later ;;; Commentary: ;; This file contains debug functions for troubleshooting wttrin.el behavior. ;; It is only loaded when `wttrin-debug' is non-nil. ;; ;; Enable with: ;; (setq wttrin-debug t) ;; (require 'wttrin) ;; ;; Available debug functions: ;; - `debug-wttrin-show-raw' - View raw weather data with line numbers ;; - `debug-wttrin-mode-line' - Diagnose mode-line lighter issues ;; - `wttrin--debug-mode-line-info' - Auto-called when wttrin runs (if debug enabled) ;; ;; Interactive commands: ;; - M-x debug-wttrin-enable - Enable debug mode ;; - M-x debug-wttrin-disable - Disable debug mode ;; ;; When debug mode is enabled, raw weather data is automatically saved to ;; timestamped files in `temporary-file-directory' for bug reports. ;;; Code: ;; wttrin-debug.el is loaded by wttrin.el, so wttrin is already loaded ;; No need for (require 'wttrin) here ;; Declare variables and functions from wttrin.el (defvar wttrin-debug) (declare-function wttrin--get-cached-or-fetch "wttrin") ;;;###autoload (defun debug-wttrin-show-raw (location) "Fetch and display raw wttr.in data for LOCATION with line numbers. This is useful for debugging header parsing issues. Always fetches fresh data from the API, bypassing cache." (interactive "sLocation: ") (let ((wttrin--force-refresh t)) (wttrin--get-cached-or-fetch location (lambda (raw-string) (with-current-buffer (get-buffer-create "*wttrin-debug*") (erase-buffer) (when raw-string (insert raw-string)) (goto-char (point-min)) (let ((line-num 1)) (while (not (eobp)) (beginning-of-line) (insert (format "%2d: " line-num)) (setq line-num (1+ line-num)) (forward-line 1))) (goto-char (point-min)) (switch-to-buffer (current-buffer))))))) ;;;###autoload (defun debug-wttrin-enable () "Enable wttrin debug mode. Raw weather data will be saved to timestamped files for bug reports." (interactive) (setq wttrin-debug t) (message "Wttrin debug mode enabled. Raw data will be saved to: %s" temporary-file-directory)) ;;;###autoload (defun debug-wttrin-disable () "Disable wttrin debug mode." (interactive) (setq wttrin-debug nil) (message "Wttrin debug mode disabled")) ;;;###autoload (defun debug-wttrin-mode-line () "Display detailed mode-line information for the wttrin buffer. This is useful for diagnosing why the mode-line lighter isn't appearing." (interactive) (if-let ((buf (get-buffer "*wttr.in*"))) (with-current-buffer buf (let* ((has-custom-modeline (boundp 'cj/modeline-major-mode)) (formatted-mode (when has-custom-modeline (format-mode-line mode-name)))) (with-output-to-temp-buffer "*wttrin-mode-debug*" (princ (format "=== Wttrin Mode-Line Debug Info ===\n\n")) (princ (format "Buffer: %s\n" (buffer-name))) (princ (format "Major mode: %s\n" major-mode)) (princ (format "mode-name variable: %S\n" mode-name)) (princ (format "mode-name type: %s\n" (type-of mode-name))) (princ (format "\nCustom modeline detected: %s\n" has-custom-modeline)) (when has-custom-modeline (princ (format "format-mode-line result: %S\n" formatted-mode))) (princ (format "\nmode-line-format first 5 elements:\n")) (let ((i 0)) (dolist (elem mode-line-format) (when (< i 5) (princ (format " [%d] %S\n" i elem)) (setq i (1+ i))))) (princ (format "\nSpecial-mode parent: %s\n" (get 'wttrin-mode 'derived-mode-parent))) (princ (format "Is special-mode active: %s\n" (derived-mode-p 'special-mode)))))) (message "No *wttr.in* buffer exists. Run M-x wttrin first."))) (defun wttrin--debug-mode-line-info () "Auto-generate mode-line diagnostic information. This function is called automatically when wttrin runs if debug mode is enabled. It creates the *wttrin-mode-debug* buffer with diagnostic information." (debug-wttrin-mode-line)) (defvar wttrin--debug-log nil "List of debug log entries. Each entry is (timestamp . message).") (defun wttrin--debug-log (format-string &rest args) "Log a debug message if wttrin-debug is enabled. FORMAT-STRING and ARGS are passed to `format'. Messages are stored in `wttrin--debug-log' for later review." (when wttrin-debug (let ((msg (apply #'format format-string args)) (timestamp (format-time-string "%H:%M:%S.%3N"))) (push (cons timestamp msg) wttrin--debug-log)))) ;;;###autoload (defun wttrin-debug-clear-log () "Clear the debug log." (interactive) (setq wttrin--debug-log nil) (message "Wttrin debug log cleared")) ;;;###autoload (defun wttrin-debug-show-log () "Display the wttrin debug log in a buffer." (interactive) (with-current-buffer (get-buffer-create "*wttrin-debug-log*") (erase-buffer) (insert "=== WTTRIN DEBUG LOG ===\n") (insert (format "Total entries: %d\n\n" (length wttrin--debug-log))) (if wttrin--debug-log (dolist (entry (reverse wttrin--debug-log)) (insert (format "[%s] %s\n" (car entry) (cdr entry)))) (insert "(No log entries yet)\n")) (goto-char (point-min)) (display-buffer (current-buffer)))) (provide 'wttrin-debug) ;;; wttrin-debug.el ends here