detubifier.el (8943B)
1 ;;; detubifier.el --- Kill text and replace youtube.com and youtu.be or whatever domain with whatever the fuck you want. -*- lexical-binding: t; -*- 2 3 ;; Copyright (C) 2024 Yuval Langer 4 5 ;; Author: Yuval Langer <yuval.langer@gmail.com> 6 ;; Version: 0.3.0 7 ;; Keywords: web, youtube 8 ;; URL: https://codebarg.org/kakafarm/emacs-detubifier-mode/ 9 10 11 ;; This program is free software: you can redistribute it and/or modify 12 ;; it under the terms of the GNU Affero General Public License as 13 ;; published by the Free Software Foundation, either version 3 of the 14 ;; License, or (at your option) any later version. 15 16 ;; This program is distributed in the hope that it will be useful, 17 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 18 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 ;; GNU Affero General Public License for more details. 20 21 ;; You should have received a copy of the GNU Affero General Public License 22 ;; along with this program. If not, see <https://www.gnu.org/licenses/>. 23 24 ;;; Commentary: 25 26 ;; Usage: 27 ;; 28 ;; Let's say you have the text 29 ;; "https://twitter.com/Nadav_Eyal/status/1809975194926055629" and 30 ;; would rather have something like 31 ;; "https://nitter.poast.org/Nadav_Eyal/status/1809975194926055629" 32 ;; instead. A possible solution is to: 33 ;; 34 ;; 0. Set up `detubifier-regexp-replacement-pairs'. 35 ;; 1. Mark that text. 36 ;; 2. Kill it. 37 ;; 3. Run `detubifier-regexp-replacement-pairs'. 38 ;; 4. Yank it in your chat room. 39 40 ;;; Code: 41 42 (require 'browse-url) 43 44 (defgroup detubifier '() 45 "Replace the usual enshittified suspects with nonenshittified front end services." 46 :group 'communcation) 47 48 (defcustom detubifier-regexp-replacement-pairs 49 `((,(rx "https://www.youtube.com/") . "https://invidious.jing.rocks/") 50 (,(rx "https://youtube.com/") . "https://invidious.jing.rocks/") 51 (,(rx "https://youtu.be/") . "https://invidious.jing.rocks/watch?v=") 52 (,(rx "https://twitter.com/") . "https://nitter.poast.org/") 53 (,(rx "https://x.com/") . "https://farside.link/")) 54 "List of pairs, each with a regexp and its replacement." 55 :type '(repeat (cons regexp string)) 56 :group 'detubifier 57 ) 58 59 (defcustom detubifier-farside-url 60 "https://farside.link/" 61 "Base address to the farside service." 62 :type 'string 63 :group 'detubifier 64 ) 65 66 (defcustom detubifier-detubifying-method 67 'farside 68 "Method of detubifying." 69 :type '(radio (symbol farside) 70 (symbol custom)) 71 :group 'detubifier 72 ) 73 74 (defcustom detubifier-enshittified-urls 75 '( 76 "https://reddit.com/" 77 "https://twitter.com/" 78 "https://www.reddit.com/" 79 "https://www.twitter.com/" 80 "https://www.youtube.com/" 81 "https://x.com/" 82 "https://youtu.be/" 83 "https://youtube.com/" 84 "https://github.com" 85 ) 86 "URLs of enshittified services." 87 :type '(repeat string) 88 :group 'detubifier 89 ) 90 91 ;;;###autoload 92 (defun detubifier-browse-url (url &rest args) 93 "Open URL using `browse-url' with the usual suspect URLs replaced. 94 95 Replace the usual suspect URLs with the method chosen by the 96 `detubifier-detubifying-method' custom variable. 97 98 ARGS is passed as the ARGS of `browse-url'. 99 100 TODO: What are args in `browse-url'?" 101 102 (interactive (browse-url-interactive-arg "URL: ")) 103 104 (pcase detubifier-detubifying-method 105 ('farside (browse-url (detubifier-farsidify-string url) args)) 106 ('custom (browse-url (detubifier-custom-detubify-string url) args)))) 107 108 ;;;###autoload 109 (defun detubifier-custom-detubify-region (beg end) 110 "Replace the usual suspect URLs in region. 111 112 Region is defined either by (region-beginning) and (region-end), 113 or, if provided, between between BEG and END. 114 115 Use custom variable `detubifier-regexp-replacement-pairs' to do so." 116 117 (interactive (list (region-beginning) 118 (region-end))) 119 120 (save-excursion 121 (pcase-dolist (`(,current-regexp . ,current-replacement) 122 detubifier-regexp-replacement-pairs) 123 (replace-regexp-in-region current-regexp 124 current-replacement 125 beg 126 end)))) 127 128 ;;;###autoload 129 (defun detubifier-custom-detubify-string (str) 130 "Replace the usual suspect URLs in string STR. 131 132 Use custom variable `detubifier-regexp-replacement-pairs' to do so." 133 134 (let ((str str)) 135 (pcase-dolist (`(,current-regexp . ,current-replacement) 136 detubifier-regexp-replacement-pairs) 137 (setq str (replace-regexp-in-string current-regexp 138 current-replacement 139 str))) 140 str)) 141 142 ;;;###autoload 143 (defun detubifier-detubify-top-kill () 144 "Replace all occurances of the usual suspects in the top of the kill ring. 145 146 Use the method chosen by the `detubifier-detubifying-method' custom variable." 147 148 (interactive) 149 150 (save-excursion 151 (with-temp-buffer 152 (yank) 153 (goto-char (point-min)) 154 (pcase detubifier-detubifying-method 155 ('farside (detubifier-farsidify-region (point-min) (point-max))) 156 ('custom (detubifier-custom-detubify-region (point-min) (point-max)))) 157 (kill-region (point-min) (point-max)))) 158 ) 159 160 ;;;###autoload 161 (defun detubifier-farsidify-region (beg end) 162 "Prefix `detubifier-farside-url' the usual suspect URLs in a region. 163 164 Region is defined either by (region-beginning) and (region-end), 165 or, if provided, between between BEG and END. 166 167 The usual suspects are replaced in this way: 168 169 example.com/blah/blah 170 171 is replaced with: 172 173 https://farside.link/example.com/blah/blah" 174 175 (interactive (list (region-beginning) 176 (region-end))) 177 178 (save-excursion 179 (save-restriction ;; Save narrowing setting and revert to it when finishing. 180 (narrow-to-region beg end) 181 (rx-let-eval `((urls () (group (or ,@detubifier-enshittified-urls)))) 182 (let ((r (rx-to-string '(urls)))) 183 (replace-regexp-in-region r 184 (concat detubifier-farside-url "\\1") 185 beg 186 end)))))) 187 188 ;;;###autoload 189 (defun detubifier-farsidify-string (str) 190 "Prefix `detubifier-farside-url' the usual suspects URLs in string STR." 191 192 (rx-let-eval `((urls () (group (or ,@detubifier-enshittified-urls)))) 193 (replace-regexp-in-string (rx-to-string '(urls)) 194 (concat detubifier-farside-url "\\1") 195 str)) 196 ) 197 198 (define-obsolete-function-alias 199 'detubifier-replace-contents 200 'detubifier-detubify-top-kill 201 "2024-09-25") 202 203 ;;; Testing: 204 205 (ert-deftest test-detubifier-farsidify-string () 206 "Test `detubifier-farsidify-string'." 207 (should (equal (detubifier-farsidify-string "sdfljdsf sdfkjl https://youtube.com/moo 208 https://twitter.com/blah") 209 (concat "sdfljdsf sdfkjl " 210 detubifier-farside-url 211 "https://youtube.com/moo 212 " 213 detubifier-farside-url 214 "https://twitter.com/blah")))) 215 216 (ert-deftest test-detubifier-farsidify-region () 217 "Test `detubifier-farsidify-region'." 218 (with-temp-buffer 219 (should (equal (let () 220 (insert "sdfljdsf sdfkjl https://youtube.com/moo 221 https://twitter.com/blah") 222 (detubifier-farsidify-region (point-min) 223 (point-max)) 224 (buffer-substring-no-properties (point-min) 225 (point-max))) 226 (concat "sdfljdsf sdfkjl " 227 detubifier-farside-url 228 "https://youtube.com/moo 229 " 230 detubifier-farside-url 231 "https://twitter.com/blah"))))) 232 233 (ert-deftest test-detubifier-custom-detubify-string () 234 "Test `detubifier-custom-detubify-string'. 235 236 TODO: Test only works with the default `detubifier-regexp-replacement-pairs'. 237 Make it work in general!" 238 (should (equal (detubifier-custom-detubify-string "sdfljdsf sdfkjl https://youtube.com/moo 239 https://twitter.com/blah") 240 (concat "sdfljdsf sdfkjl https://invidious.jing.rocks/moo 241 https://nitter.poast.org/blah")))) 242 243 (ert-deftest test-detubifier-custom-detubify-region () 244 "Test `detubifier-custom-detubify-region'. 245 246 TODO: Test only works with the default `detubifier-regexp-replacement-pairs'. 247 Make it work in general!" 248 (with-temp-buffer 249 (should (equal (let () 250 (insert "sdfljdsf sdfkjl https://youtube.com/moo 251 https://twitter.com/blah") 252 (detubifier-custom-detubify-region (point-min) 253 (point-max)) 254 (buffer-substring-no-properties (point-min) 255 (point-max))) 256 (concat "sdfljdsf sdfkjl https://invidious.jing.rocks/moo 257 https://nitter.poast.org/blah"))))) 258 259 (provide 'detubifier) 260 ;;; detubifier.el ends here