summaryrefslogtreecommitdiffstats
path: root/.emacs.d/lisp
diff options
context:
space:
mode:
authorAmin Bandali <bandali@gnu.org>2020-10-05 23:38:06 -0400
committerAmin Bandali <bandali@gnu.org>2020-10-05 23:38:06 -0400
commitd7dee82420a04e5c92e5b5ad316e14a49bd4d689 (patch)
tree9dceac59e3b0d40b0357e8854e191ac5559d41ab /.emacs.d/lisp
parent927b50b7aec2da105bd5125dec272a89e38663c3 (diff)
downloadconfigs-d7dee82420a04e5c92e5b5ad316e14a49bd4d689.tar.gz
configs-d7dee82420a04e5c92e5b5ad316e14a49bd4d689.tar.xz
configs-d7dee82420a04e5c92e5b5ad316e14a49bd4d689.zip
Move GNU Emacs configs from ./ into .emacs.d/
I will be using the repository to store my configurations for other non-Emacs pieces of software. The repository itself will be located at ~/ rather than ~/.emacs.d/.
Diffstat (limited to '.emacs.d/lisp')
m---------.emacs.d/lisp/alloy-mode0
m---------.emacs.d/lisp/amx0
-rw-r--r--.emacs.d/lisp/bandali-dired.el93
-rw-r--r--.emacs.d/lisp/bandali-ebdb.el52
-rw-r--r--.emacs.d/lisp/bandali-erc.el178
-rw-r--r--.emacs.d/lisp/bandali-eshell.el86
-rw-r--r--.emacs.d/lisp/bandali-exwm.el239
-rw-r--r--.emacs.d/lisp/bandali-gnus.el478
-rw-r--r--.emacs.d/lisp/bandali-ibuffer.el110
-rw-r--r--.emacs.d/lisp/bandali-ivy.el74
-rw-r--r--.emacs.d/lisp/bandali-magit.el70
-rw-r--r--.emacs.d/lisp/bandali-message.el138
-rw-r--r--.emacs.d/lisp/bandali-org.el119
-rw-r--r--.emacs.d/lisp/bandali-theme.el87
m---------.emacs.d/lisp/boxquote0
-rw-r--r--.emacs.d/lisp/gnus-article-treat-patch.el465
m---------.emacs.d/lisp/hl-todo0
m---------.emacs.d/lisp/page-break-lines0
m---------.emacs.d/lisp/s0
m---------.emacs.d/lisp/scpaste0
20 files changed, 2189 insertions, 0 deletions
diff --git a/.emacs.d/lisp/alloy-mode b/.emacs.d/lisp/alloy-mode
new file mode 160000
+Subproject 0d05bdd10c77ec04c3d61eccf67e68c08284951
diff --git a/.emacs.d/lisp/amx b/.emacs.d/lisp/amx
new file mode 160000
+Subproject ccfc92c600df681df5e8b5fecec328c462ceb71
diff --git a/.emacs.d/lisp/bandali-dired.el b/.emacs.d/lisp/bandali-dired.el
new file mode 100644
index 0000000..9ed1030
--- /dev/null
+++ b/.emacs.d/lisp/bandali-dired.el
@@ -0,0 +1,93 @@
+;;; bandali-dired.el --- bandali's dired setup -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2018-2020 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
+ (csetq
+ dired-dwim-target t
+ dired-listing-switches "-alh"
+ 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)
+ (csetq 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-ebdb.el b/.emacs.d/lisp/bandali-ebdb.el
new file mode 100644
index 0000000..4d21978
--- /dev/null
+++ b/.emacs.d/lisp/bandali-ebdb.el
@@ -0,0 +1,52 @@
+;;; bandali-ebdb.el --- bandali's EBDB configuration -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2018-2020 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 EBDB setup.
+
+;;; Code:
+
+(with-eval-after-load 'gnus
+ (require 'ebdb)
+ (csetq ebdb-sources (b/var "ebdb"))
+ (with-eval-after-load 'swiper
+ (add-to-list 'swiper-font-lock-exclude #'ebdb-mode t))
+ ;; local key bindings
+ (define-key gnus-group-mode-map (kbd "e") #'ebdb))
+
+(with-eval-after-load 'ebdb
+ (with-eval-after-load 'ebdb-complete
+ ;; (csetq ebdb-complete-mail 'capf)
+ (ebdb-complete-enable))
+
+ (require 'ebdb-message)
+
+ (require 'ebdb-gnus)
+ (csetq ebdb-gnus-window-size 0.3)
+
+ (require 'ebdb-mua)
+ (csetq ebdb-mua-pop-up t))
+
+;; (with-eval-after-load 'company-ebdb
+;; (defun company-ebdb--post-complete (_) nil))
+
+(provide 'bandali-ebdb)
+;;; bandali-ebdb.el ends here
diff --git a/.emacs.d/lisp/bandali-erc.el b/.emacs.d/lisp/bandali-erc.el
new file mode 100644
index 0000000..41a152c
--- /dev/null
+++ b/.emacs.d/lisp/bandali-erc.el
@@ -0,0 +1,178 @@
+;;; bandali-erc.el --- bandali's ERC setup -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2018-2020 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 ERC setup for IRC. It uses my fork of ZNC.el.
+
+;;; Code:
+
+(defvar b/erc-detach-on-kill t
+ "Whether killing a channel should send a DETACH command (for ZNC).")
+
+(with-eval-after-load 'erc
+ (make-directory (b/var "erc/dcc/") t)
+ (csetq
+ erc-auto-query 'bury
+ erc-autojoin-domain-only nil
+ erc-dcc-get-default-directory (b/var "erc/dcc/")
+ erc-format-nick-function 'erc-format-@nick
+ erc-join-buffer 'bury
+ erc-log-channels-directory (b/var "erc/log-channels/")
+ erc-lurker-hide-list '("JOIN" "PART" "QUIT")
+ erc-nick "bandali"
+ erc-prompt "erc>"
+ erc-prompt-for-password nil
+ 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 ()
+ "Request chanserv to op me."
+ (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 from current channel."
+ (erc-cmd-DEOP (format "%s" (erc-current-nick))))
+ (add-to-list 'erc-modules 'keep-place)
+ (add-to-list 'erc-modules 'notifications)
+ (add-to-list 'erc-modules 'smiley)
+ (add-to-list 'erc-modules 'spelling)
+ (declare-function erc-update-modules "erc")
+ (erc-update-modules)
+
+ (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
+ ;; (csetq
+ ;; erc-fill-column 77
+ ;; erc-fill-function 'erc-fill-variable
+ ;; erc-fill-static-center 18)
+ ;; to disable:
+ ;; (erc-fill-mode -1)
+
+ ;; erc-match
+ (csetq
+ erc-pal-highlight-type 'nick
+ erc-pals
+ '("aindilis" "blackbeard" "bremner" "brettgilio" "civodul"
+ "dto" "ggoes" "jrasata" "mplsCorwin" "rwp" "technomancy"))
+ (with-eval-after-load 'erc-match
+ (set-face-attribute
+ 'erc-pal-face nil
+ :foreground 'unspecified
+ :weight 'unspecified
+ :inherit 'erc-nick-default-face
+ :background (face-attribute 'font-lock-string-face :background)))
+
+ ;; erc-pcomplete
+ (csetq erc-pcomplete-nick-postfix ", ")
+
+ ;; erc-stamp
+ (csetq 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))
+
+ ;; erc-track
+ (csetq
+ 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)
+
+ ;; 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)
+
+ ;; hooks
+ (defun b/erc-detach-or-kill-channel ()
+ (if b/erc-detach-on-kill
+ (when (erc-server-process-alive)
+ (let ((tgt (erc-default-target)))
+ (erc-server-send (format "DETACH %s" tgt) nil tgt)))
+ (erc-kill-channel)))
+ (add-hook 'erc-kill-channel-hook #'b/erc-detach-or-kill-channel)
+ (remove-hook 'erc-kill-channel-hook #'erc-kill-channel))
+
+;; global key bindings
+(global-set-key
+ (kbd "C-c a e f")
+ (lambda ()
+ (interactive)
+ (let* ((auth (auth-source-search :host "znca"))
+ (p (if (null auth)
+ (error "Couldn't find znca's authinfo")
+ (funcall (plist-get (car auth) :secret)))))
+ (erc-tls :server "znc.emacsconf.org" :port 6697
+ :password (concat "bandali/freenode:" p)))))
+(global-set-key
+ (kbd "C-c a e o")
+ (lambda ()
+ (interactive)
+ (let* ((auth (auth-source-search :host "znca"))
+ (p (if (null auth)
+ (error "Couldn't find znca's authinfo")
+ (funcall (plist-get (car auth) :secret)))))
+ (erc-tls :server "znc.emacsconf.org" :port 6697
+ :password (concat "bandali/oftc:" p)))))
+(global-set-key
+ (kbd "C-c a e t")
+ (lambda ()
+ (interactive)
+ (let* ((auth (auth-source-search :host "znca"))
+ (p (if (null auth)
+ (error "Couldn't find znca's authinfo")
+ (funcall (plist-get (car auth) :secret)))))
+ (erc-tls :server "znc.emacsconf.org" :port 6697
+ :password (concat "bandali/tildechat:" p)))))
+
+(provide 'bandali-erc)
+;;; bandali-erc.el ends here
diff --git a/.emacs.d/lisp/bandali-eshell.el b/.emacs.d/lisp/bandali-eshell.el
new file mode 100644
index 0000000..820dc05
--- /dev/null
+++ b/.emacs.d/lisp/bandali-eshell.el
@@ -0,0 +1,86 @@
+;;; bandali-eshell.el --- bandali's Eshell setup -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2018-2020 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)
+ (csetq
+ 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))))
+ (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-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-mode-map (kbd "M-r")
+ #'counsel-esh-history)
+ ;; (define-key eshell-mode-map [tab]
+ ;; #'company-complete)
+ (define-key eshell-hist-mode-map (kbd "M-r")
+ #'counsel-esh-history)))
+;; global key bindings
+(global-set-key (kbd "C-c a 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
new file mode 100644
index 0000000..6b57898
--- /dev/null
+++ b/.emacs.d/lisp/bandali-exwm.el
@@ -0,0 +1,239 @@
+;;; bandali-exwm.el --- bandali's EXWM configuration -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2018-2020 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:
+
+(use-package exwm
+ :if b/exwm-p
+ :demand
+ :config
+ ;; 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)
+ :hook ((exwm-update-class . b/exwm-rename-buffer)
+ (exwm-update-title . b/exwm-rename-buffer)))
+
+(use-package exwm-config
+ :demand
+ :after exwm
+ :hook (exwm-init . exwm-config--fix/ido-buffer-window-other-frame))
+
+(use-package exwm-input
+ :demand
+ :after exwm
+ :config
+ (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)))
+
+ ;; shorten 'C-c C-q' to 'C-q'
+ (define-key exwm-mode-map [?\C-q] #'exwm-input-send-next-key)
+
+ (setq exwm-workspace-number 4
+ exwm-input-global-keys
+ `(([?\s-R] . exwm-reset)
+ ([?\s-\\] . exwm-workspace-switch)
+ ([?\s-\s] . dmenu)
+ ([?\S-\s-\s] . (lambda (command)
+ (interactive
+ (list (read-shell-command "➜ ")))
+ (start-process-shell-command
+ command nil command)))
+ ([s-return] . (lambda ()
+ (interactive)
+ (start-process "" nil "urxvt")))
+ ([?\C-\s-\s] . counsel-linux-app)
+ ([?\M-\s-\s] . (lambda ()
+ (interactive)
+ (start-process-shell-command
+ "rofi-pass" nil "rofi-pass")))
+ ([?\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)
+ ([?\M-\s-h] . shrink-window-horizontally)
+ ([?\M-\s-l] . enlarge-window-horizontally)
+ ([?\M-\s-k] . shrink-window)
+ ([?\M-\s-j] . enlarge-window)
+ ([?\s-\[] . (lambda ()
+ (interactive)
+ (exwm-workspace-switch-create
+ (b/exwm-ws-prev-index))))
+ ([?\s-\]] . (lambda ()
+ (interactive)
+ (exwm-workspace-switch-create
+ (b/exwm-ws-next-index))))
+ ([?\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)))
+ ([?\s-t] . 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
+ "rofi-light" nil "rofi-light")))
+ ([XF86AudioMute] .
+ (lambda ()
+ (interactive)
+ (start-process "" nil "amixer" "set" "'Master',0" "toggle")))
+ ([XF86AudioLowerVolume] .
+ (lambda ()
+ (interactive)
+ (start-process
+ "" nil "amixer" "set" "'Master',0" "5%-")))
+ ([XF86AudioRaiseVolume] .
+ (lambda ()
+ (interactive)
+ (start-process
+ "" nil "amixer" "set" "'Master',0" "5%+")))
+ ([XF86AudioPlay] .
+ (lambda ()
+ (interactive)
+ (start-process "" nil "mpc" "toggle")))
+ ([XF86AudioPrev] .
+ (lambda ()
+ (interactive)
+ (start-process "" nil "mpc" "prev")))
+ ([XF86AudioNext] .
+ (lambda ()
+ (interactive)
+ (start-process "" nil "mpc" "next")))
+ ([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-s] . [?\C-s])
+ ([?\C-g] . [escape]))))
+
+(use-package exwm-manage
+ :demand
+ :after exwm
+ :hook
+ (exwm-manage-finish . (lambda ()
+ (when exwm-class-name
+ (cond
+ ((string= exwm-class-name "IceCat")
+ (exwm-input-set-local-simulation-keys
+ `(,@exwm-input-simulation-keys
+ ([?\C-\S-d] . [?\C-d]))))
+ ((string= exwm-class-name "URxvt")
+ (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])))))))))
+
+(use-package exwm-randr
+ :demand
+ :after exwm
+ :config
+ (exwm-randr-enable)
+ :custom
+ (exwm-randr-workspace-monitor-plist '(1 "VGA-1")))
+
+(use-package exwm-systemtray
+ :demand
+ :after exwm
+ :config
+ (exwm-systemtray-enable))
+
+(use-package exwm-workspace)
+
+(use-package exwm-edit
+ :demand
+ :after exwm)
+
+(provide 'bandali-exwm)
+;;; bandali-exwm.el ends here
diff --git a/.emacs.d/lisp/bandali-gnus.el b/.emacs.d/lisp/bandali-gnus.el
new file mode 100644
index 0000000..1958793
--- /dev/null
+++ b/.emacs.d/lisp/bandali-gnus.el
@@ -0,0 +1,478 @@
+;;; bandali-gnus.el --- bandali's Gnus setup -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2018-2020 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))
+
+(csetq
+ mail-user-agent 'gnus-user-agent
+ read-mail-command 'gnus
+
+ gnus-select-method '(nnnil "")
+ gnus-secondary-select-methods
+ '((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")
+ ;; keep debbugs emails in INBOX
+ (list ".*<\\(.*\\)\\.debbugs\\.gnu\\.org>.*" "INBOX")
+ ;; gnu
+ (list ".*<\\(.*\\)\\.\\(non\\)?gnu\\.org>.*" "l.\\1")
+ ;; gnus
+ (list ".*<\\(.*\\)\\.gnus\\.org>.*" "l.\\1")
+ ;; libreplanet
+ (list ".*<\\(.*\\)\\.libreplanet\\.org>.*" "l.\\1")
+ ;; iana (e.g. tz-announce)
+ (list ".*<\\(.*\\)\\.iana\\.org>.*" "l.\\1")
+ ;; orbitalfox (e.g. gemini)
+ (list ".*<\\(.*\\)\\.lists\\.orbitalfox\\.eu>.*" "l.\\1")
+ ;; *.lists.sr.ht, omitting one dot if present
+ ;; add more \\.?\\([^.]*\\) if needed
+ (list ".*<~\\(.*\\)/\\([^.]*\\)\\.?\\([^.]*\\)\\.lists\\.sr\\.ht>.*" "l.~\\1.\\2\\3")
+ ;; 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 ".*haskell-cafe.haskell.org" "l.haskell-cafe")
+ ;; (list ".*notmuch.notmuchmail.org" "l.notmuch") ;u
+ (list ".*dev.lists.parabola.nu" "l.parabola-dev")
+ ;; ----------------------------------
+ ;; legend: (u)nsubscribed | (d)ead
+ ;; ----------------------------------
+ ;; spam
+ ("X-Spam_action" "reject" "Junk")
+ ;; otherwise, leave mail in INBOX
+ "INBOX")))
+ (nnimap "uwaterloo"
+ (nnimap-stream plain)
+ (nnimap-address "127.0.0.1")
+ (nnimap-server-port 143)
+ (nnimap-authenticator plain)
+ (nnimap-user "abandali@uwaterloo.local")
+ (nnimap-inbox "INBOX")
+ (nnimap-split-methods 'nnimap-split-fancy)
+ (nnimap-split-fancy (|
+ ;; (: gnus-registry-split-fancy-with-parent)
+ ;; se212-f19
+ ("subject" "SE\\s-?212" "course.se212-f19")
+ (from "SE\\s-?212" "course.se212-f19")
+ ;; catch-all
+ "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 tls)
+ (nnimap-address "mail.savoirfairelinux.com")
+ (nnimap-user "amin.bandali")))
+ gnus-message-archive-group "nnimap+gnu:INBOX"
+ gnus-parameters
+ '(("l\\.atreus"
+ (to-address . "atreus@freelists.org")
+ (to-list . "atreus@freelists.org"))
+ ("l\\.deepspec"
+ (to-address . "deepspec@lists.cs.princeton.edu")
+ (to-list . "deepspec@lists.cs.princeton.edu")
+ (list-identifier . "\\[deepspec\\]"))
+ ("l\\.emacs-devel"
+ (to-address . "emacs-devel@gnu.org")
+ (to-list . "emacs-devel@gnu.org"))
+ ("l\\.help-gnu-emacs"
+ (to-address . "help-gnu-emacs@gnu.org")
+ (to-list . "help-gnu-emacs@gnu.org"))
+ ("l\\.info-gnu-emacs"
+ (to-address . "info-gnu-emacs@gnu.org")
+ (to-list . "info-gnu-emacs@gnu.org"))
+ ("l\\.emacs-orgmode"
+ (to-address . "emacs-orgmode@gnu.org")
+ (to-list . "emacs-orgmode@gnu.org")
+ (list-identifier . "\\[O\\]"))
+ ("l\\.emacs-tangents"
+ (to-address . "emacs-tangents@gnu.org")
+ (to-list . "emacs-tangents@gnu.org"))
+ ("l\\.emacsconf-committee"
+ (to-address . "emacsconf-committee@gnu.org")
+ (to-list . "emacsconf-committee@gnu.org"))
+ ("l\\.emacsconf-discuss"
+ (to-address . "emacsconf-discuss@gnu.org")
+ (to-list . "emacsconf-discuss@gnu.org"))
+ ("l\\.emacsconf-org"
+ (to-address . "emacsconf-org@gnu.org")
+ (to-list . "emacsconf-org@gnu.org"))
+ ("l\\.emacsconf-org-private"
+ (to-address . "emacsconf-org-private@gnu.org")
+ (to-list . "emacsconf-org-private@gnu.org"))
+ ("l\\.emacsconf-register"
+ (to-address . "emacsconf-register@gnu.org")
+ (to-list . "emacsconf-register@gnu.org"))
+ ("l\\.emacsconf-submit"
+ (to-address . "emacsconf-submit@gnu.org")
+ (to-list . "emacsconf-submit@gnu.org"))
+ ("l\\.fencepost-users"
+ (to-address . "fencepost-users@gnu.org")
+ (to-list . "fencepost-users@gnu.org")
+ (list-identifier . "\\[Fencepost-users\\]"))
+ ("l\\.gnewsense-art"
+ (to-address . "gnewsense-art@nongnu.org")
+ (to-list . "gnewsense-art@nongnu.org")
+ (list-identifier . "\\[gNewSense-art\\]"))
+ ("l\\.gnewsense-dev"
+ (to-address . "gnewsense-dev@nongnu.org")
+ (to-list . "gnewsense-dev@nongnu.org")
+ (list-identifier . "\\[Gnewsense-dev\\]"))
+ ("l\\.gnewsense-users"
+ (to-address . "gnewsense-users@nongnu.org")
+ (to-list . "gnewsense-users@nongnu.org")
+ (list-identifier . "\\[gNewSense-users\\]"))
+ ("l\\.gnunet-developers"
+ (to-address . "gnunet-developers@gnu.org")
+ (to-list . "gnunet-developers@gnu.org")
+ (list-identifier . "\\[GNUnet-developers\\]"))
+ ("l\\.help-gnunet"
+ (to-address . "help-gnunet@gnu.org")
+ (to-list . "help-gnunet@gnu.org")
+ (list-identifier . "\\[Help-gnunet\\]"))
+ ("l\\.bug-gnuzilla"
+ (to-address . "bug-gnuzilla@gnu.org")
+ (to-list . "bug-gnuzilla@gnu.org")
+ (list-identifier . "\\[Bug-gnuzilla\\]"))
+ ("l\\.gnuzilla-dev"
+ (to-address . "gnuzilla-dev@gnu.org")
+ (to-list . "gnuzilla-dev@gnu.org")
+ (list-identifier . "\\[Gnuzilla-dev\\]"))
+ ("l\\.guile-devel"
+ (to-address . "guile-devel@gnu.org")
+ (to-list . "guile-devel@gnu.org"))
+ ("l\\.guile-user"
+ (to-address . "guile-user@gnu.org")
+ (to-list . "guile-user@gnu.org"))
+ ("l\\.guix-devel"
+ (to-address . "guix-devel@gnu.org")
+ (to-list . "guix-devel@gnu.org"))
+ ("l\\.help-guix"
+ (to-address . "help-guix@gnu.org")
+ (to-list . "help-guix@gnu.org"))
+ ("l\\.info-guix"
+ (to-address . "info-guix@gnu.org")
+ (to-list . "info-guix@gnu.org"))
+ ("l\\.savannah-hackers-public"
+ (to-address . "savannah-hackers-public@gnu.org")
+ (to-list . "savannah-hackers-public@gnu.org"))
+ ("l\\.savannah-users"
+ (to-address . "savannah-users@gnu.org")
+ (to-list . "savannah-users@gnu.org"))
+ ("l\\.www-commits"
+ (to-address . "www-commits@gnu.org")
+ (to-list . "www-commits@gnu.org"))
+ ("l\\.www-discuss"
+ (to-address . "www-discuss@gnu.org")
+ (to-list . "www-discuss@gnu.org"))
+ ("l\\.haskell-art"
+ (to-address . "haskell-art@we.lurk.org")
+ (to-list . "haskell-art@we.lurk.org")
+ (list-identifier . "\\[haskell-art\\]"))
+ ("l\\.haskell-cafe"
+ (to-address . "haskell-cafe@haskell.org")
+ (to-list . "haskell-cafe@haskell.org")
+ (list-identifier . "\\[Haskell-cafe\\]"))
+ ("l\\.notmuch"
+ (to-address . "notmuch@notmuchmail.org")
+ (to-list . "notmuch@notmuchmail.org"))
+ ("l\\.parabola-dev"
+ (to-address . "dev@lists.parabola.nu")
+ (to-list . "dev@lists.parabola.nu")
+ (list-identifier . "\\[Dev\\]"))
+ ("l\\.~bandali\\.public-inbox"
+ (to-address . "~bandali/public-inbox@lists.sr.ht")
+ (to-list . "~bandali/public-inbox@lists.sr.ht"))
+ ("l\\.~sircmpwn\\.free-writers-club"
+ (to-address . "~sircmpwn/free-writers-club@lists.sr.ht")
+ (to-list . "~sircmpwn/free-writers-club@lists.sr.ht"))
+ ("l\\.~sircmpwn\\.srht-admins"
+ (to-address . "~sircmpwn/sr.ht-admins@lists.sr.ht")
+ (to-list . "~sircmpwn/sr.ht-admins@lists.sr.ht"))
+ ("l\\.~sircmpwn\\.srht-announce"
+ (to-address . "~sircmpwn/sr.ht-announce@lists.sr.ht")
+ (to-list . "~sircmpwn/sr.ht-announce@lists.sr.ht"))
+ ("l\\.~sircmpwn\\.srht-dev"
+ (to-address . "~sircmpwn/sr.ht-dev@lists.sr.ht")
+ (to-list . "~sircmpwn/sr.ht-dev@lists.sr.ht"))
+ ("l\\.~sircmpwn\\.srht-discuss"
+ (to-address . "~sircmpwn/sr.ht-discuss@lists.sr.ht")
+ (to-list . "~sircmpwn/sr.ht-discuss@lists.sr.ht"))
+ ("webmasters"
+ (to-address . "webmasters@gnu.org")
+ (to-list . "webmasters@gnu.org"))
+ ("gnu.*"
+ (gcc-self . t))
+ ("l\\."
+ (subscribed . t))
+ ("nnimap\\+uwaterloo:.*"
+ (gcc-self . t)))
+ ;; nnimap-record-commands t
+ gnus-large-newsgroup 50
+ 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-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)))
+
+ ;; (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 "s-m") #'gnus-plugged)
+(global-set-key (kbd "s-M") #'gnus-unplugged)
+(global-set-key (kbd "C-c a m") #'gnus-plugged)
+(global-set-key (kbd "C-c a M") #'gnus-unplugged)
+
+(with-eval-after-load 'gnus-art
+ (csetq
+ 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-lapsed article dates
+ ;; from https://www.emacswiki.org/emacs/GnusFormatting#toc11
+ gnus-article-date-headers '(user-defined)
+ gnus-article-time-format
+ (lambda (time)
+ (let* ((date (format-time-string "%a, %d %b %Y %T %z" time))
+ (local (article-make-date-line date 'local))
+ (combined-lapsed (article-make-date-line date
+ 'combined-lapsed))
+ (lapsed (progn
+ (string-match " (.+" combined-lapsed)
+ (match-string 0 combined-lapsed))))
+ (concat local lapsed))))
+ ;; local key bindings
+ (define-key gnus-article-mode-map (kbd "M-L") #'org-store-link))
+
+(with-eval-after-load 'gnus-sum
+ (csetq gnus-thread-sort-functions '(gnus-thread-sort-by-number
+ gnus-thread-sort-by-subject
+ gnus-thread-sort-by-date))
+ ;; local key bindings
+ (define-key gnus-summary-mode-map (kbd "M-L") #'org-store-link)
+ (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")
+ #'gnus-summary-reply)
+ (define-key b/gnus-summary-prefix-map (kbd "w")
+ #'gnus-summary-wide-reply)
+ (define-key b/gnus-summary-prefix-map (kbd "v")
+ #'gnus-summary-show-raw-article))
+;; hooks
+(add-hook 'gnus-summary-mode-hook #'b/no-mouse-autoselect-window)
+
+(defvar b/sfl-p nil)
+(with-eval-after-load 'gnus-msg
+ (defvar b/shemshak-signature "Amin Bandali
+https://shemshak.org/~bandali")
+ (defvar b/uwaterloo-signature "Amin Bandali, MMath
+https://bndl.org")
+ (defvar b/csc-signature "Amin Bandali (https://bndl.org)
+Systems Committee <syscom@csclub.uwaterloo.ca>
+Computer Science Club of the University of Waterloo")
+ (defvar b/sfl-signature "Amin Bandali
+Free Software Consultant
+Savoir-faire Linux
+GNU Jami: bandali")
+ (csetq
+ gnus-message-replysign t
+ gnus-posting-styles
+ '((".*"
+ (address "bandali@gnu.org"))
+ ("nnimap\\+gnu:l\\..*"
+ (signature nil))
+ ("nnimap\\+gnu:.*"
+ (organization "GNU"))
+ ((header "subject" "ThankCRM")
+ (to "webmasters-comment@gnu.org")
+ (body "")
+ (eval (setq b/message-cite-say-hi nil)))
+ ("nnimap\\+shemshak:.*"
+ (address "amin@shemshak.org")
+ (body "\nBest,\n")
+ (signature b/shemshak-signature)
+ (gcc "nnimap+shemshak:Sent")
+ (eval (setq b/message-cite-say-hi t)))
+ ("nnimap\\+uwaterloo:.*"
+ (address "bandali@uwaterloo.ca")
+ (body "\nBest,\n")
+ (signature b/uwaterloo-signature))
+ ("nnimap\\+uwaterloo:INBOX"
+ (gcc "\"nnimap+uwaterloo:Sent Items\""))
+ ("nnimap\\+csc:.*"
+ (address "bandali@csclub.uwaterloo.ca")
+ (signature b/csc-signature)
+ (gcc "nnimap+csc:Sent"))
+ ("nnimap\\+sfl:.*"
+ (address "amin.bandali@savoirfairelinux.com")
+ (signature b/sfl-signature)
+ (gcc "nnimap+sfl:Sent")
+ (eval (setq-local b/sfl-p t))))))
+;; 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
+ (csetq gnus-topic-line-format "%i[ %A: %(%{%n%}%) ]%v\n"))
+
+(with-eval-after-load 'gnus-agent
+ (csetq gnus-agent-synchronize-flags 'ask))
+
+(with-eval-after-load 'gnus-group
+ (csetq gnus-permanently-visible-groups "\\(:INBOX$\\|:gnu$\\)"))
+
+;; problematic with ebdb's popup, *EBDB-Gnus*
+;; (with-eval-after-load 'gnus-win
+;; (csetq gnus-use-full-window nil))
+
+(with-eval-after-load 'gnus-dired
+ (add-hook 'dired-mode-hook 'gnus-dired-mode))
+
+;; (with-eval-after-load 'gnus-utils
+;; (csetq gnus-completing-read-function 'gnus-ido-completing-read))
+
+(with-eval-after-load 'mm-decode
+ (csetq mm-discouraged-alternatives '("text/html" "text/richtext")
+ mm-decrypt-option 'known
+ mm-verify-option 'known))
+
+(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")
+ (csetq mm-uu-diff-groups-regexp ".")))
+
+(with-eval-after-load 'mml-sec
+ (csetq mml-secure-openpgp-encrypt-to-self t
+ mml-secure-openpgp-sign-with-sender t))
+
+;; (require 'gnus-article-treat-patch)
+;; ;; note: be sure to customize faces with `:foreground "white"' when
+;; ;; using a theme with a white/light background :)
+;; (setq ft/gnus-article-patch-conditions
+;; '("^@@ -[0-9]+,[0-9]+ \\+[0-9]+,[0-9]+ @@"))
+
+(provide 'bandali-gnus)
+;;; bandali-gnus.el ends here
diff --git a/.emacs.d/lisp/bandali-ibuffer.el b/.emacs.d/lisp/bandali-ibuffer.el
new file mode 100644
index 0000000..7cd4331
--- /dev/null
+++ b/.emacs.d/lisp/bandali-ibuffer.el
@@ -0,0 +1,110 @@
+;;; bandali-ibuffer.el --- bandali's Ibuffer setup -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2018-2020 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:
+
+(csetq
+ 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-ivy.el b/.emacs.d/lisp/bandali-ivy.el
new file mode 100644
index 0000000..973323a
--- /dev/null
+++ b/.emacs.d/lisp/bandali-ivy.el
@@ -0,0 +1,74 @@
+;;; bandali-ivy.el --- bandali's Ivy setup -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2018-2020 Amin Bandali
+
+;; Author: Amin Bandali <bandali@gnu.org>
+;; Keywords: matching
+
+;; 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 configuration for Ivy and family.
+
+;;; Code:
+
+(run-with-idle-timer 0.3 nil #'require 'ivy)
+(with-eval-after-load 'ivy
+ ;; ivy
+ (csetq ivy-wrap t
+ ;; ivy-height 14
+ ivy-use-virtual-buffers t
+ ivy-virtual-abbreviate 'abbreviate
+ ivy-count-format "%d/%d ")
+
+ (defvar b/ivy-ignore-buffer-modes
+ '(;; dired-mode
+ ;; magit-mode
+ erc-mode))
+ (defun b/ivy-ignore-buffer-p (str)
+ "Return non-nil if str names a buffer with a major mode
+derived from one of `b/ivy-ignore-buffer-modes'.
+
+This function is intended for use with `ivy-ignore-buffers'."
+ (let* ((buf (get-buffer str))
+ (mode (and buf (buffer-local-value 'major-mode buf))))
+ (and mode
+ (apply #'provided-mode-derived-p mode b/ivy-ignore-buffer-modes))))
+ (add-to-list 'ivy-ignore-buffers #'b/ivy-ignore-buffer-p)
+
+ (define-key ivy-minibuffer-map [escape] #'keyboard-escape-quit)
+ (define-key ivy-minibuffer-map [S-up]
+ #'ivy-previous-history-element)
+ (define-key ivy-minibuffer-map [S-down]
+ #'ivy-next-history-element)
+ (define-key ivy-minibuffer-map (kbd "DEL")
+ #'ivy-backward-delete-char)
+
+ (ivy-mode 1)
+
+ ;; swiper
+ (require 'swiper)
+ (global-set-key (kbd "C-S-s") #'swiper-isearch)
+
+ ;; counsel
+ (require 'counsel)
+ (counsel-mode 1)
+ (defalias 'locate #'counsel-locate)
+ (global-set-key (kbd "C-c f r") #'counsel-recentf)
+ (define-key minibuffer-local-map
+ (kbd "C-r") #'counsel-minibuffer-history))
+
+(provide 'bandali-ivy)
+;;; bandali-ivy.el ends here
diff --git a/.emacs.d/lisp/bandali-magit.el b/.emacs.d/lisp/bandali-magit.el
new file mode 100644
index 0000000..7432a11
--- /dev/null
+++ b/.emacs.d/lisp/bandali-magit.el
@@ -0,0 +1,70 @@
+;;; bandali-magit.el --- bandali's magit configuration -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2018-2020 Amin Bandali
+
+;; Author: Amin Bandali <bandali@gnu.org>
+;; Keywords: vc
+
+;; 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:
+
+;; It's Magit!
+
+;;; Code:
+
+(csetq transient-history-file (b/var "transient/history.el")
+ transient-levels-file (b/etc "transient/levels.el")
+ transient-values-file (b/etc "transient/values.el"))
+(with-eval-after-load 'magit
+ (declare-function magit-add-section-hook "magit-section"
+ (hook function &optional at append local))
+ (magit-add-section-hook 'magit-status-sections-hook
+ 'magit-insert-modules
+ 'magit-insert-stashes
+ 'append)
+ ;; (magit-add-section-hook 'magit-status-sections-hook
+ ;; 'magit-insert-ignored-files
+ ;; 'magit-insert-untracked-files
+ ;; 'append)
+ (declare-function magit-display-buffer-fullframe-status-v1
+ "magit-mode" (buffer))
+ (csetq
+ magit-diff-refine-hunk t
+ magit-repository-directories '(("~/.emacs.d/" . 0)
+ ("~/src/git/" . 2))
+ ;; magit-completing-read-function 'magit-ido-completing-read
+ magit-display-buffer-function
+ #'magit-display-buffer-fullframe-status-v1)
+ (nconc magit-section-initial-visibility-alist
+ '(([unpulled status] . show)
+ ([unpushed status] . show)))
+ (custom-set-faces '(magit-diff-file-heading ((t (:weight normal)))))
+
+ (with-eval-after-load 'magit-extras
+ (csetq
+ magit-pop-revision-stack-format
+ (pcase-let ((`(,pt ,_eob ,index-regexp)
+ (default-value 'magit-pop-revision-stack-format)))
+ `(,pt "[%N: %h]: %ci\n %s
+ https://git.savannah.gnu.org/cgit/emacs.git/commit/?id=%H"
+ ,index-regexp)))))
+;; global key bindings
+(global-set-key (kbd "C-x g") #'magit-status)
+(global-set-key (kbd "C-c g b") #'magit-blame-addition)
+(global-set-key (kbd "C-c g l") #'magit-log-buffer-file)
+(global-set-key (kbd "C-c g y") #'magit-pop-revision-stack)
+
+(provide 'bandali-magit)
+;;; bandali-magit.el ends here
diff --git a/.emacs.d/lisp/bandali-message.el b/.emacs.d/lisp/bandali-message.el
new file mode 100644
index 0000000..c13bffc
--- /dev/null
+++ b/.emacs.d/lisp/bandali-message.el
@@ -0,0 +1,138 @@
+;;; bandali-message.el --- bandali's message.el setup -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2018-2020 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
+ (if b/message-cite-say-hi
+ (concat "Hi %F,\n\n" b/message-cite-style-format)
+ b/message-cite-style-format)))
+ "Citation style based on Mozilla Thunderbird's. Use with message-cite-style.")
+ (csetq
+ message-elide-ellipsis "[...]\n"
+ ;; message-cite-style 'message-cite-style-bandali
+ message-citation-line-format "%N writes:\n"
+ message-citation-line-function 'message-insert-formatted-citation-line
+ message-kill-buffer-on-exit t
+ message-send-mail-function 'message-send-mail-with-sendmail
+ message-sendmail-envelope-from 'header
+ message-subscribed-address-functions
+ '(gnus-find-subscribed-addresses)
+ message-dont-reply-to-names
+ "\\(\\(amin@shemshak\\.org\\)\\|\\(.*@aminb\\.org\\)\\|\\(\\(bandali\\|mab\\|aminb?\\)@gnu\\.org\\)\\|bandali@fsf\\.org\\|\\(a?bandali@\\(csclub\\.\\)?uwaterloo\\.ca\\)\\|amin\\.bandali@savoirfairelinux\\.com\\)")
+ ;; (require 'company-ebdb)
+ ;; (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))))
+
+ ;; footnote
+ (with-eval-after-load 'footnote
+ ;; (csetq footnote-start-tag ""
+ ;; footnote-end-tag ""
+ ;; footnote-style 'unicode)
+ (when (featurep 'which-key)
+ (which-key-add-major-mode-key-based-replacements 'message-mode
+ "C-c f n" "footnote")))
+
+ ;; orgalist
+ (add-hook 'message-mode-hook
+ (lambda ()
+ ;; work around incompatibility between
+ ;; orgalist and yasnippet
+ (yas-minor-mode -1)
+ (orgalist-mode 1)
+ (yas-minor-mode 1)))
+
+ ;; local key bindings
+ (defvar b/footnote-prefix-map)
+ (define-prefix-command 'b/footnote-prefix-map)
+ (define-key message-mode-map (kbd "C-c f n")
+ 'b/footnote-prefix-map)
+ (define-key b/footnote-prefix-map (kbd "a")
+ #'footnote-add-footnote)
+ (define-key b/footnote-prefix-map (kbd "b")
+ #'footnote-back-to-message)
+ (define-key b/footnote-prefix-map (kbd "c")
+ #'footnote-cycle-style)
+ (define-key b/footnote-prefix-map (kbd "d")
+ #'footnote-delete-footnote)
+ (define-key b/footnote-prefix-map (kbd "g")
+ #'footnote-goto-footnote)
+ (define-key b/footnote-prefix-map (kbd "r")
+ #'footnote-renumber-footnotes)
+ (define-key b/footnote-prefix-map (kbd "s")
+ #'footnote-set-style))
+;; hooks
+;; (add-hook 'message-setup-hook #'mml-secure-message-sign-pgpmime)
+(add-hook 'message-mode-hook #'flyspell-mode)
+(add-hook 'message-mode-hook
+ (lambda ()
+ ;; (setq-local fill-column b/fill-column
+ ;; message-fill-column b/fill-column)
+ (eval-when-compile (defvar company-idle-delay))
+ (make-local-variable 'company-idle-delay)
+ (setq company-idle-delay 0.2)))
+
+;; (with-eval-after-load 'message-x
+;; (csetq
+;; message-x-completion-alist
+;; '(("\\([rR]esent-\\|[rR]eply-\\)?[tT]o:\\|[bB]?[cC][cC]:"
+;; . gnus-harvest-find-address)
+;; ((if
+;; (boundp
+;; (quote message-newgroups-header-regexp))
+;; message-newgroups-header-regexp message-newsgroups-header-regexp)
+;; . message-expand-group))))
+
+;; (require 'gnus-harvest)
+;; (if (featurep 'message-x)
+;; (gnus-harvest-install 'message-x)
+;; (gnus-harvest-install))
+
+(provide 'bandali-message)
+;;; bandali-message.el ends here
diff --git a/.emacs.d/lisp/bandali-org.el b/.emacs.d/lisp/bandali-org.el
new file mode 100644
index 0000000..38a4a5a
--- /dev/null
+++ b/.emacs.d/lisp/bandali-org.el
@@ -0,0 +1,119 @@
+;;; bandali-org.el --- bandali's Org setup -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2018-2020 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:
+
+(with-eval-after-load 'org
+ (csetq 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-block-begin-line
+ ((t (:foreground "#5a5b5a" :background "#1d1f21"))))
+ '(org-block ((t (:background "#1d1f21"))))
+ '(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
+ (add-hook 'org-mode-hook #'org-indent-mode)
+ (add-hook 'org-mode-hook #'auto-fill-mode)
+ (add-hook 'org-mode-hook #'flyspell-mode)
+
+ ;; 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
+ (csetq 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-theme.el b/.emacs.d/lisp/bandali-theme.el
new file mode 100644
index 0000000..13929cb
--- /dev/null
+++ b/.emacs.d/lisp/bandali-theme.el
@@ -0,0 +1,87 @@
+;;; 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:
+
+(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)
+ (when (featurep 'smart-mode-line)
+ (let ((sml/no-confirm-load-theme t))
+ (sml/apply-theme 'respectful)))
+ (font-lock-remove-keywords
+ 'org-mode b/org-mode-font-lock-keywords)
+ (when (featurep 'erc-hl-nicks)
+ (erc-hl-nicks-reset-face-table))
+ (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)
+ (when (featurep 'smart-mode-line)
+ (let ((sml/no-confirm-load-theme t))
+ (sml/apply-theme 'dark)))
+ (font-lock-add-keywords
+ 'org-mode b/org-mode-font-lock-keywords t)
+ (when (featurep 'erc-hl-nicks)
+ (erc-hl-nicks-reset-face-table))
+ (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
diff --git a/.emacs.d/lisp/boxquote b/.emacs.d/lisp/boxquote
new file mode 160000
+Subproject 7e47e0e2853bc1215739b2e28f260e9eed93b2c
diff --git a/.emacs.d/lisp/gnus-article-treat-patch.el b/.emacs.d/lisp/gnus-article-treat-patch.el
new file mode 100644
index 0000000..f2f5c21
--- /dev/null
+++ b/.emacs.d/lisp/gnus-article-treat-patch.el
@@ -0,0 +1,465 @@
+;;; gnus-article-treat-patch.el --- Highlight inline patches in articles
+;;
+;; Copyright © 2011-2019 Frank Terbeck <ft@bewatermyfriend.org>
+;;
+;; This file is not part of GNU Emacs.
+;;
+;; This file 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 Soft-
+;; ware Foundation; either version 3, or (at your option) any later version.
+;;
+;; This file 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 file. If not, see <http://www.gnu.org/licenses/>.
+;;
+;;
+;;; Commentary:
+;;
+;; Gnus addon to beautify patch-like emails. This uses a "ft/" prefix for
+;; everything to avoid clashing with anything upstream. That prefix can be
+;; savely s,ft/,,'d - if this is to be submitted to the gnus developers.
+
+(require 'diff-mode)
+
+(add-hook 'gnus-part-display-hook 'ft/gnus-article-treat-patch)
+
+;; Colour handling and faces
+(defun ft/gnus-colour-line (use-face)
+ "Set text overlay to `use-face' for the current line."
+ (overlay-put (make-overlay (point-at-bol) (point-at-eol)) 'face use-face))
+
+(make-face 'ft/gnus-three-dashes)
+(set-face-attribute 'ft/gnus-three-dashes nil :foreground "brightblue")
+(make-face 'ft/gnus-scissors)
+(set-face-attribute 'ft/gnus-scissors nil :foreground "brown")
+(make-face 'ft/gnus-diff-index)
+(set-face-attribute 'ft/gnus-diff-index nil :foreground "brightmagenta")
+(make-face 'ft/gnus-diff-hunk)
+(set-face-attribute 'ft/gnus-diff-hunk nil :foreground "brightblue")
+(make-face 'ft/gnus-diff-equals)
+(set-face-attribute 'ft/gnus-diff-equals nil :foreground "brightmagenta")
+(make-face 'ft/gnus-commit-message)
+(set-face-attribute 'ft/gnus-commit-message nil :foreground "white")
+(make-face 'ft/gnus-diff-stat-file)
+(set-face-attribute 'ft/gnus-diff-stat-file nil :foreground "yellow")
+(make-face 'ft/gnus-diff-stat-bar)
+(set-face-attribute 'ft/gnus-diff-stat-bar nil :foreground "magenta")
+(make-face 'ft/gnus-diff-stat-num)
+(set-face-attribute 'ft/gnus-diff-stat-num nil :foreground "white")
+(make-face 'ft/gnus-diff-misc)
+(set-face-attribute 'ft/gnus-diff-misc nil :foreground "magenta")
+(make-face 'ft/gnus-commit-comment)
+(set-face-attribute 'ft/gnus-commit-comment nil :inherit 'default)
+(make-face 'ft/gnus-diff-header)
+(set-face-attribute 'ft/gnus-diff-header nil :inherit 'diff-header)
+(make-face 'ft/gnus-diff-add)
+(set-face-attribute 'ft/gnus-diff-add nil :inherit 'diff-added)
+(make-face 'ft/gnus-diff-remove)
+(set-face-attribute 'ft/gnus-diff-remove nil :inherit 'diff-removed)
+
+;; Pseudo-headers
+(defvar ft/gnus-article-patch-pseudo-headers
+ '(("^Acked-by: " 'gnus-header-name 'gnus-header-from)
+ ("^C\\(c\\|C\\): " 'gnus-header-name 'gnus-header-from)
+ ("^From: " 'gnus-header-name 'gnus-header-from)
+ ("^Link: " 'gnus-header-name 'gnus-header-from)
+ ("^Reported-by: " 'gnus-header-name 'gnus-header-from)
+ ("^Reviewed-by: " 'gnus-header-name 'gnus-header-from)
+ ("^Signed-off-by: " 'gnus-header-name 'gnus-header-from)
+ ("^Subject: " 'gnus-header-name 'gnus-header-from)
+ ("^Suggested-by: " 'gnus-header-name 'gnus-header-from))
+ "List of lists of regular expressions (with two face names)
+which are used to determine the highlighting of pseudo headers in
+the commit message (such as \"Signed-off-by:\").
+
+The first face if used to highlight the header's name; the second
+highlights the header's value.")
+
+(defun ft/gnus-pseudo-header-get (line)
+ "Check if `line' is a pseudo header, and if so return its enty in
+`ft/gnus-article-patch-pseudo-headers'."
+ (catch 'done
+ (dolist (entry ft/gnus-article-patch-pseudo-headers)
+ (let ((regex (car entry)))
+ (if (string-match regex line)
+ (throw 'done entry))))
+ (throw 'done '())))
+
+(defun ft/gnus-pseudo-header-p (line)
+ "Returns `t' if `line' looks like a pseudo-header; `nil' otherwise.
+
+`ft/gnus-article-patch-pseudo-headers' is used to determine what a pseudo-header
+is."
+ (if (eq (ft/gnus-pseudo-header-get line) '()) nil t))
+
+(defun ft/gnus-pseudo-header-colour (line)
+ "Colourise a pseudo-header line."
+ (let ((data (ft/gnus-pseudo-header-get line)))
+ (if (eq data '())
+ nil
+ (let* ((s (point-at-bol))
+ (e (point-at-eol))
+ (colon (re-search-forward ":"))
+ (value (+ colon 1)))
+ (overlay-put (make-overlay s colon) 'face (nth 1 data))
+ (overlay-put (make-overlay value e) 'face (nth 2 data))))))
+
+;; diff-stat
+(defun ft/gnus-diff-stat-colour (line)
+ "Colourise a diff-stat line."
+ (let ((s (point-at-bol))
+ (e (point-at-eol))
+ (bar (- (re-search-forward "|") 1))
+ (num (- (re-search-forward "[0-9]") 1))
+ (pm (- (re-search-forward "\\([+-]\\|$\\)") 1)))
+
+ (overlay-put (make-overlay s (- bar 1)) 'face 'ft/gnus-diff-stat-file)
+ (overlay-put (make-overlay bar (+ bar 1)) 'face 'ft/gnus-diff-stat-bar)
+ (overlay-put (make-overlay num pm) 'face 'ft/gnus-diff-stat-num)
+
+ (goto-char pm)
+ (let* ((plus (looking-at "\\+"))
+ (regex (if plus "-+" "\\++"))
+ (brk (if plus
+ (re-search-forward "-" e t)
+ (re-search-forward "\\+" e t)))
+ (first-face (if plus 'ft/gnus-diff-add 'ft/gnus-diff-remove))
+ (second-face (if plus 'ft/gnus-diff-remove 'ft/gnus-diff-add)))
+
+ (if (eq brk nil)
+ (overlay-put (make-overlay pm e) 'face first-face)
+ (progn
+ (setq brk (- brk 1))
+ (overlay-put (make-overlay pm brk) 'face first-face)
+ (overlay-put (make-overlay brk e) 'face second-face))))))
+
+(defun ft/gnus-diff-stat-summary-colour (line)
+ "Colourise a diff-stat summary-line."
+ (let* ((e (point-at-eol))
+ (plus (- (re-search-forward "(\\+)" e t) 2))
+ (minus (- (re-search-forward "(-)" e t) 2)))
+ (overlay-put (make-overlay plus (+ plus 1)) 'face 'ft/gnus-diff-add)
+ (overlay-put (make-overlay minus (+ minus 1)) 'face 'ft/gnus-diff-remove)))
+
+(defun ft/gnus-diff-stat-line-p (line)
+ "Return `t' if `line' is a diff-stat line; `nil' otherwise."
+ (string-match "^ *[^ ]+[^|]+| +[0-9]+\\( *\\| +[+-]+\\)$" line))
+
+(defun ft/gnus-diff-stat-summary-p (line)
+ "Return `t' if `line' is a diff-stat summary-line; `nil' otherwise."
+ (string-match "^ *[0-9]+ file\\(s\\|\\) changed,.*insertion.*deletion" line))
+
+;; unified-diffs
+(defun ft/gnus-diff-header-p (line)
+ "Returns `t' if `line' looks like a diff-header; `nil' otherwise."
+ (cond
+ ((string-match "^\\(\\+\\+\\+\\|---\\) " line) t)
+ ((string-match "^diff -" line) t)
+ (t nil)))
+
+(defun ft/gnus-index-line-p (line)
+ "Returns `t' if `line' looks like an index-line; `nil' otherwise."
+ (cond
+ ((string-match "^Index: " line) t)
+ ((string-match "^index [0-9a-f]+\\.\\.[0-9a-f]+" line) t)
+ (t nil)))
+
+(defun ft/gnus-hunk-line-p (line)
+ "Returns `t' if `line' looks like a hunk-line; `nil' otherwise."
+ (string-match "^@@ -[0-9]+,[0-9]+ \\+[0-9]+,[0-9]+ @@" line))
+
+(defun ft/gnus-atp-misc-diff-p (line)
+ "Return `t' if `line' is a \"misc line\" with respect to patch
+treatment; `nil' otherwise."
+ (let ((patterns '("^new file"
+ "^RCS file:"
+ "^retrieving revision ")))
+ (catch 'done
+ (dolist (regex patterns)
+ (if (string-match regex line)
+ (throw 'done t)))
+ (throw 'done nil))))
+
+(defun ft/gnus-atp-looks-like-diff (line)
+ "Return `t' if `line' looks remotely like a line from a unified
+diff; `nil' otherwise."
+ (or (ft/gnus-index-line-p line)
+ (ft/gnus-diff-header-p line)
+ (ft/gnus-hunk-line-p line)))
+
+;; miscellaneous line handlers
+(defun ft/gnus-scissors-line-p (line)
+ "Returns `t' if `line' looks like a scissors-line; `nil' otherwise."
+ (cond
+ ((string-match "^\\( *--* *\\(8<\\|>8\\)\\)+ *-* *$" line) t)
+ (t nil)))
+
+;; Patch mail detection
+(defvar ft/gnus-article-patch-conditions nil
+ "List of conditions that will enable patch treatment. String
+values will be matched as regular expressions within the currently
+processed part. Non-string value are supposed to be code fragments,
+which determine whether or not to do treatment: The code needs to
+return `t' if treatment is wanted.")
+
+(defun ft/gnus-part-want-patch-treatment ()
+ "Run through `ft/gnus-article-patch-conditions' to determine whether
+patch treatment is wanted or not. Return `t' or `nil' accordingly."
+ (catch 'done
+ (dolist (entry ft/gnus-article-patch-conditions)
+ (cond
+ ((stringp entry)
+ (if (re-search-forward entry nil t)
+ (throw 'done t)))
+ (t
+ (if (eval entry)
+ (throw 'done t)))))
+ (throw 'done nil)))
+
+
+;; The actual article treatment code
+(defun ft/gnus-article-treat-patch-state-machine ()
+ "Implement the state machine which colourises a part of an article
+if it looks patch-like.
+
+The state machine works like this:
+
+ 0a. The machinery starts at the first line of the article's body. Not
+ the header lines. We don't care about header lines at all.
+
+ 0b. The whole thing works line by line. It doesn't do any forward or
+ backward looks.
+
+ 1. Initially, we assume, that what we'll see first is part of the
+ patch's commit-message. Hence this first initial state is
+ \"commit-message\". There are several ways out of this state:
+
+ a) a scissors line is found (see 2.)
+ b) a pseudo-header line is found (see 3.)
+ c) a three-dashes line is found (see 4.)
+ d) something that looks like the start of a unified diff is
+ found (see 7.)
+
+ 2. A scissors line is something that looks like a pair of scissors running
+ through a piece of paper. Like this:
+
+ ------ 8< ----- 8< ------
+
+ or this:
+
+ ------------>8-----------
+
+ The function `ft/gnus-scissors-line-p' decides whether a line is a
+ scissors line or not. After a scissors line was treated, the machine
+ will switch back to the \"commit-mesage\" state.
+
+ 3. This is very similar to a scissors line. It'll just return to the old
+ state after its being done. The `ft/gnus-pseudo-header-p' function
+ decides if a line is a pseudo header. The line will be appropriately
+ coloured.
+
+ 4. A three-dashes line is a line that looks like this: \"---\". It's the
+ definite end of the \"commit-message\" state. The three dashes line is
+ coloured and the state switches to \"commit-comment\". (See 5.)
+
+ 5. Nothing in \"commit-comment\" will appear in the generated commit (this
+ is git-am specific semantics, but it's useful, so...). It may contain
+ things like random comments or - promimently - a diff stat. (See 6.)
+
+ 6. A diff stat provides statistics about how much changed in a given commit
+ by files and by whole commit (in a summary line). Two functions
+ `ft/gnus-diff-stat-line-p' and `ft/gnus-diff-stat-summary-p' decide if a
+ line belongs to a diff stat. It's coloured appropriately and the state
+ switches back to \"commit-comment\".
+
+ 7. There is a function `ft/gnus-unified-diff-line-p' which will cause the
+ state to switch to \"unified-diff\" state from either \"commit-message\"
+ or \"commit-comment\". In this mode there can be a set of lines types:
+
+ a) diff-header lines (`ft/gnus-diff-header-p')
+ b) index lines (`ft/gnus-index-line-p')
+ c) hunk lines (`ft/gnus-hunk-line-p')
+ d) equals line (\"^==*$\")
+ e) context lines (\"^ \")
+ f) add lines (\"^\\+\")
+ g) remove lines (\"^-\")
+ h) empty lines (\"^$\")
+
+ This state runs until the end of the part."
+ (catch 'ft/gnus-atp-done
+ (let ((state 'commit-message)
+ line do-not-move)
+
+ (while t
+ ;; Put the current line into an easy-to-handle string variable.
+ (setq line
+ (buffer-substring-no-properties (point-at-bol) (point-at-eol)))
+ (setq do-not-move nil)
+
+ ;; Switched state machine. The "real" states are `commit-message',
+ ;; `commit-comment' and `unified-diff'. The other "states" are only
+ ;; single-line colourisations that return to their respective parent-
+ ;; state. Each state may (throw 'ft/gnus-atp-done) to leave the state-
+ ;; machine immediately.
+ (setq state
+ (cond
+
+ ((eq state 'commit-message)
+ (cond
+ ((ft/gnus-scissors-line-p line)
+ (ft/gnus-colour-line 'ft/gnus-scissors)
+ 'commit-message)
+ ((ft/gnus-pseudo-header-p line)
+ (ft/gnus-pseudo-header-colour line)
+ 'commit-message)
+ ((string= line "---")
+ (ft/gnus-colour-line 'ft/gnus-three-dashes)
+ 'commit-comment)
+ ((ft/gnus-atp-looks-like-diff line)
+ (setq do-not-move t)
+ 'unified-diff)
+ (t
+ (ft/gnus-colour-line 'ft/gnus-commit-message)
+ 'commit-message)))
+
+ ((eq state 'commit-comment)
+ (cond
+ ((ft/gnus-diff-stat-line-p line)
+ (ft/gnus-diff-stat-colour line)
+ 'commit-comment)
+ ((ft/gnus-diff-stat-summary-p line)
+ (ft/gnus-diff-stat-summary-colour line)
+ 'commit-comment)
+ ((ft/gnus-atp-looks-like-diff line)
+ (setq do-not-move t)
+ 'unified-diff)
+ (t
+ (ft/gnus-colour-line 'ft/gnus-commit-comment)
+ 'commit-comment)))
+
+ ((eq state 'unified-diff)
+ (cond
+ ((ft/gnus-diff-header-p line)
+ (ft/gnus-colour-line 'ft/gnus-diff-header)
+ 'unified-diff)
+ ((ft/gnus-index-line-p line)
+ (ft/gnus-colour-line 'ft/gnus-diff-index)
+ 'unified-diff)
+ ((ft/gnus-hunk-line-p line)
+ (ft/gnus-colour-line 'ft/gnus-diff-hunk)
+ 'unified-diff)
+ ((string-match "^==*$" line)
+ (ft/gnus-colour-line 'ft/gnus-diff-equals)
+ 'unified-diff)
+ ((string-match "^$" line)
+ 'unified-diff)
+ ((string-match "^ " line)
+ (ft/gnus-colour-line 'ft/gnus-diff-context)
+ 'unified-diff)
+ ((ft/gnus-atp-misc-diff-p line)
+ (ft/gnus-colour-line 'ft/gnus-diff-misc)
+ 'unified-diff)
+ ((string-match "^\\+" line)
+ (ft/gnus-colour-line 'ft/gnus-diff-add)
+ 'unified-diff)
+ ((string-match "^-" line)
+ (ft/gnus-colour-line 'ft/gnus-diff-remove)
+ 'unified-diff)
+ (t 'unified-diff)))))
+
+ (if (not do-not-move)
+ (if (> (forward-line) 0)
+ (throw 'ft/gnus-atp-done t)))))))
+
+(defun ft/gnus-article-treat-patch ()
+ "Highlight mail parts, that look like patches (well, usually
+they *are* patches - or possibly, when you take git's format-patch output,
+entire commit exports - including comments). This treatment assumes the
+use of unified diffs. Here is how it works:
+
+The most fancy type of patch mails look like this:
+
+ From: ...
+ Subject: ...
+ Other-Headers: ...
+
+ Body text, which can be reflecting the commit message but may
+ optionally be followed by a so called scissors line, which
+ looks like this (in case of a scissors line, the text above is
+ not part of the commit message):
+
+ -------8<----------
+
+ If there really was a scissors line, then it's usually
+ followed by repeated mail-headers. Which do not *have* to
+ be the same as the one from the sender.
+
+ From: ...
+ Subject: ...
+
+ More text. Usually part of the commit message. Likely
+ multiline. What follows may be an optional diffstat. If
+ there is one, it's usually preceded by a line that contains
+ only three dashes and nothing more. Before the diffstat,
+ however, there may be a set of pseudo headers again, like
+ these:
+
+ Acked-by: Mike Dev <md@other.tld>
+ Signed-off-by: Joe D. User <jdu@example.com>
+
+ ---
+ ChangeLog | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletions(-)
+
+ Now, there is again room for optional text, which is not
+ part of the actual commit message. May be multiline. Actually,
+ anything between the three-dashes line and the diff content
+ is ignored as far as the commit message goes.
+
+ Now for the actual diff part. I want this to work for as
+ many unified diff formats as possible. What comes to mind
+ is the format used by git and the format used by cvs and
+ quilt.
+
+ CVS style looks like this:
+
+ Index: foo/bar.c
+ ============================================================
+ --- boo.orig/foo/bar.c 2010-02-24 ....
+ +++ boo/foo/bar.c 2010-02-28 ....
+ @@ -1823,7 +1823,7 @@
+ <hunk>
+
+ There may be multiple hunks. Each file gets an \"Index:\" and
+ equals line. Now the git format looks like this:
+
+ diff --git a/ChangeLog b/ChangeLog
+ index 6ffbc8c..36e5c17 100644
+ --- a/ChangeLog
+ +++ b/ChangeLog
+ @@ -3,6 +3,9 @@
+ <hunk>
+
+ Again, there may be multiple hunks.
+
+ When all hunks and all files are done, there may be additional
+ text below the actual text.
+
+And that's it.
+
+You may define the look of several things: pseudo headers, scissor
+lines, three-dashes-line, equals lines, diffstat lines, diffstat
+summary. Then there is added lines, removed lines, context lines,
+diff-header lines and diff-file-header lines, for which we are
+borrowing the highlighting faces for from `diff-mode'."
+ (if (ft/gnus-part-want-patch-treatment)
+ (save-excursion
+ (progn
+ (let ((inhibit-read-only t))
+ (goto-char (point-min))
+ (ft/gnus-article-treat-patch-state-machine))))))
+
+(provide 'gnus-article-treat-patch)
diff --git a/.emacs.d/lisp/hl-todo b/.emacs.d/lisp/hl-todo
new file mode 160000
+Subproject 0598b98f63b623c1778cbd2e2f60b774b7a311b
diff --git a/.emacs.d/lisp/page-break-lines b/.emacs.d/lisp/page-break-lines
new file mode 160000
+Subproject f8c4cd7fc67638ae4113551dcffdf87fcd252d9
diff --git a/.emacs.d/lisp/s b/.emacs.d/lisp/s
new file mode 160000
+Subproject 43ba8b563bee3426cead0e6d4ddc09398e1a349
diff --git a/.emacs.d/lisp/scpaste b/.emacs.d/lisp/scpaste
new file mode 160000
+Subproject cd4fa0aafecd839736e0b6cba68b4fc4d704547