about summary refs log tree commit diff stats
path: root/lisp
diff options
context:
space:
mode:
Diffstat (limited to 'lisp')
-rw-r--r--lisp/+browse-url.el117
-rw-r--r--lisp/+elfeed.el24
-rw-r--r--lisp/+emacs.el1
-rw-r--r--lisp/+key.el14
-rw-r--r--lisp/+modeline.el8
-rw-r--r--lisp/+org.el55
-rw-r--r--lisp/+util.el8
7 files changed, 223 insertions, 4 deletions
diff --git a/lisp/+browse-url.el b/lisp/+browse-url.el new file mode 100644 index 0000000..fad0826 --- /dev/null +++ b/lisp/+browse-url.el
@@ -0,0 +1,117 @@
1;;; +browse-url.el -*- lexical-binding: t; -*-
2
3;;; Code:
4
5(require 'cl-lib)
6
7(defgroup +browse-url nil
8 "Group for my `browse-url' extras."
9 :group 'browse-url)
10
11;;; URL Handlers
12
13(defun +browse-url-set-handlers (handlers)
14 "Set handlers for `browse-url'.
15Set `browse-url-handlers', if they exist; else
16`browse-url-browser-function'. The reason for this switch is
17that the latter is deprecated in Emacs 28+."
18 (set-default (if (boundp 'browse-url-handlers)
19 'browse-url-handlers
20 'browse-url-browser-function)
21 handlers))
22
23(cl-defmacro +browse-url-make-external-viewer-handler
24 (viewer default-args &optional (prompt "URL: ")
25 &key
26 (custom-group '+browse-url)
27 (name (format "+browse-url-with-%s" viewer)))
28 "Create a `browse-url' handler function that calls VIEWER on the url.
29Also create a `customize' setting in CUSTOM-GROUP for VIEWER's
30arguments. DEFAULT-ARGS specifies the default arguments that
31setting should have. PROMPT will be shown to user in the
32function's `interactive' spec, as an argument to
33`browse-url-interactive-arg'. The resulting function will be
34named NAME, defaulting to \"+browse-url-with-VIEWER\", and the variable
35\"NAME-args\"."
36 (declare (indent 1))
37 `(progn
38 (defcustom ,(intern (format "%s-args" name))
39 ,default-args
40 ,(format "Arguments to pass to %s in `%s'." viewer name)
41 :type '(repeat :tag "Command-line argument" string)
42 :group ',custom-group)
43 (defun ,(intern name) (url &optional _new-window)
44 ,(format "Open URL in %s." viewer)
45 (interactive (browse-url-interactive-arg ,prompt))
46 (let* ((url (browse-url-encode-url url))
47 (process-environment (browse-url-process-environment)))
48 (message ,(format "Opening %%s in %s..." viewer) url)
49 (apply #'start-process
50 (concat ,viewer " " url) nil
51 ,viewer
52 (append ,(intern (format "%s-args" name)) (list url)))))))
53
54;; Reference implementation: mpv
55(+browse-url-make-external-viewer-handler "mpv" nil "Video URL: ")
56;; And feh too
57(+browse-url-make-external-viewer-handler "feh" '("--auto-zoom"
58 "--geometry" "800x600"))
59;; And ... mpv, but for images
60(+browse-url-make-external-viewer-handler "mpv"
61 '("--image-display-duration=inf")
62 "Image URL: "
63 :name "+browse-image-with-mpv")
64
65;;; URL Transformation Functions
66;; There's a lot of bad websites out there. Luckily we can easily redirect
67;; requests to more privacy-respecting, or just less javascript-ridden, sites
68;; using some basic regex magic. Inspired by add-ons like
69;; https://einaregilsson.com/redirector/.
70
71(defcustom +browse-url-transformations nil
72 "Transformation rules for various URLs.
73This is an alist, the keys of which are regexen to match URLs
74against, and the values are how to transform them. Match capture
75data will be used in the transformations."
76 :type
77 '(alist :key-type (string :tag "URL regex match")
78 :value-type (string :tag "URL regex transformation"))
79 :group '+browse-url)
80
81(defun +browse-url-transform-advice (url &rest args)
82 "ADVICE to transform URL for later opening by `browse-url'.
83ARGS are ignored here, but passed on for later processing."
84 ;; Basically, loop through `+browse-url-transformations' until finding a CAR
85 ;; that matches the URL. If one is found, transform it using `replace-match'
86 ;; with the CDR of that cell, or if one isn't, just pass the URL unchanged,
87 ;; along with the rest of the args, in a list to the original caller (probably
88 ;; `browse-url'.)
89 (apply 'list
90 (cl-loop with url = (substring-no-properties
91 (if (consp url) (car url) url))
92 for (regex . transformation) in +browse-url-transformations
93 if (string-match regex url)
94 return (replace-match transformation nil nil url)
95 ;; else
96 finally return url)
97 args))
98
99(define-minor-mode +browse-url-transform-url-mode
100 "Minor mode to transform a URL before passing it to `browse-url'.
101This can be used to \"redirect\" URLs, for example from an
102information silo to a more privacy-respecting one (e.g.,
103\"twitter.com\" -> \"nitter.com\"), by adding advice to `browse-url'.
104
105When using this mode, ensure that the transformed URL is also in
106`browse-url-handlers', since that's what `browse-url' will see."
107 :lighter " Xurl"
108 :keymap nil
109 (if +browse-url-transform-url-mode
110 (advice-add 'browse-url :filter-args '+browse-url-transform-advice)
111 (advice-remove 'browse-url '+browse-url-transform-advice)))
112
113(define-global-minor-mode +browse-url-transform-url-global-mode
114 +browse-url-transform-url-mode +browse-url-transform-url-mode)
115
116(provide '+browse-url)
117;;; +browse-url.el ends here
diff --git a/lisp/+elfeed.el b/lisp/+elfeed.el new file mode 100644 index 0000000..823902b --- /dev/null +++ b/lisp/+elfeed.el
@@ -0,0 +1,24 @@
1;;; +elfeed.el -*- lexical-binding: t; -*-
2
3;;; Code:
4
5(require 'elfeed)
6
7(defun +elfeed-scroll-up-command (&optional arg)
8 "Scroll up or go to next feed item in Elfeed"
9 (interactive "^P")
10 (let ((scroll-error-top-bottom nil))
11 (condition-case-unless-debug nil
12 (scroll-up-command arg)
13 (error (elfeed-show-next)))))
14
15(defun +elfeed-scroll-down-command (&optional arg)
16 "Scroll up or go to next feed item in Elfeed"
17 (interactive "^P")
18 (let ((scroll-error-top-bottom nil))
19 (condition-case-unless-debug nil
20 (scroll-down-command arg)
21 (error (elfeed-show-prev)))))
22
23(provide '+elfeed)
24;;; +elfeed.el ends here
diff --git a/lisp/+emacs.el b/lisp/+emacs.el index 147bb76..a858cf6 100644 --- a/lisp/+emacs.el +++ b/lisp/+emacs.el
@@ -69,7 +69,6 @@ Do this only if the buffer is not visiting a file."
69 kill-do-not-save-duplicates t 69 kill-do-not-save-duplicates t
70 kill-read-only-ok t 70 kill-read-only-ok t
71 kill-ring-max 500 71 kill-ring-max 500
72 kill-whole-line t
73 kmacro-ring-max 20 72 kmacro-ring-max 20
74 load-prefer-newer t 73 load-prefer-newer t
75 major-mode '+set-major-mode-from-buffer-name 74 major-mode '+set-major-mode-from-buffer-name
diff --git a/lisp/+key.el b/lisp/+key.el index 5b4f467..7a51be1 100644 --- a/lisp/+key.el +++ b/lisp/+key.el
@@ -14,6 +14,9 @@
14 14
15;;; Code: 15;;; Code:
16 16
17(require 'easy-mmode)
18(require 'setup nil t)
19
17;; I need to define this map before the proper mode map. 20;; I need to define this map before the proper mode map.
18(defvar +key-leader-map (let ((map (make-sparse-keymap)) 21(defvar +key-leader-map (let ((map (make-sparse-keymap))
19 (c-z (global-key-binding "\C-z"))) 22 (c-z (global-key-binding "\C-z")))
@@ -30,13 +33,18 @@
30(define-minor-mode +key-mode 33(define-minor-mode +key-mode
31 "A minor mode with keybindings that will override every other mode." 34 "A minor mode with keybindings that will override every other mode."
32 :init-value t 35 :init-value t
33 :lighter " +" 36 :lighter " +")
34 :keymap +key-mode-map) 37(add-to-list 'emulation-mode-map-alists `((+key-mode . ,+key-mode-map)))
35 38
36;;;###autoload 39;;;###autoload
37(define-globalized-minor-mode +key-global-mode +key-mode +key-mode) 40(define-globalized-minor-mode +key-global-mode +key-mode +key-mode)
38 41
39(add-to-list 'emulation-mode-map-alists `((+key-mode . ,+key-mode-map))) 42;;;###autoload
43(defun +key-setup ()
44 "Setup `+key-mode' after everything else."
45 (if after-init-time
46 (+key-global-mode +1)
47 (add-hook 'after-init-hook '+key-global-mode)))
40 48
41(defun turn-off-+key-mode () 49(defun turn-off-+key-mode ()
42 "Turn off `+key-mode'." 50 "Turn off `+key-mode'."
diff --git a/lisp/+modeline.el b/lisp/+modeline.el index 0dc34c7..7c74f76 100644 --- a/lisp/+modeline.el +++ b/lisp/+modeline.el
@@ -153,5 +153,13 @@ The order of elements matters: whichever one matches first is applied."
153 "Display `anzu--update-mode-line'." 153 "Display `anzu--update-mode-line'."
154 (concat " " (anzu--update-mode-line))) 154 (concat " " (anzu--update-mode-line)))
155 155
156(defun +modeline-text-scale ()
157 "Display text scaling level."
158 ;; adapted from https://github.com/seagle0128/doom-modeline
159 (when (and (boundp 'text-scale-mode-amount)
160 (/= text-scale-mode-amount 0))
161 (format (if (> text-scale-mode-amount 0) " (%+d)" " (%-d)")
162 text-scale-mode-amount)))
163
156(provide '+modeline) 164(provide '+modeline)
157;;; +modeline.el ends here 165;;; +modeline.el ends here
diff --git a/lisp/+org.el b/lisp/+org.el index a4ce230..9a91ef1 100644 --- a/lisp/+org.el +++ b/lisp/+org.el
@@ -337,5 +337,60 @@ the deletion might narrow the column."
337 (backward-delete-char-untabify N) 337 (backward-delete-char-untabify N)
338 (org-fix-tags-on-the-fly)))) 338 (org-fix-tags-on-the-fly))))
339 339
340;;; Smarter {super,sub}scripts
341;; https://old.reddit.com/r/emacs/comments/qzlzm0/what_are_your_top_key_bindings_rebindings_minor/hmwyhm3/
342;; I don't use this currently because I found out about
343;; `org-pretty-entities-include-sub-superscripts', which really does exactly
344;; what I wanted.
345
346(defface +org-script-markers '((t :inherit shadow))
347 "Face to be used for sub/superscripts markers i.e., ^, _, {, }.")
348
349;; Hiding the super and subscript markers is extremely annoying
350;; since any remotely complex equation becomes a chore. And leaving
351;; it not raised is jarring to the eye. So this fontifies the
352;; buffer just like how auctex does -- use a muted colour to
353;; highlight the markup and raise the script.
354(defun +org-raise-scripts (limit)
355 "Differences from `org-raise-scripts' are:
356
357- It doesn't actually hide the markup used for super and subscript.
358- It uses a custom face to highlight the markup: +org-script-markers.
359- It doesn't require `org-pretty-entities' to be t."
360 (when (and org-pretty-entities-include-sub-superscripts
361 (re-search-forward
362 (if (eq org-use-sub-superscripts t)
363 org-match-substring-regexp
364 org-match-substring-with-braces-regexp)
365 limit t))
366 (let* ((pos (point)) table-p comment-p
367 (mpos (match-beginning 3))
368 (emph-p (get-text-property mpos 'org-emphasis))
369 (link-p (get-text-property mpos 'mouse-face))
370 (keyw-p (eq 'org-special-keyword (get-text-property mpos 'face))))
371 (goto-char (point-at-bol))
372 (setq table-p (looking-at-p org-table-dataline-regexp)
373 comment-p (looking-at-p "^[ \t]*#[ +]"))
374 (goto-char pos)
375 ;; Handle a_b^c
376 (when (member (char-after) '(?_ ?^)) (goto-char (1- pos)))
377 (unless (or comment-p emph-p link-p keyw-p)
378 (put-text-property (match-beginning 3) (match-end 0)
379 'display
380 (if (equal (char-after (match-beginning 2)) ?^)
381 ;; (nth (if table-p 3 1) org-script-display)
382 (nth 3 org-script-display)
383 ;; (nth (if table-p 2 0) org-script-display)
384 (nth 2 org-script-display)))
385 (put-text-property (match-beginning 2) (match-end 2)
386 'face 'vz/org-script-markers)
387 (when (and (eq (char-after (match-beginning 3)) ?{)
388 (eq (char-before (match-end 3)) ?}))
389 (put-text-property (match-beginning 3) (1+ (match-beginning 3))
390 'face '+org-script-markers)
391 (put-text-property (1- (match-end 3)) (match-end 3)
392 'face '+org-script-markers)))
393 t)))
394
340(provide '+org) 395(provide '+org)
341;;; +org.el ends here 396;;; +org.el ends here
diff --git a/lisp/+util.el b/lisp/+util.el index 0184a48..fb77278 100644 --- a/lisp/+util.el +++ b/lisp/+util.el
@@ -79,6 +79,14 @@ ALIGNMENT can be one of these:
79 79
80;;; COMMANDS 80;;; COMMANDS
81 81
82(defun +dos2unix (buffer)
83 "Replace \r\n with \n in BUFFER."
84 (interactive "*b")
85 (save-excursion
86 (with-current-buffer buffer
87 (goto-char (point-min))
88 (while (search-forward (string ?\C-m ?\C-j) nil t)
89 (replace-match (string ?\C-j) nil t)))))
82 90
83(provide '+util) 91(provide '+util)
84;;; +util.el ends here 92;;; +util.el ends here