;;; browse-url-transform --- transform URLs (defgroup browse-url-transform nil "Transformations for urls passed to `browse-url'." :group 'browse-url) (defcustom browse-url-transform-alist nil "Transformation rules for URLs. The keys are regexps matching URLs, and the values are how to transform them. The replacements will use match capture data." :type '(alist :key-type (string :tag "URL regexp match") :value-type (string :tag "URL regexp transformation"))) (defun browse-url-transform-url (url) "Transform URL before passing it to `browse-url'." (cl-loop with url = (substring-no-properties (if (consp url) (car url) url)) for (regex . transformation) in browse-url-transform-alist if (string-match regex url) return (replace-match transformation nil nil url) finally return url)) (defun browse-url-transform-advice (url &rest args) "Advice to `browse-url' for URL transformations. ARGS are passed on for further processing." (apply #'list (and url (browse-url-transform-url url)) args)) (define-minor-mode browse-url-transform-mode "Minor mode to transform a URL before passing it to `browse-url'. This can be used to \"redirect\" URLs, for example from an information silo to a more privacy-respecting one (e.g., \"twitter.com\" -> \"nitter.com\"), by adding advice to `browse-url'. When using this mode, ensure that the transformed URL is also in `browse-url-handlers', since that's what `browse-url' will see." :lighter " Turl" :keymap nil :global t (cond (browse-url-transform-mode (advice-add 'browse-url :filter-args #'browse-url-transform-advice)) (:else (advice-remove 'browse-url #'browse-url-transform-advice)))) (provide 'browse-url-transform) ;;; browse-url-transform.el ends here