Lots of changes, most interestingly browse-url stuff

This commit is contained in:
Case Duckworth 2021-12-13 10:29:50 -06:00
parent c7a9cba824
commit b11adad984
8 changed files with 332 additions and 28 deletions

133
init.el
View File

@ -25,8 +25,7 @@
;; necessary for good functioning. In this block, I add extra
;; things or more "experimental" ones that might not belong in a
;; separate file.
(:global "M-o" 'other-buffer
"C-x C-k" 'kill-this-buffer)
(:global "C-x C-k" 'kill-this-buffer)
;; C-h deletes backward - see https://idiomdrottning.org/bad-emacs-defaults
(global-set-key (kbd "C-h") 'delete-backward-char)
(keyboard-translate ?\C-h ?\C-?))
@ -39,7 +38,7 @@
(:hook '+init-add-setup-to-imenu))
(setup (:require +key)
(+key-global-mode +1))
(+key-setup))
(setup (:require auth-source)
(:option auth-sources (list (private/ "authinfo")
@ -51,7 +50,8 @@
(:also-load +pulse)
(:option pulse-flag nil
pulse-delay 0.5
pulse-iterations 1)
pulse-iterations 1
(append +pulse-location-commands) 'lui-track-jump-to-indicator)
(+pulse-location-mode +1))
(setup calendar
@ -168,7 +168,7 @@
(setup (:straight anzu)
(:option anzu-cons-mode-line-p nil)
(:+key [remap query-replace] 'anzu-query-replace-regexp
[remap query-replace-regexp] 'anzu-query-replace-regexp)
[remap query-replace-regexp] 'anzu-query-replace-regexp)
(global-anzu-mode +1)
(:bind-into isearch
[remap isearch-query-replace]
@ -206,8 +206,8 @@
(circadian-setup))
(setup (:straight circe)
(:require _circe)
(:require +circe)
(:require _circe
+circe)
(autoload '+irc "+circe" "Connect to IRC." t)
;; Formatting options
@ -315,7 +315,7 @@
("C-M-#" . consult-register)
;; Other custom bindings
("M-y" . consult-yank-pop)
("<help> a" . consult-apropos)
("<f1> a" . consult-apropos)
;; M-g bindings (goto-map)
("M-g e" . consult-compile-error)
("M-g f" . consult-flymake) ; or consult-flycheck
@ -339,7 +339,7 @@
("M-s u" . consult-focus-lines)
;; Isearch integration
("M-s e" . consult-isearch-history)))
(global-set-key (kbd (car binding)) (cdr binding)))
(define-key +key-mode-map (kbd (car binding)) (cdr binding)))
(with-eval-after-load 'isearch-mode
(dolist (binding '(("M-e" . consult-isearch-history)
("M-s e" . consult-isearch-history)
@ -370,8 +370,8 @@
(setup (:straight crux)
(:+key "C-o" 'crux-smart-open-line
"M-o" 'crux-other-window-or-switch-buffer
"C-x 4 t" 'crux-transpose-windows)
"M-o" 'crux-other-window-or-switch-buffer
"C-x 4 t" 'crux-transpose-windows)
(el-patch-feature crux)
(with-eval-after-load 'crux
@ -419,8 +419,8 @@ See also `crux-reopen-as-root-mode'."
(setup (:straight embark)
(:option prefix-help-command 'embark-prefix-help-command)
(:+key "C-." 'embark-act
"M-." 'embark-dwim
"<help> B" 'embark-bindings))
"M-." 'embark-dwim
"<f1> B" 'embark-bindings))
(setup (:straight embark-consult)
(:load-after consult embark)
@ -461,10 +461,12 @@ See also `crux-reopen-as-root-mode'."
(gcmh-mode +1))
(setup (:straight helpful)
(:+key "<help> f" 'helpful-callable
"<help> v" 'helpful-variable
"<help> k" 'helpful-key
"C-c C-d" 'helpful-at-point))
(run-with-idle-timer 0.5 nil
'require 'helpful)
(:+key "<f1> f" 'helpful-callable
"<f1> v" 'helpful-variable
"<f1> k" 'helpful-key
"C-c C-d" 'helpful-at-point))
(setup (:straight (hippie-completing-read
:host github
@ -531,7 +533,7 @@ See also `crux-reopen-as-root-mode'."
(setup (:straight mwim)
(:+key "C-a" #'mwim-beginning
"C-e" #'mwim-end))
"C-e" #'mwim-end))
(setup (:straight orderless)
(:option completion-styles '(orderless)))
@ -589,6 +591,7 @@ See also `crux-reopen-as-root-mode'."
org-log-into-drawer t
org-outline-path-complete-in-steps nil
org-pretty-entities t
org-pretty-entities-include-sub-superscripts nil
org-refile-use-outline-path 'file
org-special-ctrl-a/e t
org-special-ctrl-k t
@ -666,6 +669,7 @@ See also `crux-reopen-as-root-mode'."
+modeline-vc
simple-modeline-segment-misc-info
simple-modeline-segment-process
+modeline-text-scale
+modeline-narrowed
+modeline-minions
+modeline-major-mode)))
@ -719,7 +723,7 @@ See also `crux-reopen-as-root-mode'."
(setup (:straight undo-fu)
(:+key "C-/" #'undo-fu-only-undo
"C-?" #'undo-fu-only-redo))
"C-?" #'undo-fu-only-redo))
(setup (:straight undo-fu-session)
(:option undo-fu-session-incompatible-files '("/COMMIT_EDITMSG\\'"
@ -730,7 +734,8 @@ See also `crux-reopen-as-root-mode'."
(setup (:straight (unfill :host github :repo "purcell/unfill"
:fork (:host github :repo "duckwork/unfill")))
(:+key "M-q" #'unfill-toggle))
(:bind-into text-mode
"M-q" #'unfill-toggle))
(setup (:straight (vertico
:host github
@ -765,7 +770,87 @@ See also `crux-reopen-as-root-mode'."
(setup (:straight zzz-to-char)
(:+key "M-z" (lambda (prefix)
"Call `zzz-to-char' or `zzz-up-to-char' with PREFIX arg."
(interactive "P")
(call-interactively
(if prefix #'zzz-up-to-char #'zzz-to-char)))))
"Call `zzz-to-char' or `zzz-up-to-char' with PREFIX arg."
(interactive "P")
(call-interactively
(if prefix #'zzz-up-to-char #'zzz-to-char)))))
(setup (:straight elfeed)
(:also-load +elfeed)
(:option elfeed-use-curl t
elfeed-curl-extra-arguments '("--insecure")
elfeed-show-unique-buffers t
elfeed-db-directory (sync/ "elfeed/db/" t))
(:with-mode elfeed-show-mode
(:bind "SPC" '+elfeed-scroll-up-command
"S-SPC" '+elfeed-scroll-down-command)))
(setup (:straight elfeed-org)
(:option rmh-elfeed-org-files (list (sync/ "elfeed/elfeed.org" t)))
(elfeed-org))
(setup (:straight (lin :host gitlab :repo "protesilaos/lin"))
(require 'lin)
(:hook-into dired-mode
elfeed-search-mode
git-rebase-mode
ibuffer-mode
ledger-report-mode
log-view-mode
magit-log-mode
notmuch-search-mode
notmuch-tree-mode
org-agenda-mode
tabulated-list-mode))
(setup browse-url
(:also-load +browse-url)
(:option browse-url-secondary-browser-function (if (executable-find "firefox")
'browse-url-firefox
'browse-url-default-browser)
browse-url-new-window-flag nil
browse-url-firefox-arguments '("--new-tab")
browse-url-firefox-new-window-is-tab t)
;; Set up URL handlers.
(+browse-url-set-handlers
(list
(cons (rx ; images
"." (or "jpeg" "jpg" "png") eos)
(lambda (&rest args)
(apply
(cond ((executable-find "feh") '+browse-url-with-feh)
((executable-find "mpv") '+browse-image-with-mpv)
(t 'eww-browse-url))
args)))
(cons (rx ; videos
(or "youtube.com" "youtu.be" "yewtu.be"
(seq "." (or "mp4" "gif" "mov" "MOV") eos)))
(lambda (&rest args)
(apply (if (executable-find "mpv")
'browse-url-mpv
browse-url-secondary-browser-function)
args)))
(cons (rx ; non-eww-friendly websites
(or
"github.com"
"gitlab.com"
"google.com"
"imgur.com"
"pixelfed"
"reddit.com"
"taskiq"
"twitter.com"
))
browse-url-secondary-browser-function)
(cons "." ; everything else
'eww-browse-url)))
;; Transform URLs before passing to `browse-url'
(:option +browse-url-transformations `((,(rx "//" (or "youtube.com"
"youtu.be"))
. "//yewtu.be")))
(+browse-url-transform-url-global-mode +1))
(setup (:straight-when pdf-tools
(eq system-type 'gnu/linux))
(pdf-tools-install))

117
lisp/+browse-url.el Normal file
View File

@ -0,0 +1,117 @@
;;; +browse-url.el -*- lexical-binding: t; -*-
;;; Code:
(require 'cl-lib)
(defgroup +browse-url nil
"Group for my `browse-url' extras."
:group 'browse-url)
;;; URL Handlers
(defun +browse-url-set-handlers (handlers)
"Set handlers for `browse-url'.
Set `browse-url-handlers', if they exist; else
`browse-url-browser-function'. The reason for this switch is
that the latter is deprecated in Emacs 28+."
(set-default (if (boundp 'browse-url-handlers)
'browse-url-handlers
'browse-url-browser-function)
handlers))
(cl-defmacro +browse-url-make-external-viewer-handler
(viewer default-args &optional (prompt "URL: ")
&key
(custom-group '+browse-url)
(name (format "+browse-url-with-%s" viewer)))
"Create a `browse-url' handler function that calls VIEWER on the url.
Also create a `customize' setting in CUSTOM-GROUP for VIEWER's
arguments. DEFAULT-ARGS specifies the default arguments that
setting should have. PROMPT will be shown to user in the
function's `interactive' spec, as an argument to
`browse-url-interactive-arg'. The resulting function will be
named NAME, defaulting to \"+browse-url-with-VIEWER\", and the variable
\"NAME-args\"."
(declare (indent 1))
`(progn
(defcustom ,(intern (format "%s-args" name))
,default-args
,(format "Arguments to pass to %s in `%s'." viewer name)
:type '(repeat :tag "Command-line argument" string)
:group ',custom-group)
(defun ,(intern name) (url &optional _new-window)
,(format "Open URL in %s." viewer)
(interactive (browse-url-interactive-arg ,prompt))
(let* ((url (browse-url-encode-url url))
(process-environment (browse-url-process-environment)))
(message ,(format "Opening %%s in %s..." viewer) url)
(apply #'start-process
(concat ,viewer " " url) nil
,viewer
(append ,(intern (format "%s-args" name)) (list url)))))))
;; Reference implementation: mpv
(+browse-url-make-external-viewer-handler "mpv" nil "Video URL: ")
;; And feh too
(+browse-url-make-external-viewer-handler "feh" '("--auto-zoom"
"--geometry" "800x600"))
;; And ... mpv, but for images
(+browse-url-make-external-viewer-handler "mpv"
'("--image-display-duration=inf")
"Image URL: "
:name "+browse-image-with-mpv")
;;; URL Transformation Functions
;; There's a lot of bad websites out there. Luckily we can easily redirect
;; requests to more privacy-respecting, or just less javascript-ridden, sites
;; using some basic regex magic. Inspired by add-ons like
;; https://einaregilsson.com/redirector/.
(defcustom +browse-url-transformations nil
"Transformation rules for various URLs.
This is an alist, the keys of which are regexen to match URLs
against, and the values are how to transform them. Match capture
data will be used in the transformations."
:type
'(alist :key-type (string :tag "URL regex match")
:value-type (string :tag "URL regex transformation"))
:group '+browse-url)
(defun +browse-url-transform-advice (url &rest args)
"ADVICE to transform URL for later opening by `browse-url'.
ARGS are ignored here, but passed on for later processing."
;; Basically, loop through `+browse-url-transformations' until finding a CAR
;; that matches the URL. If one is found, transform it using `replace-match'
;; with the CDR of that cell, or if one isn't, just pass the URL unchanged,
;; along with the rest of the args, in a list to the original caller (probably
;; `browse-url'.)
(apply 'list
(cl-loop with url = (substring-no-properties
(if (consp url) (car url) url))
for (regex . transformation) in +browse-url-transformations
if (string-match regex url)
return (replace-match transformation nil nil url)
;; else
finally return url)
args))
(define-minor-mode +browse-url-transform-url-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 " Xurl"
:keymap nil
(if +browse-url-transform-url-mode
(advice-add 'browse-url :filter-args '+browse-url-transform-advice)
(advice-remove 'browse-url '+browse-url-transform-advice)))
(define-global-minor-mode +browse-url-transform-url-global-mode
+browse-url-transform-url-mode +browse-url-transform-url-mode)
(provide '+browse-url)
;;; +browse-url.el ends here

24
lisp/+elfeed.el Normal file
View File

@ -0,0 +1,24 @@
;;; +elfeed.el -*- lexical-binding: t; -*-
;;; Code:
(require 'elfeed)
(defun +elfeed-scroll-up-command (&optional arg)
"Scroll up or go to next feed item in Elfeed"
(interactive "^P")
(let ((scroll-error-top-bottom nil))
(condition-case-unless-debug nil
(scroll-up-command arg)
(error (elfeed-show-next)))))
(defun +elfeed-scroll-down-command (&optional arg)
"Scroll up or go to next feed item in Elfeed"
(interactive "^P")
(let ((scroll-error-top-bottom nil))
(condition-case-unless-debug nil
(scroll-down-command arg)
(error (elfeed-show-prev)))))
(provide '+elfeed)
;;; +elfeed.el ends here

View File

@ -69,7 +69,6 @@ Do this only if the buffer is not visiting a file."
kill-do-not-save-duplicates t
kill-read-only-ok t
kill-ring-max 500
kill-whole-line t
kmacro-ring-max 20
load-prefer-newer t
major-mode '+set-major-mode-from-buffer-name

View File

@ -14,6 +14,9 @@
;;; Code:
(require 'easy-mmode)
(require 'setup nil t)
;; I need to define this map before the proper mode map.
(defvar +key-leader-map (let ((map (make-sparse-keymap))
(c-z (global-key-binding "\C-z")))
@ -30,13 +33,18 @@
(define-minor-mode +key-mode
"A minor mode with keybindings that will override every other mode."
:init-value t
:lighter " +"
:keymap +key-mode-map)
:lighter " +")
(add-to-list 'emulation-mode-map-alists `((+key-mode . ,+key-mode-map)))
;;;###autoload
(define-globalized-minor-mode +key-global-mode +key-mode +key-mode)
(add-to-list 'emulation-mode-map-alists `((+key-mode . ,+key-mode-map)))
;;;###autoload
(defun +key-setup ()
"Setup `+key-mode' after everything else."
(if after-init-time
(+key-global-mode +1)
(add-hook 'after-init-hook '+key-global-mode)))
(defun turn-off-+key-mode ()
"Turn off `+key-mode'."

View File

@ -153,5 +153,13 @@ The order of elements matters: whichever one matches first is applied."
"Display `anzu--update-mode-line'."
(concat " " (anzu--update-mode-line)))
(defun +modeline-text-scale ()
"Display text scaling level."
;; adapted from https://github.com/seagle0128/doom-modeline
(when (and (boundp 'text-scale-mode-amount)
(/= text-scale-mode-amount 0))
(format (if (> text-scale-mode-amount 0) " (%+d)" " (%-d)")
text-scale-mode-amount)))
(provide '+modeline)
;;; +modeline.el ends here

View File

@ -337,5 +337,60 @@ the deletion might narrow the column."
(backward-delete-char-untabify N)
(org-fix-tags-on-the-fly))))
;;; Smarter {super,sub}scripts
;; https://old.reddit.com/r/emacs/comments/qzlzm0/what_are_your_top_key_bindings_rebindings_minor/hmwyhm3/
;; I don't use this currently because I found out about
;; `org-pretty-entities-include-sub-superscripts', which really does exactly
;; what I wanted.
(defface +org-script-markers '((t :inherit shadow))
"Face to be used for sub/superscripts markers i.e., ^, _, {, }.")
;; Hiding the super and subscript markers is extremely annoying
;; since any remotely complex equation becomes a chore. And leaving
;; it not raised is jarring to the eye. So this fontifies the
;; buffer just like how auctex does -- use a muted colour to
;; highlight the markup and raise the script.
(defun +org-raise-scripts (limit)
"Differences from `org-raise-scripts' are:
- It doesn't actually hide the markup used for super and subscript.
- It uses a custom face to highlight the markup: +org-script-markers.
- It doesn't require `org-pretty-entities' to be t."
(when (and org-pretty-entities-include-sub-superscripts
(re-search-forward
(if (eq org-use-sub-superscripts t)
org-match-substring-regexp
org-match-substring-with-braces-regexp)
limit t))
(let* ((pos (point)) table-p comment-p
(mpos (match-beginning 3))
(emph-p (get-text-property mpos 'org-emphasis))
(link-p (get-text-property mpos 'mouse-face))
(keyw-p (eq 'org-special-keyword (get-text-property mpos 'face))))
(goto-char (point-at-bol))
(setq table-p (looking-at-p org-table-dataline-regexp)
comment-p (looking-at-p "^[ \t]*#[ +]"))
(goto-char pos)
;; Handle a_b^c
(when (member (char-after) '(?_ ?^)) (goto-char (1- pos)))
(unless (or comment-p emph-p link-p keyw-p)
(put-text-property (match-beginning 3) (match-end 0)
'display
(if (equal (char-after (match-beginning 2)) ?^)
;; (nth (if table-p 3 1) org-script-display)
(nth 3 org-script-display)
;; (nth (if table-p 2 0) org-script-display)
(nth 2 org-script-display)))
(put-text-property (match-beginning 2) (match-end 2)
'face 'vz/org-script-markers)
(when (and (eq (char-after (match-beginning 3)) ?{)
(eq (char-before (match-end 3)) ?}))
(put-text-property (match-beginning 3) (1+ (match-beginning 3))
'face '+org-script-markers)
(put-text-property (1- (match-end 3)) (match-end 3)
'face '+org-script-markers)))
t)))
(provide '+org)
;;; +org.el ends here

View File

@ -79,6 +79,14 @@ ALIGNMENT can be one of these:
;;; COMMANDS
(defun +dos2unix (buffer)
"Replace \r\n with \n in BUFFER."
(interactive "*b")
(save-excursion
(with-current-buffer buffer
(goto-char (point-min))
(while (search-forward (string ?\C-m ?\C-j) nil t)
(replace-match (string ?\C-j) nil t)))))
(provide '+util)
;;; +util.el ends here