summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Shumaker <lukeshu@datawire.io>2022-11-18 18:36:53 -0700
committerLuke Shumaker <lukeshu@datawire.io>2022-11-18 18:36:53 -0700
commit9a62b4a64933f116b08e9e3cb06e013319610e4c (patch)
tree27bb1b131d5a0d35d34fa31e73f72b2446576dc8
parent9adc8a2aeaf034f5172b32c9bd000c686465ab21 (diff)
stuff
-rw-r--r--.config/.gitignore6
-rw-r--r--.config/emacs/custom.el63
-rw-r--r--.config/emacs/early-init.el5
-rw-r--r--.config/emacs/init.el200
m---------.config/emacs/use-package0
-rw-r--r--.config/emacs/wl.el9
-rw-r--r--.config/git/config33
-rw-r--r--.config/git/ignore2
-rw-r--r--.config/maildirproc/default.rc491
-rw-r--r--.config/ssh/config5
l---------.config/systemd/user/X11@.target.wants/fix-dpi@.service1
l---------.config/systemd/user/default.target.wants/kbfs.service1
l---------.config/systemd/user/default.target.wants/keybase.service1
l---------.config/systemd/user/default.target.wants/mail.target1
-rw-r--r--.config/systemd/user/dunst@.service3
-rw-r--r--.config/systemd/user/element-desktop@.service11
-rw-r--r--.config/systemd/user/emacs.service.d/shell.conf2
-rw-r--r--.config/systemd/user/keybase-gui@.service1
l---------.config/systemd/user/keybase-gui@.service.d/00-base.conf1
-rw-r--r--.config/systemd/user/keybase-gui@.service.d/01-override.conf9
-rw-r--r--.config/systemd/user/rbar@.service3
-rw-r--r--.config/systemd/user/redshift@.service13
-rw-r--r--.config/systemd/user/signal-desktop@.service11
l---------.config/systemd/user/sockets.target.wants/gnome-keyring-daemon.socket1
l---------.config/systemd/user/sockets.target.wants/gpg-agent-ssh.socket1
l---------.config/systemd/user/sockets.target.wants/pulseaudio.socket1
-rw-r--r--.config/systemd/user/wmii@.service3
l---------.config/systemd/user/wmii@.service.wants/element-desktop@.service1
l---------.config/systemd/user/wmii@.service.wants/keybase-gui@.service1
l---------.config/systemd/user/wmii@.service.wants/rbar@98_wifi.service1
l---------.config/systemd/user/wmii@.service.wants/signal-desktop@.service1
l---------.config/systemd/user/wmii@.service.wants/zoom@.service1
-rw-r--r--.config/systemd/user/wmii@.socket3
-rw-r--r--.config/systemd/user/wmiirc@.service4
-rw-r--r--.config/systemd/user/zoom@.service10
-rw-r--r--.config/wmii-hg/config.sh2
-rw-r--r--.config/wmii-hg/rules2
-rw-r--r--.config/wmii-hg/theme-abyss28
-rw-r--r--.config/wmii-hg/theme-emacs16
-rw-r--r--.config/wmii-hg/theme-emacs.el43
-rw-r--r--.config/wmii-hg/theme-solarized17
-rw-r--r--.config/wmii-hg/theme-solarized-dark12
-rw-r--r--.config/wmii-hg/theme-tango10
-rw-r--r--.config/wmii-hg/theme-tango-dark11
-rwxr-xr-x.local/bin/git-fetch-pr42
-rwxr-xr-x.local/bin/git-prune-merged-branches6
-rwxr-xr-x.local/bin/git-prune-pushed-branches6
-rw-r--r--.local/bin/unzlib.go34
48 files changed, 919 insertions, 210 deletions
diff --git a/.config/.gitignore b/.config/.gitignore
index fe11c55..895bae7 100644
--- a/.config/.gitignore
+++ b/.config/.gitignore
@@ -22,3 +22,9 @@
/transmission/
/gcloud/logs/
+
+# Electron apps tend to dump all kinds of crap
+/Signal/
+/Element/
+/Keybase/
+/Slack/
diff --git a/.config/emacs/custom.el b/.config/emacs/custom.el
index ef8cdbe..6f7fa36 100644
--- a/.config/emacs/custom.el
+++ b/.config/emacs/custom.el
@@ -3,43 +3,62 @@
;; If you edit it by hand, you could mess it up, so be careful.
;; Your init file should contain only one such instance.
;; If there is more than one, they won't work right.
+ '(ansi-color-faces-vector
+ [default default default italic underline success warning error])
+ '(auth-source-save-behavior nil)
'(erc-nick "lukeshu")
'(global-whitespace-mode nil)
'(graphviz-dot-auto-indent-on-semi nil)
'(package-selected-packages
- (quote
- (terraform-mode protobuf-mode web-mode outline-magic dockerfile-mode plantuml-mode vue-mode typescript-mode scss-mode php-mode haml-mode coffee-mode yaml-mode nginx-mode meson-mode markdown-mode graphviz-dot-mode go-mode glsl-mode cmake-mode bison-mode bats-mode editorconfig smart-tabs-mode page-break-lines abyss-theme)))
+ '(adaptive-wrap mmm-mode jq-mode graphql-mode bazel multiple-cursors jq-format terraform-mode protobuf-mode web-mode outline-magic dockerfile-mode plantuml-mode vue-mode typescript-mode scss-mode php-mode haml-mode coffee-mode yaml-mode nginx-mode meson-mode markdown-mode graphviz-dot-mode go-mode glsl-mode cmake-mode bison-mode bats-mode editorconfig smart-tabs-mode page-break-lines abyss-theme))
'(safe-local-variable-values
- (quote
- ((eval outline-show-all)
+ '((Indent-tabs-mode)
+ (c-file-offsets
+ (block-close . 0)
+ (brace-list-close . 0)
+ (brace-list-entry . 0)
+ (brace-list-intro . +)
+ (case-label . 0)
+ (class-close . 0)
+ (defun-block-intro . +)
+ (defun-close . 0)
+ (defun-open . 0)
+ (else-clause . 0)
+ (inclass . +)
+ (label . 0)
+ (statement . 0)
+ (statement-block-intro . +)
+ (statement-case-intro . +)
+ (statement-cont . +)
+ (substatement . +)
+ (topmost-intro . 0))
+ (eval outline-show-all)
(sgml-basic-offset . 8)
(nxml-child-indent . 2)
(sentence-end-double-space nil)
(Fill-Column . 64)
- (eval c-set-offset
- (quote arglist-close)
- 0)
- (eval c-set-offset
- (quote arglist-intro)
- (quote ++))
- (eval c-set-offset
- (quote case-label)
- 0)
- (eval c-set-offset
- (quote statement-case-open)
- 0)
- (eval c-set-offset
- (quote substatement-open)
- 0)
+ (eval c-set-offset 'arglist-close 0)
+ (eval c-set-offset 'arglist-intro '++)
+ (eval c-set-offset 'case-label 0)
+ (eval c-set-offset 'statement-case-open 0)
+ (eval c-set-offset 'substatement-open 0)
(Nginx-indent-tabs-mode)
(Nginx-indent-level . 4)
(Nginx-indent-level . 8)
- (c-set-style . "K&R"))))
- '(use-package-verbose (quote debug))
+ (c-set-style . "K&R")))
+ '(use-package-verbose 'debug)
'(yaml-block-literal-electric-alist nil))
(custom-set-faces
;; custom-set-faces was added by Custom.
;; If you edit it by hand, you could mess it up, so be careful.
;; Your init file should contain only one such instance.
;; If there is more than one, they won't work right.
- )
+ '(flyspell-incorrect ((t (:background "dark red" :underline (:color "#ef8690" :style wave)))))
+ '(mmm-cleanup-submode-face ((((class color) (min-colors 89)) :background "#693200")))
+ '(mmm-code-submode-face ((((class color) (min-colors 89)) :background "#323232")))
+ '(mmm-comment-submode-face ((((class color) (min-colors 89)) :background "#242679")))
+ '(mmm-declaration-submode-face ((((class color) (min-colors 89)) :background "#004065")))
+ '(mmm-default-submode-face ((((class color) (min-colors 89)) :background "#191a1b")))
+ '(mmm-init-submode-face ((((class color) (min-colors 89)) :background "#71206a")))
+ '(mmm-output-submode-face ((((class color) (min-colors 89)) :background "#77002a")))
+ '(mmm-special-submode-face ((((class color) (min-colors 89)) :background "#00422a"))))
diff --git a/.config/emacs/early-init.el b/.config/emacs/early-init.el
new file mode 100644
index 0000000..7beda69
--- /dev/null
+++ b/.config/emacs/early-init.el
@@ -0,0 +1,5 @@
+;; Hey, Emacs: -*- Indent-tabs-mode: nil -*-
+
+;; Don't automatically initialize package.el, wait for us to configure
+;; it in init.el and then manually call (package-initialize).
+(setq package-enable-at-startup nil)
diff --git a/.config/emacs/init.el b/.config/emacs/init.el
index 9c46633..5a92f14 100644
--- a/.config/emacs/init.el
+++ b/.config/emacs/init.el
@@ -1,6 +1,9 @@
-;; This config requires Emacs 24.4(+?)
;; Hey, Emacs: -*- Indent-tabs-mode: nil -*-
+
+;; This config requires Emacs 27.
+;; With some differences in package.el initialization it should work with Emacs 24.4(+?).
;; Without (advice-add) it should work in older versions of Emacs 24.
+
;;;; Use XDG-ish locations ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(let ((xdg-cache-home (file-name-as-directory (or (getenv "XDG_CACHE_HOME") "~/.cache")))
(xdg-data-home (file-name-as-directory (or (getenv "XDG_DATA_HOME") "~/.local/share"))))
@@ -45,39 +48,81 @@
;;;; Early settings ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; This isn't particularly important, but set it before doing a whole
;; lot (loading packages), so there isn't a weird change in text size.
-(set-face-attribute 'default nil :height 80)
+(set-face-attribute 'default nil
+ :family "DejaVu Sans Mono"
+ :height 80
+ ;:weight 'semi-bold
+ )
;;;; Package management ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; package.el
-(require 'package)
-(add-to-list 'package-archives '("melpa" . "http://melpa.org/packages/") t)
-(setq package-enable-at-startup nil)
-(package-initialize)
+(when (require 'package)
+ (add-to-list 'package-archives
+ '("melpa-stable" . "https://stable.melpa.org/packages/") t)
+ (add-to-list 'package-archives
+ '("melpa" . "http://melpa.org/packages/") t)
+ ;; Always prefer versions from GNU > Melpa-Stable > Melpa, even if the
+ ;; later have higher version numbers.
+ (setq package-archive-priorities
+ '(("gnu" . 99)
+ ("melpa-stable" . 5)
+ ("melpa" . 0)))
+ (package-initialize))
+
;; use-package.el
-(setq use-package-always-ensure t)
-(add-to-list 'load-path (concat user-emacs-directory "use-package"))
-(require 'use-package)
+(eval-when-compile
+ (add-to-list 'load-path (concat user-emacs-directory "use-package"))
+ (require 'use-package)
+ (setq use-package-always-ensure t))
(require 'bind-key)
-;; Themes
-(use-package abyss-theme
- :config (load-theme 'abyss t))
-;; Minor modes
-;(use-package dtrt-indent ;; Detect indent style for existing files
-; :config (dtrt-indent-mode 1))
-(use-package page-break-lines ;; Display form-feeds pretty
- :init (advice-add 'page-break-lines-mode-maybe
- :override #'page-break-lines-mode)
- :config (global-page-break-lines-mode 1))
-;; (use-package smart-tabs-mode ;; Indent with tabs, align with spaces
-;; :config (progn
-;; (smart-tabs-mode 1)
-;; (apply 'smart-tabs-insinuate
-;; (mapcar 'car smart-tabs-insinuate-alist))))
+;; Themes ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+(use-package modus-themes
+ :config (progn
+ ;; Modus makes MMM regions almost impossible to see
+ (add-hook 'modus-themes-after-load-theme-hook
+ '(lambda ()
+ (modus-themes-with-colors
+ (custom-set-faces
+ `(mmm-cleanup-submode-face ((,class :background ,yellow-refine-bg)))
+ `(mmm-code-submode-face ((,class :background ,bg-active)))
+ `(mmm-comment-submode-face ((,class :background ,blue-refine-bg)))
+ `(mmm-declaration-submode-face ((,class :background ,cyan-refine-bg)))
+ `(mmm-default-submode-face ((,class :background ,bg-alt)))
+ `(mmm-init-submode-face ((,class :background ,magenta-refine-bg)))
+ `(mmm-output-submode-face ((,class :background ,red-refine-bg)))
+ `(mmm-special-submode-face ((,class :background ,green-refine-bg)))))
+ ))
+ ;; Load the theme. Use this function instead of
+ ;; load-theme in order to get the above hook.
+ (modus-themes-load-vivendi)
+ ))
+
+;; Minor modes ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+(use-package adaptive-wrap
+; :config (progn
+; (adaptive-wrap-prefix-mode 1))
+ )
(use-package editorconfig
- :config (editorconfig-mode 1))
+ :config (progn
+ (editorconfig-mode 1)
+ (add-to-list 'editorconfig-indentation-alist '(protobuf-mode c-basic-offset))
+ (add-to-list 'editorconfig-indentation-alist '(terraform-mode terra-indent-level
+ terraform-indent-level
+ hcl-indent-level))
+ ))
+(use-package jq-format
+ :commands (jq-format-json-buffer
+ jq-format-json-region
+ jq-format-json-on-save-mode
+ jq-format-jsonlines-buffer
+ jq-format-jsonlines-region
+ jq-format-jsonlines-on-save-mode))
+(use-package multiple-cursors
+ :bind (("C-c m l" . mc/edit-lines)
+ ("C-c m n" . mc/insert-numbers)))
(use-package outline-magic
:commands (outline-cycle
outline-next-line
@@ -85,8 +130,24 @@
outline-move-subtree-down
outline-promote
outline-demote))
-;; Major modes (non-HTML-related)
+(use-package page-break-lines ;; Display form-feeds pretty
+ :init (advice-add 'page-break-lines-mode-maybe
+ :override #'page-break-lines-mode)
+ :config (global-page-break-lines-mode 1))
+(use-package smart-tabs-mode ;; Indent with tabs, align with spaces
+ :config (progn
+ (smart-tabs-mode 1)
+ (apply 'smart-tabs-insinuate
+ (mapcar 'car smart-tabs-insinuate-alist))))
+
+;; Major modes (non-HTML-related) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(use-package bats-mode :mode "\\.bats\\'")
+(use-package bazel
+ :mode (((rx "/" (or "BUILD" "BUILD.bazel") eos) . bazel-build-mode)
+ ((rx "/" (or "WORKSPACE" "WORKSPACE.bazel") eos) . bazel-workspace-mode)
+ ((rx "/" (+ nonl) ".bzl" eos) . bazel-starlark-mode)
+ ((rx "/" (or "bazel.bazelrc" ".bazelrc") eos) . bazelrc-mode)
+ ((rx "/.bazelignore" eos) . bazelignore-mode)))
(use-package bison-mode
:mode (("\\.l\\'" . bison-mode)
("\\.y\\'" . bison-mode)
@@ -98,12 +159,19 @@
dockerfile-build-no-cache-buffer))
(use-package glsl-mode :mode ("\\.vert\\'" "\\.frag\\'" "\\.geom\\'" "\\.glsl\\'"))
(use-package go-mode :mode ("\\.go\\'" "go\\.mod"))
+(use-package graphql-mode :mode ("\\.graphql\\'" "\\.gql\\'"))
(use-package graphviz-dot-mode
:mode ("\\.dot\\'" "\\.gv\\'")
:config (add-hook 'graphviz-dot-mode-hook
'(lambda ()
(set (make-local-variable 'graphviz-dot-auto-indent-on-semi) nil)
)))
+(use-package jq-mode
+ :mode "\\.jq\\'"
+ :interpreter "jq")
+(use-package lua-mode
+ :mode "\\.lua\\'"
+ :interpreter "lua")
(use-package markdown-mode :mode ("\\.markdown\\'" "\\.md\\'" "\\.ronn\\'"))
(use-package meson-mode :mode "/meson\\(\\.build\\|_options\\.txt\\)\\'")
(use-package nginx-mode :mode ("nginx\\.conf\\'" "/nginx/.+\\.conf\\'"))
@@ -116,7 +184,8 @@
(outline-minor-mode t)
(set (make-local-variable 'outline-regexp) "[ \t]*[A-Za-z-]")
)))
-;; Major modes (HTML-related)
+
+;; Major modes (HTML-related) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(use-package coffee-mode
:mode ("\\.coffee\\'"
"\\.iced\\'"
@@ -134,25 +203,35 @@
:mode ("\\.php[s345t]?\\'" "/\\.php_cs\\(\\.dist\\)?\\'" "\\.phtml\\'" "/Amkfile\\'" "\\.amk\\'")
:interpreter "php\\(?:-?[3457]\\(?:\\.[0-9]+\\)*\\)?")
(use-package scss-mode :mode "\\.scss\\'")
-(use-package typescript-mode :mode "\\.ts\\'")
-(use-package web-mode :mode "\\.html\\'")
-
-;;(use-package nxhtml) ; nxhtml is invasive, only enable if actively using
-
-;; IDK? I guess I decided that plain php-mode had improved?
-;;
-;;(use-package php-mode-improved
-;; :mode (("\\.php[s34]?\\'" . php-mode)
-;; ("\\.phtml\\'" . php-mode)
-;; ("\\.inc\\'" . php-mode))
-;; :config (add-hook 'php-mode-hook
-;; '(lambda ()
-;; (c-set-offset 'cpp-macro 0)
-;; )))
+(use-package typescript-mode :mode "\\.tsx?\\'")
+(use-package web-mode
+ :mode ("\\.html\\'"
+ "\\.vue\\'"))
+(use-package mmm-mode
+ :load mmm-auto
+ :config (progn
+ ;; Define the class
+ (mmm-add-classes
+ '((js-graphql
+ :submode graphql-mode
+ :face mmm-code-submode-face
+ :front "[^a-zA-Z]graphql`"
+ :back "`")))
+ ;; Add too mmm-mode-ext-classes-alist
+ (mmm-add-mode-ext-class 'js-mode nil 'js-graphql)
+ (setq
+ ;; Enable MMM for modes/files named in
+ ;; mmm-mode-ext-classes-alist, and only modes/files named
+ ;; in mmm-mode-ext-classes-alist.
+ mmm-global-mode 'maybe
+ ;; 0 = none, 1 = low, 2 = high
+ mmm-submode-decoration-level 2)
+ ))
+;; Email ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(if (file-exists-p "~/Maildir")
- ;;'(apel flim semi wanderlust)
(use-package wanderlust
+ :commands (wl)
:config (progn
(define-mail-user-agent
'wl-user-agent
@@ -264,12 +343,14 @@ sh-script.el is broken."
;; Backup settings
(setq
- backup-by-copying t ;; don't clobber symlinks
- backup-directory-alist '(("." . "~/.cache/emacs/saves")) ;; don't litter my fs tree
- delete-old-versions t
- kept-new-versions 6
- kept-old-versions 2
- version-control t ;; use versioned backups
+ backup-by-copying t ;; don't clobber symlinks
+ backup-directory-alist '(("." . "~/.cache/emacs/saves")) ;; don't litter my fs tree
+ delete-old-versions t
+ kept-new-versions 6
+ kept-old-versions 2
+ version-control t ;; use versioned backups
+
+ create-lockfiles nil ;; don't litter my fs tree
)
;; Web browser settings
@@ -356,14 +437,35 @@ sh-script.el is broken."
(local-set-key [C-tab] 'hs-toggle-hiding)
))
+(add-hook 'python-mode-hook
+ (lambda ()
+ (hs-minor-mode t)
+ (local-set-key [C-tab] 'hs-toggle-hiding)
+ ))
+
(add-hook 'outline-minor-mode-hook
(lambda ()
(define-key outline-minor-mode-map [C-tab] 'outline-cycle)))
+(add-hook 'web-mode-hook
+ (lambda ()
+ (setq web-mode-enable-auto-closing nil)
+ (setq web-mode-enable-auto-pairing nil)
+ (setq web-mode-enable-auto-opening nil)
+ (setq web-mode-enable-auto-quoting nil)
+ (setq web-mode-enable-auto-expanding nil)
+ (setq web-mode-enable-auto-indentation nil)
+ ))
+
(add-to-list 'auto-mode-alist '("PKGBUILD" . sh-mode))
(add-to-list 'auto-mode-alist '("SRCBUILD" . sh-mode))
(add-to-list 'auto-mode-alist '("\\.mak\\'" . makefile-gmake-mode))
(add-to-list 'auto-mode-alist '("\\.jad\\'" . java-mode))
+(add-to-list 'auto-mode-alist '("\\.schema\\'" . js-mode))
+
+(eval-when-compile
+ (add-to-list 'load-path (concat user-emacs-directory "go-template-mode"))
+ (require 'go-template-mode))
;; Anything that gets magically appended ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
diff --git a/.config/emacs/use-package b/.config/emacs/use-package
new file mode 160000
+Subproject a7422fb8ab1baee19adb2717b5b47b9c3812a84
diff --git a/.config/emacs/wl.el b/.config/emacs/wl.el
index deefef9..fce75c1 100644
--- a/.config/emacs/wl.el
+++ b/.config/emacs/wl.el
@@ -6,8 +6,7 @@
(setq
;; Misc ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
wl-local-domain "lan.lukeshu.com"
- wl-icon-directory "~/.emacs.d/el-get/wanderlust/icons"
- wl-message-id-domain user-mail-address
+ wl-message-id-domain user-mail-address
;; Network ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; This only deals with sending--I use offlineimap to fetch
@@ -15,6 +14,10 @@
;; Folders/File system ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
elmo-maildir-folder-path "~/Maildir" ;; where I store my mail
+ elmo-localdir-folder-path "~/Maildir.MH" ;; I don't use MH, but ELMO needs to use it internally?
+ wl-temporary-file-directory (file-name-as-directory (or (getenv "XDG_RUNTIME_DIR")
+ (getenv "TMPDIR")
+ ("/tmp")))
;; note: all below are dirs (Maildirs) under elmo-maildir-folder-path
;; the '.'-prefix is for marking them as maildirs
@@ -50,7 +53,7 @@
wl-message-visible-field-list (mapcar (lambda (str) ;; but then display these
(apply 'concat (mapcar (lambda (c)
(if (and (<= ?a c) (<= c ?z))
- (list ?[ c (upcase c) ?])
+ (list ?\[ c (upcase c) ?\])
(list c)))
str)))
'(
diff --git a/.config/git/config b/.config/git/config
index 453b799..83d0dec 100644
--- a/.config/git/config
+++ b/.config/git/config
@@ -10,8 +10,39 @@
default = nothing
[merge "merge-changelog"]
name = GNU-style ChangeLog merge driver
- driver =git-merge-changelog %O %A %B
+ driver = git-merge-changelog %O %A %B
[alias]
+ # Things I use all the time
+ mergek = !gitk HEAD MERGE_HEAD ^$(git merge-base HEAD MERGE_HEAD)
+ k = !gitk
+ ref = show --format=reference --no-patch
+ git = !git
+ # Things I don't use because I forgot I have them
lg = log --graph --format='%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit --date=relative
hist = log --format='%h %ci -%C(yellow)%d%Creset %s %C(bold blue)<%an>%Creset' --abbrev-commit
graphviz = "!f() { echo 'digraph git {' ; git log --pretty='format: %h -> { %p }' \"$@\" | sed 's/[0-9a-f][0-9a-f]*/\"&\"/g' ; echo '}'; }; f"
+ apply-gitignore = "!git ls-files --cached --ignored --exclude-standard -z | xargs -r -0 git rm --cached"
+[filter "lfs"]
+ clean = git-lfs clean -- %f
+ smudge = git-lfs smudge -- %f
+ process = git-lfs filter-process
+ required = true
+[gui]
+ fontui = -family monospace -size 9 -weight normal -slant roman -underline 0 -overstrike 0
+ fontdiff = -family monospace -size 9 -weight normal -slant roman -underline 0 -overstrike 0
+[versionsort]
+ suffix = -
+[tag]
+ sort = version:refname
+[rerere]
+ enabled = false
+[url "git+ssh://lukeshu@git.launchpad.net/"]
+ insteadof = lp:
+[url "git@github.com:datawire/aes-ratelimit"]
+ insteadOf = https://github.com/datawire/aes-ratelimit
+[url "git@github.com:datawire/apro"]
+ insteadOf = https://github.com/datawire/apro
+[url "git@github.com:datawire/telepresence2-proprietary"]
+ insteadOf = https://github.com/datawire/telepresence2-proprietary
+[url "git@github.com:datawire/telepresence-pro"]
+ insteadOf = https://github.com/datawire/telepresence-pro
diff --git a/.config/git/ignore b/.config/git/ignore
index a227edd..f18f89f 100644
--- a/.config/git/ignore
+++ b/.config/git/ignore
@@ -1,4 +1,4 @@
-#*#
+\#*#
.#*
*~
.nfs*
diff --git a/.config/maildirproc/default.rc b/.config/maildirproc/default.rc
index 2b6e3c8..7dc3c0e 100644
--- a/.config/maildirproc/default.rc
+++ b/.config/maildirproc/default.rc
@@ -7,7 +7,8 @@ import subprocess
import datetime
import re
import email.utils
-#
+
+#
# Mail attribute utilities
def parse_address(x):
@@ -95,6 +96,15 @@ def majordomo_domain(mail, domain):
return m.group(1)
return None
+def github_domain(mail):
+ """
+ Return a string that is the list-name for a GitHub domain
+ """
+ m = match_re(parse_address(mail["List-Id"]), "(.*)\."+re.escape("github.com"))
+ if m:
+ return ".".join(reversed(m.group(1).split(".")))
+ return None
+
def is_from(mail, address):
return any(match_glob(addr, address) for addr in originator_addresses(mail))
def is_from_re(mail, address):
@@ -115,7 +125,7 @@ def is_me(address):
def is_to_me(mail):
return any(is_me(addr) for addr in destination_addresses(mail))
-#
+#
# bogofilter utilites
def bogofilter_auto(mail):
@@ -134,12 +144,11 @@ def bogofilter_ham(mail):
subprocess.call(["bogofilter", "-S", "-n", "-I", mail.path])
def bogofilter_spam(mail):
subprocess.call(["bogofilter", "-N", "-s", "-I", mail.path])
-#
+
+#
# The core of my filters
-def move_ham(mail, folder):
- y = datetime.datetime.now().year
- folder = "MAIN/Ham."+str(y)+folder
+def ensure_folder(folder):
dir = processor.maildir_base+"/"+folder
if not os.path.isfile(dir+"/maildirfolder"):
os.makedirs(dir+"/tmp", 0o777, True)
@@ -147,64 +156,303 @@ def move_ham(mail, folder):
os.makedirs(dir+"/cur", 0o777, True)
open(dir+"/maildirfolder", 'a').close()
subprocess.call(['make', '-C', os.environ['XDG_CONFIG_HOME']])
+
+def move_ham(mail, folder):
+ now = datetime.datetime.now()
+ # now = email.utils.parsedate_to_datetime('%s' % mail["Date"])
+ big_folders = [
+ ".software.nongnu.qemu-devel",
+ ".software.kernel.git",
+ ".software.gnu.emacs-devel",
+ ".software.sourceware.libc-alpha",
+ ]
+ if folder in big_folders:
+ folder += ".%02d" % now.month
+ folder = "MAIN/Ham."+str(now.year)+folder
+ ensure_folder(folder)
+ mail.move(folder)
+
+def move_other(mail, typ):
+ now = datetime.datetime.now()
+ folder = "MAIN/"+typ+"."+str(now.year)
+ ensure_folder(folder)
mail.move(folder)
def my_whitelist(mail):
return (
False
- or is_to_or_from(mail, "opengroup.org")
- or is_to_or_from(mail, "reproducible-builds.org")
- or is_to_or_from(mail, "purestorage.com")
- or is_to_or_from(mail, "sourceware.org")
- or is_to_or_from(mail, "vger.kernel.org")
+
+ # Specific people
or is_to_or_from(mail, "Bryan@ChankTunUnGi.onmicrosoft.com")
+ or is_to_or_from(mail, "bill-auger@peers.community")
or is_to_or_from(mail, "cacnedcomms@gmail.com")
+ or is_from(mail, "3174451635@mms.att.net")
+ or is_from(mail, "AnimalRescueoftheRockies@mailman.bloomerang-mail.com")
+ or is_from(mail, "Firecrafter38@wildapricot.org")
+ or is_from(mail, "MAILER-DAEMON@yahoo.com")
+ or is_from(mail, "Promo@email.newegg.com")
+ or is_from(mail, "flynn@kodachi.com")
+ or is_from(mail, "info@email2.mysimplemobile.com")
+ or is_from(mail, "luke.t.shumaker@gmail.com")
+ or is_from(mail, "margieshu@gmail.com")
+ or is_from(mail, "margieshu@sbcglobal.net")
+ or is_from(mail, "no-reply@sns.amazonaws.com")
+ or is_from(mail, "TrackingUpdates@fedex.com")
+ or is_to_or_from(mail, "shupetech.com")
+ or is_from(mail, "gunbarrelod@gmail.com") # Gunbarrel Optometry
+ or is_from(mail, "oral-b@reorder.com")
+
+ # Software wildcard domains
or is_to_or_from(mail, "fsf.org")
or is_to_or_from(mail, "gnu.org")
or is_to_or_from(mail, "nongnu.org")
+ or is_to_or_from(mail, "opengroup.org")
or is_to_or_from(mail, "parabola.nu")
or is_to_or_from(mail, "parabolagnulinux.org")
- or is_from(mail, "schwab.com")
- or is_from(mail, "redhat.com")
- or is_from(mail, "linkedin.com")
- or is_from(mail, "guru.com")
- or is_from(mail, "3174451635@mms.att.net")
- or is_from(mail, "MAILER-DAEMON@yahoo.com")
+ or is_to_or_from(mail, "puri.sm")
+ or is_to_or_from(mail, "reproducible-builds.org")
+ or is_to_or_from(mail, "sfconservancy.org")
+ or is_to_or_from(mail, "sourceware.org")
+ or is_to_or_from(mail, "sr.ht")
+ or is_to_or_from(mail, "vger.kernel.org")
+ or is_from(mail, "datawire.io")
+ or is_from(mail, "debian.org")
+ or is_from(mail, "google.com")
+ or is_from(mail, "keyboard.io")
+ or is_from(mail, "pine64.com")
+
+ # Living situation domains
+ # Colorado
+ or is_from(mail, "meadowcreekapartments@emailrelay.com")
+ or is_from(mail, "@aircommunities.com")
+ or is_from(mail, "@kingsleyassociates.com")
+ or is_from(mail, "@luxerone.com")
+ or is_from(mail, "@mail.welcomehome.com")
+ or is_from(mail, "@myaimcohome.com")
+ or is_from(mail, "@myaircommunitieshome.com")
+ or is_from(mail, "aimco.com")
+ or is_from(mail, "alerts.comcast.net")
+ or is_from(mail, "boulder.noshdelivery.co")
+ or is_from(mail, "colorado.gov")
+ or is_from(mail, "conservicemail.com")
+ or is_from(mail, "emails.xfinity.com")
+ or is_from(mail, "entrata.com")
+ or is_from(mail, "govdelivery.com")
+ or is_from(mail, "realpage.com")
+ or is_from(mail, "residentportal.com")
+ or is_from(mail, "state.co.us")
+ or is_from(mail, "bch.org")
+ or is_from(mail, "mailer@messages.lhmailer.com") # Thomas Bogan DDS
+ or is_from(mail, "bouldercountyvotes.org")
+
+ # Massachusetts
+ or is_from(mail, "eversource.com")
+ or is_from(mail, "getgreenmountainenergy.com")
+ or is_from(mail, "greenmountain.com")
+ or is_from(mail, "kelleyryan.com")
+ or is_from(mail, "mbta.com")
+ or is_from(mail, "nationalgrid.com")
+ or is_from(mail, "nationalgridus.com")
+ or is_from(mail, "rcn.com")
+ or is_from(mail, "rcn.net")
+ or is_from(mail, "state.ma.us")
+ # Indiana
+ or is_from(mail, "vectren.com")
+ or is_from(mail, "vectrenemail.com")
+
+ # Other wildcard domains
+ or is_from(mail, "academia-mail.com") # academia.edu
+ or is_from(mail, "accounts.google.com")
+ or is_from(mail, "alibaba.com")
+ or is_from(mail, "amazon.com")
+ or is_from(mail, "amctheatres.com")
+ or is_from(mail, "att-mail.com")
+ or is_from(mail, "backerkit.com")
+ or is_from(mail, "bricklink.com")
+ or is_from(mail, "butcherbox.com")
or is_from(mail, "careereco.com")
+ or is_from(mail, "carta.com")
+ or is_from(mail, "chewy.com")
+ or is_from(mail, "chiefdelphi.com")
or is_from(mail, "ciholas.com")
- or is_from(mail, "e.oldnational.com")
+ or is_from(mail, "circleci.com")
+ or is_from(mail, "discoursemail.com")
+ or is_from(mail, "docker.com")
+ or is_from(mail, "docusign.net")
+ or is_from(mail, "dominos.com")
+ or is_from(mail, "e.healthequity.com")
+ or is_from(mail, "ebay.com")
+ or is_from(mail, "emailbcbsma.com")
+ or is_from(mail, "eorderstart.com")
+ or is_from(mail, "etsy.com")
+ or is_from(mail, "eyemed.com")
or is_from(mail, "facebookmail.com")
+ or is_from(mail, "firefox.com")
+ or is_from(mail, "flyfrontier.com")
or is_from(mail, "gandi.net")
+ or is_from(mail, "gencon.com")
or is_from(mail, "github.com")
+ or is_from(mail, "globeasphalt.net")
or is_from(mail, "goodwillindy.org")
+ or is_from(mail, "groupmemailer.com")
+ or is_from(mail, "grubhub.com")
+ or is_from(mail, "guru.com")
+ or is_from(mail, "hellofresh.com")
+ or is_from(mail, "hulumail.com")
+ or is_from(mail, "intuit.com")
or is_from(mail, "kickstarter.com")
+ or is_from(mail, "lego.com")
+ or is_from(mail, "linkedin.com")
or is_from(mail, "list.cr.yp.to")
or is_from(mail, "lpi.org")
or is_from(mail, "lulzbot.com")
+ or is_from(mail, "lyftmail.com")
+ or is_from(mail, "mail.disneyplus.com")
+ or is_from(mail, "mail.plus.espn.com")
or is_from(mail, "mail.scribd.com")
+ or is_from(mail, "maildl.att-mail.com")
or is_from(mail, "massdrop.com")
or is_from(mail, "msdlt.k12.in.us")
+ or is_from(mail, "naviabenefits.com")
+ or is_from(mail, "netflix.com")
+ or is_from(mail, "netlify.com")
+ or is_from(mail, "newegg.com")
+ or is_from(mail, "nintendo.com")
+ or is_from(mail, "oldnational.com")
+ or is_from(mail, "oralb.com")
+ or is_from(mail, "orderstart.com")
+ or is_from(mail, "ordertrack.wireless.att-mail.com")
+ or is_from(mail, "oreillyauto.com")
+ or is_from(mail, "patreon.com")
+ or is_from(mail, "paypal.com")
+ or is_from(mail, "peacocktv.com")
+ or is_from(mail, "plugable.com")
or is_from(mail, "post.oreilly.com")
+ or is_from(mail, "proxyvote.com")
+ or is_from(mail, "publishingconcepts.com") # National Eagle Scout Association thing
+ or is_from(mail, "qobuz.com")
+ or is_from(mail, "raphnet-tech.com")
+ or is_from(mail, "raphnet.com")
+ or is_from(mail, "raphnet.net")
+ or is_from(mail, "redditmail.com")
+ or is_from(mail, "redhat.com")
+ or is_from(mail, "rockauto.com")
+ or is_from(mail, "scaleway.com")
+ or is_from(mail, "scaleway.net")
+ or is_from(mail, "schwab.com")
or is_from(mail, "scouting.org")
+ or is_from(mail, "seeed.cc")
+ or is_from(mail, "slack.com")
or is_from(mail, "solutionsinplastic.com")
or is_from(mail, "startcom.org")
+ or is_from(mail, "steampowered.com")
+ or is_from(mail, "target.com")
+ or is_from(mail, "travelers.com")
+ or is_from(mail, "uhc.com") # united health care
+ or is_from(mail, "ultramobile.com")
+ or is_from(mail, "united.com") # airlines
+ or is_from(mail, "unitedhealthcare.com")
+ or is_from(mail, "upwork.com")
or is_from(mail, "usfirst.org")
- or is_from(mail, "vectren.com")
- or is_from(mail, "vectrenemail.com")
+ or is_from(mail, "wikimedia.org")
or is_from(mail, "wolframalpha.com")
- or is_from(mail, "Promo@email.newegg.com")
- or is_from(mail, "info@email2.mysimplemobile.com")
- or is_from(mail, "margieshu@sbcglobal.net")
- or is_from(mail, "parabolagnulinux.org")
- or is_from(mail, "gandi.net")
+
or match_re(parse_address(mail["List-Id"]), ".*\.(gnu|gnome|archlinux|parabolagnulinuxlibre|fedorahosted)\.org")
or match_re(parse_address(mail["List-Id"]), ".*\.parabola\.nu")
+ or match_re(parse_address(mail["List-Id"]), ".*\.lists\.arthurdejong\.org")
or mail["Subject"].contains("[Dev]")
or mail["Subject"].contains("[Maintenance]")
or mail["Subject"].contains("[PATCH")
or mail["Subject"].contains("[systemd-devel]")
)
+def my_blacklist(mail):
+ return (
+ False
+ or ((mail['Subject'] == "Предложение") and (email.utils.parseaddr(str(mail['From']))[0] == "Aleksandr"))
+ or ((mail['Subject'] == "Сотрудничество") and (email.utils.parseaddr(str(mail['From']))[0] == "Александр Николаевич"))
+ or ((mail['Subject'] == "Сотрудничество") and (email.utils.parseaddr(str(mail['From']))[0] == "Alex"))
+ or ((mail['Subject'] == "Ответьте на предложение (Respond to the offer)") and (email.utils.parseaddr(str(mail['From']))[0] == "Alex"))
+ or ((mail['Subject'] == "Offer (Предложение)") and (email.utils.parseaddr(str(mail['From']))[0] == "Aleksandr"))
+ # 126.com
+ or is_from(mail, "adalul@126.com")
+ or is_from(mail, "dangshiganggu614@126.com")
+ or is_from(mail, "dhutvnjj5566@126.com")
+ or is_from(mail, "jiushiyao554321@126.com")
+ or is_from(mail, "junlong16515@126.com")
+ or is_from(mail, "keqijiaozhuo2891@126.com")
+ or is_from(mail, "lisawu1985@126.com")
+ or is_from(mail, "massagegun@126.com")
+ or is_from(mail, "rondtang@126.com")
+ or is_from(mail, "sefunm1@126.com")
+ or is_from(mail, "smile202999@126.com")
+ or is_from(mail, "taoji22157902@126.com")
+ # 163.com
+ or is_from(mail, "13277914293@163.com")
+ or is_from(mail, "allycrystal@163.com")
+ or is_from(mail, "andycbd@163.com")
+ or is_from(mail, "anpingboliwiremesh@163.com")
+ or is_from(mail, "bouncesportswear@163.com")
+ or is_from(mail, "chinaagent2015@163.com")
+ or is_from(mail, "gavinsolar11@163.com")
+ or is_from(mail, "handsomeartsdec@163.com")
+ or is_from(mail, "hsly_toby@163.com")
+ or is_from(mail, "huixinrj01@163.com")
+ or is_from(mail, "jerry_truck@163.com")
+ or is_from(mail, "jessicaw8708@163.com")
+ or is_from(mail, "liangtongluo@163.com")
+ or is_from(mail, "megliuextract@163.com")
+ or is_from(mail, "mincsx@163.com")
+ or is_from(mail, "nbdef1@163.com")
+ or is_from(mail, "newhopeglassmirror@163.com")
+ or is_from(mail, "sally121386@163.com")
+ or is_from(mail, "sdfghjklxczc@163.com")
+ or is_from(mail, "smile6677888@163.com")
+ or is_from(mail, "steelbottle@163.com")
+ or is_from(mail, "sunonwirecloth2021@163.com")
+ or is_from(mail, "windyzhong2013@163.com")
+ or is_from(mail, "xingdui369@163.com")
+ or is_from(mail, "zmevergreen@163.com")
+ # gmail.com
+ or is_from(mail, "affasonrabi@gmail.com")
+ or is_from(mail, "bellawilliams9060@gmail.com")
+ or is_from(mail, "carlsen.monika@gmail.com")
+ or is_from(mail, "chiboy062@gmail.com")
+ or is_from(mail, "dinamckenna1894@gmail.com")
+ or is_from(mail, "edmondpamela60@gmail.com")
+ or is_from(mail, "evelynrichards10@gmail.com")
+ or is_from(mail, "farisethill630@gmail.com")
+ or is_from(mail, "h.vandrad@gmail.com")
+ or is_from(mail, "hanksrugo@gmail.com")
+ or is_from(mail, "harrykuunda@gmail.com")
+ or is_from(mail, "henrygunter835@gmail.com")
+ or is_from(mail, "ibrahimidewu4@gmail.com")
+ or is_from(mail, "jessicadaniel7833@gmail.com")
+ or is_from(mail, "jimmymoore265@gmail.com")
+ or is_from(mail, "laviis7111@gmail.com")
+ or is_from(mail, "lishalu25@gmail.com")
+ or is_from(mail, "lw23675851@gmail.com")
+ or is_from(mail, "mamadele79@gmail.com")
+ or is_from(mail, "mimihassan971@gmail.com")
+ or is_from(mail, "mrs.doris.david02@gmail.com")
+ or is_from(mail, "odemartha01@gmail.com")
+ or is_from(mail, "roseamedin02@gmail.com")
+ or is_from(mail, "sdltdkggl3455@gmail.com")
+ or is_from(mail, "sgtkalamanthey@gmail.com")
+ or is_from(mail, "sgtkaylama@gmail.com")
+ or is_from(mail, "sgtkaylamanthey612@gmail.com")
+ or is_from(mail, "weboutloock4@gmail.com")
+ # other
+ or is_from(mail, "info@frejgon.ru")
+ or is_from(mail, "sale3@victoriapcb.com")
+ or is_from(mail, "bcbssettlement.com")
+ or is_from(mail, "factor75.com")
+ or is_from(mail, "hannahjohnson8856@gmail.com")
+ or is_from(mail, "web@equiposhosteleria.com")
+ or (email.utils.parseaddr(str(mail['From']))[0] == "Louis Vuitton")
+ or (email.utils.parseaddr(str(mail['From']))[0] == "BOOM OF SALES")
+ )
+
def my_filters(mail):
if mail["From"].contains("Parabola Website Notification <nobody@parabola.nu>"):
move_ham(mail, ".software.parabola.dev.web-notif")
@@ -220,7 +468,8 @@ def my_filters(mail):
return
# .software.* (GNU Mailman)
for pair in [
- [ 'archlinux.org' , 'archlinux' ], # @sbcglobal.net and @lukeshu.com ; problems delivering to Yahoo!
+ [ 'lists.archlinux.org' , 'archlinux' ], # @sbcglobal.net and @lukeshu.com ; problems delivering to Yahoo! (new: https://archlinux.org/news/arch-linux-mailing-list-id-changes/)
+ [ 'archlinux.org' , 'archlinux' ], # @sbcglobal.net and @lukeshu.com ; problems delivering to Yahoo! (old: https://archlinux.org/news/arch-linux-mailing-list-id-changes/)
[ 'gnome.org' , 'gnome' ], # https://mail.gnome.org/mailman/options/networkmanager-list/lukeshu@lukeshu.com
[ 'gnu.org' , 'gnu' ], # https://lists.gnu.org/mailman/options/bug-librejs/lukeshu@lukeshu.com
[ 'listas.trisquel.info' , 'trisquel' ],
@@ -257,6 +506,14 @@ def my_filters(mail):
if list:
move_ham(mail, ".software."+pair[1]+"."+list)
return
+ # .software.GitHub
+ if is_to_or_from(mail, "github.com"):
+ list = github_domain(mail)
+ if list:
+ move_ham(mail, ".software.GitHub."+list)
+ return
+ move_ham(mail, ".software.GitHub")
+ return
# .software.parabola
if (
False
@@ -279,13 +536,18 @@ def my_filters(mail):
move_ham(mail, ".software.parabola")
return
# .software.TravisCI
- if is_from(mail, "builds@travis-ci.org"):
+ if is_from(mail, "builds@travis-ci.org") or is_from(mail, "builds@travis-ci.com"):
move_ham(mail, ".software.TravisCI")
return
+ # .software.CircleCI
+ if is_from(mail, "builds@circleci.com"):
+ move_ham(mail, ".software.CircleCI")
+ return
# .software
for address in [
"archlinux.org",
"canonical.org",
+ "circleci.com",
"cnuk.org",
"core3.amsl.com",
"defectivebydesign.org",
@@ -293,7 +555,6 @@ def my_filters(mail):
"fedorahosted.org",
"foocorp.net",
"fsf.org",
- "github.com",
"gitorious.org",
"gnome.org",
"gnu.org",
@@ -306,10 +567,15 @@ def my_filters(mail):
"savoirfairelinux.com",
"sourceforge.com",
"thyrsus.com",
+ "travis-ci.com",
+ "travis-ci.org",
]:
if is_to_or_from(mail, address):
move_ham(mail, ".software")
return
+ if mail["Subject"].contains("[PATCH"):
+ move_ham(mail, ".software")
+ return
# .servers
if (
False
@@ -323,9 +589,99 @@ def my_filters(mail):
or is_from(mail, "local")
or is_from(mail, "lan")
or is_from(mail, "lukeshu.com")
+ or is_from(mail, "sns.amazonaws.com")
+ or is_from(mail, "no-reply-aws@amazon.com")
+ or is_from(mail, "rsync.net")
):
move_ham(mail, ".servers")
return
+ # .MeadowCreek
+ if (
+ False
+ or is_from(mail, "meadowcreekapartments@emailrelay.com")
+ or is_from(mail, "@aircommunities.com")
+ or is_from(mail, "@kingsleyassociates.com")
+ or is_from(mail, "@mail.welcomehome.com")
+ or is_from(mail, "@myaimcohome.com")
+ or is_from(mail, "@myaircommunitieshome.com")
+ or is_from(mail, "aimco.com")
+ or is_from(mail, "conservicemail.com")
+ or is_from(mail, "entrata.com")
+ or is_from(mail, "realpage.com")
+ or is_from(mail, "residentportal.com")
+ ):
+ move_ham(mail, ".MeadowCreek")
+ return
+ # .MeadowCreek.LuxerOne
+ if is_from(mail, "@luxerone.com"):
+ move_ham(mail, ".MeadowCreek.LuxerOne")
+ return
+ # .bills
+ if (
+ False
+ or is_from(mail, "eversource.com")
+ or is_from(mail, "getgreenmountainenergy.com")
+ or is_from(mail, "greenmountain.com")
+ or is_from(mail, "kelleyryan.com")
+ or is_from(mail, "mbta.com")
+ or is_from(mail, "nationalgrid.com")
+ or is_from(mail, "nationalgridus.com")
+ or is_from(mail, "oldnational.com")
+ or is_from(mail, "rcn.com")
+ or is_from(mail, "rcn.net")
+ or is_from(mail, "tello.com")
+ or is_from(mail, "travelers.com")
+ or is_from(mail, "ultramobile.com")
+ ):
+ move_ham(mail, ".bills")
+ return
+ if is_from(mail, "alerts.comcast.net"):
+ move_ham(mail, ".bills.xfinity")
+ return
+ if is_from(mail, "emails.xfinity.com"):
+ move_ham(mail, ".bills.xfinity.probable-spam")
+ return
+ # .shopping
+ if (
+ False
+ # special
+ or (is_from(mail, "messages@email.oreillyauto.com") and mail["Subject"].contains("rder"))
+ or (is_from(mail, "no-reply@lyftmail.com") and mail["Subject"].contains("Your ride"))
+ or (is_from(mail, "no-reply@dmsguild.com") and mail["Subject"].contains("Thank you for your Dungeon Masters Guild order"))
+ or (is_from(mail, "foresee.com") and email.utils.parseaddr(str(mail['From']))[0] == "OReillyAuto.com")
+ # @
+ or is_from(mail, "auto-confirm@amazon.com")
+ or is_from(mail, "order-update@amazon.com")
+ or is_from(mail, "payments-messages@amazon.com")
+ or is_from(mail, "shipment-tracking@amazon.com")
+ or is_from(mail, "atoz-guarantee-no-reply@amazon.com")
+ or is_from(mail, "sales@covertinstruments.com")
+ or is_from(mail, "googlestore-noreply@google.com")
+ or is_from(mail, "shop@raphnet.com")
+ or is_from(mail, "orders@eat.grubhub.com")
+ # no @
+ or is_from(mail, "boulder.noshdelivery.co")
+ or is_from(mail, "dominos.com")
+ or is_from(mail, "electroware.pl")
+ or is_from(mail, "eorderstart.com") # Rusty Melon
+ or is_from(mail, "etsy.com")
+ or is_from(mail, "inhouseorders.io") # Yurihana
+ or is_from(mail, "order.homedepot.com")
+ or is_from(mail, "orderstart.com") # Rusty Melon
+ or is_from(mail, "pine64.com")
+ or is_from(mail, "rockauto.com") # Snarf's
+ or is_from(mail, "rrtusa.com") # Snarf's
+ or is_from(mail, "stripe.com") # Yurihana
+ or is_from(mail, "swathestore.com")
+ ):
+ move_ham(mail, ".shopping")
+ return
+ if is_from(mail, "butcherbox.com"):
+ move_ham(mail, ".shopping.ButcherBox")
+ return
+ if is_from(mail, "hellofresh.com"):
+ move_ham(mail, ".shopping.HelloFresh")
+ return
# .Social.*
if is_from_re(mail, ".*[@.]facebook(|mail)\.com"):
move_ham(mail, ".Social.Facebook")
@@ -342,6 +698,18 @@ def my_filters(mail):
if is_from(mail, "linkedin.com"):
move_ham(mail, ".Social.LinkedIn")
return
+ if is_from(mail, "redditmail.com"):
+ move_ham(mail, ".Social.Reddit")
+ return
+ if is_from(mail, "discord.com"):
+ move_ham(mail, ".Social.Discord")
+ return
+ if is_from(mail, "bingo@patreon.com"):
+ move_ham(mail, ".Social.Patreon")
+ return
+ if is_from(mail, "githubcommunity@discoursemail.com"):
+ move_ham(mail, ".Social.GitHubForum")
+ return
# .jobs.*
if is_from(mail, "guru.com"):
move_ham(mail, ".jobs.Guru")
@@ -349,6 +717,15 @@ def my_filters(mail):
if is_from(mail, "glassdoor.com"):
move_ham(mail, ".jobs.Glassdoor")
return
+ if is_from(mail, "bountysource.com"):
+ move_ham(mail, ".jobs.Bountysource")
+ return
+ if is_from(mail, "upwork.com"):
+ move_ham(mail, ".jobs.Upwork")
+ return
+ if is_from(mail, "datawire.io"):
+ move_ham(mail, ".jobs.Datawire")
+ return
# .BSA
if (
False
@@ -479,13 +856,27 @@ def my_filters(mail):
if is_from(mail, "paypal.com"):
move_ham(mail, ".misc.paypal")
return
+ if is_from(mail, "intuit.com"):
+ move_ham(mail, ".misc.Intuit")
+ return
+ if is_from(mail, "qobuz.com"):
+ move_ham(mail, ".misc.Qobuz")
+ return
if (
False
or is_to_or_from(mail, "margieshu@sbcglobal.net")
+ or is_to_or_from(mail, "margieshu@gmail.com")
or is_to_or_from(mail, "3174451635@mms.att.net")
):
move_ham(mail, ".misc.Mom")
return
+ if (
+ False
+ or is_from(mail, "carta.com")
+ or is_from(mail, "proxyvote.com")
+ ):
+ move_ham(mail, ".misc.stocks")
+ return
if is_to_or_from(mail, "freelancer.com"):
move_ham(mail, ".misc.Freelancer")
return
@@ -512,6 +903,7 @@ def my_filters(mail):
or mail["Subject"].contains("Project Update")))
or mail["From"].contains("Info@mailing.jamendo.com")
or mail["From"].contains("Promo@email.newegg.com")
+ or mail["From"].contains("Promo@promo.newegg.com")
or mail["From"].contains("auto@comicsbyemail.com")
or mail["From"].contains("info@demandprogress.org")
or mail["From"].contains("info@email2.mysimplemobile.com")
@@ -524,19 +916,38 @@ def my_filters(mail):
or mail["From"].contains("social@goodwillindy.org")
or mail["From"].contains("support@support.digitalocean.com")
or mail["From"].contains("@pardonsnowden.org")
+ or mail["List-Id"].contains("sparkpostmail.com")
+ or mail["List-Id"].contains("mcsv.net")
+ or is_from(mail, "AnimalRescueoftheRockies@mailman.bloomerang-mail.com")
+ or is_from(mail, "support@vetsfirstchoice.com")
+ or is_from(mail, "customersupport@eatajs.com")
+ or is_from(mail, "boulder@noshdelivery.co")
+ or is_from(mail, "disneyplus@mail.disneyplus.com")
+ or is_from(mail, "fanservices@mail.plus.espn.com")
+ or is_from(mail, "ORewards@e3.oreillyauto.com")
+ or is_from(mail, "store-news@amazon.com")
):
move_ham(mail, ".misc.Newsletters")
return
if (
False
+ or (is_from(mail, "no-reply@patreon.com") and mail["Subject"].contains("Patreon log in attempt"))
+ or (is_from(mail, "noreply@lyftmail.com") and mail["Subject"].contains("New Login"))
+ or (is_from(mail, "service@notice.alibaba.com") and mail["Subject"].contains("Verification Code"))
+ or (is_from(mail, "service@notice.alibaba.com") and mail["Subject"].contains("Verification Code"))
or mail["Subject"].contains("password")
or mail["Subject"].contains("account")
or mail["From"].contains("accounts")
+ or is_from(mail, "account-update@amazon.com")
):
move_ham(mail, ".misc.accounts")
return
+ if is_from(mail, "alibaba.com"):
+ move_ham(mail, ".shopping.alibaba")
+ return
move_ham(mail, "")
+
#
# call the above
@@ -545,18 +956,25 @@ def handle_incoming_ham_training(mail):
handle_incoming_ham(mail)
def handle_incoming_spam_training(mail):
bogofilter_spam(mail)
- mail.move("MAIN/Spam")
+ handle_incoming_spam(mail)
def handle_incoming_ham(mail):
my_filters(mail)
def handle_incoming_spam(mail):
- mail.move("MAIN/Spam")
+ if my_blacklist(mail):
+ move_other(mail, "SpammySpam")
+ else:
+ move_other(mail, "Spam")
def handle_incoming_unknown(mail):
# Whitelist
if my_whitelist(mail):
handle_incoming_ham_training(mail)
return
+ # Blacklist
+ if my_blacklist(mail):
+ handle_incoming_spam_training(mail)
+ return
spam = bogofilter_auto(mail)
if spam == 0:
@@ -566,23 +984,26 @@ def handle_incoming_unknown(mail):
handle_incoming_ham(mail)
return
elif spam == 2:
- mail.move("MAIN/MysteryMeat")
+ move_other(mail, "MysteryMeat")
return
else:
- mail.move("MAIN/BogoFail")
+ move_other(mail, "BogoFail")
return
# hook the above functions into the maildirproc processor
processor.maildir_base = "~/Maildir"
processor.auto_reload_rcfile = True
handle_mapping = {
-# "REMOTES/ATT/Inbox": handle_incoming_unknown,
-# "REMOTES/ATT/Bulk Mail": handle_incoming_unknown, # fucking Yahoo!
+ # "REMOTES/ATT/Inbox": handle_incoming_unknown,
+ # "REMOTES/ATT/Bulk Mail": handle_incoming_unknown, # fucking Yahoo!
"REMOTES/lukeshu/INBOX": handle_incoming_unknown,
"QUEUES/Unknown": handle_incoming_unknown,
"QUEUES/Spam": handle_incoming_spam_training,
+ "QUEUES/SpamNoTrain": handle_incoming_spam,
"QUEUES/Ham": handle_incoming_ham_training,
- }
+}
+for folder in handle_mapping:
+ ensure_folder(folder)
processor.maildirs = handle_mapping.keys()
for mail in processor:
handle_mapping[mail.maildir](mail)
diff --git a/.config/ssh/config b/.config/ssh/config
index b827df5..8020cb1 100644
--- a/.config/ssh/config
+++ b/.config/ssh/config
@@ -1,10 +1,11 @@
Host *
Protocol 2
- ControlMaster auto
- ControlPath ~/.r/%l/ssh-%r@%h:%p
+ #ControlMaster auto
+ #ControlPath ~/.r/%l/ssh-%r@%h:%p
Compression yes
#ProxyCommand proxytunnel --proxy=lukeshu.com:8443 --proxyauth=frc4272:password --encrypt-proxy --dest=%h:%p
#ProxyCommand proxytunnel --proxy=lukeshu.com:8080 --proxyauth=frc4272:password --dest=%h:%p
+ AddKeysToAgent yes
# Purdue ###################################################
diff --git a/.config/systemd/user/X11@.target.wants/fix-dpi@.service b/.config/systemd/user/X11@.target.wants/fix-dpi@.service
deleted file mode 120000
index af1d134..0000000
--- a/.config/systemd/user/X11@.target.wants/fix-dpi@.service
+++ /dev/null
@@ -1 +0,0 @@
-../fix-dpi@.service \ No newline at end of file
diff --git a/.config/systemd/user/default.target.wants/kbfs.service b/.config/systemd/user/default.target.wants/kbfs.service
new file mode 120000
index 0000000..78fc054
--- /dev/null
+++ b/.config/systemd/user/default.target.wants/kbfs.service
@@ -0,0 +1 @@
+/usr/lib/systemd/user/kbfs.service \ No newline at end of file
diff --git a/.config/systemd/user/default.target.wants/keybase.service b/.config/systemd/user/default.target.wants/keybase.service
new file mode 120000
index 0000000..29d286b
--- /dev/null
+++ b/.config/systemd/user/default.target.wants/keybase.service
@@ -0,0 +1 @@
+/usr/lib/systemd/user/keybase.service \ No newline at end of file
diff --git a/.config/systemd/user/default.target.wants/mail.target b/.config/systemd/user/default.target.wants/mail.target
new file mode 120000
index 0000000..beb3ac9
--- /dev/null
+++ b/.config/systemd/user/default.target.wants/mail.target
@@ -0,0 +1 @@
+../mail.target \ No newline at end of file
diff --git a/.config/systemd/user/dunst@.service b/.config/systemd/user/dunst@.service
index bf923df..e5d96ef 100644
--- a/.config/systemd/user/dunst@.service
+++ b/.config/systemd/user/dunst@.service
@@ -7,6 +7,7 @@ Requisite=X11@%i.target
[Service]
Environment=DISPLAY=%I
-Type=simple
+Type=dbus
+BusName=org.freedesktop.Notifications
ExecStart=/usr/bin/env dunst
SyslogIdentifier=dunst
diff --git a/.config/systemd/user/element-desktop@.service b/.config/systemd/user/element-desktop@.service
new file mode 100644
index 0000000..9f737b1
--- /dev/null
+++ b/.config/systemd/user/element-desktop@.service
@@ -0,0 +1,11 @@
+[Unit]
+Description=Element Desktop on X display %I
+After=X11@%i.target
+Requisite=X11@%i.target
+
+[Service]
+Type=simple
+Environment=DISPLAY=%I
+ExecStart=/usr/bin/element-desktop --hidden
+KillMode=process
+Restart=always
diff --git a/.config/systemd/user/emacs.service.d/shell.conf b/.config/systemd/user/emacs.service.d/shell.conf
new file mode 100644
index 0000000..da4f1c3
--- /dev/null
+++ b/.config/systemd/user/emacs.service.d/shell.conf
@@ -0,0 +1,2 @@
+[Service]
+OOMPolicy=continue
diff --git a/.config/systemd/user/keybase-gui@.service b/.config/systemd/user/keybase-gui@.service
new file mode 100644
index 0000000..3a8466d
--- /dev/null
+++ b/.config/systemd/user/keybase-gui@.service
@@ -0,0 +1 @@
+[Unit]
diff --git a/.config/systemd/user/keybase-gui@.service.d/00-base.conf b/.config/systemd/user/keybase-gui@.service.d/00-base.conf
new file mode 120000
index 0000000..1dc61ec
--- /dev/null
+++ b/.config/systemd/user/keybase-gui@.service.d/00-base.conf
@@ -0,0 +1 @@
+/usr/lib/systemd/user/keybase.gui.service \ No newline at end of file
diff --git a/.config/systemd/user/keybase-gui@.service.d/01-override.conf b/.config/systemd/user/keybase-gui@.service.d/01-override.conf
new file mode 100644
index 0000000..35fa1ed
--- /dev/null
+++ b/.config/systemd/user/keybase-gui@.service.d/01-override.conf
@@ -0,0 +1,9 @@
+[Unit]
+Description=Keybase GUI on X display %I
+After=X11@%i.target
+Requisite=X11@%i.target
+
+[Service]
+Environment=DISPLAY=%I
+# start minimized
+Environment=KEYBASE_AUTOSTART=1
diff --git a/.config/systemd/user/rbar@.service b/.config/systemd/user/rbar@.service
index 498d577..0304613 100644
--- a/.config/systemd/user/rbar@.service
+++ b/.config/systemd/user/rbar@.service
@@ -6,3 +6,6 @@ StopWhenUnneeded=true
Type=simple
ExecStart=/bin/sh -c '%h/.wmii-hg/rbar %I'
SyslogIdentifier=rbar_%I
+
+[Install]
+WantedBy=wmii@.service
diff --git a/.config/systemd/user/redshift@.service b/.config/systemd/user/redshift@.service
deleted file mode 100644
index ed5bbae..0000000
--- a/.config/systemd/user/redshift@.service
+++ /dev/null
@@ -1,13 +0,0 @@
-[Unit]
-Description=Redshift display colour temperature adjustment on X display %I
-Documentation=http://jonls.dk/redshift/
-After=X11@%i.target
-Requisite=X11@%i.target
-
-[Service]
-Environment=DISPLAY=%I
-
-Type=simple
-ExecStart=/usr/bin/env redshift
-ExecStopPost=/usr/bin/env redshift -x
-SyslogIdentifier=redshift
diff --git a/.config/systemd/user/signal-desktop@.service b/.config/systemd/user/signal-desktop@.service
new file mode 100644
index 0000000..cdeab25
--- /dev/null
+++ b/.config/systemd/user/signal-desktop@.service
@@ -0,0 +1,11 @@
+[Unit]
+Description=Signal Desktop on X display %I
+After=X11@%i.target
+Requisite=X11@%i.target
+
+[Service]
+Type=simple
+Environment=DISPLAY=%I
+ExecStart=/usr/bin/signal-desktop --start-in-tray
+KillMode=process
+Restart=always
diff --git a/.config/systemd/user/sockets.target.wants/gnome-keyring-daemon.socket b/.config/systemd/user/sockets.target.wants/gnome-keyring-daemon.socket
new file mode 120000
index 0000000..775243d
--- /dev/null
+++ b/.config/systemd/user/sockets.target.wants/gnome-keyring-daemon.socket
@@ -0,0 +1 @@
+/usr/lib/systemd/user/gnome-keyring-daemon.socket \ No newline at end of file
diff --git a/.config/systemd/user/sockets.target.wants/gpg-agent-ssh.socket b/.config/systemd/user/sockets.target.wants/gpg-agent-ssh.socket
new file mode 120000
index 0000000..acb12ad
--- /dev/null
+++ b/.config/systemd/user/sockets.target.wants/gpg-agent-ssh.socket
@@ -0,0 +1 @@
+/usr/lib/systemd/user/gpg-agent-ssh.socket \ No newline at end of file
diff --git a/.config/systemd/user/sockets.target.wants/pulseaudio.socket b/.config/systemd/user/sockets.target.wants/pulseaudio.socket
new file mode 120000
index 0000000..b166523
--- /dev/null
+++ b/.config/systemd/user/sockets.target.wants/pulseaudio.socket
@@ -0,0 +1 @@
+/usr/lib/systemd/user/pulseaudio.socket \ No newline at end of file
diff --git a/.config/systemd/user/wmii@.service b/.config/systemd/user/wmii@.service
index 92f3b40..ff9ef68 100644
--- a/.config/systemd/user/wmii@.service
+++ b/.config/systemd/user/wmii@.service
@@ -13,3 +13,6 @@ ExecStart=/usr/bin/env bash -c 'exec 8>%t/x11-wm@%I; echo "$DISPLAY"; exec wmii
ExecStop=/usr/bin/env wmiir -a unix!%t/.%N.sock xwrite /ctl Quit
ExecStopPost=/bin/rm -f -- %t/.%N.sock
SyslogIdentifier=wmii
+
+[Install]
+RequiredBy=X11@%i.target
diff --git a/.config/systemd/user/wmii@.service.wants/element-desktop@.service b/.config/systemd/user/wmii@.service.wants/element-desktop@.service
new file mode 120000
index 0000000..f9550a3
--- /dev/null
+++ b/.config/systemd/user/wmii@.service.wants/element-desktop@.service
@@ -0,0 +1 @@
+../element-desktop@.service \ No newline at end of file
diff --git a/.config/systemd/user/wmii@.service.wants/keybase-gui@.service b/.config/systemd/user/wmii@.service.wants/keybase-gui@.service
new file mode 120000
index 0000000..d9a724c
--- /dev/null
+++ b/.config/systemd/user/wmii@.service.wants/keybase-gui@.service
@@ -0,0 +1 @@
+../keybase-gui@.service \ No newline at end of file
diff --git a/.config/systemd/user/wmii@.service.wants/rbar@98_wifi.service b/.config/systemd/user/wmii@.service.wants/rbar@98_wifi.service
new file mode 120000
index 0000000..286989e
--- /dev/null
+++ b/.config/systemd/user/wmii@.service.wants/rbar@98_wifi.service
@@ -0,0 +1 @@
+../rbar@.service \ No newline at end of file
diff --git a/.config/systemd/user/wmii@.service.wants/signal-desktop@.service b/.config/systemd/user/wmii@.service.wants/signal-desktop@.service
new file mode 120000
index 0000000..755126c
--- /dev/null
+++ b/.config/systemd/user/wmii@.service.wants/signal-desktop@.service
@@ -0,0 +1 @@
+../signal-desktop@.service \ No newline at end of file
diff --git a/.config/systemd/user/wmii@.service.wants/zoom@.service b/.config/systemd/user/wmii@.service.wants/zoom@.service
new file mode 120000
index 0000000..3f63e6a
--- /dev/null
+++ b/.config/systemd/user/wmii@.service.wants/zoom@.service
@@ -0,0 +1 @@
+../zoom@.service \ No newline at end of file
diff --git a/.config/systemd/user/wmii@.socket b/.config/systemd/user/wmii@.socket
index b1583a6..3ba0171 100644
--- a/.config/systemd/user/wmii@.socket
+++ b/.config/systemd/user/wmii@.socket
@@ -4,6 +4,3 @@ Description=Window Manager Improved Improved on X display %I socket
[Socket]
ListenStream=%t/wmii@%I.sock
Service=wmii-proxy@%i.service
-
-[Install]
-RequiredBy=X11@.target
diff --git a/.config/systemd/user/wmiirc@.service b/.config/systemd/user/wmiirc@.service
index a8af5a9..d075cf2 100644
--- a/.config/systemd/user/wmiirc@.service
+++ b/.config/systemd/user/wmiirc@.service
@@ -15,3 +15,7 @@ ExecStopPost=/bin/rm -rf -- %t/wmii@%I/
Environment=DISPLAY=%I WMII_ADDRESS=unix!%t/wmii@%I.sock
ExecStart=/usr/bin/env WMII_CONFPATH=${XDG_CONFIG_HOME}/wmii-hg ${XDG_CONFIG_HOME}/wmii-hg/wmiirc
SyslogIdentifier=wmiirc
+
+[Install]
+RequiredBy=wm-running@%i.target
+WantedBy=wmii@%i.service
diff --git a/.config/systemd/user/zoom@.service b/.config/systemd/user/zoom@.service
new file mode 100644
index 0000000..5ff384f
--- /dev/null
+++ b/.config/systemd/user/zoom@.service
@@ -0,0 +1,10 @@
+[Unit]
+Description=Zoom Video Calls on X display %I
+After=X11@%i.target
+Requisite=X11@%i.target
+
+[Service]
+Type=simple
+Environment=DISPLAY=%I
+ExecStart=/usr/bin/zoom
+Restart=always
diff --git a/.config/wmii-hg/config.sh b/.config/wmii-hg/config.sh
index 02ec65b..6efe4f1 100644
--- a/.config/wmii-hg/config.sh
+++ b/.config/wmii-hg/config.sh
@@ -10,7 +10,7 @@ HIST="$XDG_CACHE_HOME/wmii/history"
mkdir -p -- "${HIST%/*}"
# Colors tuples: "<text> <background> <border>"
-. theme-abyss
+. theme-emacs
log() {
echo "wmiirc[$$]: $*"
diff --git a/.config/wmii-hg/rules b/.config/wmii-hg/rules
index 65f8339..e3a40a2 100644
--- a/.config/wmii-hg/rules
+++ b/.config/wmii-hg/rules
@@ -1,6 +1,8 @@
/wimenu/ floating=always
/panel/ tags=/.*/ floating=always
+/^zoom *:zoom *:/ tags=/.*/ floating=always
+
/^FLTK:FLTK:/ floating=always
/Emacs|Navigator/ force-tags=+sel floating=never
diff --git a/.config/wmii-hg/theme-abyss b/.config/wmii-hg/theme-abyss
deleted file mode 100644
index e297faf..0000000
--- a/.config/wmii-hg/theme-abyss
+++ /dev/null
@@ -1,28 +0,0 @@
-#!/hint/bash
-# Abyss
-
-abyss_orange="#e69f00"
-abyss_skyblue="#56b4e9"
-abyss_bluegreen="#009e73"
-abyss_yellow="#f8ec59"
-abyss_vanilla_cream="#fcfbe3"
-abyss_blue="#0072b2"
-abyss_vermillion="#d55e00"
-abyss_redpurple="#cc79a7"
-abyss_scarlet="#FF1A00"
-abyss_bluegray="#848ea9"
-abyss_background="#050000"
-abyss_background2="#0d1000"
-abyss_foreground="#bbe0f0"
-abyss_hl_line="#00f000"
-abyss_magenta="#ff00ff"
-abyss_hilite="#dd5542"
-abyss_white="#ffffff"
-abyss_green="#00ff00"
-
-WMII_BACKGROUND="${abyss_background}"
-
-# ="<text> <background> <border>"
-WMII_NORMCOLORS="${abyss_redpurple} ${abyss_background2} ${abyss_background2}"
-WMII_FOCUSCOLORS="${abyss_background2} ${abyss_skyblue} ${abyss_bluegray}"
-WMII_URGENTCOLORS="${abyss_vanilla_cream} ${abyss_skyblue} ${abyss_bluegray}"
diff --git a/.config/wmii-hg/theme-emacs b/.config/wmii-hg/theme-emacs
new file mode 100644
index 0000000..a45901c
--- /dev/null
+++ b/.config/wmii-hg/theme-emacs
@@ -0,0 +1,16 @@
+#!/hint/bash
+# Get theme settings from Emacs
+
+# emacs_unquote QUOTED_STRING
+emacs_unquote() {
+ local str="$*"
+ if [[ $str =~ ^\"(.*)\"$ ]]; then
+ str=${BASH_REMATCH[1]} # un-quote it
+ str="${str//\\\\/\\}" # \\ -> \
+ str="${str//\\\"/\"}" # \" -> "
+ str="${str//\\n/$'\n'}" # \n -> NL
+ fi
+ printf '%s' "$str"
+}
+
+eval "$(emacs_unquote "$(emacsclient --eval "(when (load \"${WMII_CONFPATH}/theme-emacs.el\") (wmii-theme-for-display \"${DISPLAY}\"))")")"
diff --git a/.config/wmii-hg/theme-emacs.el b/.config/wmii-hg/theme-emacs.el
new file mode 100644
index 0000000..2d74e3b
--- /dev/null
+++ b/.config/wmii-hg/theme-emacs.el
@@ -0,0 +1,43 @@
+(defvar wmii-unspecified-fg "black")
+(defvar wmii-unspecified-bg "white")
+(defvar wmii-unspecified-box "black")
+
+(defun wmii-normalize-color (frame colorname &optional default)
+ "Given an Emacs colorname, normalize it to an \"#rrggbb\" string."
+ (let ((rgb (color-name-to-rgb (or colorname default) frame)))
+ (if rgb
+ (apply 'color-rgb-to-hex (append rgb '(2)))
+ (when default
+ (wmii-normalize-color frame default)))))
+
+(defun wmii-face2triplet (face &optional frame)
+ "Dump an Emacs face as a WMII color triplet."
+ (let ((fg (face-foreground face frame 'default))
+ (bg (face-background face frame 'default))
+ (box (face-attribute face :box frame 'default))
+ (inv (face-inverse-video-p face frame 'default)))
+ (let ((fg (if inv bg fg))
+ (bg (if inv fg bg)))
+ (list (wmii-normalize-color frame fg wmii-unspecified-fg)
+ (wmii-normalize-color frame bg wmii-unspecified-bg)
+ (wmii-normalize-color frame
+ (cond
+ ((equal box nil) bg)
+ ((equal box t) fg)
+ ((stringp box) box)
+ ((listp box) (or (plist-get box :color) fg)))
+ wmii-unspecified-box)))))
+
+(defun wmii-theme (&optional frame)
+ "Dump the current Emacs theme as a WMII theme."
+ (concat
+ "WMII_BACKGROUND='" (car (wmii-face2triplet 'default frame)) "'\n"
+ "WMII_NORMCOLORS='" (string-join (wmii-face2triplet 'mode-line-inactive frame) " ") "'\n"
+ "WMII_FOCUSCOLORS='" (string-join (wmii-face2triplet 'mode-line frame) " ") "'\n"
+ "WMII_URGENTCOLORS='" (string-join (wmii-face2triplet 'mode-line-highlight frame) " ") "'\n"))
+
+(defun wmii-theme-for-display (display)
+ (let ((frame (make-frame-on-display display)))
+ (let ((theme (wmii-theme frame)))
+ (delete-frame frame)
+ theme)))
diff --git a/.config/wmii-hg/theme-solarized b/.config/wmii-hg/theme-solarized
deleted file mode 100644
index 8c40e4d..0000000
--- a/.config/wmii-hg/theme-solarized
+++ /dev/null
@@ -1,17 +0,0 @@
-#!/hint/bash
-SOL_BASE03='#002b36'
-SOL_BASE02='#073642'
-SOL_BASE01='#586e75'
-SOL_BASE00='#657b83'
-SOL_BASE0='#839496'
-SOL_BASE1='#93a1a1'
-SOL_BASE2='#eee8d5'
-SOL_BASE3='#fdf6e3'
-SOL_YELLOW='#b58900'
-SOL_ORANGE='#cb4b16'
-SOL_RED='#dc322f'
-SOL_MAGENTA='#d33682'
-SOL_VIOLET='#6c71c4'
-SOL_BLUE='#268bd2'
-SOL_CYAN='#2aa198'
-SOL_GREEN='#859900'
diff --git a/.config/wmii-hg/theme-solarized-dark b/.config/wmii-hg/theme-solarized-dark
deleted file mode 100644
index fc74b6c..0000000
--- a/.config/wmii-hg/theme-solarized-dark
+++ /dev/null
@@ -1,12 +0,0 @@
-#!/hint/bash
-# Solarized-dark
-
-. theme-solarized
-
-WMII_BACKGROUND="$SOL_BASE02"
-
-# ="<text> <background> <border>"
-WMII_NORMCOLORS="$SOL_BASE0 $SOL_BASE03 $SOL_BASE02"
-WMII_FOCUSCOLORS="$SOL_BASE0 $SOL_BASE02 $SOL_BASE0"
-WMII_URGENTCOLORS="$SOL_RED $SOL_BASE03 $SOL_RED"
-
diff --git a/.config/wmii-hg/theme-tango b/.config/wmii-hg/theme-tango
deleted file mode 100644
index 6ba744f..0000000
--- a/.config/wmii-hg/theme-tango
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/hint/bash
-TANGO_butter=("#fce94f" "#edd400" "#c4a000")
-TANGO_orange=("#fcaf3e" "#f57900" "#ce5c00")
-TANGO_choc=( "#e9b96e" "#c17d11" "#8f5902")
-TANGO_cham=( "#8ae234" "#73d216" "#4e9a06")
-TANGO_blue=( "#729fcf" "#3465a4" "#204a87")
-TANGO_plum=( "#ad7fa8" "#75507b" "#5c3566")
-TANGO_red=( "#ef2929" "#cc0000" "#a40000")
-TANGO_alum=( "#eeeeec" "#d3d7cf" "#babdb6"
- "#888a85" "#555753" "#2e3436")
diff --git a/.config/wmii-hg/theme-tango-dark b/.config/wmii-hg/theme-tango-dark
deleted file mode 100644
index efea1e9..0000000
--- a/.config/wmii-hg/theme-tango-dark
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/hint/bash
-# Tango-tark
-
-. theme-tango
-
-WMII_BACKGROUND="${TANGO_alum[5]}"
-
-# ="<text> <background> <border>"
-WMII_NORMCOLORS="${TANGO_alum[0]} ${TANGO_alum[4]} ${TANGO_alum[3]}"
-WMII_FOCUSCOLORS="${TANGO_alum[5]} ${TANGO_alum[1]} ${TANGO_alum[0]}"
-WMII_URGENTCOLORS="${TANGO_orange[0]} ${TANGO_alum[4]} ${TANGO_orange[4]}"
diff --git a/.local/bin/git-fetch-pr b/.local/bin/git-fetch-pr
new file mode 100755
index 0000000..ba9fa2d
--- /dev/null
+++ b/.local/bin/git-fetch-pr
@@ -0,0 +1,42 @@
+#!/bin/bash
+set -euE
+
+is_int() {
+ local re='^[0-9]+$'
+ [[ $1 =~ $re ]]
+}
+
+errusage() {
+ if [[ $# != 0 ]]; then
+ echo >&2 "${0##*/}: error: $*"
+ fi
+ echo >&2 "Usage: ${0##*/} [REMOTE] PR_NUMS..."
+ return 2
+}
+
+main() {
+ if [[ $# == 0 ]]; then
+ errusage 'require 1 or more PR numbers'
+ fi
+ local remote=origin
+ if ! is_int "$1"; then
+ remote=$1
+ shift
+ if [[ $# == 0 ]]; then
+ errusage 'require 1 or more PR numbers'
+ fi
+ fi
+ local refspecs=()
+ for pr in "$@"; do
+ if ! is_int "$pr"; then
+ errusage "not a number: ${pr@Q}"
+ fi
+ refspecs+=(
+ "refs/pull/${pr}/head:refs/pull/${pr}/head"
+ #"refs/pull/${pr}/merge:refs/pull/${pr}/merge"
+ )
+ done
+ git fetch --force "$remote" "${refspecs[@]}"
+}
+
+main "$@"
diff --git a/.local/bin/git-prune-merged-branches b/.local/bin/git-prune-merged-branches
new file mode 100755
index 0000000..772b4ad
--- /dev/null
+++ b/.local/bin/git-prune-merged-branches
@@ -0,0 +1,6 @@
+#!/bin/bash
+git for-each-ref --format='%(refname)' refs/heads/ |while read -r ref; do
+ if git merge-base --is-ancestor "$ref" HEAD; then
+ echo "${ref#refs/heads/}"
+ fi
+done | xargs -r git branch -d
diff --git a/.local/bin/git-prune-pushed-branches b/.local/bin/git-prune-pushed-branches
new file mode 100755
index 0000000..e711560
--- /dev/null
+++ b/.local/bin/git-prune-pushed-branches
@@ -0,0 +1,6 @@
+#!/bin/bash
+git for-each-ref --format='%(refname)' refs/heads/ |while read -r ref; do
+ if git merge-base --is-ancestor "$ref" "refs/remotes/origin/${ref#refs/heads/}"; then
+ echo "${ref#refs/heads/}"
+ fi
+done | xargs -r git branch -D
diff --git a/.local/bin/unzlib.go b/.local/bin/unzlib.go
new file mode 100644
index 0000000..764449d
--- /dev/null
+++ b/.local/bin/unzlib.go
@@ -0,0 +1,34 @@
+package main
+
+import (
+ "compress/zlib"
+ "fmt"
+ "io"
+ "os"
+)
+
+func main() {
+ if err := Main(os.Stdin, os.Stdout); err != nil {
+ fmt.Fprintf(os.Stderr, "%s: error: %v\n", os.Args[0], err)
+ os.Exit(1)
+ }
+}
+
+func Main(zin io.Reader, out io.Writer) (err error) {
+ maybeSetErr := func(_err error) {
+ if err == nil && _err != nil {
+ err = _err
+ }
+ }
+ in, err := zlib.NewReader(zin)
+ if err != nil {
+ return err
+ }
+ defer func() {
+ maybeSetErr(in.Close())
+ }()
+ if _, err := io.Copy(out, in); err != nil {
+ return err
+ }
+ return nil
+}