summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--.emacs.d/eshell/alias (renamed from .emacs.d/etc/eshell/aliases)0
-rw-r--r--.emacs.d/etc/.dir-locals.el4
-rw-r--r--.emacs.d/etc/secrets.el5
-rw-r--r--.emacs.d/init.el1434
-rw-r--r--.emacs.d/lisp/bandali-dired.el95
-rw-r--r--.emacs.d/lisp/bandali-erc.el200
-rw-r--r--.emacs.d/lisp/bandali-eshell.el97
-rw-r--r--.emacs.d/lisp/bandali-exwm.el352
-rw-r--r--.emacs.d/lisp/bandali-gnus.el430
-rw-r--r--.emacs.d/lisp/bandali-ibuffer.el110
-rw-r--r--.emacs.d/lisp/bandali-message.el110
-rw-r--r--.emacs.d/lisp/bandali-org.el125
-rw-r--r--.emacs.d/lisp/bandali-po.el61
-rw-r--r--.emacs.d/lisp/bandali-theme.el79
14 files changed, 1031 insertions, 2071 deletions
diff --git a/.emacs.d/etc/eshell/aliases b/.emacs.d/eshell/alias
index 113ef31..113ef31 100644
--- a/.emacs.d/etc/eshell/aliases
+++ b/.emacs.d/eshell/alias
diff --git a/.emacs.d/etc/.dir-locals.el b/.emacs.d/etc/.dir-locals.el
deleted file mode 100644
index e007adb..0000000
--- a/.emacs.d/etc/.dir-locals.el
+++ /dev/null
@@ -1,4 +0,0 @@
-;;; Directory Local Variables
-;;; For more information see (info "(emacs) Directory Variables")
-
-((emacs-lisp-mode . ((flycheck-disabled-checkers . (emacs-lisp-checkdoc)))))
diff --git a/.emacs.d/etc/secrets.el b/.emacs.d/etc/secrets.el
deleted file mode 100644
index edfa1a6..0000000
--- a/.emacs.d/etc/secrets.el
+++ /dev/null
@@ -1,5 +0,0 @@
-(eval-when-compile (require 'auth-source))
-(defvar nday-students-token (eval-when-compile (plist-get (car (auth-source-search :host "nday-students.slack.com" :max 1)) :token)))
-
-(defvar canlock-password (eval-when-compile (funcall (plist-get (car (auth-source-search :host "gnus-canlock-password" :max 1)) :secret))))
-
diff --git a/.emacs.d/init.el b/.emacs.d/init.el
index 6e038d4..c9e5c8e 100644
--- a/.emacs.d/init.el
+++ b/.emacs.d/init.el
@@ -17,17 +17,20 @@
;;; Commentary:
-;; GNU Emacs configuration of bandali, free software activist,
-;; computing scientist, and GNU maintainer and volunteer.
-
-;; Over the years, I've taken inspiration from configurations of many
-;; great people. Some that I can remember off the top of my head are:
+;; bandali's opinionated GNU Emacs configs. I tend to use the latest
+;; development trunk of emacs.git, but I try to maintain backward
+;; compatibility with a few of the recent older GNU Emacs releases
+;; so I could easily reuse it on machines stuck with older Emacsen.
+
+;; When initially putting this together, I took inspiration from
+;; configurations of many great people. Some that I could remember
+;; off the top of my head are:
;;
;; - https://github.com/dieggsy/dotfiles
;; - https://github.com/dakra/dmacs
-;; - http://pages.sachachua.com/.emacs.d/Sacha.html
+;; - https://pages.sachachua.com/.emacs.d/Sacha.html
;; - https://github.com/dakrone/eos
-;; - http://doc.rix.si/cce/cce.html
+;; - https://cce.whatthefuck.computer/
;; - https://github.com/jwiegley/dot-emacs
;; - https://github.com/wasamasa/dotemacs
;; - https://github.com/hlissner/doom-emacs
@@ -42,11 +45,10 @@
(defconst b/gc-cons-threshold gc-cons-threshold)
(defconst b/gc-cons-percentage gc-cons-percentage)
(defvar b/file-name-handler-alist file-name-handler-alist)
-(setq gc-cons-threshold (* 30 1024 1024) ; 30 MiB
- gc-cons-percentage 0.6
- file-name-handler-alist nil
- ;; sidesteps a bug when profiling with esup
- esup-child-profile-require-level 0)
+(setq
+ gc-cons-threshold (* 30 1024 1024) ; 30 MiB
+ gc-cons-percentage 0.6
+ file-name-handler-alist nil)
;; Set them back to their defaults once we're done initializing.
(defun b/post-init ()
@@ -55,92 +57,107 @@
b/emacs-initialized t
gc-cons-threshold b/gc-cons-threshold
gc-cons-percentage b/gc-cons-percentage
- file-name-handler-alist b/file-name-handler-alist))
+ file-name-handler-alist b/file-name-handler-alist)
+
+ (require 'package)
+ (package-initialize))
(add-hook 'after-init-hook #'b/post-init)
;; whoami
-(setq user-full-name "Amin Bandali"
- user-mail-address "bandali@kelar.org")
-
-
-;;; Package management
-
-;; variables of interest:
-;; package-archive-priorities
-;; package-load-list
-;; package-pinned-packages
-
-;; (let* ((b (find-file-noselect "refinery-theme.el"))
-;; (d (with-current-buffer b (package-buffer-info))))
-;; (package-generate-description-file d "refinery-theme-pkg.el"))
-(run-with-idle-timer 0.01 nil #'require 'package)
-(with-eval-after-load 'package
- ;; (setq
- ;; ;; package-archives
- ;; ;; `(,@package-archives
- ;; ;; ("bndl" . "https://p.bndl.org/elpa/"))
- ;; package-load-list
- ;; '(;; GNU ELPA
- ;; (debbugs "0.29")
- ;; (delight "1.7")
- ;; (emms "7.7")
- ;; (rt-liberation "2.4")))
- (package-initialize))
+(setq
+ user-full-name "Amin Bandali"
+ user-mail-address "bandali@kelar.org")
;;; Initial setup
-;; Keep ~/.emacs.d clean.
-(defvar b/etc-dir
- (expand-file-name
- (convert-standard-filename "etc/") user-emacs-directory)
- "The directory where packages place their configuration files.")
-(defvar b/var-dir
- (expand-file-name
- (convert-standard-filename "var/") user-emacs-directory)
- "The directory where packages place their persistent data files.")
-(defvar b/lisp-dir
- (expand-file-name
- (convert-standard-filename "lisp/") user-emacs-directory)
- "The directory where packages place their persistent data files.")
-(defun b/etc (file)
- "Expand filename FILE relative to `b/etc-dir'."
- (expand-file-name (convert-standard-filename file) b/etc-dir))
-(defun b/var (file)
- "Expand filename FILE relative to `b/var-dir'."
- (expand-file-name (convert-standard-filename file) b/var-dir))
-(defun b/lisp (file)
- "Expand filename FILE relative to `b/lisp-dir'."
- (expand-file-name (convert-standard-filename file) b/lisp-dir))
+(eval-and-compile
+ (defsubst b/emacs.d (path)
+ "Expand path PATH relative to `user-emacs-directory'."
+ (expand-file-name
+ (convert-standard-filename path) user-emacs-directory))
+
+ ;; Wrappers around the new keybinding functions, with fallback to
+ ;; the corresponding older lower level function on older Emacsen.
+ (defsubst b/keymap-set (keymap key definition)
+ (if (version< emacs-version "29")
+ (define-key keymap (kbd key) definition)
+ (keymap-set keymap key definition)))
+ (defsubst b/keymap-global-set (key command)
+ (if (version< emacs-version "29")
+ (global-set-key (kbd key) command)
+ (keymap-global-set key command)))
+ (defsubst b/keymap-local-set (key command)
+ (if (version< emacs-version "29")
+ (local-set-key (kbd key) command)
+ (keymap-local-set key command)))
+ (defsubst b/keymap-global-unset (key)
+ (if (version< emacs-version "29")
+ (global-unset-key (kbd key))
+ (keymap-global-unset key 'remove)))
+ (defsubst b/keymap-local-unset (key)
+ (if (version< emacs-version "29")
+ (local-unset-key (kbd key))
+ (keymap-local-unset key 'remove)))
+
+ (when (version< emacs-version "29")
+ ;; Emacs 29 introduced the handy `setopt' macro for setting user
+ ;; options (defined with `defcustom') with a syntax similar to
+ ;; `setq'. So, we define it on older Emacsen that don't have it.
+ (defmacro setopt (&rest pairs)
+ "Set VARIABLE/VALUE pairs, and return the final VALUE.
+This is like `setq', but is meant for user options instead of
+plain variables. This means that `setopt' will execute any
+`custom-set' form associated with VARIABLE.
+
+\(fn [VARIABLE VALUE]...)"
+ (declare (debug setq))
+ (unless (zerop (mod (length pairs) 2))
+ (error "PAIRS must have an even number of variable/value members"))
+ (let ((expr nil))
+ (while pairs
+ (unless (symbolp (car pairs))
+ (error "Attempting to set a non-symbol: %s" (car pairs)))
+ (push `(setopt--set ',(car pairs) ,(cadr pairs))
+ expr)
+ (setq pairs (cddr pairs)))
+ (macroexp-progn (nreverse expr))))
+
+ (defun setopt--set (variable value)
+ (custom-load-symbol variable)
+ ;; Check that the type is correct.
+ (when-let ((type (get variable 'custom-type)))
+ (unless (widget-apply (widget-convert type) :match value)
+ (warn "Value `%S' does not match type %s" value type)))
+ (put variable 'custom-check-value (list value))
+ (funcall (or (get variable 'custom-set) #'set-default) variable value))))
;; Separate custom file (don't want it mixing with init.el).
+(setopt custom-file (b/emacs.d "custom.el"))
(with-eval-after-load 'custom
- (setq custom-file (b/etc "custom.el"))
(when (file-exists-p custom-file)
- (load custom-file))
- ;; Only one custom theme at a time.
- ;; (defadvice load-theme (before clear-previous-themes activate)
- ;; "Clear existing theme settings instead of layering them"
- ;; (mapc #'disable-theme custom-enabled-themes))
- )
-
-;; Load the secrets file if it exists, otherwise show a warning.
-;; (with-demoted-errors
-;; (load (b/etc "secrets")))
-
-;; Start up emacs server:
-;; https://www.gnu.org/software/emacs/manual/html_node/emacs/Emacs-Server.html
+ (load custom-file)))
+
+;; Start Emacs server
+;; (https://www.gnu.org/software/emacs/manual/html_node/emacs/Emacs-Server.html)
(run-with-idle-timer 0.5 nil #'require 'server)
(with-eval-after-load 'server
(declare-function server-edit "server")
- (global-set-key (kbd "C-c F D") #'server-edit)
+ (b/keymap-global-set "C-c F D" #'server-edit)
(declare-function server-running-p "server")
(or (server-running-p) (server-mode)))
;;; Defaults
-;;;; C-level customizations
+;;;; C source code
+
+(setq-default
+ ;; Case-sensitive search (and `dabbrev-expand').
+ ;; case-fold-search nil
+ indent-tabs-mode nil ; always use space for indentation
+ ;; tab-width 4
+ indicate-buffer-boundaries 'left)
(setq
;; line-spacing 3
@@ -153,83 +170,53 @@
;; mouse-autoselect-window t
scroll-conservatively 15
scroll-preserve-screen-position 1
- ;; I don't feel like jumping out of my chair every now and again;
- ;; so...don't *BEEP* at me, Emacs. =)
+ ;; I don't feel like randomly jumping out of my chair.
ring-bell-function 'ignore)
-(setq-default
- ;; Case-sensitive search (and `dabbrev-expand').
- ;; case-fold-search nil
- indent-tabs-mode nil ; always use space for indentation
- tab-width 4
- indicate-buffer-boundaries 'left)
-
-;; Lazy-person-friendly yes/no prompts.
-(defalias 'yes-or-no-p #'y-or-n-p)
-
-(when (display-graphic-p)
- ;; (set-frame-font "Source Code Pro-10.5:weight=medium" nil t)
- ;; (set-frame-font "FreeSans" nil t)
- (set-fontset-font t 'arabic "Sahel WOL"))
-
-;;;; Elisp-level customizations
+;;;; elisp source code
(with-eval-after-load 'minibuffer
- (setq read-file-name-completion-ignore-case t))
-
-;; `startup'
-(setq auto-save-list-file-prefix (b/var "auto-save/sessions/"))
+ (setopt read-file-name-completion-ignore-case t))
(with-eval-after-load 'files
- (setq
- ;; backups (C-h v make-backup-files RET)
- backup-by-copying t
- backup-directory-alist (list (cons "." (b/var "backup/")))
- version-control t
- delete-old-versions t
- ;; auto-save
- auto-save-file-name-transforms `((".*" ,(b/var "auto-save/") t))
- ;; insert newline at the end of files
+ (setopt
+ make-backup-files nil
+ ;; Insert newline at the end of files
;; require-final-newline t
- ;; open read-only file buffers in view-mode
- ;; (enables niceties like `q' for quit)
- view-read-only t))
+ ;; Open read-only file buffers in view-mode;
+ ;; it enables niceties like `q' for quit.
+ view-read-only t)
+ (add-to-list 'auto-mode-alist '("\\.*rc$" . conf-mode))
+ (add-to-list 'auto-mode-alist '("\\.bashrc$" . sh-mode)))
-;; `novice'
(setq disabled-command-function nil)
-;; `subr'
-;; (keyboard-translate ?\( ?\[)
-;; (keyboard-translate ?\) ?\])
-;; (keyboard-translate ?\[ ?\()
-;; (keyboard-translate ?\] ?\))
-
(run-with-idle-timer 0.1 nil #'require 'autorevert)
(with-eval-after-load 'autorevert
- (setq
+ (setopt
;; auto-revert-verbose nil
global-auto-revert-non-file-buffers nil)
(global-auto-revert-mode 1))
(run-with-idle-timer 0.1 nil #'require 'time)
(with-eval-after-load 'time
- (setq
+ (setopt
display-time-default-load-average nil
display-time-format " %a %Y-%m-%d %-l:%M%P"
- display-time-mail-icon '(image :type xpm
- :file "gnus/gnus-pointer.xpm"
- :ascent center)
+ display-time-mail-icon
+ '(image :type xpm :file "gnus/gnus-pointer.xpm" :ascent center)
display-time-use-mail-icon t
zoneinfo-style-world-list
`(,@zoneinfo-style-world-list
("Etc/UTC" "UTC")
("Asia/Tehran" "Tehran")
("Australia/Melbourne" "Melbourne")))
- (display-time-mode))
+ (unless (display-graphic-p)
+ (display-time-mode)))
(run-with-idle-timer 0.1 nil #'require 'battery)
(with-eval-after-load 'battery
- (setq battery-mode-line-format " [%p%% %t]")
+ (setopt battery-mode-line-format " [%b%p%% %t]")
(display-battery-mode))
(progn ; display system volume in mode-line
@@ -299,30 +286,18 @@ microphone) instead of the default sink."
(run-with-idle-timer 0.5 nil #'require 'winner)
(with-eval-after-load 'winner
- (winner-mode 1)
- (when (featurep 'exwm)
- ;; prevent a bad interaction between EXWM and winner-mode, where
- ;; sometimes closing a window (like closing a terminal after
- ;; entering a GPG password via pinentry-gnome3's floating window)
- ;; results in a dead frame somewhere and effectively freezes EXWM.
- (advice-add
- 'winner-insert-if-new
- :around
- (lambda (orig-fun &rest args)
- ;; only add the frame if it's live
- (when (frame-live-p (car args))
- (apply orig-fun args))))))
+ (winner-mode 1))
(run-with-idle-timer 0.5 nil #'require 'windmove)
(with-eval-after-load 'windmove
- (setq windmove-wrap-around t)
- (global-set-key (kbd "M-H") #'windmove-left)
- (global-set-key (kbd "M-L") #'windmove-right)
- (global-set-key (kbd "M-K") #'windmove-up)
- (global-set-key (kbd "M-J") #'windmove-down))
+ (setopt windmove-wrap-around t)
+ (b/keymap-global-set "M-H" #'windmove-left)
+ (b/keymap-global-set "M-L" #'windmove-right)
+ (b/keymap-global-set "M-K" #'windmove-up)
+ (b/keymap-global-set "M-J" #'windmove-down))
(with-eval-after-load 'isearch
- (setq
+ (setopt
;; Allow scrolling in Isearch.
isearch-allow-scroll t
isearch-lazy-count t
@@ -334,27 +309,28 @@ microphone) instead of the default sink."
;; (with-eval-after-load 'replace
;; ;; Uncomment to extend the above behaviour to query-replace.
-;; (setq replace-char-fold t))
+;; (setopt replace-char-fold t))
-;; `vc'
-(global-set-key (kbd "C-x v C-=") #'vc-ediff)
+(b/keymap-global-set "C-x v C-=" #'vc-ediff)
(with-eval-after-load 'vc-git
- (setq vc-git-print-log-follow t
- vc-git-show-stash 0))
+ (setopt
+ ;; vc-git-show-stash 0
+ vc-git-print-log-follow t))
(with-eval-after-load 'ediff
- (setq ediff-window-setup-function 'ediff-setup-windows-plain
- ediff-split-window-function 'split-window-horizontally))
+ (setopt
+ ediff-window-setup-function #'ediff-setup-windows-plain
+ ediff-split-window-function #'split-window-horizontally))
-(with-eval-after-load 'face-remap
- (setq
- ;; Gentler font resizing.
- text-scale-mode-step 1.05))
+;; (with-eval-after-load 'face-remap
+;; (setopt
+;; ;; Gentler font resizing.
+;; text-scale-mode-step 1.05))
(run-with-idle-timer 0.4 nil #'require 'mwheel)
(with-eval-after-load 'mwheel
- (setq
+ (setopt
mouse-wheel-scroll-amount '(1 ((shift) . 1)) ; one line at a time
mouse-wheel-progressive-speed nil ; don't accelerate scrolling
mouse-wheel-follow-mouse t)) ; scroll window under mouse
@@ -364,17 +340,17 @@ microphone) instead of the default sink."
(pixel-scroll-mode 1))
(with-eval-after-load 'epg-config
- (setq
+ (setopt
epg-gpg-program (executable-find "gpg")
;; Ask for GPG passphrase in minibuffer.
;; Will fail if gpg >= 2.1 is not available.
epg-pinentry-mode 'loopback))
-(with-eval-after-load 'auth-source
- (setq
- auth-sources '("~/.authinfo.gpg")
- authinfo-hidden
- (regexp-opt '("password" "client-secret" "token"))))
+;; (with-eval-after-load 'auth-source
+;; (setopt
+;; auth-sources '("~/.authinfo.gpg")
+;; authinfo-hidden
+;; (regexp-opt '("password" "client-secret" "token"))))
(with-eval-after-load 'info
(setq
@@ -385,6 +361,7 @@ microphone) instead of the default sink."
"/usr/share/info/")))
(when (display-graphic-p)
+ (set-fontset-font t 'arabic "Sahel WOL")
(with-eval-after-load 'faces
(let ((grey "#e7e7e7"))
(set-face-attribute 'fixed-pitch nil
@@ -394,10 +371,10 @@ microphone) instead of the default sink."
:background grey
:inherit 'fixed-pitch))))
-(when (version< emacs-version "28")
- ;; Manually make some `mode-line' spaces smaller. Emacs 28 (and
- ;; above) does a terrific job at this out of the box when
- ;; `mode-line-compact' is set to t (see above)."
+(when (and (version< emacs-version "28") mode-line-compact)
+ ;; Manually make some `mode-line' spaces smaller.
+ ;; Emacs 28 and above do a terrific job at this out of the box
+ ;; when `mode-line-compact' is set to t (see above)."
(setq-default
mode-line-format
(mapcar
@@ -414,12 +391,6 @@ microphone) instead of the default sink."
;;; Useful utilities
-(defun b/add-elisp-section ()
- (interactive)
- (insert "\n")
- (forward-line -1)
- (insert "\n \n;;; "))
-
(defun b/insert-asterism ()
"Insert a centred asterism."
(interactive)
@@ -433,39 +404,13 @@ microphone) instead of the default sink."
asterism
"\n"))))
-(defun b/start-process (program &rest args)
- "Same as `start-process', but doesn't bother about name and buffer."
- (let ((process-name (concat program "_process"))
- (buffer-name (generate-new-buffer-name
- (concat program "_output"))))
- (apply #'start-process
- process-name buffer-name program args)))
-
-(defun b/no-mouse-autoselect-window ()
- "Conveniently disable `focus-follows-mouse'.
-For disabling the behaviour for certain buffers and/or modes."
- (make-local-variable 'mouse-autoselect-window)
- (setq mouse-autoselect-window nil))
-
-;; (defun b/move-indentation-or-beginning-of-line (arg)
-;; "Move to the indentation or to the beginning of line."
-;; (interactive "^p")
-;; ;; (if (bolp)
-;; ;; (back-to-indentation)
-;; ;; (move-beginning-of-line arg))
-;; (if (= (point)
-;; (progn (back-to-indentation)
-;; (point)))
-;; (move-beginning-of-line arg)))
-
(defun b/join-line-top ()
"Like `join-line', but join next line to the current line."
(interactive)
(join-line 1))
(defun b/*scratch* ()
- "Switch to `*scratch*' buffer, creating it if it does not
- exist."
+ "Switch to `*scratch*' buffer, creating it if it does not exist."
(interactive)
(let ((fun (if (functionp #'get-scratch-buffer-create)
#'get-scratch-buffer-create ; (version<= "29" emacs-version)
@@ -500,88 +445,54 @@ for all frames."
(let ((frame (unless arg
(selected-frame))))
(invert-face 'default frame)
- (invert-face 'mode-line frame))
- (when (fboundp #'exwm-systemtray--refresh-background-color)
- (exwm-systemtray--refresh-background-color 'remap)))
-
-(defun b/export-frame ()
- (interactive)
- ;; TODO: ask for fn and/or take as arg
- (let* ((fn (make-temp-file "emacs" nil ".pdf"))
- (data (x-export-frames nil 'pdf)))
- (with-temp-file fn
- (insert data))
- (kill-new fn)
- (message fn)))
+ (invert-face 'mode-line frame)))
;;; General key bindings
-;; (global-set-key (kbd "C-a") #'b/move-indentation-or-beginning-of-line)
-(global-set-key (kbd "C-c i") #'ielm)
-(global-set-key (kbd "C-c d") #'b/duplicate-line-or-region)
-(global-set-key (kbd "C-c j") #'b/join-line-top)
-(global-set-key (kbd "C-S-j") #'b/join-line-top)
-(global-set-key (kbd "C-c s c") #'b/*scratch*)
-(global-set-key (kbd "C-c v") #'b/invert-default-face)
+(b/keymap-global-set "C-c i" #'ielm)
+(b/keymap-global-set "C-c d" #'b/duplicate-line-or-region)
+(b/keymap-global-set "C-c j" #'b/join-line-top)
+(b/keymap-global-set "C-S-j" #'b/join-line-top)
+(b/keymap-global-set "C-c s c" #'b/*scratch*)
+(b/keymap-global-set "C-c v" #'b/invert-default-face)
;; evaling and macro-expanding
-(global-set-key (kbd "C-c e b") #'eval-buffer)
-(global-set-key (kbd "C-c e e") #'eval-last-sexp)
-(global-set-key (kbd "C-c e m") #'pp-macroexpand-last-sexp)
-(global-set-key (kbd "C-c e r") #'eval-region)
+(b/keymap-global-set "C-c e b" #'eval-buffer)
+(b/keymap-global-set "C-c e e" #'eval-last-sexp)
+(b/keymap-global-set "C-c e m" #'pp-macroexpand-last-sexp)
+(b/keymap-global-set "C-c e r" #'eval-region)
;; emacs things
-(global-set-key (kbd "C-c e i") #'emacs-init-time)
-(global-set-key (kbd "C-c e u") #'emacs-uptime)
-(global-set-key (kbd "C-c e v") #'emacs-version)
+(b/keymap-global-set "C-c e i" #'emacs-init-time)
+(b/keymap-global-set "C-c e u" #'emacs-uptime)
+(b/keymap-global-set "C-c e v" #'emacs-version)
;; finding
-(global-set-key (kbd "C-c f .") #'find-file)
-(global-set-key (kbd "C-c f d") #'find-name-dired)
-(global-set-key (kbd "C-c f l") #'find-library)
-(global-set-key (kbd "C-c f p") #'find-file-at-point)
+(b/keymap-global-set "C-c f ." #'find-file)
+(b/keymap-global-set "C-c f l" #'find-library)
+(b/keymap-global-set "C-c f p" #'find-file-at-point)
;; frames
-(global-set-key (kbd "C-c F m") #'make-frame-command)
-(global-set-key (kbd "C-c F d") #'delete-frame)
+(b/keymap-global-set "C-c F m" #'make-frame-command)
+(b/keymap-global-set "C-c F d" #'delete-frame)
;; help/describe
-(global-set-key (kbd "C-S-h F") #'describe-face)
+(b/keymap-global-set "C-c h F" #'describe-face)
-(define-key emacs-lisp-mode-map (kbd "C-<return>") #'b/add-elisp-section)
-
-(when (display-graphic-p)
- (global-unset-key (kbd "C-z")))
+;; (when (display-graphic-p)
+;; ;; Too easy to accidentally suspend (freeze) Emacs GUI.
+;; (b/keymap-global-unset "C-z"))
;;; Essential packages
-(add-to-list
- 'load-path
- (expand-file-name
- (convert-standard-filename "lisp") user-emacs-directory))
-
-(when
- (and
- (display-graphic-p)
- ;; we're not running in another WM/DE
- (not (getenv "XDG_CURRENT_DESKTOP"))
- (member (system-name) '("chaman" "langa")))
- (require 'bandali-exwm)
- (global-set-key (kbd "C-x b") #'exwm-workspace-switch-to-buffer))
-
-(require 'bandali-org)
-
-;; (require 'bandali-theme)
+(add-to-list 'load-path (b/emacs.d "lisp"))
;; recently opened files
(run-with-idle-timer 0.2 nil #'require 'recentf)
(with-eval-after-load 'recentf
- (setq
- recentf-max-saved-items 2000
- recentf-save-file (b/var "recentf-save.el"))
- ;; (add-to-list 'recentf-keep #'file-remote-p)
+ (setopt recentf-max-saved-items 2000)
(recentf-mode)
(defun b/recentf-open ()
@@ -589,7 +500,7 @@ for all frames."
(interactive)
(find-file
(completing-read "Find recent file: " recentf-list)))
- (global-set-key (kbd "C-c f r") #'b/recentf-open))
+ (b/keymap-global-set "C-c f r" #'b/recentf-open))
;; (define-key minibuffer-local-completion-map
;; "\t" #'minibuffer-force-complete)
@@ -627,69 +538,812 @@ for all frames."
;; completion-styles '(basic substring partial-completion flex))))
;; (add-hook 'minibuffer-setup-hook #'b/icomplete--fido-mode-setup 1)
-(require 'bandali-eshell)
-
-(require 'bandali-ibuffer)
-
-(require 'bandali-dired)
-
-(with-eval-after-load 'help
- (temp-buffer-resize-mode)
- (setq help-window-select t))
+(with-eval-after-load 'eshell
+ (setopt
+ eshell-hist-ignoredups t
+ eshell-input-filter #'eshell-input-filter-initial-space
+ eshell-prompt-regexp "^[^#$\n]* [#$] ; "
+ eshell-prompt-function
+ (lambda ()
+ (let ((uid (if (functionp #'file-user-uid)
+ #'file-user-uid ; (version<= "30" emacs-version)
+ #'user-uid))) ; (version< emacs-version "30")
+ (concat ": "
+ (system-name)
+ ":"
+ (abbreviate-file-name (eshell/pwd))
+ (unless (eshell-exit-success-p)
+ (format " [%d]" eshell-last-command-status))
+ (if (= (funcall uid) 0) " # " " $ ")
+ "; "))))
+ (eval-when-compile
+ (defvar eshell-prompt-regexp)
+ (declare-function eshell-life-is-too-much "esh-mode")
+ (declare-function eshell-send-input "esh-mode"
+ (&optional use-region queue-p no-newline)))
+ (defun b/eshell-quit-or-delete-char (arg)
+ (interactive "p")
+ (if (and (eolp) (looking-back eshell-prompt-regexp nil))
+ (eshell-life-is-too-much)
+ (delete-char arg)))
+ (defun b/eshell-clear ()
+ (interactive)
+ (let ((inhibit-read-only t))
+ (erase-buffer))
+ (eshell-send-input))
+ (defun b/eshell-history ()
+ (interactive)
+ (completing-read "Eshell history: "
+ (ring-elements eshell-history-ring)))
+ (with-eval-after-load 'esh-mode
+ (let ((m eshell-mode-map))
+ (b/keymap-set m "C-d" #'b/eshell-quit-or-delete-char)
+ (b/keymap-set m "C-S-l" #'b/eshell-clear)))
+ (with-eval-after-load 'esh-hist
+ (let ((m eshell-hist-mode-map))
+ (b/keymap-set m "M-r" #'b/eshell-history))))
+(b/keymap-global-set "C-c s e" #'eshell)
+
+(with-eval-after-load 'ibuffer
+ (setopt
+ ibuffer-saved-filter-groups
+ '(("default"
+ ("dired" (mode . dired-mode))
+ ("erc" (mode . erc-mode))
+ ("gnus"
+ (or
+ (mode . gnus-group-mode)
+ (mode . gnus-server-mode)
+ (mode . gnus-summary-mode)
+ (mode . gnus-article-mode)
+ (mode . message-mode)))
+ ("shell"
+ (or
+ (mode . eshell-mode)
+ (mode . shell-mode)
+ (mode . term-mode)))
+ ("tex"
+ (or
+ (mode . tex-mode)
+ (mode . bibtex-mode)
+ (mode . latex-mode)))))
+ ibuffer-formats
+ `((mark modified read-only locked
+ " " (name 18 18 :left :elide)
+ " " (size-h 9 -1 :right)
+ " " (mode 16 16 :left :elide) " " filename-and-process)
+ ,@ibuffer-formats))
+ ;; Use human readable Size column instead of original one
+ (define-ibuffer-column size-h
+ (:name "Size" :inline t)
+ (cond
+ ((> (buffer-size) (* 1024 1024))
+ (format "%7.1fM" (/ (buffer-size) (* 1024.0 1024.0))))
+ ((> (buffer-size) (* 100 1024))
+ (format "%7.0fK" (/ (buffer-size) 1024.0)))
+ ((> (buffer-size) 1024)
+ (format "%7.1fK" (/ (buffer-size) 1024.0)))
+ (t (format "%8d" (buffer-size)))))
+
+ (let ((m ibuffer-mode-map))
+ (b/keymap-set m "P" #'ibuffer-backward-filter-group)
+ (b/keymap-set m "N" #'ibuffer-forward-filter-group)
+ (b/keymap-set m "M-p" #'ibuffer-do-print)
+ (b/keymap-set m "M-n" #'ibuffer-do-shell-command-pipe-replace)))
+(b/keymap-global-set "C-x C-b" #'ibuffer)
+(declare-function
+ ibuffer-switch-to-saved-filter-groups "ibuf-ext" (name))
+(add-hook
+ 'ibuffer-hook
+ (lambda () (ibuffer-switch-to-saved-filter-groups "default")))
+
+(with-eval-after-load 'dired
+ ;; (require 'ls-lisp)
+ (setopt
+ dired-dwim-target t
+ ;; dired-listing-switches "-alh --group-directories-first"
+ dired-listing-switches "-alh"
+ ;; ls-lisp-dirs-first t
+ ls-lisp-use-insert-directory-program nil)
+
+ (declare-function dired-dwim-target-directory "dired-aux")
+ ;; easily diff 2 marked files
+ ;; https://oremacs.com/2017/03/18/dired-ediff/
+ (defun dired-ediff-files ()
+ (interactive)
+ (require 'dired-aux)
+ (defvar ediff-after-quit-hook-internal)
+ (let ((files (dired-get-marked-files))
+ (wnd (current-window-configuration)))
+ (if (<= (length files) 2)
+ (let ((file1 (car files))
+ (file2 (if (cdr files)
+ (cadr files)
+ (read-file-name
+ "file: "
+ (dired-dwim-target-directory)))))
+ (if (file-newer-than-file-p file1 file2)
+ (ediff-files file2 file1)
+ (ediff-files file1 file2))
+ (add-hook 'ediff-after-quit-hook-internal
+ (lambda ()
+ (setq ediff-after-quit-hook-internal nil)
+ (set-window-configuration wnd))))
+ (error "no more than 2 files should be marked"))))
+
+ ;; local key bindings
+ (let ((m dired-mode-map))
+ (b/keymap-set m "b" #'dired-up-directory)
+ (b/keymap-set m "E" #'dired-ediff-files)
+ (b/keymap-set m "e" #'dired-toggle-read-only)
+ (b/keymap-set m "\\" #'dired-hide-details-mode))
+
+ (require 'dired-x)
+ (setopt
+ dired-guess-shell-alist-user
+ '(("\\.pdf\\'" "atril" "evince" "zathura" "okular")
+ ("\\.doc\\'" "libreoffice")
+ ("\\.docx\\'" "libreoffice")
+ ("\\.ppt\\'" "libreoffice")
+ ("\\.pptx\\'" "libreoffice")
+ ("\\.xls\\'" "libreoffice")
+ ("\\.xlsx\\'" "libreoffice")
+ ("\\.flac\\'" "mpv"))))
+(add-hook 'dired-mode-hook #'dired-hide-details-mode)
+
+;; (with-eval-after-load 'help
+;; (temp-buffer-resize-mode)
+;; (setopt help-window-select t))
(with-eval-after-load 'help-mode
- (define-key help-mode-map (kbd "p") #'backward-button)
- (define-key help-mode-map (kbd "n") #'forward-button))
+ (let ((m help-mode-map))
+ (b/keymap-set m "p" #'backward-button)
+ (b/keymap-set m "n" #'forward-button)
+ (b/keymap-set m "b" #'help-go-back)
+ (b/keymap-set m "f" #'help-go-forward)))
(with-eval-after-load 'tramp
- (setq tramp-auto-save-directory (b/var "tramp/auto-save/")
- tramp-persistency-file-name (b/var "tramp/persistency.el"))
+ (setopt tramp-auto-save-directory (b/emacs.d "tramp-auto-save/"))
(add-to-list 'tramp-default-proxies-alist '(nil "\\`root\\'" "/ssh:%h:"))
(add-to-list 'tramp-default-proxies-alist '("localhost" nil nil))
(add-to-list 'tramp-default-proxies-alist
(list (regexp-quote (system-name)) nil nil)))
(with-eval-after-load 'doc-view
- (define-key doc-view-mode-map (kbd "M-RET") #'image-previous-line))
+ (b/keymap-set doc-view-mode-map "M-RET" #'image-previous-line))
+
+(with-eval-after-load 'shr
+ (setopt shr-max-width 80))
-(setq shr-max-width 80)
+
+;;; Email
+
+(defvar b/maildir
+ (expand-file-name (convert-standard-filename "~/mail/")))
+(with-eval-after-load 'recentf
+ (add-to-list 'recentf-exclude b/maildir))
+
+(setopt
+ mail-user-agent 'gnus-user-agent
+ read-mail-command #'gnus)
+
+(eval-when-compile
+ (progn
+ (defvar nndraft-directory)
+ (defvar gnus-read-newsrc-file)
+ (defvar gnus-save-newsrc-file)
+ (defvar gnus-gcc-mark-as-read)
+ (defvar nnmail-split-abbrev-alist)))
+
+(declare-function article-make-date-line "gnus-art" (date type))
+
+(with-eval-after-load 'gnus
+ (with-eval-after-load 'nnimap
+ (setq nnimap-record-commands init-file-debug))
+
+ (setopt
+ gnus-select-method '(nnnil "")
+ gnus-secondary-select-methods
+ `(,@(when (member (system-name) '("darya" "nostalgia"))
+ '((nnimap
+ "canonical"
+ (nnimap-stream plain)
+ (nnimap-address "127.0.0.1")
+ (nnimap-server-port 143)
+ (nnimap-authenticator plain)
+ (nnimap-user "bandali@canonical.local"))))
+ (nnimap
+ "kelar"
+ (nnimap-stream plain)
+ (nnimap-address "127.0.0.1")
+ (nnimap-server-port 143)
+ (nnimap-authenticator plain)
+ (nnimap-user "bandali@kelar.local")
+ ;; (nnmail-expiry-wait immediate)
+ (nnmail-expiry-target nnmail-fancy-expiry-target)
+ (nnmail-fancy-expiry-targets
+ (("from" ".*" "nnimap+kelar:Archive.%Y"))))
+ (nnimap
+ "shemshak"
+ (nnimap-stream plain)
+ (nnimap-address "127.0.0.1")
+ (nnimap-server-port 143)
+ (nnimap-authenticator plain)
+ (nnimap-user "bandali@shemshak.local"))
+ (nnimap
+ "gnu"
+ (nnimap-stream plain)
+ (nnimap-address "127.0.0.1")
+ (nnimap-server-port 143)
+ (nnimap-authenticator plain)
+ (nnimap-user "bandali@gnu.local")
+ (nnimap-inbox "INBOX")
+ (nnimap-split-methods 'nnimap-split-fancy)
+ (nnimap-split-fancy
+ (|
+ ;; (: gnus-registry-split-fancy-with-parent)
+ ;; (: gnus-group-split-fancy "INBOX" t "INBOX")
+ ;; spam
+ ("X-Spam_action" "reject" "Junk")
+ ;; keep debbugs emails in INBOX
+ (list ".*<\\(.*\\)\\.debbugs\\.gnu\\.org>.*" "INBOX")
+ ;; list moderation emails
+ (from ".+-\\(owner\\|bounces\\)@\\(non\\)?gnu\\.org" "listmod")
+ ;; gnu
+ (list ".*<\\(.*\\)\\.\\(non\\)?gnu\\.org>.*" "l.\\1")
+ ("Envelope-To" "emacsconf-donations@gnu.org" "l.emacsconf-donations")
+ ;; board-eval
+ (|
+ (list ".*<.*\\.board-eval\\.fsf\\.org>.*" "l.board-eval")
+ (from ".*@board-eval\\.fsf\\.org" "l.board-eval"))
+ ;; fsf
+ (list ".*<\\(.*\\)\\.fsf\\.org>.*" "l.\\1")
+ ;; cfarm
+ (from "cfarm-.*@lists\\.tetaneutral\\.net" "l.cfarm")
+ ;; debian
+ (list ".*<\\(.*\\)\\.\\(lists\\|other\\)\\.debian\\.org>.*" "l.\\1")
+ (list ".*<\\(.*\\)\\.alioth-lists\\.debian\\.net>.*" "l.\\1")
+ ;; gnus
+ (list ".*<\\(.*\\)\\.gnus\\.org>.*" "l.\\1")
+ ;; libreplanet
+ (list ".*<\\(.*\\)\\.libreplanet\\.org>.*" "l.\\1")
+ ;; iana (e.g. tz-announce)
+ (list ".*<\\(.*\\)\\.iana\\.org>.*" "l.\\1")
+ ;; mailop
+ (list ".*<\\(.*\\)\\.mailop\\.org>.*" "l.\\1")
+ ;; sdlu
+ (list ".*<\\(.*\\)\\.spammers\\.dontlike\\.us>.*" "l.sdlu")
+ ;; bitfolk
+ (from ".*@\\(.+\\)?bitfolk\\.com>.*" "bitfolk")
+ ;; haskell
+ (list ".*<\\(.*\\)\\.haskell\\.org>.*" "l.\\1")
+ ;; webmasters
+ (from "webmasters\\(-comment\\)?@gnu\\.org" "webmasters")
+ ;; other
+ (list ".*atreus.freelists.org" "l.atreus")
+ (list ".*deepspec.lists.cs.princeton.edu" "l.deepspec")
+ ;; (list ".*haskell-art.we.lurk.org" "l.haskell.art") ;d
+ ;; (list ".*notmuch.notmuchmail.org" "l.notmuch") ;u
+ (list ".*dev.lists.parabola.nu" "l.parabola-dev")
+ ;; ----------------------------------
+ ;; legend: (u)nsubscribed | (d)ead
+ ;; ----------------------------------
+ ;; otherwise, leave mail in INBOX
+ "INBOX")))
+ (nnimap
+ "csc"
+ (nnimap-stream plain)
+ (nnimap-address "127.0.0.1")
+ (nnimap-server-port 143)
+ (nnimap-authenticator plain)
+ (nnimap-user "abandali@csclub.uwaterloo.local")
+ (nnimap-inbox "INBOX")
+ (nnimap-split-methods 'nnimap-split-fancy)
+ (nnimap-split-fancy
+ (|
+ ;; cron reports and other messages from root
+ (from "root@\\(.*\\.\\)?csclub\\.uwaterloo\\.ca" "INBOX")
+ ;; spam
+ ("X-Spam-Flag" "YES" "Junk")
+ ;; catch-all
+ "INBOX")))
+ (nnimap
+ "sfl"
+ (nnimap-stream plain)
+ (nnimap-address "127.0.0.1")
+ (nnimap-server-port 143)
+ (nnimap-authenticator plain)
+ (nnimap-user "amin.bandali@savoirfairelinux.local")))
+ gnus-message-archive-group "nnimap+kelar:INBOX"
+ gnus-parameters
+ '(("l\\.fencepost-users"
+ (to-address . "fencepost-users@gnu.org")
+ (to-list . "fencepost-users@gnu.org")
+ (list-identifier . "\\[Fencepost-users\\]"))
+ ("l\\.haskell-cafe"
+ (to-address . "haskell-cafe@haskell.org")
+ (to-list . "haskell-cafe@haskell.org")
+ (list-identifier . "\\[Haskell-cafe\\]")))
+ ;; gnus-large-newsgroup 50
+ gnus-process-mark-toggle t
+ gnus-home-directory (b/emacs.d "gnus/")
+ gnus-directory
+ (expand-file-name
+ (convert-standard-filename "news/") gnus-home-directory)
+ gnus-interactive-exit nil
+ gnus-user-agent '(emacs gnus type))
+
+ (with-eval-after-load 'message
+ (setopt
+ message-directory
+ (expand-file-name
+ (convert-standard-filename "mail/") gnus-home-directory)))
+
+ (with-eval-after-load 'nndraft
+ (setopt
+ nndraft-directory
+ (expand-file-name
+ (convert-standard-filename "drafts/") gnus-home-directory)))
+
+ (when (version< emacs-version "27")
+ (with-eval-after-load 'nnmail
+ (add-to-list
+ 'nnmail-split-abbrev-alist
+ '(list . "list-id\\|list-post\\|x-mailing-list\\|x-beenthere\\|x-loop")
+ 'append)))
+
+ (with-eval-after-load 'gnus-agent
+ (setopt gnus-agent-synchronize-flags 'ask))
+
+ (with-eval-after-load 'gnus-art ; article
+ (setopt
+ gnus-buttonized-mime-types
+ '("multipart/\\(signed\\|encrypted\\)")
+ gnus-sorted-header-list
+ '("^From:"
+ "^X-RT-Originator"
+ "^Newsgroups:"
+ "^Subject:"
+ "^Date:"
+ "^Envelope-To:"
+ "^Followup-To:"
+ "^Reply-To:"
+ "^Organization:"
+ "^Summary:"
+ "^Abstract:"
+ "^Keywords:"
+ "^To:"
+ "^[BGF]?Cc:"
+ "^Posted-To:"
+ "^Mail-Copies-To:"
+ "^Mail-Followup-To:"
+ "^Apparently-To:"
+ "^Resent-From:"
+ "^User-Agent:"
+ "^X-detected-operating-system:"
+ "^X-Spam_action:"
+ "^X-Spam_bar:"
+ "^Message-ID:"
+ ;; "^References:"
+ "^List-Id:"
+ "^Gnus-Warning:")
+ gnus-visible-headers
+ (mapconcat #'identity gnus-sorted-header-list "\\|")))
+
+ (with-eval-after-load 'gnus-dired
+ (with-eval-after-load 'dired
+ (add-hook 'dired-mode-hook #'gnus-dired-mode)))
+
+ (with-eval-after-load 'gnus-group
+ (setopt
+ gnus-permanently-visible-groups "\\(:INBOX$\\|:gnu$\\)")
+ (add-hook 'gnus-group-mode-hook #'gnus-topic-mode)
+ (add-hook 'gnus-group-mode-hook #'gnus-agent-mode))
+
+ (with-eval-after-load 'gnus-msg
+ (let ((bandali "Amin Bandali%s - https://kelar.org/~bandali"))
+ (defvar b/csc-signature
+ (mapconcat
+ #'identity
+ `(,(format bandali ", MMath")
+ "Systems Committee <syscom@csclub.uwaterloo.ca>"
+ "Computer Science Club of the University of Waterloo")
+ "\n"))
+ (defvar b/sfl-signature
+ (mapconcat
+ #'identity
+ `(,(format bandali "")
+ "Volunteer, Savoir-faire Linux"
+ "jami:bandali")
+ "\n")))
+ (setopt
+ gnus-gcc-mark-as-read t
+ gnus-message-replysign t
+ gnus-posting-styles
+ '(("nnimap\\+kelar:.*"
+ (address "bandali@kelar.org")
+ ("X-Message-SMTP-Method" "smtp mail.kelar.org 587")
+ (gcc "nnimap+kelar:INBOX"))
+ ("nnimap\\+shemshak:.*"
+ (address "amin@shemshak.org")
+ ("X-Message-SMTP-Method" "smtp mail.shemshak.org 587")
+ (gcc "nnimap+shemshak:Sent"))
+ ("nnimap\\+gnu:.*"
+ (address "bandali@gnu.org")
+ ("X-Message-SMTP-Method" "smtp fencepost.gnu.org 587")
+ (gcc "nnimap+gnu:INBOX"))
+ ("nnimap\\+canonical:.*"
+ (address "bandali@canonical.com")
+ ("X-Message-SMTP-Method" "smtp smtp.canonical.com 587")
+ (signature nil)
+ (gcc "nnimap+canonical:Sent"))
+ ((header "to" "amin\\.bandali@canonical\\.com")
+ (address "amin.bandali@canonical.com"))
+ ((header "cc" "amin\\.bandali@canonical\\.com")
+ (address "amin.bandali@canonical.com"))
+ ;; ("nnimap\\+.*:l\\.ubuntu-.*"
+ ;; (address "bandali@ubuntu.com")
+ ;; ("X-Message-SMTP-Method" "smtp mail.kelar.org 587"))
+ ;; ((header "list-id" ".*\\.lists.ubuntu.com")
+ ;; (address "bandali@ubuntu.com")
+ ;; ("X-Message-SMTP-Method" "smtp mail.kelar.org 587"))
+ ("nnimap\\+csc:.*"
+ (address "bandali@csclub.uwaterloo.ca")
+ ("X-Message-SMTP-Method" "smtp mail.csclub.uwaterloo.ca 587")
+ (signature b/csc-signature)
+ (gcc "nnimap+csc:Sent"))
+ ("nnimap\\+sfl:.*"
+ (address "amin.bandali@savoirfairelinux.com")
+ ("X-Message-SMTP-Method" "smtp mail.savoirfairelinux.com 587")
+ (signature b/sfl-signature)
+ (gcc "nnimap+sfl:Sent")))))
+
+ ;; (require 'gnus-registry)
+ ;; (with-eval-after-load 'gnus-registry
+ ;; (setopt
+ ;; gnus-registry-max-entries 2500
+ ;; gnus-registry-ignored-groups
+ ;; (append gnus-registry-ignored-groups
+ ;; '(("^nnimap:gnu\\.l" t) ("webmasters$" t))))
+ ;; (gnus-registry-initialize))
+
+ (with-eval-after-load 'gnus-search
+ (setopt
+ gnus-search-use-parsed-queries t))
+
+ (with-eval-after-load 'gnus-start
+ (setopt
+ gnus-save-newsrc-file nil
+ gnus-read-newsrc-file nil)
+ (add-hook 'gnus-after-getting-new-news-hook #'gnus-notifications))
+
+ (with-eval-after-load 'gnus-sum ; summary
+ (setopt
+ gnus-thread-sort-functions
+ '(gnus-thread-sort-by-number
+ gnus-thread-sort-by-subject
+ gnus-thread-sort-by-date))
+ (with-eval-after-load 'message
+ (setopt
+ gnus-ignored-from-addresses message-dont-reply-to-names))
+
+ (defun b/gnus-junk-article (&optional n)
+ (interactive "P" gnus-summary-mode)
+ (gnus-summary-move-article
+ n
+ (gnus-group-prefixed-name
+ "Junk"
+ (gnus-find-method-for-group gnus-newsgroup-name))))
+
+ (defvar b/gnus-summary-prefix-map)
+ (define-prefix-command 'b/gnus-summary-prefix-map)
+ (b/keymap-set
+ gnus-summary-mode-map "v" 'b/gnus-summary-prefix-map)
+ (let ((m b/gnus-summary-prefix-map))
+ (b/keymap-set m "r r" #'gnus-summary-very-wide-reply)
+ (b/keymap-set m "r q" #'gnus-summary-very-wide-reply-with-original)
+ (b/keymap-set m "R r" #'gnus-summary-reply)
+ (b/keymap-set m "R q" #'gnus-summary-reply-with-original)
+ (b/keymap-set m "r a w" #'gnus-summary-show-raw-article)
+ (b/keymap-set m "s" #'b/gnus-junk-article)))
+
+ (with-eval-after-load 'gnus-topic
+ ;; (setopt gnus-topic-line-format "%i[ %A: %(%{%n%}%) ]%v\n")
+ (setopt gnus-topic-line-format "%i[ %(%{%n%}%) (%A) ]%v\n")
+ (setq gnus-topic-topology
+ `(("Gnus" visible nil nil)
+ (("misc" visible nil nil))
+ ,@(when (member (system-name) '("darya" "nostalgia"))
+ '((("canonical" visible nil nil))))
+ (("csc" visible nil nil))
+ (("kelar" visible nil nil))
+ (("shemshak" visible nil nil))
+ (("gnu" visible nil nil))
+ ;; (("old-gnu" visible nil nil))
+ (("sfl" visible nil nil)))))
+
+ (with-eval-after-load 'gnus-win
+ (setopt gnus-use-full-window nil))
+
+ (with-eval-after-load 'mm-archive
+ (add-to-list
+ 'mm-archive-decoders
+ '("application/gzip" nil "gunzip" "-S" ".zip" "-kd" "%f" "-r")))
+
+ (with-eval-after-load 'mm-decode
+ (setopt
+ ;; mm-attachment-override-types `("text/x-diff" "text/x-patch"
+ ;; ,@mm-attachment-override-types)
+ mm-discouraged-alternatives '("text/html" "text/richtext")
+ mm-decrypt-option 'known
+ mm-verify-option 'known)
+ (add-to-list
+ 'mm-inline-media-tests
+ `("application/gzip" mm-archive-dissect-and-inline identity))
+ (add-to-list 'mm-inlined-types "application/gzip" 'append))
+
+ (with-eval-after-load 'mm-uu
+ (when (version< "27" emacs-version)
+ (set-face-attribute 'mm-uu-extract nil :extend t))
+ (when (version< emacs-version "27")
+ (setopt mm-uu-diff-groups-regexp ".")))
+
+ (with-eval-after-load 'mml
+ (setopt
+ mml-attach-file-at-the-end t
+ mml-content-disposition-alist
+ '((text
+ (markdown . "attachment")
+ (rtf . "attachment")
+ (t . "inline"))
+ (t . "attachment"))))
+
+ (with-eval-after-load 'mml-sec
+ (setopt
+ mml-secure-openpgp-encrypt-to-self t
+ mml-secure-openpgp-sign-with-sender t))
+
+ (with-eval-after-load 'recentf
+ (add-to-list 'recentf-exclude gnus-home-directory)))
+(b/keymap-global-set "C-c g" #'gnus-plugged)
+(b/keymap-global-set "C-c G" #'gnus-unplugged)
+
+(with-eval-after-load 'message
+ ;; Redefine for a simplified In-Reply-To header
+ ;; (https://todo.sr.ht/~sircmpwn/lists.sr.ht/67)
+ (defun message-make-in-reply-to ()
+ "Return the In-Reply-To header for this message."
+ (when message-reply-headers
+ (let ((from (mail-header-from message-reply-headers))
+ (msg-id (mail-header-id message-reply-headers)))
+ (when from
+ msg-id))))
+
+ (setopt
+ message-elide-ellipsis "[...]\n"
+ message-citation-line-format "%N writes:\n"
+ message-citation-line-function
+ #'message-insert-formatted-citation-line
+ message-confirm-send t
+ message-fill-column 70
+ message-forward-as-mime t
+ ;; message-kill-buffer-on-exit t
+ message-send-mail-function #'smtpmail-send-it
+ message-subscribed-address-functions
+ '(gnus-find-subscribed-addresses)
+ message-dont-reply-to-names
+ (mapconcat
+ #'identity
+ '("bandali@kelar\\.org"
+ "amin@shemshak\\.org"
+ "\\(bandali\\|mab\\|aminb?\\)@gnu\\.org"
+ "a?bandali@\\(csclub\\.\\)?uwaterloo\\.ca"
+ "amin\\.bandali@savoirfairelinux\\.com"
+ "\\(amin\\.\\)?bandali@canonical\\.com"
+ "bandali@ubuntu\\.com"
+ "bandali@debian\\.org")
+ "\\|"))
+
+ (defun b/newlines-or-asterism (arg)
+ "Create newlines per my liking, or insert asterism if ARG is
+non-nil."
+ (interactive "P")
+ (if arg
+ (b/insert-asterism)
+ (progn
+ (beginning-of-line)
+ (delete-region (point) (line-end-position))
+ (newline)
+ (open-line 1))))
+ (b/keymap-set message-mode-map "M-RET" #'b/newlines-or-asterism)
+
+ (add-hook 'message-mode-hook #'flyspell-mode)
+ (add-hook
+ 'message-mode-hook (lambda () (b/keymap-local-unset "C-c C-s"))))
-;; Email (with Gnus, message, and smtpmail)
;; (with-eval-after-load 'sendmail
-;; (setq mail-header-separator ""))
-(require 'bandali-gnus)
-(require 'bandali-message)
+;; (setopt mail-header-separator ""))
+
;; (with-eval-after-load 'smtpmail
-;; (setq smtpmail-queue-mail t
-;; smtpmail-queue-dir (concat b/maildir "queue/")))
+;; (setopt smtpmail-queue-mail t
+;; smtpmail-queue-dir (concat b/maildir "queue/")))
-;; IRC (with ERC)
-(require 'bandali-erc)
+
+;;; IRC
+(with-eval-after-load 'erc
+ (setopt
+ erc-auto-query 'bury
+ erc-autojoin-domain-only nil
+ erc-dcc-get-default-directory (b/emacs.d "erc-dcc")
+ erc-email-userid "bandali"
+ ;; erc-join-buffer 'bury
+ ;; erc-lurker-hide-list '("JOIN" "PART" "QUIT")
+ erc-nick "bandali"
+ erc-prompt "erc>"
+ erc-prompt-for-password nil
+ erc-query-display 'buffer
+ ;; erc-server-reconnect-attempts 5
+ erc-server-reconnect-timeout 3)
+
+ (if (version< erc-version "5.6-git")
+ (setopt erc-format-nick-function #'erc-format-@nick)
+ (setopt erc-show-speaker-membership-status t))
+
+ (unless (version< erc-version "5.5")
+ (setopt erc-rename-buffers t))
+
+ (unless (version< erc-version "5.4")
+ (declare-function
+ erc-message "erc-backend" (message-command line &optional force))
+ (declare-function erc-default-target "erc")
+ (declare-function erc-current-nick "erc")
+ (defun erc-cmd-OPME ()
+ "Ask chanserv to op me in the current channel."
+ (erc-message "PRIVMSG"
+ (format "chanserv op %s %s"
+ (erc-default-target)
+ (erc-current-nick))
+ nil))
+ (declare-function erc-cmd-DEOP "erc" (&rest people))
+ (defun erc-cmd-DEOPME ()
+ "Deop myself in the current channel."
+ (erc-cmd-DEOP (format "%s" (erc-current-nick)))))
+
+ (add-to-list 'erc-modules 'keep-place)
+ (add-to-list 'erc-modules 'log)
+ (when (display-graphic-p)
+ (add-to-list 'erc-modules 'notifications)
+ (add-to-list 'erc-modules 'smiley))
+ (add-to-list 'erc-modules 'spelling)
+
+ ;; (set-face-attribute
+ ;; 'erc-nick-default-face nil
+ ;; ;; :weight 'semibold
+ ;; ;; :background "#f2f2f2"
+ ;; ;; :foreground "#222222"
+ ;; :weight 'bold
+ ;; :background "#f8f8f8"
+ ;; :foreground "#6a6a6a")
+
+ ;; (set-face-attribute
+ ;; 'erc-notice-face nil
+ ;; ;; :background "#fffadf"
+ ;; ;; :background "#f9f9f9"
+ ;; :background 'unspecified
+ ;; ;; :foreground "#809de5"
+ ;; :foreground "steel blue")
+
+ (setopt
+ ;; erc-enable-logging 'erc-log-all-but-server-buffers
+ erc-log-file-coding-system 'utf-8
+ erc-log-write-after-insert t
+ erc-log-write-after-send t
+ erc-save-buffer-on-part nil
+ erc-save-queries-on-quit nil)
+
+ (with-eval-after-load 'erc-match
+ (setopt
+ erc-pal-highlight-type 'nick
+ erc-pals
+ '("corwin" "^gopar" "^iank" "^rwp" "technomancy" "thomzane"))
+ (set-face-attribute
+ 'erc-pal-face nil
+ :foreground 'unspecified
+ :weight 'unspecified
+ :inherit 'erc-nick-default-face
+ ;; :background (face-attribute 'font-lock-string-face :background)
+ :background "#ffffdf"))
+
+ (with-eval-after-load 'erc-pcomplete
+ (setopt erc-pcomplete-nick-postfix ",")
+ ;; for matterircd nick (username) completions
+ ;; (advice-add
+ ;; #'pcomplete-erc-nicks
+ ;; :around
+ ;; (lambda (orig-fun &rest args)
+ ;; (let ((nicks (apply orig-fun args)))
+ ;; (if (string-match-p "matterircd" (symbol-name (erc-network)))
+ ;; (mapcar (lambda (nick) (concat "@" nick)) nicks)
+ ;; nicks))))
+ )
+
+ (with-eval-after-load 'erc-stamp
+ (setopt
+ erc-timestamp-only-if-changed-flag nil
+ erc-timestamp-format "%T "
+ erc-insert-timestamp-function #'erc-insert-timestamp-left)
+ (set-face-attribute
+ 'erc-timestamp-face nil
+ :foreground "#aaaaaa"
+ :weight 'unspecified
+ :background 'unspecified))
+
+ (with-eval-after-load 'erc-track
+ (setopt
+ erc-track-enable-keybindings nil
+ erc-track-exclude-types
+ '("JOIN" "MODE" "NICK" "PART" "QUIT"
+ "324" "329" "332" "333" "353" "477")
+ erc-track-position-in-mode-line t
+ erc-track-priority-faces-only 'all
+ erc-track-shorten-function nil
+ erc-track-showcount t))
+
+ (declare-function erc-update-modules "erc")
+ (erc-update-modules)
+
+ (b/keymap-global-set "C-c w e" #'erc-switch-to-buffer-other-window)
+ (b/keymap-set erc-mode-map "M-a" #'erc-track-switch-buffer))
+(b/keymap-global-set
+ "C-c e l"
+ (lambda ()
+ (interactive)
+ (erc-tls :server "irc.libera.chat" :port 6697
+ :client-certificate t)))
+(b/keymap-global-set
+ "C-c e o"
+ (lambda ()
+ (interactive)
+ (erc-tls :server "irc.oftc.net" :port 6697
+ :client-certificate t)))
+(b/keymap-global-set
+ "C-c e t"
+ (lambda ()
+ (interactive)
+ (erc-tls :server "na.tilde.chat" :port 6697
+ :client-certificate t)))
+
+;; (b/keymap-global-set
+;; "C-c e c"
+;; (lambda ()
+;; (interactive)
+;; (erc :server "localhost" :port 6667
+;; :id 'matterircd-canonical)))
;;; Editing
-(when (featurep 'eldoc)
- ;; Display Lisp objects at point in the echo area.
- (with-eval-after-load 'eldoc
- (setq eldoc-minor-mode-string " eldoc")
- (global-eldoc-mode)))
+;; Display Lisp objects at point in the echo area.
+(with-eval-after-load 'eldoc
+ (setopt eldoc-minor-mode-string " eldoc")
+ (global-eldoc-mode 1))
;; highlight matching parens
(run-with-idle-timer 0.2 nil #'require 'paren)
(with-eval-after-load 'paren
- (show-paren-mode))
+ (show-paren-mode 1))
;; (run-with-idle-timer 0.2 nil #'require 'elec-pair)
;; (with-eval-after-load 'elec-pair
;; (electric-pair-mode))
(with-eval-after-load 'simple
- (setq
- ;; Save what I copy into clipboard from other applications into Emacs'
- ;; kill-ring, which would allow me to still be able to easily access
- ;; it in case I kill (cut or copy) something else inside Emacs before
- ;; yanking (pasting) what I'd originally intended to.
+ (setopt
+ ;; Save what I copy into clipboard from other applications into
+ ;; Emacs' kill-ring, which would allow me to still be able to
+ ;; easily access it in case I kill (cut or copy) something else
+ ;; inside Emacs before yanking (pasting) what I'd originally
+ ;; intended to.
save-interprogram-paste-before-kill t)
(column-number-mode 1)
(line-number-mode 1))
@@ -697,82 +1351,50 @@ for all frames."
(run-with-idle-timer 0.2 nil #'require 'savehist)
(with-eval-after-load 'savehist
;; Save minibuffer history.
- (setq savehist-file (b/var "savehist.el"))
- (savehist-mode)
+ (savehist-mode 1)
(add-to-list 'savehist-additional-variables 'kill-ring))
;; Automatically save place in files.
-(setq save-place-file (b/var "save-place.el"))
(run-with-idle-timer 0.2 nil #'require 'saveplace nil 'noerror)
(with-eval-after-load 'saveplace
- ;; (setq save-place-file (b/var "save-place.el"))
- (save-place-mode))
-
-(add-to-list 'auto-mode-alist '("\\.*rc$" . conf-mode))
-(add-to-list 'auto-mode-alist '("\\.bashrc$" . sh-mode))
+ (save-place-mode 1))
(with-eval-after-load 'flyspell
- (setq flyspell-mode-line-string " fly"))
+ (setopt flyspell-mode-line-string " fly"))
(with-eval-after-load 'text-mode
(add-hook 'text-mode-hook #'flyspell-mode)
- (define-key text-mode-map (kbd "C-<return>") #'b/insert-asterism))
-
-;; ;; http://endlessparentheses.com/ispell-and-apostrophes.html
-;; (run-with-idle-timer 0.6 nil #'require 'ispell)
-;; (with-eval-after-load 'ispell
-;; ;; ’ can be part of a word.
-;; (setq ispell-local-dictionary-alist
-;; `((nil "[[:alpha:]]" "[^[:alpha:]]"
-;; "['\x2019]" nil ("-B") nil utf-8))
-;; ispell-program-name (executable-find "hunspell"))
-;; ;; Don't send ’ to the subprocess.
-;; (defun endless/replace-apostrophe (args)
-;; (cons (replace-regexp-in-string
-;; "’" "'" (car args))
-;; (cdr args)))
-;; (advice-add #'ispell-send-string :filter-args
-;; #'endless/replace-apostrophe)
-;; ;; Convert ' back to ’ from the subprocess.
-;; (defun endless/replace-quote (args)
-;; (if (not (derived-mode-p 'org-mode))
-;; args
-;; (cons (replace-regexp-in-string
-;; "'" "’" (car args))
-;; (cdr args))))
-;; (advice-add #'ispell-parse-output :filter-args
-;; #'endless/replace-quote))
+ (b/keymap-set text-mode-map "M-RET" #'b/insert-asterism))
(with-eval-after-load 'abbrev
- (setq abbrev-file-name (b/etc "abbrev.el")))
-(add-hook 'text-mode-hook #'abbrev-mode)
+ (add-hook 'text-mode-hook #'abbrev-mode))
;;; Programming modes
-(with-eval-after-load 'lisp-mode
- (defun indent-spaces-mode ()
- (setq indent-tabs-mode nil))
- (add-hook 'lisp-interaction-mode-hook #'indent-spaces-mode))
-
-(add-to-list 'load-path (b/lisp "alloy-mode"))
-(autoload 'alloy-mode "alloy-mode" nil t)
-(with-eval-after-load 'alloy-mode
- (setq alloy-basic-offset 2)
- ;; (defun b/alloy-simple-indent (start end)
- ;; (interactive "r")
- ;; ;; (if (region-active-p)
- ;; ;; (indent-rigidly start end alloy-basic-offset)
- ;; ;; (if (bolp)
- ;; ;; (indent-rigidly (line-beginning-position)
- ;; ;; (line-end-position)
- ;; ;; alloy-basic-offset)))
- ;; (indent-to (+ (current-column) alloy-basic-offset)))
- (define-key alloy-mode-map (kbd "RET") #'electric-newline-and-maybe-indent)
- ;; (define-key alloy-mode-map (kbd "TAB") #'b/alloy-simple-indent)
- (define-key alloy-mode-map (kbd "TAB") #'indent-for-tab-command))
-(add-to-list 'auto-mode-alist '("\\.\\(als\\|dsh\\)\\'" . alloy-mode))
-(add-hook 'alloy-mode-hook (lambda nil (setq-local indent-tabs-mode nil)))
+;; (with-eval-after-load 'lisp-mode
+;; (defun indent-spaces-mode ()
+;; (setq indent-tabs-mode nil))
+;; (add-hook 'lisp-interaction-mode-hook #'indent-spaces-mode))
+
+;; (add-to-list 'load-path (b/lisp "alloy-mode"))
+;; (autoload 'alloy-mode "alloy-mode" nil t)
+;; (with-eval-after-load 'alloy-mode
+;; (setq alloy-basic-offset 2)
+;; ;; (defun b/alloy-simple-indent (start end)
+;; ;; (interactive "r")
+;; ;; ;; (if (region-active-p)
+;; ;; ;; (indent-rigidly start end alloy-basic-offset)
+;; ;; ;; (if (bolp)
+;; ;; ;; (indent-rigidly (line-beginning-position)
+;; ;; ;; (line-end-position)
+;; ;; ;; alloy-basic-offset)))
+;; ;; (indent-to (+ (current-column) alloy-basic-offset)))
+;; (define-key alloy-mode-map (kbd "RET") #'electric-newline-and-maybe-indent)
+;; ;; (define-key alloy-mode-map (kbd "TAB") #'b/alloy-simple-indent)
+;; (define-key alloy-mode-map (kbd "TAB") #'indent-for-tab-command))
+;; (add-to-list 'auto-mode-alist '("\\.\\(als\\|dsh\\)\\'" . alloy-mode))
+;; (add-hook 'alloy-mode-hook (lambda nil (setq-local indent-tabs-mode nil)))
;; (eval-when-compile (defvar lean-mode-map))
;; (run-with-idle-timer 0.4 nil #'require 'lean-mode)
@@ -788,63 +1410,48 @@ for all frames."
;; (define-key lean-mode-map (kbd "S-SPC") #'company-complete))
(with-eval-after-load 'sgml-mode
- (setq sgml-basic-offset 0))
+ (setopt sgml-basic-offset 0))
(with-eval-after-load 'css-mode
- (setq css-indent-offset 2))
-
-;; (with-eval-after-load 'auctex
-;; (setq font-latex-fontify-sectioning 'color))
+ (setopt css-indent-offset 2))
-(with-eval-after-load 'tex-mode
- (cl-delete-if
- (lambda (p) (string-match "^---?" (car p)))
- tex--prettify-symbols-alist))
(add-hook 'tex-mode-hook #'auto-fill-mode)
(add-hook 'tex-mode-hook #'flyspell-mode)
-(run-with-idle-timer 0.5 nil #'require 'cmake-mode)
+(autoload 'cmake-mode "cmake-mode" nil t)
+(add-to-list 'auto-mode-alist '("CMakeLists\\.txt\\'" . cmake-mode))
+(add-to-list 'auto-mode-alist '("\\.cmake\\'" . cmake-mode))
(with-eval-after-load 'cmake-mode
- ;; (setq cmake-tab-width 4)
- (add-to-list 'load-path (b/lisp "cmake-font-lock"))
- (run-with-idle-timer 0.5 nil #'require 'cmake-font-lock))
+ ;; (setopt cmake-tab-width 4)
+ (add-to-list 'load-path (b/emacs.d "lisp/cmake-font-lock"))
+ (require 'cmake-font-lock))
;;; Emacs enhancements & auxiliary packages
-
-(with-eval-after-load 'nsm
- (setq nsm-settings-file (b/var "nsm-settings.el")))
-
(with-eval-after-load 'man
- (setq Man-width 80))
+ (setopt Man-width 80))
;; `debbugs'
-(global-set-key (kbd "C-c D d") #'debbugs-gnu)
-(global-set-key (kbd "C-c D b") #'debbugs-gnu-bugs)
-(global-set-key (kbd "C-c D e") ; bug-gnu-emacs
+(b/keymap-global-set "C-c D d" #'debbugs-gnu)
+(b/keymap-global-set "C-c D b" #'debbugs-gnu-bugs)
+(b/keymap-global-set "C-c D e" ; bug-gnu-emacs
(lambda ()
(interactive)
(setq debbugs-gnu-current-suppress t)
(debbugs-gnu debbugs-gnu-default-severities
'("emacs"))))
-(global-set-key (kbd "C-c D g") ; bug-gnuzilla
+(b/keymap-global-set "C-c D g" ; bug-gnuzilla
(lambda ()
(interactive)
(setq debbugs-gnu-current-suppress t)
(debbugs-gnu debbugs-gnu-default-severities
'("gnuzilla"))))
-(with-eval-after-load 'url
- (setq url-configuration-directory (b/var "url/configuration/")))
-
-(with-eval-after-load 'url-cache
- (setq url-cache-directory (b/var "url/cache/")))
-
(with-eval-after-load 'eww
- (setq
+ (setopt
eww-download-directory
(file-name-as-directory (getenv "XDG_DOWNLOAD_DIR"))))
-(global-set-key (kbd "C-c e w") #'eww)
+(b/keymap-global-set "C-c e w" #'eww)
(run-with-idle-timer
0.2 nil #'require 'display-fill-column-indicator nil 'noerror)
@@ -852,19 +1459,8 @@ for all frames."
(global-display-fill-column-indicator-mode 1))
(with-eval-after-load 'window
- (setq split-width-threshold 150))
-
-;; Uncomment to disable reftex-cite's default choice of previous word.
-;; (with-eval-after-load 'reftex
-;; (require 'reftex-cite)
-;; (defun reftex-get-bibkey-default ()
-;; "If the cursor is in a citation macro, return the word before
-;; the macro."
-;; (let* ((macro (reftex-what-macro 1)))
-;; (save-excursion
-;; (when (and macro (string-match "cite" (car macro)))
-;; (goto-char (cdr macro)))
-;; (reftex-this-word)))))
+ (setopt split-width-threshold 150))
+
(add-hook 'latex-mode-hook #'reftex-mode)
(run-with-idle-timer 0.5 nil #'require 'delight)
@@ -873,12 +1469,44 @@ for all frames."
(delight 'abbrev-mode "" "abbrev")
(delight 'mml-mode " mml" "mml"))
-(require 'bandali-po)
-
-(add-to-list 'load-path (b/lisp "ffs"))
+(with-eval-after-load 'po-mode
+ ;; Based on the `po-wrap' function from the GNUN manual:
+ ;; https://www.gnu.org/s/trans-coord/manual/gnun/html_node/Wrapping-Long-Lines.html
+ (defun b/po-wrap ()
+ "Run the current `po-mode' buffer through `msgcat' to wrap all
+lines."
+ (interactive)
+ (when (eq major-mode 'po-mode)
+ (let ((tmp-file (make-temp-file "po-wrap."))
+ (tmp-buffer (generate-new-buffer "*temp*")))
+ (unwind-protect
+ (progn
+ (write-region (point-min) (point-max) tmp-file nil 1)
+ (if (zerop
+ (call-process "msgcat" nil tmp-buffer t
+ (shell-quote-argument tmp-file)))
+ (let ((saved (point))
+ (inhibit-read-only t))
+ (delete-region (point-min) (point-max))
+ (insert-buffer-substring tmp-buffer)
+ (goto-char (min saved (point-max))))
+ (with-current-buffer tmp-buffer
+ (error (buffer-string)))))
+ (kill-buffer tmp-buffer)
+ (delete-file tmp-file)))))
+
+ (add-hook
+ 'po-mode-hook (lambda () (run-with-timer 0.1 nil #'View-exit)))
+ (b/keymap-set po-mode-map "M-q" #'b/po-wrap))
+
+(autoload #'po-mode "po-mode"
+ "Major mode for editing PO translation files" t)
+(add-to-list 'auto-mode-alist '("\\.po\\'\\|\\.po\\." . po-mode))
+
+(add-to-list 'load-path (b/emacs.d "lisp/ffs"))
(run-with-idle-timer 0.5 nil #'require 'ffs)
(with-eval-after-load 'ffs
- (setq ffs-default-face-height 250)
+ (setopt ffs-default-face-height 250)
(global-set-key (kbd "C-c f s") #'ffs))
(add-hook 'ffs-start-hook
(lambda ()
@@ -913,7 +1541,7 @@ for all frames."
scroll-bar-mode))
(fringe-mode nil)))
-(add-to-list 'load-path (b/lisp "debian-el"))
+(add-to-list 'load-path (b/emacs.d "lisp/debian-el"))
(run-with-idle-timer 0.5 nil #'require 'debian-el)
(with-eval-after-load 'debian-el
(require 'apt-sources)
@@ -923,7 +1551,7 @@ for all frames."
(require 'gnus-BTS)
(require 'preseed))
-(add-to-list 'load-path (b/lisp "dpkg-dev-el"))
+(add-to-list 'load-path (b/emacs.d "lisp/dpkg-dev-el"))
(run-with-idle-timer 0.5 nil #'require 'dpkg-dev-el)
(with-eval-after-load 'dpkg-dev-el
(require 'debian-changelog-mode)
diff --git a/.emacs.d/lisp/bandali-dired.el b/.emacs.d/lisp/bandali-dired.el
deleted file mode 100644
index 0cbd7ed..0000000
--- a/.emacs.d/lisp/bandali-dired.el
+++ /dev/null
@@ -1,95 +0,0 @@
-;;; bandali-dired.el --- bandali's dired setup -*- lexical-binding: t; -*-
-
-;; Copyright (C) 2018-2022 Amin Bandali
-
-;; Author: Amin Bandali <bandali@gnu.org>
-;; Keywords: files
-
-;; This program is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; This program is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with this program. If not, see <https://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; My dired setup and customizations.
-
-;;; Code:
-
-(with-eval-after-load 'dired
- ;; (require 'ls-lisp)
- (setq
- dired-dwim-target t
- dired-listing-switches "-alh --group-directories-first"
- dired-recent-directories-file (b/var "dired-recent-directories.el")
- ls-lisp-dirs-first t
- ls-lisp-use-insert-directory-program nil)
-
- (declare-function dired-dwim-target-directory "dired-aux")
- ;; easily diff 2 marked files
- ;; https://oremacs.com/2017/03/18/dired-ediff/
- (defun dired-ediff-files ()
- (interactive)
- (require 'dired-aux)
- (defvar ediff-after-quit-hook-internal)
- (let ((files (dired-get-marked-files))
- (wnd (current-window-configuration)))
- (if (<= (length files) 2)
- (let ((file1 (car files))
- (file2 (if (cdr files)
- (cadr files)
- (read-file-name
- "file: "
- (dired-dwim-target-directory)))))
- (if (file-newer-than-file-p file1 file2)
- (ediff-files file2 file1)
- (ediff-files file1 file2))
- (add-hook 'ediff-after-quit-hook-internal
- (lambda ()
- (setq ediff-after-quit-hook-internal nil)
- (set-window-configuration wnd))))
- (error "no more than 2 files should be marked"))))
-
- (defun b/dired-start-process (program &optional args)
- "Open current file with a PROGRAM."
- ;; Shell command looks like this: "program [ARGS]... FILE" (ARGS
- ;; can be nil, so remove it).
- (declare-function dired-get-file-for-visit "dired")
- (apply #'b/start-process
- program
- (remove nil (list args (dired-get-file-for-visit)))))
-
- ;; local key bindings
- (define-key dired-mode-map (kbd "b") #'dired-up-directory)
- (define-key dired-mode-map (kbd "E") #'dired-ediff-files)
- (define-key dired-mode-map (kbd "e") #'dired-toggle-read-only)
- (define-key dired-mode-map (kbd "\\") #'dired-hide-details-mode)
- (define-key dired-mode-map (kbd "z")
- (lambda ()
- (interactive)
- (b/dired-start-process "zathura")))
-
- (require 'dired-x)
- (setq
- dired-guess-shell-alist-user
- '(("\\.pdf\\'" "evince" "zathura" "okular")
- ("\\.doc\\'" "libreoffice")
- ("\\.docx\\'" "libreoffice")
- ("\\.ppt\\'" "libreoffice")
- ("\\.pptx\\'" "libreoffice")
- ("\\.xls\\'" "libreoffice")
- ("\\.xlsx\\'" "libreoffice")
- ("\\.flac\\'" "mpv"))))
-;; hooks
-(add-hook 'dired-mode-hook #'dired-hide-details-mode)
-
-(provide 'bandali-dired)
-;;; bandali-dired.el ends here
diff --git a/.emacs.d/lisp/bandali-erc.el b/.emacs.d/lisp/bandali-erc.el
deleted file mode 100644
index 8cd1457..0000000
--- a/.emacs.d/lisp/bandali-erc.el
+++ /dev/null
@@ -1,200 +0,0 @@
-;;; bandali-erc.el --- bandali's ERC setup -*- lexical-binding: t; -*-
-
-;; Copyright (C) 2018-2022 Amin Bandali
-
-;; Author: Amin Bandali <bandali@gnu.org>
-;; Keywords: IRC, chat, client, Internet
-
-;; This program is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; This program is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with this program. If not, see <https://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; My ERC setup for IRC in GNU Emacs.
-
-;;; Code:
-
-(with-eval-after-load 'erc
- (make-directory (b/var "erc/dcc") t)
- (setq
- erc-auto-query 'bury
- erc-autojoin-domain-only nil
- erc-dcc-get-default-directory (b/var "erc/dcc")
- erc-email-userid "bandali"
- erc-format-nick-function 'erc-format-@nick
- erc-join-buffer 'bury
- ;; erc-lurker-hide-list '("JOIN" "PART" "QUIT")
- erc-nick "bandali"
- erc-prompt "erc>"
- erc-prompt-for-password nil
- erc-query-display 'buffer
- erc-rename-buffers t
- erc-server-reconnect-attempts 5
- erc-server-reconnect-timeout 3)
-
- (declare-function erc-message "erc-backend"
- (message-command line &optional force))
- (declare-function erc-default-target "erc")
- (declare-function erc-current-nick "erc")
- (defun erc-cmd-OPME ()
- "Ask chanserv to op me in the current channel."
- (erc-message "PRIVMSG"
- (format "chanserv op %s %s"
- (erc-default-target)
- (erc-current-nick))
- nil))
- (declare-function erc-cmd-DEOP "erc" (&rest people))
- (defun erc-cmd-DEOPME ()
- "Deop myself in the current channel."
- (erc-cmd-DEOP (format "%s" (erc-current-nick))))
- (add-to-list 'erc-modules 'keep-place)
- (add-to-list 'erc-modules 'log)
- (when (display-graphic-p)
- (add-to-list 'erc-modules 'notifications)
- (add-to-list 'erc-modules 'smiley))
- (add-to-list 'erc-modules 'spelling)
-
- ;; (set-face-attribute
- ;; 'erc-nick-default-face nil
- ;; ;; :weight 'semibold
- ;; ;; :background "#f2f2f2"
- ;; ;; :foreground "#222222"
- ;; :weight 'bold
- ;; :background "#f8f8f8"
- ;; :foreground "#6a6a6a")
-
- ;; (set-face-attribute
- ;; 'erc-notice-face nil
- ;; ;; :background "#fffadf"
- ;; ;; :background "#f9f9f9"
- ;; :background 'unspecified
- ;; ;; :foreground "#809de5"
- ;; :foreground "steel blue")
-
- ;; erc-fill
- ;; (setq
- ;; erc-fill-column 77
- ;; erc-fill-function 'erc-fill-variable
- ;; erc-fill-static-center 18)
- ;; to disable:
- ;; (erc-fill-mode -1)
-
- ;; erc-log
- (defun b/erc-log-directory (buffer target _nick server _port)
- (let ((directory (concat (b/var "erc/logs/")
- ;; (or (with-current-buffer buffer
- ;; (symbol-name erc-network))
- ;; server)
- server
- (if (erc-server-buffer-p buffer)
- (concat "/" server)
- (and target (concat "/" target))))))
- (unless (file-exists-p directory)
- (make-directory directory 'make-parents))
- directory))
- (defun b/erc-log-file-name (&rest _)
- (concat (format-time-string "%Y-%m-%d") ".log"))
- (setq
- ;; erc-enable-logging 'erc-log-all-but-server-buffers
- erc-generate-log-file-name-function #'b/erc-log-file-name
- erc-log-channels-directory #'b/erc-log-directory
- erc-log-file-coding-system 'utf-8
- erc-log-write-after-insert t
- erc-log-write-after-send t
- erc-save-buffer-on-part nil
- erc-save-queries-on-quit nil)
-
- (with-eval-after-load 'erc-match
- (setq
- erc-pal-highlight-type 'nick
- erc-pals
- '("bremner" "^gopar" "^iank" "quidam" "^rwp" "sudoman"
- "technomancy" "thomzane"))
- (set-face-attribute
- 'erc-pal-face nil
- :foreground 'unspecified
- :weight 'unspecified
- :inherit 'erc-nick-default-face
- ;; :background (face-attribute 'font-lock-string-face :background)
- :background "#ffffdf"))
-
- (with-eval-after-load 'erc-pcomplete
- (setq erc-pcomplete-nick-postfix ",")
- ;; for matterircd nick (username) completions
- ;; (advice-add
- ;; #'pcomplete-erc-nicks
- ;; :around
- ;; (lambda (orig-fun &rest args)
- ;; (let ((nicks (apply orig-fun args)))
- ;; (if (string-match-p "matterircd" (symbol-name (erc-network)))
- ;; (mapcar (lambda (nick) (concat "@" nick)) nicks)
- ;; nicks))))
- )
-
- (with-eval-after-load 'erc-stamp
- (setq erc-timestamp-only-if-changed-flag nil
- erc-timestamp-format "%T "
- erc-insert-timestamp-function 'erc-insert-timestamp-left))
- (with-eval-after-load 'erc-match
- (set-face-attribute
- 'erc-timestamp-face nil
- :foreground "#aaaaaa"
- :weight 'unspecified
- :background 'unspecified))
-
- (with-eval-after-load 'erc-track
- (setq
- erc-track-enable-keybindings nil
- erc-track-exclude-types '("JOIN" "MODE" "NICK" "PART" "QUIT"
- "324" "329" "332" "333" "353" "477")
- erc-track-position-in-mode-line t
- erc-track-priority-faces-only 'all
- erc-track-shorten-function nil
- erc-track-showcount t))
-
- (declare-function erc-update-modules "erc")
- (erc-update-modules)
-
- ;; key bindings
- (global-set-key (kbd "C-c w e") #'erc-switch-to-buffer-other-window)
- (define-key erc-mode-map (kbd "M-a") #'erc-track-switch-buffer))
-
-;; global key bindings
-(global-set-key
- (kbd "C-c e l")
- (lambda ()
- (interactive)
- (erc-tls :server "irc.libera.chat" :port 6697
- :client-certificate t)))
-(global-set-key
- (kbd "C-c e o")
- (lambda ()
- (interactive)
- (erc-tls :server "irc.oftc.net" :port 6697
- :client-certificate t)))
-(global-set-key
- (kbd "C-c e t")
- (lambda ()
- (interactive)
- (erc-tls :server "na.tilde.chat" :port 6697
- :client-certificate t)))
-
-;; (global-set-key
-;; (kbd "C-c e c")
-;; (lambda ()
-;; (interactive)
-;; (erc :server "localhost" :port 6667
-;; :id 'matterircd-canonical)))
-
-(provide 'bandali-erc)
-;;; bandali-erc.el ends here
diff --git a/.emacs.d/lisp/bandali-eshell.el b/.emacs.d/lisp/bandali-eshell.el
deleted file mode 100644
index 7bf3b4f..0000000
--- a/.emacs.d/lisp/bandali-eshell.el
+++ /dev/null
@@ -1,97 +0,0 @@
-;;; bandali-eshell.el --- bandali's Eshell setup -*- lexical-binding: t; -*-
-
-;; Copyright (C) 2018-2022 Amin Bandali
-
-;; Author: Amin Bandali <bandali@gnu.org>
-;; Keywords: processes
-
-;; This program is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; This program is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with this program. If not, see <https://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; My awesome Eshell setup.
-
-;;; Code:
-
-(with-eval-after-load 'eshell
- (make-directory (b/etc "eshell/") t)
- (setq
- eshell-aliases-file (b/etc "eshell/aliases")
- eshell-directory-name (b/var "eshell/")
- eshell-hist-ignoredups t
- eshell-input-filter #'eshell-input-filter-initial-space
- ;; eshell-prompt-regexp "\\(.*\n\\)*[$#] "
- ;; eshell-prompt-function
- ;; (lambda ()
- ;; (concat
- ;; (propertize (format "%s@%s:" (user-login-name) (system-name))
- ;; 'face 'default)
- ;; (propertize (abbreviate-file-name default-directory)
- ;; 'face 'font-lock-comment-face)
- ;; (propertize "\n" 'face 'default)
- ;; (if (= (user-uid) 0)
- ;; (propertize "#" 'face 'red)
- ;; (propertize "$" 'face 'default))
- ;; (propertize " " 'face 'default)))
- eshell-prompt-regexp "^[^#$\n]* [#$] ; "
- eshell-prompt-function
- (lambda ()
- (concat ": "
- (system-name)
- ":"
- (abbreviate-file-name (eshell/pwd))
- (unless (eshell-exit-success-p)
- (format " [%d]" eshell-last-command-status))
- (if (= (file-user-uid) 0) " # " " $ ")
- "; ")))
- (eval-when-compile
- (defvar eshell-prompt-regexp)
- (declare-function eshell-life-is-too-much "esh-mode")
- (declare-function eshell-send-input "esh-mode"
- (&optional use-region queue-p no-newline)))
- (defun b/eshell-quit-or-delete-char (arg)
- (interactive "p")
- (if (and (eolp) (looking-back eshell-prompt-regexp nil))
- (eshell-life-is-too-much)
- (delete-char arg)))
- (defun b/eshell-clear ()
- (interactive)
- (let ((inhibit-read-only t))
- (erase-buffer))
- (eshell-send-input))
- (defun b/eshell-history ()
- (interactive)
- (completing-read "Eshell history: "
- (ring-elements eshell-history-ring)))
- (defun b/eshell-setup ()
- (make-local-variable 'company-idle-delay)
- (defvar company-idle-delay)
- (eval-when-compile
- (defvar eshell-mode-map)
- (defvar eshell-hist-mode-map))
- (setq company-idle-delay nil)
- ;; local key bindings
- (define-key eshell-mode-map (kbd "C-d")
- #'b/eshell-quit-or-delete-char)
- (define-key eshell-mode-map (kbd "C-S-l")
- #'b/eshell-clear)
- (define-key eshell-hist-mode-map (kbd "M-r")
- #'b/eshell-history)))
-;; global key bindings
-(global-set-key (kbd "C-c s e") #'eshell)
-;; hooks
-(add-hook 'eshell-mode-hook #'b/eshell-setup)
-
-(provide 'bandali-eshell)
-;;; bandali-eshell.el ends here
diff --git a/.emacs.d/lisp/bandali-exwm.el b/.emacs.d/lisp/bandali-exwm.el
deleted file mode 100644
index e7f83ce..0000000
--- a/.emacs.d/lisp/bandali-exwm.el
+++ /dev/null
@@ -1,352 +0,0 @@
-;;; bandali-exwm.el --- bandali's EXWM configuration -*- lexical-binding: t; -*-
-
-;; Copyright (c) 2018-2023 Amin Bandali
-
-;; Author: Amin Bandali <bandali@gnu.org>
-;; Keywords: tools
-
-;; This program is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; This program is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with this program. If not, see <https://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; My EXWM setup. Makes good use of its simulation keys.
-
-;;; Code:
-
-(add-to-list 'load-path (b/lisp "xelb"))
-(add-to-list 'load-path (b/lisp "exwm"))
-(require 'exwm)
-;; (setq exwm-replace t)
-;; make class name the buffer name, truncating beyond 60 characters
-(defun b/exwm-rename-buffer ()
- (interactive)
- (exwm-workspace-rename-buffer
- (concat exwm-class-name ":"
- (if (<= (length exwm-title) 60) exwm-title
- (concat (substring exwm-title 0 59) "...")))))
-;; Enable EXWM
-(exwm-enable)
-(add-hook 'exwm-update-class-hook #'b/exwm-rename-buffer)
-(add-hook 'exwm-update-title-hook #'b/exwm-rename-buffer)
-
-(require 'exwm-config)
-(add-hook 'exwm-init-hook #'exwm-config--fix/ido-buffer-window-other-frame)
-
-(require 'exwm-input)
-(defun b/exwm-ws-prev-index ()
- "Return the index for the previous EXWM workspace, wrapping
-around if needed."
- (if (= exwm-workspace-current-index 0)
- (1- exwm-workspace-number)
- (1- exwm-workspace-current-index)))
-
-(defun b/exwm-ws-next-index ()
- "Return the index for the next EXWM workspace, wrapping
-around if needed."
- (if (= exwm-workspace-current-index
- (1- exwm-workspace-number))
- 0
- (1+ exwm-workspace-current-index)))
-
-(defun b/exwm-ws-prev ()
- "Switch to previous EXWM workspace, wrapping around if needed."
- (interactive)
- (exwm-workspace-switch-create
- (b/exwm-ws-prev-index)))
-
-(defun b/exwm-ws-next ()
- "Switch to next EXWM workspace, wrapping around if needed."
- (interactive)
- (exwm-workspace-switch-create
- (b/exwm-ws-next-index)))
-
-;; shorten 'C-c C-q' to 'C-q'
-(define-key exwm-mode-map [?\C-q] #'exwm-input-send-next-key)
-
-;; scroll up/down/left/right on the echo area
-(define-key minibuffer-inactive-mode-map [mouse-4] #'b/exwm-ws-prev)
-(define-key minibuffer-inactive-mode-map [mouse-5] #'b/exwm-ws-next)
-(define-key minibuffer-inactive-mode-map [mouse-6] #'b/exwm-ws-prev)
-(define-key minibuffer-inactive-mode-map [mouse-7] #'b/exwm-ws-next)
-
-(defvar b/shifted-ws-names
- '(0 \) 1 \! 2 \@ 3 \# 4 \$
- 5 \% 6 \^ 7 \& 8 \* 9 \()
- "Mapping of shifted numbers on my keyboard.")
-
-(setq
- exwm-workspace-number 10
- exwm-input-global-keys
- `(([?\s-R] . exwm-reset)
- ;; ([?\s-b] . exwm-workspace-switch-to-buffer)
- ([?\s-/] . exwm-workspace-switch)
- ([?\s-\s] . dmenu)
- ([?\s-\\] . (lambda ()
- (interactive)
- (start-process-shell-command
- "passmenu" nil "passmenu --type")))
- ([?\S-\s-\s] . (lambda (command)
- (interactive
- (list (read-shell-command "➜ ")))
- (start-process-shell-command
- command nil command)))
- ([s-return] . (lambda ()
- (interactive)
- (start-process "" nil "xterm")))
- ([S-s-return] . (lambda ()
- (interactive)
- (start-process "" nil "xterm"
- "-name" "floating")))
- ([?\C-\s-\s] . counsel-linux-app)
- ([?\s-h] . windmove-left)
- ([?\s-j] . windmove-down)
- ([?\s-k] . windmove-up)
- ([?\s-l] . windmove-right)
- ([?\s-H] . windmove-swap-states-left)
- ([?\s-J] . windmove-swap-states-down)
- ([?\s-K] . windmove-swap-states-up)
- ([?\s-L] . windmove-swap-states-right)
- ([?\s-N ?d] . (lambda ()
- (interactive)
- (start-process
- "" nil "dunstctl" "close")))
- ([?\s-N ?D] . (lambda ()
- (interactive)
- (start-process
- "" nil "dunstctl" "close-all")))
- ([?\s-N ?h] . (lambda ()
- (interactive)
- (start-process
- "" nil "dunstctl" "history-pop")))
- ([?\s-N return] . (lambda ()
- (interactive)
- (start-process
- "" nil "dunstctl" "context")))
- ([?\M-\s-h] . shrink-window-horizontally)
- ([?\M-\s-l] . enlarge-window-horizontally)
- ([?\M-\s-k] . shrink-window)
- ([?\M-\s-j] . enlarge-window)
- ([?\s-\[] . b/exwm-ws-prev)
- ([?\s-\]] . b/exwm-ws-next)
- ([mode-line mouse-4] . b/exwm-ws-prev) ; up
- ([mode-line mouse-5] . b/exwm-ws-next) ; down
- ([mode-line mouse-6] . b/exwm-ws-prev) ; left
- ([mode-line mouse-7] . b/exwm-ws-next) ; right
- ([?\s-{] . (lambda ()
- (interactive)
- (exwm-workspace-move-window
- (b/exwm-ws-prev-index))))
- ([?\s-}] . (lambda ()
- (interactive)
- (exwm-workspace-move-window
- (b/exwm-ws-next-index))))
- ,@(mapcar (lambda (i)
- `(,(kbd (format "s-%d" i)) .
- (lambda ()
- (interactive)
- (exwm-workspace-switch-create ,i))))
- (number-sequence 0 (1- exwm-workspace-number)))
- ,@(mapcar
- (lambda (i)
- `(,(kbd (format "s-%s"
- (plist-get b/shifted-ws-names i)))
- .
- (lambda ()
- (interactive)
- (exwm-workspace-move-window ,i))))
- (number-sequence 0 (1- exwm-workspace-number)))
- ([?\s-.] . exwm-floating-toggle-floating)
- ([?\s-f] . exwm-layout-toggle-fullscreen)
- ([?\s-W] . (lambda ()
- (interactive)
- (kill-buffer (current-buffer))))
- ([?\s-Q] . (lambda ()
- (interactive)
- (exwm-manage--kill-client)))
- ([?\s-\'] . (lambda ()
- (interactive)
- (start-process-shell-command
- "dmneu-light" nil "dmenu-light")))
- ([?\s-\;] . (lambda ()
- (interactive)
- (start-process-shell-command
- "dmneu-pamixer" nil "dmenu-pamixer")
- (b/volume-update)))
- ([XF86AudioMute] . ; borken on my X200 :-(
- (lambda ()
- (interactive)
- (start-process "" nil "pamixer" "--toggle-mute")
- (b/volume-update)))
- ([\s-XF86AudioMute] . ; toggle mic mute
- (lambda ()
- (interactive)
- (start-process
- "" nil "pamixer" "--default-source" "--toggle-mute")
- (b/volume-update)))
- ([XF86Launch1] .
- (lambda ()
- (interactive)
- (start-process "" nil "pamixer" "--toggle-mute")
- (b/volume-update)))
- ([\s-XF86Launch1] . ; toggle mic mute
- (lambda ()
- (interactive)
- (start-process
- "" nil "pamixer" "--default-source" "--toggle-mute")
- (b/volume-update)))
- ([XF86AudioLowerVolume] .
- (lambda ()
- (interactive)
- (start-process
- "" nil "pamixer" "--allow-boost" "--decrease" "5")
- (b/volume-update)))
- ([XF86AudioRaiseVolume] .
- (lambda ()
- (interactive)
- (start-process
- "" nil "pamixer" "--allow-boost" "--increase" "5")
- (b/volume-update)))
- ([\s-XF86AudioLowerVolume] .
- (lambda ()
- (interactive)
- (start-process
- "" nil "pamixer" "--default-source" "--decrease" "5")
- (b/volume-update)))
- ([\s-XF86AudioRaiseVolume] .
- (lambda ()
- (interactive)
- (start-process
- "" nil "pamixer" "--default-source" "--increase" "5")
- (b/volume-update)))
- ([XF86AudioPlay] .
- (lambda ()
- (interactive)
- (start-process "" nil "mpc" "toggle")))
- ([XF86AudioPrev] .
- (lambda ()
- (interactive)
- (start-process "" nil "mpc" "prev")))
- ([XF86AudioNext] .
- (lambda ()
- (interactive)
- (start-process "" nil "mpc" "next")))
- ([XF86MonBrightnessDown] .
- (lambda ()
- (interactive)
- (start-process "" nil "light" "-U" "5")))
- ([XF86MonBrightnessUp] .
- (lambda ()
- (interactive)
- (start-process "" nil "light" "-A" "5")))
- ([XF86ScreenSaver] .
- (lambda ()
- (interactive)
- (start-process "" nil "dm-tool" "lock")))
- ([\s-XF86Back] . previous-buffer)
- ([\s-XF86Forward] . next-buffer)))
-
-;; Line-editing shortcuts
-(setq
- exwm-input-simulation-keys
- '(;; movement
- ([?\C-b] . [left])
- ([?\M-b] . [C-left])
- ([?\C-f] . [right])
- ([?\M-f] . [C-right])
- ([?\C-p] . [up])
- ([?\C-n] . [down])
- ([?\C-a] . [home])
- ([?\C-e] . [end])
- ([?\M-v] . [prior])
- ([?\C-v] . [next])
- ([?\C-d] . [delete])
- ([?\C-k] . [S-end ?\C-x])
- ([?\M-<] . C-home)
- ([?\M->] . C-end)
- ;; cut/copy/paste
- ([?\C-w] . [?\C-x])
- ([?\M-w] . [?\C-c])
- ([?\C-y] . [?\C-v])
- ([?\M-d] . [C-S-right ?\C-x])
- ([?\M-\d] . [C-S-left ?\C-x])
- ;; window
- ([?\s-w] . [?\C-w])
- ([?\s-q] . [?\C-q])
- ;; misc
- ([?\C-s] . [?\C-f])
- ([?\s-g] . [?\C-g])
- ([?\s-s] . [?\C-s])
- ([?\C-g] . [escape])
- ([?\C-/] . [?\C-z])))
-
-(require 'exwm-manage)
-(setq
- exwm-manage-configurations
- '(((equal exwm-instance-name "floating")
- floating t
- floating-mode-line nil)))
-(add-hook 'exwm-manage-finish-hook
- (lambda ()
- (when exwm-class-name
- (cond
- ((member exwm-class-name '("Abrowser" "IceCat" "Iceweasel"))
- (exwm-input-set-local-simulation-keys
- `(,@exwm-input-simulation-keys
- ([?\C-\S-d] . [?\C-d]))))
- ((member exwm-class-name '("XTerm" "Mate-terminal"))
- (exwm-input-set-local-simulation-keys
- '(([?\C-c ?\C-c] . [?\C-c])
- ([?\C-c ?\C-u] . [?\C-u]))))
- ((string= exwm-class-name "Zathura")
- (exwm-input-set-local-simulation-keys
- '(([?\C-p] . [C-up])
- ([?\C-n] . [C-down]))))))))
-
-(require 'exwm-randr)
-(setq
- exwm-randr-workspace-monitor-plist
- '(0 "eDP-1"
- 1 "eDP-1" 2 "eDP-1" 3 "eDP-1"
- 4 "eDP-1" 5 "eDP-1" 6 "eDP-1"
- 7 "HDMI-1" 8 "HDMI-1" 9 "HDMI-1"))
-;; (add-hook
-;; 'exwm-randr-screen-change-hook
-;; (lambda ()
-;; (start-process-shell-command
-;; "xrandr" nil
-;; "xrandr --output HDMI-1 --mode 1280x720 --above eDP-1 --auto")))
-(exwm-randr-enable)
-
-(require 'exwm-systemtray)
-(exwm-systemtray-enable)
-
-(add-to-list 'load-path (b/lisp "exwm-edit"))
-(require 'exwm-edit)
-
-(with-eval-after-load 'exwm-workspace
- (setq exwm-workspace-show-all-buffers t)
- (setq-default
- mode-line-format
- (append
- mode-line-format
- '((:eval
- (format
- " [%s]" (number-to-string
- exwm-workspace-current-index)))))))
-
-(with-eval-after-load 'exwm-layout
- (setq exwm-layout-show-all-buffers t))
-
-(provide 'bandali-exwm)
-;;; bandali-exwm.el ends here
diff --git a/.emacs.d/lisp/bandali-gnus.el b/.emacs.d/lisp/bandali-gnus.el
deleted file mode 100644
index 18c6b2e..0000000
--- a/.emacs.d/lisp/bandali-gnus.el
+++ /dev/null
@@ -1,430 +0,0 @@
-;;; bandali-gnus.el --- bandali's Gnus setup -*- lexical-binding: t; -*-
-
-;; Copyright (C) 2018-2024 Amin Bandali
-
-;; Author: Amin Bandali <bandali@gnu.org>
-;; Keywords: mail, news
-
-;; This program is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; This program is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with this program. If not, see <https://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; My trusty super awesome Gnus setup.
-
-;;; Code:
-
-(defvar b/maildir (expand-file-name "~/mail/"))
-(with-eval-after-load 'recentf
- (add-to-list 'recentf-exclude b/maildir))
-
-(defvar b/gnus-init-file (b/etc "gnus"))
-
-(eval-when-compile
- (progn
- (defvar nndraft-directory)
- (defvar gnus-read-newsrc-file)
- (defvar gnus-save-newsrc-file)
- (defvar gnus-gcc-mark-as-read)
- (defvar nnmail-split-abbrev-alist)))
-
-(declare-function article-make-date-line "gnus-art" (date type))
-
-(setq
- mail-user-agent 'gnus-user-agent
- read-mail-command 'gnus
-
- gnus-select-method '(nnnil "")
- gnus-secondary-select-methods
- `(,@(when (member (system-name) '("darya" "nostalgia"))
- '((nnimap
- "canonical"
- (nnimap-stream plain)
- (nnimap-address "127.0.0.1")
- (nnimap-server-port 143)
- (nnimap-authenticator plain)
- (nnimap-user "bandali@canonical.local"))))
- (nnimap
- "kelar"
- (nnimap-stream plain)
- (nnimap-address "127.0.0.1")
- (nnimap-server-port 143)
- (nnimap-authenticator plain)
- (nnimap-user "bandali@kelar.local")
- ;; (nnmail-expiry-wait immediate)
- (nnmail-expiry-target nnmail-fancy-expiry-target)
- (nnmail-fancy-expiry-targets
- (("from" ".*" "nnimap+kelar:Archive.%Y"))))
- (nnimap
- "shemshak"
- (nnimap-stream plain)
- (nnimap-address "127.0.0.1")
- (nnimap-server-port 143)
- (nnimap-authenticator plain)
- (nnimap-user "bandali@shemshak.local"))
- (nnimap
- "gnu"
- (nnimap-stream plain)
- (nnimap-address "127.0.0.1")
- (nnimap-server-port 143)
- (nnimap-authenticator plain)
- (nnimap-user "bandali@gnu.local")
- (nnimap-inbox "INBOX")
- (nnimap-split-methods 'nnimap-split-fancy)
- (nnimap-split-fancy
- (|
- ;; (: gnus-registry-split-fancy-with-parent)
- ;; (: gnus-group-split-fancy "INBOX" t "INBOX")
- ;; spam
- ("X-Spam_action" "reject" "Junk")
- ;; keep debbugs emails in INBOX
- (list ".*<\\(.*\\)\\.debbugs\\.gnu\\.org>.*" "INBOX")
- ;; list moderation emails
- (from ".+-\\(owner\\|bounces\\)@\\(non\\)?gnu\\.org" "listmod")
- ;; gnu
- (list ".*<\\(.*\\)\\.\\(non\\)?gnu\\.org>.*" "l.\\1")
- ("Envelope-To" "emacsconf-donations@gnu.org" "l.emacsconf-donations")
- ;; board-eval
- (|
- (list ".*<.*\\.board-eval\\.fsf\\.org>.*" "l.board-eval")
- (from ".*@board-eval\\.fsf\\.org" "l.board-eval"))
- ;; fsf
- (list ".*<\\(.*\\)\\.fsf\\.org>.*" "l.\\1")
- ;; cfarm
- (from "cfarm-.*@lists\\.tetaneutral\\.net" "l.cfarm")
- ;; debian
- (list ".*<\\(.*\\)\\.\\(lists\\|other\\)\\.debian\\.org>.*" "l.\\1")
- (list ".*<\\(.*\\)\\.alioth-lists\\.debian\\.net>.*" "l.\\1")
- ;; gnus
- (list ".*<\\(.*\\)\\.gnus\\.org>.*" "l.\\1")
- ;; libreplanet
- (list ".*<\\(.*\\)\\.libreplanet\\.org>.*" "l.\\1")
- ;; iana (e.g. tz-announce)
- (list ".*<\\(.*\\)\\.iana\\.org>.*" "l.\\1")
- ;; mailop
- (list ".*<\\(.*\\)\\.mailop\\.org>.*" "l.\\1")
- ;; sdlu
- (list ".*<\\(.*\\)\\.spammers\\.dontlike\\.us>.*" "l.sdlu")
- ;; bitfolk
- (from ".*@\\(.+\\)?bitfolk\\.com>.*" "bitfolk")
- ;; haskell
- (list ".*<\\(.*\\)\\.haskell\\.org>.*" "l.\\1")
- ;; webmasters
- (from "webmasters\\(-comment\\)?@gnu\\.org" "webmasters")
- ;; other
- (list ".*atreus.freelists.org" "l.atreus")
- (list ".*deepspec.lists.cs.princeton.edu" "l.deepspec")
- ;; (list ".*haskell-art.we.lurk.org" "l.haskell.art") ;d
- ;; (list ".*notmuch.notmuchmail.org" "l.notmuch") ;u
- (list ".*dev.lists.parabola.nu" "l.parabola-dev")
- ;; ----------------------------------
- ;; legend: (u)nsubscribed | (d)ead
- ;; ----------------------------------
- ;; otherwise, leave mail in INBOX
- "INBOX")))
- (nnimap
- "csc"
- (nnimap-stream plain)
- (nnimap-address "127.0.0.1")
- (nnimap-server-port 143)
- (nnimap-authenticator plain)
- (nnimap-user "abandali@csclub.uwaterloo.local")
- (nnimap-inbox "INBOX")
- (nnimap-split-methods 'nnimap-split-fancy)
- (nnimap-split-fancy
- (|
- ;; cron reports and other messages from root
- (from "root@\\(.*\\.\\)?csclub\\.uwaterloo\\.ca" "INBOX")
- ;; spam
- ("X-Spam-Flag" "YES" "Junk")
- ;; catch-all
- "INBOX")))
- (nnimap
- "sfl"
- (nnimap-stream plain)
- (nnimap-address "127.0.0.1")
- (nnimap-server-port 143)
- (nnimap-authenticator plain)
- (nnimap-user "amin.bandali@savoirfairelinux.local")))
- gnus-message-archive-group "nnimap+gnu:INBOX"
- gnus-parameters
- '(("l\\.fencepost-users"
- (to-address . "fencepost-users@gnu.org")
- (to-list . "fencepost-users@gnu.org")
- (list-identifier . "\\[Fencepost-users\\]"))
- ("l\\.haskell-cafe"
- (to-address . "haskell-cafe@haskell.org")
- (to-list . "haskell-cafe@haskell.org")
- (list-identifier . "\\[Haskell-cafe\\]")))
- ;; nnimap-record-commands t
- ;; gnus-large-newsgroup 50
- ;; gnus-process-mark-toggle t
- gnus-home-directory (b/var "gnus/")
- gnus-directory (concat gnus-home-directory "news/")
- message-directory (concat gnus-home-directory "mail/")
- nndraft-directory (concat gnus-home-directory "drafts/")
- gnus-save-newsrc-file nil
- gnus-read-newsrc-file nil
- gnus-search-use-parsed-queries t
- gnus-interactive-exit nil
- gnus-gcc-mark-as-read t)
-
-(with-eval-after-load 'gnus
- (when (version< emacs-version "27")
- (with-eval-after-load 'nnmail
- (add-to-list
- 'nnmail-split-abbrev-alist
- '(list . "list-id\\|list-post\\|x-mailing-list\\|x-beenthere\\|x-loop")
- t)))
-
- (setq gnus-user-agent '(emacs gnus type))
-
- ;; (require 'gnus-registry)
- ;; (setq gnus-registry-max-entries 2500)
- ;; (setq gnus-registry-ignored-groups
- ;; (append gnus-registry-ignored-groups
- ;; '(("^nnimap:gnu\\.l" t)
- ;; ("webmasters$" t))))
- ;; (gnus-registry-initialize)
-
- (with-eval-after-load 'recentf
- (add-to-list 'recentf-exclude gnus-home-directory))
-
- ;; hooks
- (add-hook 'gnus-group-mode-hook #'gnus-topic-mode)
- (add-hook 'gnus-group-mode-hook #'gnus-agent-mode))
-;; global key bindings
-(global-set-key (kbd "C-c g") #'gnus-plugged)
-(global-set-key (kbd "C-c G") #'gnus-unplugged)
-
-(with-eval-after-load 'gnus-art
- (setq
- gnus-buttonized-mime-types '("multipart/\\(signed\\|encrypted\\)")
- gnus-sorted-header-list '("^From:"
- "^X-RT-Originator"
- "^Newsgroups:"
- "^Subject:"
- "^Date:"
- "^Envelope-To:"
- "^Followup-To:"
- "^Reply-To:"
- "^Organization:"
- "^Summary:"
- "^Abstract:"
- "^Keywords:"
- "^To:"
- "^[BGF]?Cc:"
- "^Posted-To:"
- "^Mail-Copies-To:"
- "^Mail-Followup-To:"
- "^Apparently-To:"
- "^Resent-From:"
- "^User-Agent:"
- "^X-detected-operating-system:"
- "^X-Spam_action:"
- "^X-Spam_bar:"
- "^Message-ID:"
- ;; "^References:"
- "^List-Id:"
- "^Gnus-Warning:")
- gnus-visible-headers (mapconcat #'identity
- gnus-sorted-header-list
- "\\|"))
- ;; local key bindings
- (declare-function org-store-link "ol" (arg &optional interactive?))
- (define-key gnus-article-mode-map (kbd "M-L") #'org-store-link))
-
-(with-eval-after-load 'gnus-sum
- (setq gnus-thread-sort-functions '(gnus-thread-sort-by-number
- gnus-thread-sort-by-subject
- gnus-thread-sort-by-date))
- (with-eval-after-load 'message
- (setq gnus-ignored-from-addresses message-dont-reply-to-names))
-
- (defun b/gnus-junk-article (&optional n)
- (interactive "P" gnus-summary-mode)
- (gnus-summary-move-article
- n
- (gnus-group-prefixed-name
- "Junk"
- (gnus-find-method-for-group gnus-newsgroup-name))))
- ;; local key bindings
- (define-key gnus-summary-mode-map (kbd "M-L") #'org-store-link)
- ;; (define-key gnus-summary-mode-map (kbd "r")
- ;; #'gnus-summary-reply-with-original)
- ;; (define-key gnus-summary-mode-map (kbd "R")
- ;; #'gnus-summary-wide-reply-with-original)
- (defvar b/gnus-summary-prefix-map)
- (define-prefix-command 'b/gnus-summary-prefix-map)
- (define-key
- gnus-summary-mode-map (kbd "v")
- 'b/gnus-summary-prefix-map)
- (define-key
- b/gnus-summary-prefix-map (kbd "r r")
- #'gnus-summary-very-wide-reply)
- (define-key
- b/gnus-summary-prefix-map (kbd "r q")
- #'gnus-summary-very-wide-reply-with-original)
- (define-key
- b/gnus-summary-prefix-map (kbd "R r")
- #'gnus-summary-reply)
- (define-key
- b/gnus-summary-prefix-map (kbd "R q")
- #'gnus-summary-reply-with-original)
- (define-key
- b/gnus-summary-prefix-map (kbd "r a w")
- #'gnus-summary-show-raw-article)
- (define-key
- b/gnus-summary-prefix-map (kbd "s")
- #'b/gnus-junk-article))
-;; hooks
-(add-hook 'gnus-summary-mode-hook #'b/no-mouse-autoselect-window)
-
-(defvar b/sfl-p nil)
-(with-eval-after-load 'gnus-msg
- (let ((bandali "Amin Bandali%s - https://www.gnu.ca/~bandali/"))
- (defvar b/csc-signature
- (mapconcat
- #'identity
- `(,(format bandali ", MMath")
- "Systems Committee <syscom@csclub.uwaterloo.ca>"
- "Computer Science Club of the University of Waterloo")
- "\n"))
- (defvar b/sfl-signature
- (mapconcat
- #'identity
- `(,bandali
- "Volunteer, Savoir-faire Linux"
- "jami:bandali")
- "\n")
- "")) ; the "" is for bandali's %s
- (setq
- gnus-message-replysign t
- gnus-posting-styles
- '((".*"
- (address "bandali@gnu.org")
- ("X-Message-SMTP-Method" "smtp fencepost.gnu.org 587"))
- ((header "subject" "ThankCRM")
- (to "webmasters-comment@gnu.org")
- (body ""))
- ("nnimap\\+kelar:.*"
- (address "bandali@kelar.org")
- ("X-Message-SMTP-Method" "smtp mail.kelar.org 587")
- (gcc "nnimap+kelar:Sent"))
- ("nnimap\\+shemshak:.*"
- (address "amin@shemshak.org")
- ("X-Message-SMTP-Method" "smtp mail.shemshak.org 587")
- (gcc "nnimap+shemshak:Sent"))
- ("nnimap\\+canonical:.*"
- (address "bandali@canonical.com")
- ("X-Message-SMTP-Method" "smtp smtp.canonical.com 587")
- (signature nil)
- (gcc "nnimap+canonical:Sent"))
- ((header "to" "amin\\.bandali@canonical\\.com")
- (address "amin.bandali@canonical.com"))
- ((header "cc" "amin\\.bandali@canonical\\.com")
- (address "amin.bandali@canonical.com"))
- ("nnimap\\+.*:l\\.ubuntu-.*"
- (address "bandali@ubuntu.com")
- ("X-Message-SMTP-Method" "smtp mail.kelar.org 587"))
- ((header "list-id" ".*\\.lists.ubuntu.com")
- (address "bandali@ubuntu.com")
- ("X-Message-SMTP-Method" "smtp mail.kelar.org 587"))
- ("nnimap\\+csc:.*"
- (address "bandali@csclub.uwaterloo.ca")
- ("X-Message-SMTP-Method" "smtp mail.csclub.uwaterloo.ca 587")
- (signature b/csc-signature)
- (gcc "nnimap+csc:Sent"))
- ("nnimap\\+sfl:.*"
- (address "amin.bandali@savoirfairelinux.com")
- ("X-Message-SMTP-Method" "smtp mail.savoirfairelinux.com 587")
- (signature b/sfl-signature)
- (eval (setq-local b/sfl-p t))
- (gcc "nnimap+sfl:Sent")))))
-;; hooks
-;; (with-eval-after-load 'gnus
-;; (add-hook 'gnus-message-setup-hook
-;; (lambda ()
-;; (unless (or (mml-secure-is-encrypted-p)
-;; b/sfl-p)
-;; (mml-secure-message-sign)))))
-
-(with-eval-after-load 'gnus-topic
- (setq
- gnus-topic-line-format "%i[ %A: %(%{%n%}%) ]%v\n"
- gnus-topic-topology
- `(("Gnus" visible nil nil)
- (("misc" visible nil nil))
- ,@(when (member (system-name) '("darya" "nostalgia"))
- '((("canonical" visible nil nil))))
- (("csc" visible nil nil))
- (("kelar" visible nil nil))
- (("shemshak" visible nil nil))
- (("gnu" visible nil nil))
- ;(("old-gnu" visible nil nil))
- (("sfl" visible nil nil)))))
-
-(with-eval-after-load 'gnus-agent
- (setq gnus-agent-synchronize-flags 'ask))
-
-(with-eval-after-load 'gnus-group
- (setq gnus-permanently-visible-groups "\\(:INBOX$\\|:gnu$\\)"))
-
-(with-eval-after-load 'gnus-win
- (setq gnus-use-full-window nil))
-
-(with-eval-after-load 'gnus-dired
- (add-hook 'dired-mode-hook 'gnus-dired-mode))
-
-(with-eval-after-load 'mm-archive
- (add-to-list
- 'mm-archive-decoders
- '("application/gzip" nil "gunzip" "-S" ".zip" "-kd" "%f" "-r")))
-
-(with-eval-after-load 'gnus-start
- (add-hook 'gnus-after-getting-new-news-hook #'gnus-notifications))
-
-(with-eval-after-load 'mm-decode
- (setq
- ;; mm-attachment-override-types `("text/x-diff" "text/x-patch"
- ;; ,@mm-attachment-override-types)
- mm-discouraged-alternatives '("text/html" "text/richtext")
- mm-decrypt-option 'known
- mm-verify-option 'known)
- (add-to-list
- 'mm-inline-media-tests
- `("application/gzip" mm-archive-dissect-and-inline identity))
- (add-to-list 'mm-inlined-types "application/gzip" 'append))
-
-(with-eval-after-load 'mm-uu
- (when (version< "27" emacs-version)
- (set-face-attribute 'mm-uu-extract nil :extend t))
- (when (version< emacs-version "27")
- (setq mm-uu-diff-groups-regexp ".")))
-
-(with-eval-after-load 'mml
- (setq
- mml-attach-file-at-the-end t
- mml-content-disposition-alist
- '((text
- (markdown . "attachment")
- (rtf . "attachment")
- (t . "inline"))
- (t. "attachment"))))
-
-(with-eval-after-load 'mml-sec
- (setq mml-secure-openpgp-encrypt-to-self t
- mml-secure-openpgp-sign-with-sender t))
-
-(provide 'bandali-gnus)
-;;; bandali-gnus.el ends here
diff --git a/.emacs.d/lisp/bandali-ibuffer.el b/.emacs.d/lisp/bandali-ibuffer.el
deleted file mode 100644
index a706dc6..0000000
--- a/.emacs.d/lisp/bandali-ibuffer.el
+++ /dev/null
@@ -1,110 +0,0 @@
-;;; bandali-ibuffer.el --- bandali's Ibuffer setup -*- lexical-binding: t; -*-
-
-;; Copyright (C) 2018-2022 Amin Bandali
-
-;; Author: Amin Bandali <bandali@gnu.org>
-;; Keywords: tools
-
-;; This program is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; This program is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with this program. If not, see <https://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; My Ibuffer setup.
-
-;;; Code:
-
-(setq
- ibuffer-saved-filter-groups
- '(("default"
- ("dired" (mode . dired-mode))
- ("org" (mode . org-mode))
- ("gnus"
- (or
- (mode . gnus-group-mode)
- (mode . gnus-summary-mode)
- (mode . gnus-article-mode)
- (mode . message-mode)))
- ("web"
- (or
- (mode . mhtml-mode)
- (mode . css-mode)
- (mode . scss-mode)
- (mode . js2-mode)))
- ("shell"
- (or
- (mode . eshell-mode)
- (mode . shell-mode)
- (mode . term-mode)))
- ("programming"
- (or
- (mode . python-mode)
- (mode . c-mode)
- (mode . c++-mode)
- (mode . java-mode)
- (mode . emacs-lisp-mode)
- (mode . scheme-mode)
- (mode . haskell-mode)
- (mode . lean-mode)
- ;; (mode . go-mode)
- (mode . alloy-mode)))
- ("tex"
- (or
- (mode . bibtex-mode)
- (mode . latex-mode)))
- ("emacs"
- (or
- (name . "^\\*scratch\\*$")
- (name . "^\\*Messages\\*$")))
- ("exwm" (mode . exwm-mode))
- ("erc" (mode . erc-mode))))
- ibuffer-formats
- '((mark modified read-only locked " "
- (name 72 72 :left :elide)
- " "
- (size-h 9 -1 :right)
- " "
- (mode 16 16 :left :elide)
- " " filename-and-process)
- (mark " "
- (name 16 -1)
- " " filename)))
-(with-eval-after-load 'ibuffer
- ;; Use human readable Size column instead of original one
- (define-ibuffer-column size-h
- (:name "Size" :inline t)
- (cond
- ((> (buffer-size) 1000000) (format "%7.1fM" (/ (buffer-size) 1000000.0)))
- ((> (buffer-size) 100000) (format "%7.0fk" (/ (buffer-size) 1000.0)))
- ((> (buffer-size) 1000) (format "%7.1fk" (/ (buffer-size) 1000.0)))
- (t (format "%8d" (buffer-size)))))
-
- ;; local key bindings
- (define-key ibuffer-mode-map (kbd "P")
- #'ibuffer-backward-filter-group)
- (define-key ibuffer-mode-map (kbd "N")
- #'ibuffer-forward-filter-group)
- (define-key ibuffer-mode-map (kbd "M-p")
- #'ibuffer-do-print)
- (define-key ibuffer-mode-map (kbd "M-n")
- #'ibuffer-do-shell-command-pipe-replace))
-;; global key bindings
-(global-set-key (kbd "C-x C-b") #'ibuffer)
-;; hooks
-(declare-function ibuffer-switch-to-saved-filter-groups "ibuf-ext"
- (name))
-(add-hook 'ibuffer-hook
- (lambda () (ibuffer-switch-to-saved-filter-groups "default")))
-
-(provide 'bandali-ibuffer)
-;;; bandali-ibuffer.el ends here
diff --git a/.emacs.d/lisp/bandali-message.el b/.emacs.d/lisp/bandali-message.el
deleted file mode 100644
index f9f0873..0000000
--- a/.emacs.d/lisp/bandali-message.el
+++ /dev/null
@@ -1,110 +0,0 @@
-;;; bandali-message.el --- bandali's message.el setup -*- lexical-binding: t; -*-
-
-;; Copyright (C) 2018-2022 Amin Bandali
-
-;; Author: Amin Bandali <bandali@gnu.org>
-;; Keywords: mail, news
-
-;; This program is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; This program is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with this program. If not, see <https://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; My setup for message.el.
-
-;;; Code:
-
-(with-eval-after-load 'message
- ;; :bind (:map message-mode-map ("<C-return>" . b/insert-asterism))
- ;; redefine for a simplified In-Reply-To header
- ;; (see https://todo.sr.ht/~sircmpwn/lists.sr.ht/67)
- (defun message-make-in-reply-to ()
- "Return the In-Reply-To header for this message."
- (when message-reply-headers
- (let ((from (mail-header-from message-reply-headers))
- (msg-id (mail-header-id message-reply-headers)))
- (when from
- msg-id))))
-
- (defconst b/message-cite-style-format "On %Y-%m-%d %l:%M %p, %N wrote:")
- (defconst message-cite-style-bandali
- '((message-cite-function 'message-cite-original)
- (message-citation-line-function 'message-insert-formatted-citation-line)
- (message-cite-reply-position 'traditional)
- (message-yank-prefix "> ")
- (message-yank-cited-prefix ">")
- (message-yank-empty-prefix ">")
- (message-citation-line-format b/message-cite-style-format))
- "Citation style based on Mozilla Thunderbird's. Use with message-cite-style.")
- (setq
- message-elide-ellipsis "[...]\n"
- ;; message-cite-style 'message-cite-style-bandali
- message-citation-line-format "%N writes:\n"
- ;; message-citation-line-format "On %a, %d %b %Y, %N wrote:\n"
- message-citation-line-function 'message-insert-formatted-citation-line
- message-confirm-send t
- message-fill-column 70
- message-forward-as-mime t
- message-kill-buffer-on-exit t
- message-send-mail-function #'smtpmail-send-it
- message-subscribed-address-functions
- '(gnus-find-subscribed-addresses)
- message-dont-reply-to-names
- (mapconcat
- #'identity
- '("\\(bandali\\|mab\\|aminb?\\)@gnu\\.org"
- "bandali@kelar\\.org"
- "amin@shemshak\\.org"
- "a?bandali@\\(csclub\\.\\)?uwaterloo\\.ca"
- "amin\\.bandali@savoirfairelinux\\.com"
- "\\(amin\\.\\)?bandali@canonical\\.com"
- "bandali@ubuntu\\.com")
- "\\|"))
- ;; (custom-set-faces
- ;; '(message-header-subject
- ;; ((t (:foreground "#111" :weight semi-bold))))
- ;; '(message-header-to
- ;; ((t (:foreground "#111" :weight normal))))
- ;; '(message-header-cc
- ;; ((t (:foreground "#333" :weight normal))))
-
- ;; custom newline & reformat function
- (defun b/message-newline-or-asterism (arg)
- "Create newlines per my liking or insert asterism if ARG is
-non-nil."
- (interactive "P")
- (if arg
- (b/insert-asterism)
- (progn
- (beginning-of-line)
- (delete-region (point) (line-end-position))
- (newline)
- (open-line 1))))
- (define-key message-mode-map
- (kbd "M-RET") #'b/message-newline-or-asterism)
-
- ;; local key bindings
- ;; (define-key message-mode-map
- ;; [remap next-line] #'mail-abbrev-next-line)
- ;; (define-key message-mode-map
- ;; [remap end-of-buffer] #'mail-abbrev-end-of-buffer)
- )
-;; hooks
-;; (add-hook 'message-setup-hook #'mml-secure-message-sign-pgpmime)
-(add-hook 'message-mode-hook #'flyspell-mode)
-(add-hook 'message-mode-hook
- (lambda ()
- (local-unset-key (kbd "C-c C-s"))))
-
-(provide 'bandali-message)
-;;; bandali-message.el ends here
diff --git a/.emacs.d/lisp/bandali-org.el b/.emacs.d/lisp/bandali-org.el
deleted file mode 100644
index bdaff4e..0000000
--- a/.emacs.d/lisp/bandali-org.el
+++ /dev/null
@@ -1,125 +0,0 @@
-;;; bandali-org.el --- bandali's Org setup -*- lexical-binding: t; -*-
-
-;; Copyright (C) 2018-2022 Amin Bandali
-
-;; Author: Amin Bandali <bandali@gnu.org>
-;; Keywords: calendar, data, docs, hypermedia, outlines
-
-;; This program is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; This program is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with this program. If not, see <https://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; My set up for Org (org-mode) and all things Org.
-
-;;; Code:
-
-;; (setq org--inhibit-version-check t)
-
-(with-eval-after-load 'org
- (setq
- org-src-tab-acts-natively t
- org-src-preserve-indentation nil
- org-edit-src-content-indentation 0
- org-id-locations-file (b/var "org/id-locations.el")
- org-link-email-description-format "Email %c: %s" ; %.30s
- org-highlight-latex-and-related '(entities)
- org-use-speed-commands t
- org-startup-folded 'content
- org-catch-invisible-edits 'show-and-error
- org-log-done 'time
- org-pretty-entities t
- org-agenda-files '("~/usr/org/todos/personal.org"
- "~/usr/org/todos/habits.org"
- "~/src/git/masters-thesis/todo.org")
- org-agenda-start-on-weekday 0
- org-agenda-time-leading-zero t
- org-habit-graph-column 44
- org-latex-packages-alist '(("" "listings") ("" "color")))
- (add-to-list 'org-structure-template-alist '("L" . "src emacs-lisp") t)
- (add-to-list 'org-modules 'org-habit)
- (custom-set-faces
- '(org-latex-and-related ((t (:foreground "#b294bb")))))
- ;; local key bindings
- (define-key org-mode-map (kbd "M-L") #'org-insert-last-stored-link)
- (define-key org-mode-map (kbd "M-O") #'org-toggle-link-display)
- ;; hooks
- ;; `org-indent-mode' doesn't seem to play nice with
- ;; `display-fill-column-indicator'.
- ;; (add-hook 'org-mode-hook #'org-indent-mode)
- (add-hook 'org-mode-hook #'auto-fill-mode)
- (add-hook 'org-mode-hook #'flyspell-mode)
-
- ;; additional export backends
- (require 'ox-md)
-
- ;; asynchronous tangle, using emacs-async to asynchronously tangle an
- ;; org file. closely inspired by
- ;; https://github.com/dieggsy/dotfiles/tree/cc10edf7701958eff1cd94d4081da544d882a28c/emacs.d#dotfiles
- (defvar b/show-async-tangle-results nil
- "Keep *emacs* async buffers around for later inspection.")
-
- (defvar b/show-async-tangle-time nil
- "Show the time spent tangling the file.")
-
- (defun b/async-babel-tangle ()
- "Tangle org file asynchronously."
- (interactive)
- (let* ((file-tangle-start-time (current-time))
- (file (buffer-file-name))
- (file-nodir (file-name-nondirectory file))
- ;; (async-quiet-switch "-q")
- ;; (file-noext (file-name-sans-extension file))
- )
- (async-start
- `(lambda ()
- (require 'org)
- (org-babel-tangle-file ,file))
- (unless b/show-async-tangle-results
- `(lambda (result)
- (if result
- (message "Tangled %s%s"
- ,file-nodir
- (if b/show-async-tangle-time
- (format " (%.3fs)"
- (float-time (time-subtract (current-time)
- ',file-tangle-start-time)))
- ""))
- (message "Tangling %s failed" ,file-nodir)))))))
- (add-to-list
- 'safe-local-variable-values
- '(eval add-hook 'after-save-hook #'b/async-babel-tangle 'append 'local)))
-;; global key bindings
-(global-set-key (kbd "C-c a o a") #'org-agenda)
-
-(with-eval-after-load 'ox-latex
- (setq
- org-latex-listings 'listings
- ;; org-latex-prefer-user-labels t
- )
- (add-to-list 'org-latex-classes
- '("IEEEtran" "\\documentclass[11pt]{IEEEtran}"
- ("\\section{%s}" . "\\section*{%s}")
- ("\\subsection{%s}" . "\\subsection*{%s}")
- ("\\subsubsection{%s}" . "\\subsubsection*{%s}")
- ("\\paragraph{%s}" . "\\paragraph*{%s}")
- ("\\subparagraph{%s}" . "\\subparagraph*{%s}"))
- t)
- (require 'ox-beamer))
-
-(with-eval-after-load 'ox-extra
- (declare-function ox-extras-activate "ox-extra" (extras))
- (ox-extras-activate '(latex-header-blocks ignore-headlines)))
-
-(provide 'bandali-org)
-;;; bandali-org.el ends here
diff --git a/.emacs.d/lisp/bandali-po.el b/.emacs.d/lisp/bandali-po.el
deleted file mode 100644
index a31fee2..0000000
--- a/.emacs.d/lisp/bandali-po.el
+++ /dev/null
@@ -1,61 +0,0 @@
-;;; bandali-po.el --- bandali's po-mode setup -*- lexical-binding: t; -*-
-
-;; Copyright (C) 2021 Amin Bandali
-
-;; Author: Amin Bandali <bandali@gnu.org>
-;; Keywords: i18n gettext
-
-;; This program is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; This program is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with this program. If not, see <https://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; My po-mode setup for editing PO translation files in GNU Emacs.
-
-;;; Code:
-
-(with-eval-after-load 'po-mode
- ;; based on the `po-wrap' function from the GNUN manual:
- ;; https://www.gnu.org/s/trans-coord/manual/gnun/html_node/Wrapping-Long-Lines.html
- (defun b/po-wrap ()
- "Run the current `po-mode' buffer through `msgcat' to wrap all
-lines."
- (interactive)
- (when (eq major-mode 'po-mode)
- (let ((tmp-file (make-temp-file "po-wrap."))
- (tmp-buffer (generate-new-buffer "*temp*")))
- (unwind-protect
- (progn
- (write-region (point-min) (point-max) tmp-file nil 1)
- (if (zerop
- (call-process "msgcat" nil tmp-buffer t
- (shell-quote-argument tmp-file)))
- (let ((saved (point))
- (inhibit-read-only t))
- (delete-region (point-min) (point-max))
- (insert-buffer-substring tmp-buffer)
- (goto-char (min saved (point-max))))
- (with-current-buffer tmp-buffer
- (error (buffer-string)))))
- (kill-buffer tmp-buffer)
- (delete-file tmp-file)))))
-
- (add-hook 'po-mode-hook (lambda nil (run-with-timer 0.1 nil 'View-exit)))
- (define-key po-mode-map (kbd "M-q") #'b/po-wrap))
-
-(autoload #'po-mode "po-mode"
- "Major mode for editing PO translation files" t)
-(add-to-list 'auto-mode-alist '("\\.po\\'\\|\\.po\\." . po-mode))
-
-(provide 'bandali-po)
-;;; bandali-po.el ends here
diff --git a/.emacs.d/lisp/bandali-theme.el b/.emacs.d/lisp/bandali-theme.el
deleted file mode 100644
index fa5911c..0000000
--- a/.emacs.d/lisp/bandali-theme.el
+++ /dev/null
@@ -1,79 +0,0 @@
-;;; bandali-theme.el --- bandali's custom theme setup -*- lexical-binding: t; -*-
-
-;; Copyright (C) 2018-2020 Amin Bandali
-
-;; Author: Amin Bandali <bandali@gnu.org>
-;; Keywords: faces
-
-;; This program is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; This program is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with this program. If not, see <https://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; My custom theme setup.
-
-;;; Code:
-
-(when (display-graphic-p)
- (add-to-list 'load-path (b/lisp "refinery-theme"))
- (with-eval-after-load 'package
- (require 'refinery-theme)
- (load-theme 'refinery t)))
-
-;; (require 'smart-mode-line)
-;; ;; thanks, but no thanks; don't make fixed-width fills.
-;; (defun sml/fill-for-buffer-identification nil "")
-;; (setq sml/theme 'respectful)
-;; (let ((sml/no-confirm-load-theme t))
-;; (sml/setup)
-;; (smart-mode-line-enable))
-
-;; (require 'minions)
-;; (minions-mode)
-
-(defvar b/org-mode-font-lock-keywords
- '(("[ \t]*\\(#\\+\\(BEGIN\\|END\\|begin\\|end\\)_\\(\\S-+\\)\\)[ \t]*\\([^\n:]*\\)"
- (1 '(:foreground "#5a5b5a" :background "#292b2b") t) ; directive
- (3 '(:foreground "#81a2be" :background "#292b2b") t) ; kind
- (4 '(:foreground "#c5c8c6") t))) ; title
- "For use with the `doom-tomorrow-night' theme.")
-
-(eval-when-compile
- (declare-function exwm-systemtray--refresh "exwm-systemtray")
- (declare-function erc-hl-nicks-reset-face-table "erc-hl-nicks"))
-
-(defun b/lights-on ()
- "Enable my favourite light theme."
- (interactive)
- (mapc #'disable-theme custom-enabled-themes)
- (load-theme 'refinery t)
- (font-lock-remove-keywords
- 'org-mode b/org-mode-font-lock-keywords)
- (when (featurep 'exwm-systemtray)
- (exwm-systemtray--refresh)))
-
-(defun b/lights-off ()
- "Go dark."
- (interactive)
- (mapc #'disable-theme custom-enabled-themes)
- (load-theme 'refinery-dark t)
- (font-lock-add-keywords
- 'org-mode b/org-mode-font-lock-keywords t)
- (when (featurep 'exwm-systemtray)
- (exwm-systemtray--refresh)))
-
-(global-set-key (kbd "C-c t d") #'b/lights-off)
-(global-set-key (kbd "C-c t l") #'b/lights-on)
-
-(provide 'bandali-theme)
-;;; bandali-theme.el ends here