;;; init.el --- a config of one's own -*- lexical-binding: t; -*- ;; by C. Duckworth ;; Bankruptcy: 9.3 ;;; Code: ;;; Remove when done bankrupting (defkeys t "C-x C-c" #'restart-emacs) ;;; My extras (push (expand-file-name (locate-user-emacs-file "lisp")) load-path) (require 'acdw) ; Omnibus fun stuff ;;; Basic defaults (use-package no-littering :ensure t :demand t :custom (no-littering-etc-directory etc/) (no-littering-var-directory var/) (custom-file (etc/ "custom.el")) (auto-save-file-name-transforms `(("." ,(var/ "auto-save/") t))) (auto-save-list-file-prefix (var/ "auto-save/.saves-" t)) (backup-directory-alist `(("." . ,(var/ "backup/" t))))) (use-package custom-allowed :load-path "~/src/emacs/custom-allowed/" :custom (custom-file (private/ "custom.el")) :config (dolist (var '(safe-local-variable-values warning-suppress-types ispell-buffer-session-localwords calendar-latitude calendar-longitude user-full-name user-mail-address)) (add-to-list 'custom-allowed-variables var)) :hook (after-init-hook . custom-allowed-load-custom-file)) (use-package modus-themes :load-path "~/usr/share/emacs/30.0.50/etc/themes/" :custom (modus-themes-bold-constructs t) (modus-themes-italic-constructs t) (modus-themes-variable-pitch-ui nil)) (use-package dawn :load-path "~/src/emacs/dawn/" :after modus-themes :config (load-theme 'modus-operandi :noconfirm :noenable) (load-theme 'modus-vivendi :noconfirm :noenable) (defhook custom-allowed-after-load-hook (dawn-schedule-themes 'modus-operandi 'modus-vivendi) (set-face-attribute 'default nil :family "IBM Plex Mono" :height 100) (set-face-attribute 'variable-pitch nil :family "Georgia" :height 1.2))) (use-package midnight :config (add-hook 'midnight-mode-hook #'recentf-cleanup) (midnight-mode)) (use-package sophomore :load-path "~/src/emacs/sophomore/" :config (sophomore-enable-all) (sophomore-disable 'view-hello-file 'describe-gnu-project 'suspend-frame) (sophomore-mode)) ;;; Completions (use-package vertico :ensure t :custom (resize-mini-windows 'grow-only) (vertico-cycle t) :init (use-package vertico-directory :after vertico :config (add-hook 'rfn-eshadow-update-overlay-hook #'vertico-directory-tidy)) (vertico-mode)) (use-package marginalia :ensure t :demand t :config (add-hook 'minibuffer-setup-hook #'truncate-lines-local-mode) (marginalia-mode)) (use-package orderless :ensure t :custom (completion-styles '(orderless basic)) (completion-category-overrides '((file (styles basic partial-completion))))) (use-package consult :ensure t :custom (register-preview-delay 0.01) (register-preview-function #'consult-register-format) (xref-show-xrefs-function #'consult-xref) (tab-always-indent 'complete) (completion-in-region-function #'consult-completion-in-region) (consult-narrow-key "<") (consult--regexp-compiler #'consult--default-regexp-compiler) :config (advice-add #'register-preview :override #'consult-register-window) (define-advice completing-read-multiple (:filter-args (args) indicator) (cons (format "[CRM%s] %s" (replace-regexp-in-string "\\`\\[.*?]\\*\\|\\[.*?]\\*\\'" "" crm-separator) (car args)) (cdr args))) :bind (([remap switch-to-buffer] . consult-buffer) ([remap switch-to-buffer-other-window] . consult-buffer-other-window) ([remap switch-to-buffer-other-frame] . consult-buffer-other-frame) ([remap yank-pop] . consult-yank-pop) ("M-g g" . consult-goto-line) ("M-g M-g" . consult-goto-line) ("M-g i" . consult-imenu) ("M-g M-i" . consult-imenu) ("M-s l" . consult-line) ("M-s f" . consult-find) ("M-s M-f" . consult-find) ("M-s g" . consult-grep) ("M-s M-g" . consult-grep))) ;;; General enhancements (use-package embark :ensure t :custom (prefix-help-command #'embark-prefix-help-command) :bind (("C-." . embark-act) ("M-." . embark-dwim) ("C-h b" . embark-bindings)) :custom (add-to-list 'display-buffer-alist '("\\`\\*Embark Collect \\(Live\\|Completions\\)\\*" nil (window-parameters (mode-line-format . none))))) (use-package embark-consult :ensure t :after (embark consult) :hook (embark-collect-mode-hook . consult-preview-at-point-mode)) (use-package undo-fu-session :ensure t :custom (undo-fu-session-directory (etc/ "undo/" t)) (undo-fu-session-incompatible-files '("/COMMIT_EDITMSG\\'" "/git-rebase-todo\\'")) (undo-fu-session-compression (cl-loop for (exe . sym) in '(("gzip" . gz) ("bzip2" . bz2) ("xz" . xz)) if (executable-find exe) return sym)) :config (global-undo-fu-session-mode)) (use-package ws-butler :ensure t :custom (ws-butler-trim-predicate (lambda (begin end) (not (eq 'font-lock-string-face (get-text-property end 'face))))) :config (ws-butler-global-mode)) (use-package minions :ensure t :config (minions-mode)) (use-package mode-line-bell :vc ( :url "https://github.com/duckwork/mode-line-bell" :rev "remap-face") :custom (mode-line-bell-flash-time 0.25) :config (mode-line-bell-mode)) (use-package electric-cursor :load-path "~/src/emacs/electric-cursor/" :custom (electric-cursor-alist '((overwrite-mode . box) (t . bar))) (electric-cursor-mode)) (use-package visual-fill-column :ensure t :custom (visual-fill-column-center-text t) :hook ((visual-fill-column-mode-hook . visual-line-mode) (eww-mode-hook . visual-fill-column-mode)) :config (advice-add 'text-scale-adjust :after #'visual-fill-column-adjust)) (use-package cape :ensure t :demand t :init (dolist (fn '(cape-file cape-dabbrev)) (add-hook 'completion-at-point-functions fn 90)) :config (require '+cape) (advice-add 'emacs-completion-at-point :around #'cape-wrap-nonexclusive) (+cape-insinuate text-mode-hook ( cape-dict cape-ispell cape-file cape-dabbrev))) (use-package wgrep :ensure t :custom (wgrep-enable-key (kbd "C-x C-q")) :bind (:map grep-mode-map ("C-x C-q" . wgrep-change-to-wgrep-mode))) (progn (use-package-statistics-gather :use-package 'mlscroll nil) (use-package-ensure-elpa 'mlscroll '(t) 'nil) (use-package-statistics-gather :preface 'mlscroll nil) (eval-and-compile (defhook modus-themes-after-load-theme-hook :name modus-themes-load@mlscroll (mlscroll-mode -1) (when (or (memq 'modus-vivendi custom-enabled-themes) (memq 'modus-operandi custom-enabled-themes)) (modus-themes-with-colors (setf mlscroll-in-color fg-dim mlscroll-out-color bg-inactive))) (eval-after 1 (mlscroll-mode 1)))) (defvar use-package--warning99 (function (lambda (keyword err) (let ((msg (format "%s/%s: %s" 'mlscroll keyword (error-message-string err)))) (display-warning 'use-package msg :error))))) (condition-case-unless-debug err (progn (use-package-statistics-gather :init 'mlscroll nil) (condition-case-unless-debug err (when (daemonp) (add-hook 'server-after-make-frame (function modus-themes-load@ml-scroll))) (error (funcall use-package--warning99 :init err))) (run-with-idle-timer 1 nil (function require) 'mlscroll nil t) (eval-after-load 'mlscroll '(progn (use-package-statistics-gather :config 'mlscroll nil) (let ((now (current-time))) (message "%s..." "Configuring package mlscroll") (prog1 (condition-case-unless-debug err (progn (modus-themes-load@mlscroll) t) (error (funcall use-package--warning99 :config err))) (let ((elapsed (float-time (time-subtract (current-time) now)))) (if (> elapsed 0.1) (message "%s...done (%.3fs)" "Configuring package mlscroll" elapsed) (message "%s...done" "Configuring package mlscroll"))))) (use-package-statistics-gather :config 'mlscroll t))) (use-package-statistics-gather :init 'mlscroll t)) (error (funcall use-package--warning99 :catch err))) (use-package-statistics-gather :preface 'mlscroll t) (use-package-statistics-gather :use-package 'mlscroll t)) (use-package avy :ensure t :demand t :custom (avy-background t) (avy-keys (string-to-list "asdfghjklqwertyuiopzxcvbnm")) :bind (("M-j" . avy-goto-char-timer) :map isearch-mode-map ("M-j" . avy-isearch))) (use-package zzz-to-char :ensure t :bind (("M-z" . zzz-to-char))) ;;; Searching (use-package isearch-mb :ensure t :custom (isearch-lazy-count t) (isearch-regexp-lax-whitespace t) ;; Space matches whitespace, newlines, punctuation (search-whitespace-regexp "\\W+") (search-default-mode t "Search using regexp by default.") ;; Space matches any sequence of characters in a line ;; search-whitespace-regexp ".*?" (isearch-wrap-pause 'no) :config (require '+isearch) (advice-add 'isearch-cancel :before #'+isearch-cancel@add-search-to-history) (advice-add 'perform-replace :around #'+perform-replace-dont-exit-on-anykey) (eval-after (isearch-mb consult) (add-to-list 'isearch-mb--after-exit #'consult-line) (add-to-list 'isearch-mb--with-buffer #'consult-isearch-history) (defkeys isearch-mb-minibuffer-map "M-s l" #'consult-line "M-r" #'consult-isearch-history)) (eval-after (isearch-mb anzu) (add-to-list 'isearch-mb--after-exit #'anzu-isearch-query-replace) (defkeys isearch-mb-minibuffer-map "M-%" #'anzu-isearch-query-replace-regexp "C-M-%" #'anzu-isearch-query-replace)) (isearch-mb-mode)) (use-package anzu :ensure t :bind (("M-%" . anzu-query-replace-regexp) ("C-M-%" . anzu-query-replace))) (use-package frowny :load-path "~/src/emacs/frowny/" :config (global-frowny-mode)) (use-package transpose-frame :ensure t :bind (("C-x 5 t" . transpose-frame))) ;;; Text editing (use-package org :defer t :after derived :init (require 'init-org) (require '_work)) (use-package ispell :custom (ispell-program-name (choose-executable "ispell" "aspell")) :config (require '+ispell) (add-hook 'before-save-hook #'+ispell-move-buffer-words-to-dir-locals-hook) (put 'ispell-buffer-session-localwords 'safe-local-variable #'+ispell-safe-local-p)) (use-package flyspell :hook org-mode-hook) (use-package flyspell-correct :ensure t :after flyspell :custom (flyspell-correct--cr-key ";") :bind (:map flyspell-mode-map (("C-;" . flyspell-correct-wrapper) ("" . +flyspell-correct-buffer))) :config (require '+flyspell-correct) (defkeys flyspell-mode-map "C-," nil "C-." nil)) (use-package text-mode :config (defhook text-mode-hook #'abbrev-mode)) (use-package filldent :load-path "~/src/emacs/filldent/" :bind ("M-q" . filldent-dwim)) (use-package scule :load-path "~/src/emacs/scule/" :config (defkeys t "M-c" (defmap scule-map "Keymap for twiddling scules." "M-u" #'scule-upcase "M-l" #'scule-downcase "M-c" #'scule-capitalize))) (use-package titlecase :load-path "~/src/emacs/titlecase.el/" :after org :bind (:map scule-map ("M-t" . titlecase-dwim)) :config (require '+titlecase)) ;;; Programming (use-package prog-mode :config (defhook prog-mode-hook #'auto-fill-mode ;; Use `indent-tabs-mode' unless one of the following modes (indent-tabs-mode (if (derived-mode-p 'emacs-lisp-mode 'python-mode 'haskell-mode) -1 1)))) (use-package paredit :ensure t :preface (defun +paredit-newline () (interactive) (call-interactively (if (derived-mode-p 'lisp-interaction-mode) #'eval-print-last-sexp #'paredit-newline))) :hook ((emacs-lisp-mode-hook eval-expression-minibuffer-setup-hook ielm-mode-hook lisp-interaction-mode-hook lisp-mode-hook scheme-mode-hook fennel-repl-mode-hook fennel-mode-hook geiser-mode-hook geiser-repl-mode-hook ielm-mode-hook) . enable-paredit-mode) :bind (("C-j" . +paredit-newline)) :config (defkeys paredit-mode-map "RET" nil "M-s" nil) (require '+paredit) (add-to-list 'paredit-space-for-delimiter-predicates #'+paredit-space-for-delimiter) (eval-after (paredit eldoc) (eldoc-add-command #'paredit-backward-delete #'paredit-close-round))) (use-package hungry-delete :ensure t :custom (hungry-delete-chars-to-skip " \t") (hungry-delete-join-reluctantly nil) :config (dolist (m '(eshell-mode nim-mode python-mode)) (add-to-list 'hungry-delete-except-modes m)) (require '+hungry-delete) (eval-after paredit (defkeys paredit-mode-map [remap paredit-backward-delete] (+hungry-delete-define-alternative paredit-backward-delete hungry-delete-backward) [remap paredit-forward-delete] (+hungry-delete-define-alternative paredit-forward-delete hungry-delete-forward))) (global-hungry-delete-mode)) (use-package ediff :custom (ediff-keep-variants nil) (ediff-split-window-function #'split-window-horizontally) (ediff-window-setup-function #'ediff-setup-windows-plain)) ;;; Lisps (use-package elisp-mode :custom (eval-expression-print-length nil) (eval-expression-print-level nil) :preface (defun elisp-eval-region|eval-buffer () (interactive) (if (region-active-p) (let ((start (region-beginning)) (end (region-end))) (eval-region start end) (message "Region from %s to %s evaluated." start end)) (eval-buffer) (message "Buffer `%s' evaluated." (buffer-name)))) (defkeys (emacs-lisp-mode-map lisp-interaction-mode-map) "C-c C-c" #'eval-defun "C-c C-k" #'elisp-eval-region|eval-buffer "C-c C-z" #'ielm) :config (define-advice eval-region (:around (orig start end &rest args) pulse) (apply orig start end args) (pulse-momentary-highlight-region start end)) (defhook emacs-lisp-mode-hook (setq-local page-delimiter "^\\( \\|;;;+\\).*"))) (use-package macrostep :ensure t :after elisp-mode :bind ( :map emacs-lisp-mode-map ("C-c e" . macrostep-expand) :map lisp-interaction-mode-map ("C-c e" . macrostep-expand))) (use-package eros :ensure t :after elisp-mode :custom (eros-eval-result-prefix "; ") :hook emacs-lisp-mode-hook) (use-package package-lint :ensure t) (use-package sly :ensure t :when (executable-find "sbcl") :custom (inferior-lisp-program (executable-find "sbcl")) (sly-net-coding-system 'utf-8-unix) :bind (:map sly-mode-map (("C-c C-z" . sly-mrepl))) :config (sly-symbol-completion-mode -1)) (use-package edebug :preface (defun turn-off-eldoc-mode () (eldoc-mode -1)) :config (add-hook 'edebug-mode-hook #'turn-off-eldoc-mode)) ;;; Web languages (use-package web-mode :ensure t :mode ("\\.phtml\\'" "\\.tpl\\.php\\'" "\\.[agj]sp\\'" "\\.as[cp]x\\'" "\\.erb\\'" "\\.mustache\\'" "\\.djhtml\\'" "\\.html?\\'")) ;;; Applications (use-package dired :init (require 'dired-x) :custom (dired-recursive-copies 'always) (dired-recursive-deletes 'always) (dired-create-destination-dirs 'always) (dired-do-revert-buffer t) (dired-hide-details-hide-symlink-targets nil) (dired-isearch-filenames 'dwim) (delete-by-moving-to-trash t) (dired-auto-revert-buffer t) (dired-listing-switches "-AlF") (ls-lisp-dirs-first t) (dired-ls-F-marks-symlinks t) (dired-clean-confirm-killing-deleted-buffers nil) (dired-no-confirm '(byte-compile load chgrp chmod chown copy move hardlink symlink shell touch)) (dired-dwim-target t) :bind (("C-x C-j" . dired-jump) ([remap list-directory] . dired) :map dired-mode-map ("C-j" . dired-up-directory) ("" . dired-up-directory)) :init (defhook dired-mode-hook #'dired-hide-details-mode #'hl-line-mode #'truncate-lines-local-mode)) (use-package dired-subtree :ensure t :after dired :bind (:map dired-mode-map (("TAB" . dired-subtree-cycle) ("i" . dired-subtree-toggle)))) (use-package dired-collapse :ensure t :hook dired-mode-hook) (use-package dired-hide-dotfiles :ensure t :bind (:map dired-mode-map ("." . dired-hide-dotfiles-mode))) (use-package magit :ensure t :bind ("C-x g" . magit)) (use-package auth-source :custom (auth-sources '(default "secrets:passwords")) :config (defhook authinfo-mode-hook #'truncate-lines-local-mode)) (use-package keychain-environment :ensure t :when (executable-find "keychain") :hook (after-init-hook . keychain-refresh-environment)) (use-package keepassxc-shim :load-path "~/src/emacs/keepassxc-shim/" :config (keepassxc-shim-activate)) (use-package eat :ensure t :commands eat-eshell-mode :hook (eshell-load-hook . eat-eshell-mode)) (use-package dictionary :custom (dictionary-server (if (or (executable-find "dictd") (file-exists-p "/usr/sbin/dictd")) ; debian "localhost" "dict.org")) :bind (("C-c d" . dictionary-search))) (use-package pdf-tools :ensure t :mode ("\\.[pP][dD][fF]\\'" . pdf-view-mode) :magic ("%PDF" . pdf-view-mode) :config (pdf-tools-install)) ;;; Mail (use-package bbdb :ensure t :custom (bbdb-complete-mail-allow-cycling t) (bbdb-file (private/ "bbdb")) :init (defhook custom-allowed-after-load-hook :name bbdb@after-custom (require 'bbdb) (require 'bbdb-message) (bbdb-initialize 'message))) (use-package bbdb-vcard :ensure t) (use-package notmuch :load-path "~/usr/share/emacs/site-lisp/" :preface (defdir notmuch/ (sync/ "emacs/notmuch")) :init (use-package +notmuch :after notmuch :load-path "lisp/" :bind (("C-c n" . +notmuch-goto) :map notmuch-search-mode-map ("!" . +notmuch-search-mark-spam) :map notmuch-tree-mode-map ("!" . +notmuch-search-mark-spam-then-next) ("M-<" . +notmuch-tree-beginning) ("M->" . +notmuch-tree-end)) :hook (message-send-hook . +send-mail-dispatch) :config ;; Saved searches (+notmuch-make-saved-search "inbox+unread" "m" 'tree "tag:inbox" "tag:unread" "NOT tag:Spam") (+notmuch-make-saved-search "inbox" "i" 'tree "tag:inbox" "NOT tag:Spam") (+notmuch-make-saved-search "lists+unread" "l" 'tree "tag:/List/" "tag:unread") (+notmuch-make-saved-search "lists" "L" 'tree "tag:/List/") (+notmuch-make-saved-search "unread" "u" 'tree "tag:unread" "NOT tag:Spam") (+notmuch-make-saved-search "flagged" "f" 'tree "tag:flagged") (+notmuch-make-saved-search "sent" "t" 'tree "tag:sent") (+notmuch-make-saved-search "drafts" "d" 'tree "tag:draft") (+notmuch-make-saved-search "all mail" "a" 'tree "*")) (use-package message :after notmuch :hook (message-setup-hook . message-signature-setup) :config (require '+message)) (defhook (notmuch-show-mode-hook notmuch-message-mode-hook) #'visual-fill-column-mode) :custom (notmuch-init-file (notmuch/ "notmuch-init.el" t)) (notmuch-address-save-filename (notmuch/ "addresses" t)) (notmuch-address-use-company (featurep 'company)) (notmuch-search-oldest-first nil) (notmuch-archive-tags '("-inbox" "-unread")) (notmuch-draft-tags '("+draft" "-inbox" "-unread")) (mail-user-agent 'notmuch-user-agent) (bbdb-mail-user-agent 'notmuch-user-agent) (message-mail-user-agent t) (notmuch-show-indent-content nil) (message-kill-buffer-on-exit t) (message-auto-save-directory nil) (send-mail-function #'sendmail-send-it) (mail-specify-envelope-from t) (message-sendmail-envelope-from 'header) (message-envelope-from 'header) (notmuch-saved-searches nil) :bind (("C-c m" . notmuch-mua-new-mail) :map notmuch-search-mode-map ("RET" . notmuch-search-show-thread) ("M-RET" . notmuch-tree-from-search-thread)) :config (load notmuch-init-file :noerror) (advice-add 'notmuch-tag :filter-args #'+notmuch-correct-tags) ;; Mailing lists (add-to-list 'notmuch-message-headers "List-Post" :append) (define-advice notmuch-mua-new-reply (:around (orig &rest r) list-aware) "Make `notmuch-mua-new-reply' list-aware." (let ((ml (notmuch-show-get-header :List-Post))) (apply orig r) (when ml (with-buffer-modified-unmodified (message-remove-header "To") (message-add-header (format "To: %s" (replace-regexp-in-string "" "\\1" ml))) (message-goto-body)))))) ;;; The INTERNET (use-package link-hint :ensure t :demand t :preface (global-set-key (kbd "M-l") nil) :custom (link-hint-avy-style 'at-full) (link-hint-avy-all-windows t) :config (require '+link-hint) (+link-hint-open-secondary-setup) (+link-hint-open-chrome-setup) :bind (("M-l M-l" . +link-hint-open-link) ("M-l l" . +link-hint-open-link) ("M-l M-o" . +link-hint-open-secondary) ("M-l o" . +link-hint-open-secondary) ("M-l M-m" . +link-hint-open-multiple-links) ("M-l m" . +link-hint-open-multiple-links) ("M-l M-w" . link-hint-copy-link) ("M-l w" . link-hint-copy-link) ("M-l M-c" . +link-hint-open-chrome) ("M-l c" . +link-hint-open-chrome))) (use-package browse-url :demand t :preface (require '+browse-url) :config (eval-after chd (add-to-list 'browse-url-handlers (cons chd/url-regexps #'browse-url-chrome)) (add-to-list '+browse-url-other-safe-browser-functions #'chd/browse-url)) (put 'browse-url-browser-function 'safe-local-variable #'+browse-url-browser-function-safe-p) :custom (browse-url-browser-function #'eww-browse-url) (browse-url-chromium-program (choose-executable "chromium")) (browse-url-chrome-program (choose-executable "chrome" "google-chrome-stable")) (browse-url-firefox-program (choose-executable "firefox" "firefox-esr")) (browse-url-firefox-new-window-is-tab t) (browse-url-firefox-arguments '("--new-tab")) (browse-url-generic-program (or browse-url-firefox-program browse-url browse-url-chrome-program)) (browse-url-generic-args (cl-loop for prog in '(firefox chromium chrome) for progfn = (intern (format "browse-url-%s-program" prog)) for progargs = (intern (format "browse-url-%s-arguments" prog)) if (equal browse-url-generic-program (symbol-value progfn)) return (symbol-value progargs) finally return nil)) (browse-url-handlers `(;; Videos (,(+browse-url-matches "youtube\\.com" "youtu\\.be" "invidious" "yewtu\\.be" (rx "." (or "mp4" "gif" "mov" "MOV" "webm") eos)) . +browse-url-with-mpv) ;; Music (,(+browse-url-matches "soundcloud\\.com" "bandcamp\\.com" (rx "." (or "ogg" "mp3" "opus" "m4a") eos)) . +browse-url-with-mpv) ;; Images (,(+browse-url-matches "pbs\\.twimg\\.com" (rx "." (or "jpeg" "jpg" "png" "bmp" "webp") eos)) . +browse-url-with-mpv-image) ;; Blobs (binary files) (,(+browse-url-matches (rx "." (or ".tar.gz" ".pdf") eos)) . +browse-url-download) ;; External URLs --- these are URLs that don't open in EWW very well, ;; so I want to open them in the external browser. (+browse-url-external-url-p . ,(if (featurep 'xwidget-internal) #'xwidget-webkit-browse-url browse-url-secondary-browser-function)))) (+browse-url-external-domains '("github.com" "gitlab.com" "codeberg.org" "tildegit.org" "git.tilde.town" "google.com" "imgur.com" "twitch.tv" "pixelfed" "instagram.com" "bibliogram.art" "reddit.com" "teddit.net" "libreddit.de" "streamable.com" "spotify.com" "hetzner.cloud" "melpa.org" "twitter.com" ("^t\\.co$") "nitter.snopyta.org" "nitter.net"))) (use-package browse-url-transform :after browse-url :load-path "~/src/emacs/browse-url-transform/" :custom (browse-url-transform-alist `(;; Privacy-respecting alternatives ("twitter\\.com" . "nitter.snopyta.org") ("\\(?:\\(?:old\\.\\)?reddit\\.com\\)" . "libreddit.de") ("medium\\.com" . "scribe.rip") (".*substack\\.com.*" . ,substack-proxy) ;; Text-mode of non-text-mode sites ("www\\.npr\\.org" . "text.npr.org") ;; Ask for raw versions of paste sites ("^.*dpaste\\.com.*$" . "\\&.txt") ("bpa\\.st/\\(.*\\)" . "bpa.st/raw/\\1") ("\\(paste\\.debian\\.net\\)/\\(.*\\)" . "\\1/plain/\\2") ("\\(pastebin\\.com\\)/\\\(.*\\)" . "\\1/raw/\\2") ("\\(paste\\.centos\\.org/view\\)/\\(.*\\)" . "\\1/raw/\\2"))) :config (browse-url-transform-mode)) (use-package eww :custom (eww-use-browse-url ".") :config (defhook eww-mode-hook (defhook ((visual-fill-column-mode nil :local)) :name visual-fill-column@eww-mode-refresh (eww-reload t))) (defkeys eww-mode-map "&" (+browse-url-switch-external-browser eww-mode (plist-get eww-data :url)))) (use-package xwidget :when (featurep 'xwidget-internal) :preface (setenv "WEBKIT_FORCE_SANDBOX" "0") ; This is probably a bad idea :custom (xwidget-webkit-cookie-file (cache/ "xwidget-cookies")) (xwidget-webkit-download-dir (expand-file-name "~/var/download")) :config (defkeys xwidget-webkit-mode-map "&" (+browse-url-switch-external-browser xwidget-webkit-mode (xwidget-webkit-uri (xwidget-webkit-current-session))))) (use-package xwwp :load-path "~/src/emacs/xwwp/" :when (featurep 'xwidget-internal) :custom (xwwp-search-prefix "https://duckduckgo.com/?q=") :bind (:map xwidget-webkit-mode-map ("f" . xwwp-follow-link))) (use-package jabber :load-path "~/src/emacs/emacs-jabber" :custom (jabber-account-list '(("acdw@hmm.st"))) (jabber-auto-reconnect t) (jabber-chat-buffer-format "xmpp:%n") (jabber-browse-buffer-format "xmpp-browse:%n") (jabber-groupchat-buffer-format "xmpp-muc:%n") (jabber-muc-private-buffer-format "xmpp-muc-private:%n") (jabber-groupchat-prompt-format "%>10n │ ") (jabber-chat-local-prompt-format "%>10n │ ") (jabber-chat-system-prompt-format " * * * * * *") (jabber-chat-foreign-prompt-format "%>10n │ ") (jabber-muc-private-foreign-prompt-format "%g/%n ") (jabber-last-read-marker "----------------------------------------") (jabber-muc-header-line-format '("" jabber-muc-topic)) (jabber-muc-decorate-presence-patterns '(("\\( enters the room ([^)]+)\\| has left the chatroom\\)$") ("." . jabber-muc-presence-dim))) (jabber-activity-make-strings #'jabber-activity-make-strings-shorten) (jabber-rare-time-format " - - - - - - %H:%M %F") :custom-face (jabber-chat-prompt-local ((t :inherit font-lock-keyword-face :foreground unspecified))) (jabber-activity-face ((t :inherit jabber-chat-prompt-foreign :foreground unspecified :weight normal))) (jabber-activity-personal-face ((t :inherit font-lock-warning-face :foreground unspecified :weight bold))) (jabber-chat-prompt-foreign ((t :inherit font-lock-constant-face :foreground unspecified))) (jabber-chat-prompt-system ((t :inherit font-lock-doc-face :foreground unspecified))) (jabber-rare-time-face ((t :inherit font-lock-comment-face :foreground unspecified :underline nil))) :init (defhook (jabber-chat-mode-hook jabber-browse-mode-hook jabber-roster-mode-hook jabber-console-mode-hook) :name jabber-ui-setup (visual-fill-column-mode) (electric-pair-local-mode -1) (auto-fill-mode -1) (setq-local wrap-prefix (format "%13s" " "))) :bind-keymap ("C-c j" . jabber-global-keymap) :bind (("C-c C-SPC" . jabber-activity-switch-to)) :config (global-set-key (kbd "C-x C-j") #'dired-jump) ; Extremely annoying fix (require 'jabber-httpupload nil :noerror) (add-hook 'jabber-post-connect-hooks #'jabber-enable-carbons) (remove-hook 'jabber-alert-muc-hooks 'jabber-muc-echo) (remove-hook 'jabber-alert-presence-hooks 'jabber-presence-echo) (add-hook 'jabber-alert-muc-hooks (defun jabber@highlight-acdw (&optional _nick _group buf _text _title) (when buf (with-current-buffer buf (let ((regexp (rx word-boundary "acdw" ; maybe get from the config? word-boundary))) (hi-lock-unface-buffer regexp) (highlight-regexp regexp 'hi-blue)))))) (add-hook 'window-configuration-change-hook #'jabber-chat-update-focus) (eval-after consult (defvar jabber-chat-buffer-source `( :name "Jabber" :hidden nil :narrow ?j :category buffer :state ,#'consult--buffer-state :items ,(lambda () (mapcar #'buffer-name (seq-filter (lambda (buf) (with-current-buffer buf (eq major-mode 'jabber-chat-mode))) (buffer-list)))))) (add-to-list 'consult-buffer-sources 'jabber-chat-buffer-source :append) ;; Also hide xmpp buffers from regular buffer list (add-to-list 'consult-buffer-filter "\\`xmpp" nil #'string-equal)))