;;; eww-http-code-advice.el --- Add HTTP status code tracking to eww -*- lexical-binding: t; -*- ;; Copyright (C) 2026 Robert Rose ;; Author: Robert Rose ;; Version: 0.1 ;; Package-Requires: ((emacs "25.1")) ;; Keywords: comm, hypermedia ;; URL: https://consignat.io ;; This file is not part of GNU Emacs. ;; This package is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation; either version 3, or (at your option) ;; any later version. ;; This package is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License ;; along with GNU Emacs. If not, see . ;;; Commentary: ;; Advises `eww-render' to capture the HTTP response status code ;; (from `url-http-response-status') and store it in `eww-data' as ;; `:status-code'. Provides `eww-http-status-string' for display. ;;; Code: (defvar eww-http-status-codes '((100 . "Continue") (101 . "Switching Protocols") (102 . "Processing") (200 . "OK") (201 . "Created") (202 . "Accepted") (203 . "Non-Authoritative Information") (204 . "No Content") (205 . "Reset Content") (206 . "Partial Content") (300 . "Multiple Choices") (301 . "Moved Permanently") (302 . "Found") (303 . "See Other") (304 . "Not Modified") (307 . "Temporary Redirect") (308 . "Permanent Redirect") (400 . "Bad Request") (401 . "Unauthorized") (403 . "Forbidden") (404 . "Not Found") (405 . "Method Not Allowed") (408 . "Request Timeout") (409 . "Conflict") (410 . "Gone") (413 . "Payload Too Large") (414 . "URI Too Long") (415 . "Unsupported Media Type") (418 . "I'm a Teapot") (429 . "Too Many Requests") (451 . "Unavailable For Legal Reasons") (500 . "Internal Server Error") (501 . "Not Implemented") (502 . "Bad Gateway") (503 . "Service Unavailable") (504 . "Gateway Timeout")) "Alist mapping HTTP status codes to reason phrases.") (defun eww-http-status-string () "Return the HTTP status code and reason for the current eww page." (let ((code (plist-get eww-data :status-code))) (if code (format "%d %s" code (or (alist-get code eww-http-status-codes) "Unknown")) "No status"))) ;; Plain variables to shuttle data from :before to :after — the data ;; buffer is killed inside eww-render so buffer-local won't survive. (defvar eww-render-fix--pending-status nil) (defvar eww-render-fix--pending-error nil) (defun eww-render-fix--before (status _url &rest _args) "Capture `url-http-response-status' and error from STATUS. Runs as :before advice on `eww-render' in the data buffer." (setq eww-render-fix--pending-status (bound-and-true-p url-http-response-status)) (setq eww-render-fix--pending-error (plist-get status :error))) (defun eww-render-fix--after (_status _url &optional _point buffer &rest _) "Store captured status code and error into `eww-data'. Runs as :after advice on `eww-render'." (when (and buffer (buffer-live-p buffer)) (with-current-buffer buffer (plist-put eww-data :status-code eww-render-fix--pending-status) (plist-put eww-data :error eww-render-fix--pending-error)))) (advice-add 'eww-render :before #'eww-render-fix--before) (advice-add 'eww-render :after #'eww-render-fix--after) (provide 'eww-http-code-advice) ;;; eww-http-code-advice.el ends here