aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore20
-rw-r--r--.gitmodules80
-rw-r--r--IDEAS.md31
-rw-r--r--ISSUES.md33
-rw-r--r--Makefile521
-rw-r--r--README.md725
-rw-r--r--TABS.md26
-rw-r--r--VERSION4
-rw-r--r--X/Xresources2
-rw-r--r--X/Xresources.d/URxvt32
-rw-r--r--X/Xresources.d/XTerm24
-rw-r--r--X/redshift.conf10
-rw-r--r--X/sxhkdrc47
-rw-r--r--X/xinitrc17
-rw-r--r--X/xinitrc.d/browser.sh24
-rw-r--r--X/xinitrc.d/dunst.sh3
-rw-r--r--X/xinitrc.d/redshift.sh3
-rw-r--r--X/xinitrc.d/ssh.sh4
-rw-r--r--X/xinitrc.d/sxhkd.sh3
-rw-r--r--X/xinitrc.d/urxvt.sh3
-rw-r--r--X/xinitrc.d/xkb.sh5
-rw-r--r--X/xinitrc.d/xrbg.sh2
-rw-r--r--bash/bash_completion.d/_ssh_config_hosts.bash29
-rw-r--r--bash/bash_completion.d/keep.bash2
-rw-r--r--bash/bash_completion.d/mosh.bash5
-rw-r--r--bash/bash_completion.d/path.bash1
-rw-r--r--bash/bashrc4
-rw-r--r--bash/bashrc.d/keep.bash8
-rw-r--r--bash/bashrc.d/prompt.bash34
-rw-r--r--bin/clog.sh3
-rw-r--r--bin/dmp.sh31
-rw-r--r--bin/gscr.sh9
-rw-r--r--bin/han.bash23
-rw-r--r--bin/mked.sh1
-rw-r--r--bin/mktd.sh2
-rw-r--r--bin/mkvi.sh1
-rw-r--r--bin/msc.sh12
-rw-r--r--bin/osc.sh2
-rw-r--r--[-rwxr-xr-x]bin/phpcsff.mi50
-rw-r--r--bin/plmu.sh27
-rw-r--r--bin/qat.sh11
-rw-r--r--bin/rndi.awk3
-rw-r--r--bin/sls.sh3
-rw-r--r--bin/slsf.awk29
-rw-r--r--bin/td.sh2
-rw-r--r--bin/tm.sh9
-rw-r--r--bin/urlmt.sh16
-rw-r--r--bin/uts.awk1
-rw-r--r--bin/xgo.sh15
-rw-r--r--bin/xsnap.sh24
-rw-r--r--cabal/cabal.sh3
-rw-r--r--cabal/profile.d/cabal.sh2
-rw-r--r--cargo/profile.d/cargo.sh2
-rw-r--r--check/sh.sh4
-rw-r--r--check/urxvt.sh3
-rw-r--r--check/x.sh1
-rw-r--r--check/xinit.sh6
-rw-r--r--check/xsession.sh1
-rw-r--r--cpanm/profile.d/cpanm.sh3
-rw-r--r--dunst/dunstrc46
-rw-r--r--finger/pgpkey11
-rw-r--r--finger/plan6
-rw-r--r--games/xyzzy.sh13
-rw-r--r--git/config.mi5 (renamed from git/gitconfig.mi5)14
-rw-r--r--gnupg/gpg.conf14
-rw-r--r--gnupg/profile.d/gnupg.sh.mi53
-rw-r--r--gtk/gtk-3.0/settings.ini2
-rw-r--r--gtk/gtkrc-2.01
-rw-r--r--i3/config55
-rw-r--r--i3/status10
-rw-r--r--install/conf.sh7
-rw-r--r--install/helptags.vim2
-rw-r--r--irssi/aliases26
-rw-r--r--keychain/profile.d/keychain.sh5
-rw-r--r--keychain/shrc.d/keychain.sh3
-rw-r--r--ksh/kshrc.d/keep.ksh8
-rw-r--r--ksh/kshrc.d/prompt.ksh12
-rw-r--r--ksh/shrc.d/ksh.sh3
-rw-r--r--less/profile.d/less.sh2
-rw-r--r--lint/bash.sh2
-rw-r--r--lint/bin.sh4
-rw-r--r--lint/games.sh2
-rw-r--r--lint/git-template-hooks.sh2
-rw-r--r--lint/ksh.sh4
-rw-r--r--lint/sh.sh6
-rw-r--r--lint/urxvt.sh5
-rw-r--r--lint/x.sh1
-rw-r--r--lint/xinit.sh4
-rw-r--r--lint/xsession.sh1
-rw-r--r--logrotate/config5
-rw-r--r--logrotate/systemd/user/logrotate.service10
-rw-r--r--logrotate/systemd/user/logrotate.timer10
-rw-r--r--man/man1/bp.1df2
-rw-r--r--man/man1/br.1df2
-rw-r--r--man/man1/dmp.1df17
-rw-r--r--man/man1/msc.1df12
-rw-r--r--man/man1/phpcsff.1df21
-rw-r--r--man/man1/plmu.1df19
-rw-r--r--man/man1/qat.1df19
-rw-r--r--man/man1/sls.1df8
-rw-r--r--man/man1/slsf.1df8
-rw-r--r--man/man1/xrbg.1df4
-rw-r--r--man/man1/xrq.1df4
-rw-r--r--man/man1/xsnap.1df16
-rw-r--r--man/man6/pks.6df4
-rw-r--r--man/man6/xyzzy.6df4
-rw-r--r--man/man7/dotfiles.7df1054
-rw-r--r--mpd/mpdconf15
-rw-r--r--mpd/profile.d/mpd.sh3
-rw-r--r--mpv/mpv.conf32
-rw-r--r--mutt/filters/markdown-to-html.sh8
-rw-r--r--mutt/mailcap11
-rw-r--r--mutt/muttrc440
-rwxr-xr-xmutt/muttrc.d/src13
-rw-r--r--mutt/muttrc.d/src.sh24
-rw-r--r--ncmpcpp/config9
-rw-r--r--newsboat/config17
-rw-r--r--newsboat/systemd/user/newsboat.service10
-rw-r--r--parcellite/parcelliterc41
-rw-r--r--parcellite/xsession.d/parcellite.sh2
-rw-r--r--perlcritic/perlcriticrc5
-rw-r--r--perlcritic/profile.d/perlcritic.sh2
-rw-r--r--perltidy/profile.d/perltidy.sh2
-rw-r--r--plenv/profile.d/plenv.sh7
-rw-r--r--plenv/shrc.d/plenv.sh5
-rw-r--r--pyenv/profile.d/pyenv.sh2
-rw-r--r--pyenv/shrc.d/pyenv.sh20
-rw-r--r--rbenv/profile.d/rbenv.sh2
-rw-r--r--rbenv/shrc.d/rbenv.sh20
-rw-r--r--readline/inputrc102
-rw-r--r--redshift/redshift.conf6
-rw-r--r--redshift/xsession.d/redshift.sh2
-rw-r--r--rofi/bin/rofi_pass.sh92
-rw-r--r--sh/profile41
-rw-r--r--sh/profile.d/browser.sh4
-rw-r--r--sh/profile.d/downloads.sh33
-rw-r--r--sh/profile.d/editor.sh25
-rw-r--r--sh/profile.d/games.sh3
-rw-r--r--sh/profile.d/lang.sh4
-rw-r--r--sh/profile.d/options.sh1
-rw-r--r--sh/profile.d/os.sh3
-rw-r--r--sh/profile.d/pager.sh7
-rw-r--r--sh/profile.d/timezone.sh3
-rw-r--r--sh/profile.d/visual.sh3
-rw-r--r--sh/profile.d/welcome.sh49
-rw-r--r--sh/shrc4
-rw-r--r--sh/shrc.d/ed.sh2
-rw-r--r--sh/shrc.d/gdb.sh2
-rw-r--r--sh/shrc.d/ls.sh14
-rw-r--r--sh/shrc.d/path.sh8
-rw-r--r--sh/shrc.d/pd.sh2
-rw-r--r--sh/shrc.d/prompt.sh7
-rw-r--r--sh/shrc.d/rd.sh1
-rw-r--r--sh/shrc.d/sd.sh1
-rw-r--r--sh/shrc.d/sudo.sh8
-rw-r--r--sh/shrc.d/tor.sh33
-rw-r--r--sh/shrc.d/which.sh2
-rw-r--r--sxhkd/sxhkdrc53
-rw-r--r--sxhkd/xsession.d/sxhkd.sh2
-rw-r--r--systemd/parcimonie.service8
-rw-r--r--systemd/profile.d/systemd.sh3
-rw-r--r--systemd/user/notify-email@.service7
-rw-r--r--systemd/user/notify-email@.service.d/50-notify-email.conf2
-rw-r--r--systemd/user/run-.service.d/50-notify-email.conf5
-rw-r--r--systemd/user/service.d/50-notify-email.conf2
-rw-r--r--terminfo/putty-256color.ti7
-rw-r--r--terminfo/putty.ti128
-rw-r--r--terminfo/rxvt-256color.ti8
-rw-r--r--terminfo/rxvt-unicode-256color.ti4
-rw-r--r--terminfo/rxvt-unicode.ti160
-rw-r--r--terminfo/rxvt.ti151
-rw-r--r--terminfo/screen-256color.ti7
-rw-r--r--terminfo/screen.ti100
-rw-r--r--terminfo/tmux-256color.ti6
-rw-r--r--terminfo/tmux.ti104
-rw-r--r--tidy/profile.d/tidy.sh2
-rw-r--r--tmux/bin/tmux.sh11
-rw-r--r--tmux/profile.d/tmux.sh4
-rw-r--r--tmux/systemd/user/tmux.service11
-rw-r--r--tmux/tmux.conf23
-rw-r--r--urxvt/ext/select.pl93
-rw-r--r--vim/after/ftplugin/gitcommit.vim16
-rw-r--r--vim/after/ftplugin/html.vim2
-rw-r--r--vim/after/ftplugin/mail.vim16
-rw-r--r--vim/after/ftplugin/python.vim35
-rw-r--r--vim/after/ftplugin/vim.vim6
-rw-r--r--vim/after/indent/vim.vim6
-rw-r--r--vim/after/indent/yaml.vim2
-rw-r--r--vim/after/plugin/2html.vim11
-rw-r--r--vim/after/plugin/dist.vim1
-rw-r--r--vim/after/plugin/insert_cancel.vim4
-rw-r--r--vim/after/plugin/matchparen.vim4
-rw-r--r--vim/after/plugin/spellfile_local.vim13
-rw-r--r--vim/after/plugin/undofileskip.vim7
-rw-r--r--vim/after/syntax/bindzone.vim4
-rw-r--r--vim/after/syntax/mail.vim3
-rw-r--r--vim/after/syntax/resolv.vim6
-rw-r--r--vim/after/syntax/sh.vim12
-rw-r--r--vim/after/syntax/vim.vim2
-rw-r--r--vim/autoload/argument.vim8
-rw-r--r--vim/autoload/diff.vim2
-rw-r--r--vim/autoload/filetype/repeat.vim2
-rw-r--r--vim/autoload/fortune.vim59
-rw-r--r--vim/autoload/has.vim34
-rw-r--r--vim/autoload/html/timestamp.vim4
-rw-r--r--vim/autoload/indent.vim20
-rw-r--r--vim/autoload/mail.vim4
-rw-r--r--vim/autoload/mail/header/field.vim2
-rw-r--r--vim/autoload/option.vim8
-rw-r--r--vim/autoload/patch.vim35
-rw-r--r--vim/autoload/path.vim14
-rw-r--r--vim/autoload/plugin.vim7
-rw-r--r--vim/autoload/put_date.vim24
-rw-r--r--vim/autoload/quote.vim4
-rw-r--r--vim/autoload/xdg.vim67
m---------vim/bundle/copy_linebreak0
m---------vim/bundle/cursorline_current0
m---------vim/bundle/detect_indent0
m---------vim/bundle/html_spelllang0
m---------vim/bundle/paste_insert0
m---------vim/bundle/put_date0
m---------vim/bundle/redact_pass0
m---------vim/bundle/spellfile_local0
m---------vim/bundle/squeeze_repeat_blanks0
m---------vim/bundle/strip_trailing_whitespace0
m---------vim/bundle/undofileskip0
-rw-r--r--vim/compiler/pyflakes.vim9
-rw-r--r--vim/compiler/pylint.vim9
-rw-r--r--vim/filetype.vim200
-rw-r--r--vim/ftplugin/csv.vim2
-rw-r--r--vim/ftplugin/mail.vim15
-rw-r--r--vim/ftplugin/markdown.vim2
-rw-r--r--vim/ftplugin/textarea.vim12
-rw-r--r--vim/plugin/2html.vim1
-rw-r--r--vim/plugin/dist.vim2
-rw-r--r--vim/plugin/fortune.vim4
-rw-r--r--vim/plugin/matchit.vim2
-rw-r--r--vim/plugin/put_date.vim6
-rw-r--r--vim/scripts.vim10
-rw-r--r--vim/syntax/jinja2.vim2
-rw-r--r--vim/vimrc1162
-rw-r--r--vim/vimrc.stub28
-rw-r--r--vint/vintrc.yaml2
-rw-r--r--wget/profile.d/wget.sh5
-rw-r--r--x/Xresources106
-rw-r--r--x/logrotate/config.d/xsession7
-rw-r--r--x/shrc.d/x.sh (renamed from sh/shrc.d/x.sh)0
-rw-r--r--x/xsession.sh64
-rw-r--r--x/xsessionrc17
-rw-r--r--zsh/zshrc4
-rw-r--r--zsh/zshrc.d/keep.zsh8
-rw-r--r--zsh/zshrc.d/prompt.zsh12
252 files changed, 3822 insertions, 3810 deletions
diff --git a/.gitignore b/.gitignore
index 9b244d4d..417741c9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -25,7 +25,6 @@
/bin/dfv
/bin/dfv.m4
/bin/dfv.sh
-/bin/dmp
/bin/dub
/bin/edda
/bin/edda.m4
@@ -73,6 +72,7 @@
/bin/mkvi
/bin/mode
/bin/motd
+/bin/msc
/bin/murl
/bin/mw
/bin/nlbr
@@ -89,7 +89,6 @@
/bin/phpcsff.m4
/bin/phpcsff.sh
/bin/pit
-/bin/plmu
/bin/pp
/bin/pph
/bin/pst
@@ -97,6 +96,7 @@
/bin/pst.sh
/bin/pvi
/bin/pwg
+/bin/qat
/bin/quo
/bin/rep
/bin/rfcf
@@ -155,6 +155,7 @@
/bin/xgoc
/bin/xrbg
/bin/xrq
+/bin/xsnap
/dillo/dillorc
/dillo/dillorc.m4
/emacs/bin/emacsm
@@ -174,10 +175,17 @@
/games/uuu
/games/xyzzy
/games/zs
-/git/gitconfig
-/git/gitconfig.m4
+/git/config
+/git/config.m4
+/git/template/hooks/post-update
/git/template/hooks/pre-commit
/git/template/hooks/prepare-commit-msg
-/git/template/hooks/post-update
+/gnupg/profile.d/gnupg.sh
+/gnupg/profile.d/gnupg.sh.m4
/include/mktd.m4
-/urxvt/ext/select
+/less/less
+/mutt/filters/markdown-to-html
+/mutt/muttrc.d/src
+/rofi/bin/rofi_pass
+/tmux/bin/tmux
+/x/xsession
diff --git a/.gitmodules b/.gitmodules
index 92fe319f..e0ef1bf5 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,107 +1,119 @@
# Vim plugins
[submodule "vim/bundle/alternate_filetypes"]
path = vim/bundle/alternate_filetypes
- url = https://sanctum.geek.nz/code/vim-alternate-filetypes.git
+ url = https://dev.sanctum.geek.nz/code/vim-alternate-filetypes.git
[submodule "vim/bundle/big_file_options"]
path = vim/bundle/big_file_options
- url = https://sanctum.geek.nz/code/vim-big-file-options.git
+ url = https://dev.sanctum.geek.nz/code/vim-big-file-options.git
[submodule "vim/bundle/colon_operator"]
path = vim/bundle/colon_operator
- url = https://sanctum.geek.nz/code/vim-colon-operator.git
+ url = https://dev.sanctum.geek.nz/code/vim-colon-operator.git
[submodule "vim/bundle/copy_linebreak"]
path = vim/bundle/copy_linebreak
- url = https://sanctum.geek.nz/code/vim-copy-linebreak.git
+ url = https://dev.sanctum.geek.nz/code/vim-copy-linebreak.git
[submodule "vim/bundle/cursorline_current"]
path = vim/bundle/cursorline_current
- url = https://sanctum.geek.nz/code/vim-cursorline-current.git
+ url = https://dev.sanctum.geek.nz/code/vim-cursorline-current.git
+[submodule "vim/bundle/detect_indent"]
+ path = vim/bundle/detect_indent
+ url = https://dev.sanctum.geek.nz/code/vim-detect-indent.git
[submodule "vim/bundle/digraph_search"]
path = vim/bundle/digraph_search
- url = https://sanctum.geek.nz/code/vim-digraph-search.git
+ url = https://dev.sanctum.geek.nz/code/vim-digraph-search.git
[submodule "vim/bundle/equalalways_resized"]
path = vim/bundle/equalalways_resized
- url = https://sanctum.geek.nz/code/vim-equalalways-resized.git
+ url = https://dev.sanctum.geek.nz/code/vim-equalalways-resized.git
[submodule "vim/bundle/foldlevelstart_stdin"]
path = vim/bundle/foldlevelstart_stdin
- url = https://sanctum.geek.nz/code/vim-foldlevelstart-stdin.git
+ url = https://dev.sanctum.geek.nz/code/vim-foldlevelstart-stdin.git
+[submodule "vim/bundle/html_spelllang"]
+ path = vim/bundle/html_spelllang
+ url = https://dev.sanctum.geek.nz/code/vim-html-spelllang.git
[submodule "vim/bundle/insert_cancel"]
path = vim/bundle/insert_cancel
- url = https://sanctum.geek.nz/code/vim-insert-cancel.git
+ url = https://dev.sanctum.geek.nz/code/vim-insert-cancel.git
[submodule "vim/bundle/insert_suspend_hlsearch"]
path = vim/bundle/insert_suspend_hlsearch
- url = https://sanctum.geek.nz/code/vim-insert-suspend-hlsearch.git
+ url = https://dev.sanctum.geek.nz/code/vim-insert-suspend-hlsearch.git
[submodule "vim/bundle/insert_timeout"]
path = vim/bundle/insert_timeout
- url = https://sanctum.geek.nz/code/vim-insert-timeout.git
+ url = https://dev.sanctum.geek.nz/code/vim-insert-timeout.git
[submodule "vim/bundle/keep_position"]
path = vim/bundle/keep_position
- url = https://sanctum.geek.nz/code/vim-keep-position.git
+ url = https://dev.sanctum.geek.nz/code/vim-keep-position.git
[submodule "vim/bundle/paste_insert"]
path = vim/bundle/paste_insert
- url = https://sanctum.geek.nz/code/vim-paste-insert.git
+ url = https://dev.sanctum.geek.nz/code/vim-paste-insert.git
[submodule "vim/bundle/put_blank_lines"]
path = vim/bundle/put_blank_lines
- url = https://sanctum.geek.nz/code/vim-put-blank-lines.git
+ url = https://dev.sanctum.geek.nz/code/vim-put-blank-lines.git
+[submodule "vim/bundle/put_date"]
+ path = vim/bundle/put_date
+ url = https://dev.sanctum.geek.nz/code/vim-put-date.git
[submodule "vim/bundle/quickfix_auto_open"]
path = vim/bundle/quickfix_auto_open
- url = https://sanctum.geek.nz/code/vim-quickfix-auto-open.git
+ url = https://dev.sanctum.geek.nz/code/vim-quickfix-auto-open.git
[submodule "vim/bundle/redact_pass"]
path = vim/bundle/redact_pass
- url = https://sanctum.geek.nz/code/vim-redact-pass.git
+ url = https://dev.sanctum.geek.nz/code/vim-redact-pass.git
[submodule "vim/bundle/regex_escape"]
path = vim/bundle/regex_escape
- url = https://sanctum.geek.nz/code/vim-regex-escape.git
+ url = https://dev.sanctum.geek.nz/code/vim-regex-escape.git
[submodule "vim/bundle/replace_operator"]
path = vim/bundle/replace_operator
- url = https://sanctum.geek.nz/code/vim-replace-operator.git
+ url = https://dev.sanctum.geek.nz/code/vim-replace-operator.git
[submodule "vim/bundle/scratch_buffer"]
path = vim/bundle/scratch_buffer
- url = https://sanctum.geek.nz/code/vim-scratch-buffer.git
+ url = https://dev.sanctum.geek.nz/code/vim-scratch-buffer.git
[submodule "vim/bundle/select_old_files"]
path = vim/bundle/select_old_files
- url = https://sanctum.geek.nz/code/vim-select-old-files.git
+ url = https://dev.sanctum.geek.nz/code/vim-select-old-files.git
[submodule "vim/bundle/shebang_change_filetype"]
path = vim/bundle/shebang_change_filetype
- url = https://sanctum.geek.nz/code/vim-shebang-change-filetype.git
+ url = https://dev.sanctum.geek.nz/code/vim-shebang-change-filetype.git
[submodule "vim/bundle/shebang_create_exec"]
path = vim/bundle/shebang_create_exec
- url = https://sanctum.geek.nz/code/vim-shebang-create-exec.git
+ url = https://dev.sanctum.geek.nz/code/vim-shebang-create-exec.git
[submodule "vim/bundle/spellfile_local"]
path = vim/bundle/spellfile_local
- url = https://sanctum.geek.nz/code/vim-spellfile-local.git
+ url = https://dev.sanctum.geek.nz/code/vim-spellfile-local.git
[submodule "vim/bundle/squeeze_repeat_blanks"]
path = vim/bundle/squeeze_repeat_blanks
- url = https://sanctum.geek.nz/code/vim-squeeze-repeat-blanks.git
+ url = https://dev.sanctum.geek.nz/code/vim-squeeze-repeat-blanks.git
[submodule "vim/bundle/strip_trailing_whitespace"]
path = vim/bundle/strip_trailing_whitespace
- url = https://sanctum.geek.nz/code/vim-strip-trailing-whitespace.git
+ url = https://dev.sanctum.geek.nz/code/vim-strip-trailing-whitespace.git
[submodule "vim/bundle/toggle_flags"]
path = vim/bundle/toggle_flags
- url = https://sanctum.geek.nz/code/vim-toggle-flags.git
+ url = https://dev.sanctum.geek.nz/code/vim-toggle-flags.git
+[submodule "vim/bundle/undofileskip"]
+ path = vim/bundle/undofileskip
+ url = https://dev.sanctum.geek.nz/code/vim-undofileskip.git
[submodule "vim/bundle/vertical_region"]
path = vim/bundle/vertical_region
- url = https://sanctum.geek.nz/code/vim-vertical-region.git
+ url = https://dev.sanctum.geek.nz/code/vim-vertical-region.git
[submodule "vim/bundle/vimrc_reload_filetype"]
path = vim/bundle/vimrc_reload_filetype
- url = https://sanctum.geek.nz/code/vim-vimrc-reload-filetype.git
+ url = https://dev.sanctum.geek.nz/code/vim-vimrc-reload-filetype.git
[submodule "vim/bundle/write_mkpath"]
path = vim/bundle/write_mkpath
- url = https://sanctum.geek.nz/code/vim-write-mkpath.git
+ url = https://dev.sanctum.geek.nz/code/vim-write-mkpath.git
# Vim filetype plugins
[submodule "vim/bundle/diff_prune"]
path = vim/bundle/diff_prune
- url = https://sanctum.geek.nz/code/vim-diff-prune.git
+ url = https://dev.sanctum.geek.nz/code/vim-diff-prune.git
[submodule "vim/bundle/make_target"]
path = vim/bundle/make_target
- url = https://sanctum.geek.nz/code/vim-make-target.git
+ url = https://dev.sanctum.geek.nz/code/vim-make-target.git
[submodule "vim/bundle/perl_version_bump"]
path = vim/bundle/perl_version_bump
- url = https://sanctum.geek.nz/code/vim-perl-version-bump.git
+ url = https://dev.sanctum.geek.nz/code/vim-perl-version-bump.git
# Vim colorschemes
[submodule "vim/bundle/juvenile"]
path = vim/bundle/juvenile
- url = https://sanctum.geek.nz/code/vim-juvenile.git
+ url = https://dev.sanctum.geek.nz/code/vim-juvenile.git
[submodule "vim/bundle/sahara"]
path = vim/bundle/sahara
- url = https://sanctum.geek.nz/code/vim-sahara.git
+ url = https://dev.sanctum.geek.nz/code/vim-sahara.git
diff --git a/IDEAS.md b/IDEAS.md
index 7622dd97..e15d284e 100644
--- a/IDEAS.md
+++ b/IDEAS.md
@@ -1,36 +1,31 @@
Ideas
=====
-* A wrapper `ksw(1df)` (kill-switch) that traps `SIGINT` to kill a called
+- A wrapper `ksw(1df)` (kill-switch) that traps `SIGINT` to kill a called
program or loop immediately, rather than aborting a loop (is this possible?)
-* A wrapper `sil(1df)` or `nec(1df)` to turn `stty -echo` off for the duration
- of a paste?
-* I can probably share my `psql()` completions/shortcuts after sanitizing them
+- I can probably share my `psql()` completions/shortcuts after sanitizing them
a bit
-* Wouldn't be too hard to add some HTTP BASIC authentication to `ix(1df)` to
+- Wouldn't be too hard to add some HTTP BASIC authentication to `ix(1df)` to
make pastes manageable
-* Have `eds(1df)` accept standard input with the "starting content" for the
+- Have `eds(1df)` accept standard input with the "starting content" for the
script
-* Convert all the manual pages to Mandoc format maybe?
+- Convert all the manual pages to Mandoc format maybe?
<https://en.wikipedia.org/wiki/Mandoc>
-* `qmp(1df)`--quick man page
-* The solution to `chn(1df)` not running in parallel is probably backgrounded
+- `qmp(1df)`--quick man page
+- The solution to `chn(1df)` not running in parallel is probably backgrounded
processes and `mkfifo(1)`.
-* Write something like `hcat(1df)` or `tcat(1df)` that includes filename
+- Write something like `hcat(1df)` or `tcat(1df)` that includes filename
headings for each concatenated file.
-* I can probably get rid of all that nasty templated shell by writing something
+- I can probably get rid of all that nasty templated shell by writing something
that wraps around `mktd(1df)` and generates shell script to run, and calls
that via `eval`.
-* Ideally, the AWK and/or sed scripts in the bin and games directories should
+- Ideally, the AWK and/or sed scripts in the bin and games directories should
be syntax-checked or linted. I could at least add some patient application
of appropriate `gawk --lint` calls for each of the .awk scripts.
-* Write a ftplugin for Perl to switch between punctuation variable names and
+- Write a ftplugin for Perl to switch between punctuation variable names and
English variable names., i.e. \e on `$?` would change to `$CHILD_ERROR`, and
vice-versa.
-* Almost definitely going to want to try a runparts layout for Git hooks at
+- Almost definitely going to want to try a runparts layout for Git hooks at
some point
-* I'd like a Git hook that pre-fills out "Version X.Y.Z" if making an annotated
+- I'd like a Git hook that pre-fills out "Version X.Y.Z" if making an annotated
tag named `vX.Y.Z`.
-* There's no reason to limit `digraph_search.vim` to insert mode only
-* fortune.vim can be spun out into its own repository
-* put\_date.vim can be spun out into its own repository
diff --git a/ISSUES.md b/ISSUES.md
index 692bdb55..0a4abd4d 100644
--- a/ISSUES.md
+++ b/ISSUES.md
@@ -1,33 +1,38 @@
Known issues
============
-* `man(1)` completion doesn't work on OpenBSD as `manpath(1)` isn't a thing on
+- `man(1)` completion doesn't work on OpenBSD as `manpath(1)` isn't a thing on
that system; need to find some way of finding which manual directories should
be searched at runtime, if there is one.
-* The checks `gscr(1df)` makes to determine where it is are a bit naïve (don't
+- The checks `gscr(1df)` makes to determine where it is are a bit naïve (don't
work with bare repos) and could probably be improved with some appropriate
`git-reflog(1)` calls
-* `dr(6df)` is probably more practical in awk
-* Running the block of git(1) commands in the prompt leaves five "stale"
+- `dr(6df)` is probably more practical in awk
+- Running the block of git(1) commands in the prompt leaves five "stale"
jobspecs around that flee after a jobs builtin run; only saw this manifest
after `90dcadf`; either I understand job specs really poorly or this may be a
bug in bash
-* I can't find a clean way of detecting a restricted shell for ksh instances to
+- I can't find a clean way of detecting a restricted shell for ksh instances to
prevent trying to load anything fancy (works for Bash)
- * Zsh, either! $options[restricted] is "off" within the startup file
-* Would be good to complete the Makefile variables for NAME, EMAIL etc with
+ - Zsh, either! $options[restricted] is "off" within the startup file
+- Would be good to complete the Makefile variables for NAME, EMAIL etc with
educated guesses (`id -u`@`cat /etc/mailname`) etc rather than hardcoding my
own stuff in there
-* Need to decide whether I care about XDG, and implement it if I do
-* Need to decide whether I'm testing the shell snippets for MPD, Keychain etc,
- and if so how.
-* The custom shell functions really should be documented, but it's not clear to
+- Need to decide whether I care about XDG, and implement it if I do
+- The custom shell functions really should be documented, but it's not clear to
me exactly where this should happen, because the commands' availability
depends on which shell you're using; the `sd` function isn't available when
you're not using Bash. Maybe I should try to extend `help` without breaking
it?
-* The `b:undo\_indent` definition for the `perl` filetype can probably be
+- The `b:undo\_indent` definition for the `perl` filetype can probably be
pushed upstream.
-* The `_text_filenames` completion handler for Bash won't work on files with
+- The `_text_filenames` completion handler for Bash won't work on files with
newlines in their names. Can it be made to?
-* Typing the normal mode mapping for `paste_open.vim` *twice* causes an error.
+- Highlighting the variable name in e.g. `unset -v VARNAME` works with `bash`
+ highlighting, but not with `sh` highlighting
+- The Markdown underline functions should count screen columns, not characters
+ or bytes
+- > $ lesskey --output less/less less/lesskey
+ > NOTE: lesskey is deprecated.
+ > It is no longer necessary to run lesskey, when using less version 582 and
+ > later.
diff --git a/Makefile b/Makefile
index 8146f1cc..9f98ce20 100644
--- a/Makefile
+++ b/Makefile
@@ -9,9 +9,11 @@
install-bash-completion \
install-bin \
install-bin-man \
+ install-cabal \
+ install-cargo \
+ install-cpanm \
install-curl \
install-dillo \
- install-dunst \
install-emacs \
install-ex \
install-finger \
@@ -19,49 +21,41 @@
install-games-man \
install-git \
install-gnupg \
- install-gtk \
install-i3 \
+ install-init \
install-ksh \
install-less \
install-login-shell \
install-mail \
install-man \
- install-mpd \
install-mpv \
install-mutt \
install-mysql \
- install-ncmcpp \
+ install-ncmpcpp \
install-newsboat \
+ install-parcellite \
install-perlcritic \
install-perltidy \
+ install-plenv \
install-psql \
+ install-pyenv \
+ install-rbenv \
install-readline \
+ install-redshift \
+ install-rofi \
+ install-scrot \
install-sh \
install-subversion \
- install-terminfo \
+ install-sxhkd \
+ install-systemd \
install-tidy \
install-tmux \
- install-urxvt \
install-vim \
- install-vim-after \
- install-vim-after-ftplugin \
- install-vim-after-indent \
- install-vim-after-plugin \
- install-vim-after-syntax \
- install-vim-bundle \
- install-vim-compiler \
- install-vim-config \
- install-vim-filetype \
- install-vim-ftplugin \
install-vim-gui \
- install-vim-gui-config \
- install-vim-indent \
- install-vim-plugin \
- install-vim-syntax \
- install-vim-thesaurus \
install-vint \
install-wget \
install-x \
+ install-xsession \
install-zsh \
check \
check-bash \
@@ -72,8 +66,8 @@
check-login-shell \
check-man \
check-sh \
- check-urxvt \
- check-xinit \
+ check-x \
+ check-xsession \
check-zsh \
lint \
lint-bash \
@@ -82,17 +76,20 @@
lint-git-template-hooks \
lint-ksh \
lint-sh \
- lint-urxvt \
lint-vim \
- lint-xinit
+ lint-x \
+ lint-xsession
.SUFFIXES:
.SUFFIXES: .awk .bash .m4 .mi5 .pl .sed .sh
+XDG_CACHE_HOME = $(HOME)/.cache
+XDG_CONFIG_HOME = $(HOME)/.config
+XDG_DATA_HOME = $(HOME)/.local/share
+
NAME = 'Tom Ryder'
EMAIL = tom@sanctum.geek.nz
-KEY = FA09C06E1B670CD0B2F5DE60C14286EA77BB8872
-SENDMAIL = msmtp
+GPG_KEYID = FA09C06E1B670CD0B2F5DE60C14286EA77BB8872
BINS = bin/ap \
bin/apf \
@@ -117,7 +114,6 @@ BINS = bin/ap \
bin/ddup \
bin/defang \
bin/dfv \
- bin/dmp \
bin/dub \
bin/edda \
bin/eds \
@@ -132,7 +128,6 @@ BINS = bin/ap \
bin/gred \
bin/gscr \
bin/gwp \
- bin/han \
bin/hms \
bin/htdec \
bin/htenc \
@@ -161,6 +156,7 @@ BINS = bin/ap \
bin/mkvi \
bin/mode \
bin/motd \
+ bin/msc \
bin/murl \
bin/mw \
bin/nlbr \
@@ -172,13 +168,13 @@ BINS = bin/ap \
bin/ped \
bin/phpcsff \
bin/pit \
- bin/plmu \
bin/p \
bin/pp \
bin/pph \
bin/pst \
bin/pvi \
bin/pwg \
+ bin/qat \
bin/quo \
bin/rep \
bin/rfcf \
@@ -228,7 +224,8 @@ BINS = bin/ap \
bin/xgo \
bin/xgoc \
bin/xrbg \
- bin/xrq
+ bin/xrq \
+ bin/xsnap
BINS_M4 = bin/chn.m4 \
bin/dfv.m4 \
@@ -272,10 +269,16 @@ GAMES = games/aaf \
games/zs
GIT_TEMPLATE_HOOKS = git/template/hooks/post-update \
- git/template/hooks/pre-commit \
- git/template/hooks/prepare-commit-msg
+ git/template/hooks/pre-commit \
+ git/template/hooks/prepare-commit-msg
-all: $(BINS) git/gitconfig $(GIT_TEMPLATE_HOOKS)
+all: $(BINS) \
+ $(GIT_TEMPLATE_HOOKS) \
+ git/config \
+ gnupg/profile.d/gnupg.sh \
+ less/less \
+ tmux/bin/tmux \
+ x/xsession
clean distclean:
rm -f -- \
@@ -284,13 +287,18 @@ clean distclean:
$(BINS_SH) \
$(GAMES) \
$(GIT_TEMPLATE_HOOKS) \
+ bin/han \
dillo/dillorc \
dillo/dillorc.m4 \
- git/gitconfig \
- git/gitconfig.m4 \
+ git/config \
+ git/config.m4 \
+ gnupg/profile.d/gnupg.sh \
include/mktd.m4 \
- urxvt/ext/select \
- vim/dist/*
+ less/less \
+ mutt/filters/markdown-to-html \
+ mutt/muttrc.d/src \
+ tmux/bin/tmux \
+ x/xsession
.awk:
sh bin/shb.sh awk -f < $< > $@
@@ -335,13 +343,21 @@ dillo/dillorc: dillo/dillorc.m4
-D HOME=$(HOME) \
dillo/dillorc.m4 > $@
-git/gitconfig: git/gitconfig.m4
+git/config: git/config.m4
m4 \
-D NAME=$(NAME) \
-D EMAIL=$(EMAIL) \
- -D KEY=$(KEY) \
- -D SENDMAIL=$(SENDMAIL) \
- git/gitconfig.m4 > $@
+ -D GPG_KEYID=$(GPG_KEYID) \
+ -D XDG_DATA_HOME=$(XDG_DATA_HOME) \
+ git/config.m4 > $@
+
+less/less: less/lesskey
+ lesskey --output $@ less/lesskey
+
+gnupg/profile.d/gnupg.sh: gnupg/profile.d/gnupg.sh.m4
+ m4 \
+ -D GPG_KEYID=$(GPG_KEYID) \
+ gnupg/profile.d/gnupg.sh.m4 > $@
MAILDIR = $(HOME)/Mail
@@ -350,9 +366,10 @@ install: install-bin \
install-ex \
install-git \
install-gnupg \
+ install-init \
install-less \
- install-man \
install-login-shell \
+ install-man \
install-readline \
install-vim
@@ -363,39 +380,44 @@ install-abook:
mkdir -p -- $(HOME)/.abook
cp -p -- abook/abookrc $(HOME)/.abook
-install-bash: check-bash install-sh
- mkdir -p -- $(HOME)/.bashrc.d
+install-bash: check-bash install-sh bin/han
+ mkdir -p -- $(HOME)/.bashrc.d $(HOME)/.local/bin
cp -p -- bash/bashrc $(HOME)/.bashrc
- cp -p -- bash/bashrc.d/* $(HOME)/.bashrc.d
+ cp -p -- bash/bashrc.d/*.bash $(HOME)/.bashrc.d
cp -p -- bash/bash_profile $(HOME)/.bash_profile
cp -p -- bash/bash_logout $(HOME)/.bash_logout
+ cp -p -- bin/han $(HOME)/.local/bin
install-bash-completion: install-bash
- mkdir -p -- $(HOME)/.bash_completion.d $(HOME)/.config
- cp -p -- bash/bash_completion $(HOME)/.config
- cp -p -- bash/bash_completion.d/* $(HOME)/.bash_completion.d
+ mkdir -p -- $(HOME)/.bash_completion.d $(XDG_CONFIG_HOME)
+ cp -p -- bash/bash_completion $(XDG_CONFIG_HOME)
+ cp -p -- bash/bash_completion.d/*.bash $(HOME)/.bash_completion.d
install-bin: $(BINS) install-bin-man
mkdir -p -- $(HOME)/.local/bin
- find bin -type f -perm -u=x \
- -exec cp -p -- {} $(HOME)/.local/bin \;
+ cp -p -- $(BINS) $(HOME)/.local/bin
install-bin-man:
- mkdir -p -- $(HOME)/.local/share/man/man1 $(HOME)/.local/share/man/man8
- cp -p -- man/man1/*.1df $(HOME)/.local/share/man/man1
- cp -p -- man/man8/*.8df $(HOME)/.local/share/man/man8
+ mkdir -p -- $(XDG_DATA_HOME)/man/man1 $(XDG_DATA_HOME)/man/man8
+ cp -p -- man/man1/*.1df $(XDG_DATA_HOME)/man/man1
+ cp -p -- man/man8/*.8df $(XDG_DATA_HOME)/man/man8
+
+install-cabal:
+ cp -p -- cabal/profile.d/cabal.sh $(HOME)/.profile.d
+
+install-cargo:
+ cp -p -- cargo/profile.d/cargo.sh $(HOME)/.profile.d
+
+install-cpanm:
+ cp -p -- cpanm/profile.d/cpanm.sh $(HOME)/.profile.d
install-curl:
cp -p -- curl/curlrc $(HOME)/.curlrc
-install-dillo: dillo/dillorc install-x
+install-dillo: dillo/dillorc
mkdir -p -- $(HOME)/.dillo
cp -p -- dillo/dillorc $(HOME)/.dillo/dillorc
-install-dunst: install-x
- mkdir -p -- $(HOME)/.config/dunst
- cp -p -- dunst/dunstrc $(HOME)/.config/dunst
-
install-emacs: emacs/bin/emacsm install-sh
mkdir -p -- $(HOME)/.local/bin
cp -p -- emacs/emacs $(HOME)/.emacs
@@ -412,256 +434,242 @@ install-finger:
install-games: $(GAMES) install-games-man
mkdir -p -- $(HOME)/.local/games
- find games -type f -perm -u=x \
- -exec cp -p -- {} $(HOME)/.local/games \;
+ cp -p -- $(GAMES) $(HOME)/.local/games
install-games-man:
- mkdir -p -- $(HOME)/.local/share/man/man6
- cp -p -- man/man6/*.6df $(HOME)/.local/share/man/man6
-
-install-git: git/gitconfig $(GIT_TEMPLATE_HOOKS)
- cp -p -- git/gitconfig $(HOME)/.gitconfig
- find git/template \
- -type d -exec sh -c 'mkdir -p -- \
- $(HOME)/.git-template"$${1#git/template}"' \
- _ {} \; \
- -o ! -name '*.*' -exec sh -c 'cp -p -- "$$1" \
- $(HOME)/.git-template"$${1#git/template}"' \
- _ {} \;
-
-install-gnupg:
- mkdir -m 0700 -p -- $(HOME)/.gnupg
- cp -p -- gnupg/*.conf $(HOME)/.gnupg
-
-install-gtk:
- mkdir -p -- $(HOME)/.config/gtk-3.0
- cp -p -- gtk/gtkrc-2.0 $(HOME)/.gtkrc-2.0
- cp -p -- gtk/gtk-3.0/settings.ini $(HOME)/.config/gtk-3.0
+ mkdir -p -- $(XDG_DATA_HOME)/man/man6
+ cp -p -- man/man6/*.6df $(XDG_DATA_HOME)/man/man6
+
+install-git: git/config $(GIT_TEMPLATE_HOOKS)
+ mkdir -p -- $(XDG_CONFIG_HOME)/git
+ cp -p -- git/config $(XDG_CONFIG_HOME)/git/config
+ mkdir -p -- $(XDG_DATA_HOME)/git/template
+ cp -pR -- git/template/description \
+ $(XDG_DATA_HOME)/git/template/description
+ mkdir -p -- $(XDG_DATA_HOME)/git/template/hooks
+ cp -pR -- $(GIT_TEMPLATE_HOOKS) \
+ $(XDG_DATA_HOME)/git/template/hooks
+
+install-gnupg: gnupg/profile.d/gnupg.sh install-sh
+ cp -p -- gnupg/profile.d/gnupg.sh $(HOME)/.profile.d
install-i3: install-x
- mkdir -p -- $(HOME)/.i3
- cp -p -- i3/* $(HOME)/.i3
-
-install-keychain: install-sh
- cp -p -- keychain/profile.d/* $(HOME)/.profile.d
- cp -p -- keychain/shrc.d/* $(HOME)/.shrc.d
-
-install-less:
- cp -p -- less/lesskey $(HOME)/.lesskey
- lesskey
+ mkdir -p -- $(XDG_CONFIG_HOME)/i3
+ cp -p -- i3/config $(XDG_CONFIG_HOME)/i3
+ mkdir -p -- $(XDG_CONFIG_HOME)/i3status
+ cp -p -- i3/status $(XDG_CONFIG_HOME)/i3status/config
+
+install-init:
+ if test -d /run/systemd/system ; then make install-systemd ; fi
+
+install-less: less/less
+ mkdir -p -- $(HOME)/.profile.d
+ cp -p -- less/profile.d/less.sh $(HOME)/.profile.d
+ mkdir -p -- $(XDG_CONFIG_HOME)/less
+ cp -p -- less/less $(XDG_CONFIG_HOME)/less/key
+
+install-logrotate: install-systemd
+ mkdir -p -- $(XDG_CONFIG_HOME)/logrotate \
+ $(XDG_CONFIG_HOME)/logrotate/config.d
+ cp -p -- logrotate/config $(XDG_CONFIG_HOME)/logrotate
+ cp -p -- logrotate/systemd/user/logrotate.service \
+ logrotate/systemd/user/logrotate.timer \
+ $(XDG_DATA_HOME)/systemd/user
install-mail:
cp -p -- mail/signature $(HOME)/.signature
install-man:
- mkdir -p -- $(HOME)/.local/share/man/man7
- cp -p -- man/man7/dotfiles.7df $(HOME)/.local/share/man/man7
-
-install-mpd: install-sh
- mkdir -p -- $(HOME)/.mpd/playlists
- cp -p -- mpd/profile.d/* $(HOME)/.profile.d
- cp -p -- mpd/mpdconf $(HOME)/.mpdconf
+ mkdir -p -- $(XDG_DATA_HOME)/man/man7
+ cp -p -- man/man7/dotfiles.7df $(XDG_DATA_HOME)/man/man7
install-mpv:
- mkdir -p -- $(HOME)/.config/mpv
- cp -p -- mpv/* $(HOME)/.config/mpv
-
-install-mutt: install-mail
- mkdir -p -- $(HOME)/.muttrc.d $(HOME)/.cache/mutt
- cp -p -- mutt/muttrc $(HOME)/.muttrc
- cp -p -- mutt/muttrc.d/src $(HOME)/.muttrc.d
-
-install-ncmcpp: install-mpd
- mkdir -p -- $(HOME)/.ncmpcpp
- cp -p -- ncmpcpp/config $(HOME)/.ncmpcpp
+ mkdir -p -- \
+ $(XDG_CONFIG_HOME)/mpv \
+ $(XDG_DATA_HOME)/mpv/screenshots
+ cp -p -- mpv/mpv.conf $(XDG_CONFIG_HOME)/mpv
-install-newsboat:
- mkdir -p -- $(HOME)/.config/newsboat $(HOME)/.local/share/newsboat
- cp -p -- newsboat/config $(HOME)/.config/newsboat
+install-mutt: install-gnupg install-mail mutt/filters/markdown-to-html mutt/muttrc.d/src
+ mkdir -p -- \
+ $(XDG_CONFIG_HOME)/mutt \
+ $(XDG_CONFIG_HOME)/mutt/muttrc.d \
+ $(XDG_CACHE_HOME)/mutt/headers \
+ $(XDG_DATA_HOME)/mutt/autocrypt \
+ $(HOME)/.local/libexec/mutt/filters
+ cp -p -- mutt/muttrc \
+ mutt/mailcap \
+ $(XDG_CONFIG_HOME)/mutt
+ cp -p -- mutt/muttrc.d/src \
+ $(XDG_CONFIG_HOME)/mutt/muttrc.d
+ touch -- $(XDG_CONFIG_HOME)/mutt/aliases
+ cp -p -- mutt/filters/markdown-to-html \
+ $(HOME)/.local/libexec/mutt/filters
+
+install-ncmpcpp:
+ mkdir -p -- $(XDG_CONFIG_HOME)/ncmpcpp
+ cp -p -- ncmpcpp/config $(XDG_CONFIG_HOME)/ncmpcpp
+
+install-newsboat: install-systemd
+ mkdir -p -- $(XDG_CONFIG_HOME)/newsboat \
+ $(XDG_DATA_HOME)/newsboat
+ cp -p -- newsboat/config \
+ $(XDG_CONFIG_HOME)/newsboat
+ cp -p -- newsboat/systemd/user/newsboat.service \
+ $(XDG_DATA_HOME)/systemd/user
install-mysql:
cp -p -- mysql/my.cnf $(HOME)/.my.cnf
install-ksh: check-ksh install-sh
mkdir -p -- $(HOME)/.kshrc.d
- cp -p -- ksh/shrc.d/* $(HOME)/.shrc.d
+ cp -p -- ksh/shrc.d/ksh.sh $(HOME)/.shrc.d
cp -p -- ksh/kshrc $(HOME)/.kshrc
- cp -p -- ksh/kshrc.d/* $(HOME)/.kshrc.d
+ cp -p -- ksh/kshrc.d/*.ksh $(HOME)/.kshrc.d
install-login-shell: check-login-shell
sh install/login-shell.sh
-install-perlcritic:
- cp -p -- perlcritic/perlcriticrc $(HOME)/.perlcriticrc
+install-parcellite: install-x
+ cp -p -- parcellite/parcelliterc $(XDG_CONFIG_HOME)
+ cp -p -- parcellite/xsession.d/parcellite.sh $(HOME)/.xsession.d
-install-perltidy:
- cp -p -- perltidy/perltidyrc $(HOME)/.perltidyrc
+install-perlcritic: install-sh
+ cp -p -- perlcritic/profile.d/perlcritic.sh $(HOME)/.profile.d
+ mkdir -p -- $(XDG_CONFIG_HOME)/perlcritic
+ cp -p -- perlcritic/perlcriticrc $(XDG_CONFIG_HOME)/perlcritic/perlcriticrc
-install-plenv: install-sh
- cp -p -- plenv/profile.d/* $(HOME)/.profile.d
- cp -p -- plenv/shrc.d/* $(HOME)/.shrc.d
+install-perltidy: install-sh
+ cp -p -- perltidy/profile.d/perltidy.sh $(HOME)/.profile.d
+ mkdir -p -- $(XDG_CONFIG_HOME)/perltidy
+ cp -p -- perltidy/perltidyrc $(XDG_CONFIG_HOME)/perltidy/perltidyrc
+
+install-plenv: install-sh install-cpanm
+ cp -p -- plenv/profile.d/plenv.sh $(HOME)/.profile.d
+ cp -p -- plenv/shrc.d/plenv.sh $(HOME)/.shrc.d
install-psql:
cp -p -- psql/psqlrc $(HOME)/.psqlrc
+install-pyenv: install-sh
+ cp -p -- pyenv/profile.d/pyenv.sh $(HOME)/.profile.d
+ cp -p -- pyenv/shrc.d/pyenv.sh $(HOME)/.shrc.d
+
+install-rbenv: install-sh
+ cp -p -- rbenv/profile.d/rbenv.sh $(HOME)/.profile.d
+ cp -p -- rbenv/shrc.d/rbenv.sh $(HOME)/.shrc.d
+
install-readline:
cp -p -- readline/inputrc $(HOME)/.inputrc
+install-redshift: install-x
+ cp -p -- redshift/redshift.conf $(XDG_CONFIG_HOME)
+ cp -p -- redshift/xsession.d/redshift.sh $(HOME)/.xsession.d
+
+install-rofi: rofi/bin/rofi_pass
+ mkdir -p -- $(HOME)/.local/bin
+ cp -p -- rofi/bin/rofi_pass $(HOME)/.local/bin
+
+install-scrot:
+ mkdir -p -- $(XDG_DATA_HOME)/scrot/screenshots
+
install-sh: check-sh
- mkdir -p -- $(HOME)/.profile.d $(HOME)/.shrc.d
cp -p -- sh/profile $(HOME)/.profile
- cp -p -- sh/profile.d/* $(HOME)/.profile.d
+ mkdir -p -- $(HOME)/.profile.d
+ cp -p -- sh/profile.d/*.sh $(HOME)/.profile.d
cp -p -- sh/shinit $(HOME)/.shinit
cp -p -- sh/shrc $(HOME)/.shrc
- cp -p -- sh/shrc.d/* $(HOME)/.shrc.d
+ mkdir -p -- $(HOME)/.shrc.d
+ cp -p -- sh/shrc.d/*.sh $(HOME)/.shrc.d
install-subversion:
mkdir -p -- $(HOME)/.subversion
cp -p -- subversion/config $(HOME)/.subversion
-install-terminfo:
- find terminfo -type f -name '*.ti' \
- -exec tic -- {} \;
+install-sxhkd: install-scrot install-x
+ mkdir -p -- $(XDG_CONFIG_HOME)/sxhkd
+ cp -p -- sxhkd/sxhkdrc $(XDG_CONFIG_HOME)/sxhkd
+ cp -p -- sxhkd/xsession.d/sxhkd.sh $(HOME)/.xsession.d
+
+install-systemd: install-sh
+ cp -p -- systemd/profile.d/systemd.sh $(HOME)/.profile.d
+ mkdir -p -- $(XDG_DATA_HOME)/systemd/user
+ cp -p -- systemd/user/notify-email@.service \
+ $(XDG_DATA_HOME)/systemd/user
+ mkdir -p -- $(XDG_DATA_HOME)/systemd/user/service.d
+ cp -p -- systemd/user/service.d/50-notify-email.conf \
+ $(XDG_DATA_HOME)/systemd/user/service.d
+ mkdir -p -- $(XDG_DATA_HOME)/systemd/user/notify-email@.service.d
+ cp -p -- systemd/user/notify-email@.service.d/50-notify-email.conf \
+ $(XDG_DATA_HOME)/systemd/user/notify-email@.service.d
+ mkdir -p -- $(XDG_DATA_HOME)/systemd/user/run-.service.d
+ cp -p -- systemd/user/run-.service.d/50-notify-email.conf \
+ $(XDG_DATA_HOME)/systemd/user/run-.service.d
install-tidy: install-sh
- cp -p -- tidy/profile.d/* $(HOME)/.profile.d
- cp -p -- tidy/tidyrc $(HOME)/.tidyrc
+ cp -p -- tidy/profile.d/tidy.sh $(HOME)/.profile.d
+ mkdir -p -- $(XDG_CONFIG_HOME)/tidy
+ cp -p -- tidy/tidyrc $(XDG_CONFIG_HOME)/tidy/tidyrc
-install-tmux: tmux/tmux.conf install-terminfo
+install-tmux: tmux/bin/tmux tmux/tmux.conf install-systemd
+ cp -p -- tmux/bin/tmux $(HOME)/.local/bin
+ cp -p -- tmux/profile.d/tmux.sh $(HOME)/.profile.d
cp -p -- tmux/tmux.conf $(HOME)/.tmux.conf
-
-install-urxvt: urxvt/ext/select
- mkdir -p -- $(HOME)/.urxvt/ext
- find urxvt/ext -type f ! -name '*.pl' \
- -exec cp -p -- {} $(HOME)/.urxvt/ext \;
+ cp -p -- tmux/systemd/user/tmux.service \
+ $(XDG_DATA_HOME)/systemd/user
VIM = vim
VIMDIR = $(HOME)/.vim
-VIMRC = $(HOME)/.vim/vimrc
-
-install-vim: install-vim-after \
- install-vim-autoload \
- install-vim-bundle \
- install-vim-compiler \
- install-vim-config \
- install-vim-filetype \
- install-vim-ftplugin \
- install-vim-indent \
- install-vim-plugin \
- install-vim-syntax
-
-install-vim-after: install-vim-after-ftplugin \
- install-vim-after-indent \
- install-vim-after-plugin \
- install-vim-after-syntax
-
-install-vim-after-ftplugin: install-vim-compiler
- mkdir -p $(VIMDIR)/after/ftplugin
- cp -p -- vim/after/ftplugin/*.vim $(VIMDIR)/after/ftplugin
-
-install-vim-after-indent: install-vim-autoload
- mkdir -p $(VIMDIR)/after/indent
- cp -p -- vim/after/indent/*.vim $(VIMDIR)/after/indent
-
-install-vim-after-plugin: install-vim-autoload
- mkdir -p $(VIMDIR)/after/plugin
- cp -p -- vim/after/plugin/*.vim $(VIMDIR)/after/plugin
-
-install-vim-after-syntax:
- mkdir -p $(VIMDIR)/after/syntax
- cp -p -- vim/after/syntax/*.vim $(VIMDIR)/after/syntax
-
-install-vim-autoload:
- mkdir -p $(VIMDIR)/autoload
- cd vim && find autoload \
- -type d -exec sh -c \
- 'mkdir -p -- $(VIMDIR)/"$$1"' _ {} \; \
- -o \
- -type f -exec sh -c \
- 'cp -p -- "$$1" $(VIMDIR)/"$$1"' _ {} \;
-
-install-vim-bundle: install-vim-config
- cd vim/bundle && find */* \
- -type d -exec sh -c \
- 'mkdir -p -- $(VIMDIR)/"$${1#*/}"' _ {} \;
- cd vim/bundle && find */*/* \
- -type f -exec sh -c \
- 'cp -p -- "$$1" $(VIMDIR)/"$${1#*/}"' _ {} \;
- $(VIM) -e -u NONE -c 'helptags $(VIMDIR)/doc' -c quit
-
-install-vim-cache:
- mkdir -p -- \
- $(VIMDIR)/cache \
- $(VIMDIR)/cache/backup \
- $(VIMDIR)/cache/spell \
- $(VIMDIR)/cache/swap \
- $(VIMDIR)/cache/undo
-
-install-vim-compiler:
- mkdir -p -- $(VIMDIR)/compiler
- cp -p -- vim/compiler/*.vim $(VIMDIR)/compiler
+VIMRC = $(VIMDIR)/vimrc
-install-vim-config: install-vim-autoload install-vim-cache
+install-vim:
+ mkdir -p -- $(VIMDIR)
cp -p -- vim/vimrc.stub $(HOME)/.vimrc
cp -p -- vim/vimrc $(VIMRC)
-
-install-vim-filetype:
- cp -p -- vim/filetype.vim vim/scripts.vim $(VIMDIR)
-
-install-vim-ftplugin: install-vim-autoload
- mkdir -p -- $(VIMDIR)/ftplugin
- cp -p -- vim/ftplugin/*.vim $(VIMDIR)/ftplugin
+ cp -p -- vim/filetype.vim \
+ vim/scripts.vim \
+ $(VIMDIR)
+ cp -pR -- vim/after \
+ vim/autoload \
+ vim/compiler \
+ vim/ftplugin \
+ vim/indent \
+ vim/plugin \
+ vim/syntax \
+ $(VIMDIR)
+ for ent in vim/bundle/*/* ; do \
+ [ -d "$$ent" ] || continue ; \
+ cp -pR -- "$$ent" $(VIMDIR) ; \
+ done
GVIMRC = $(HOME)/.gvimrc
-install-vim-gui: install-vim \
- install-vim-gui-config
-
-install-vim-gui-config:
+install-vim-gui: install-vim
cp -p -- vim/gvimrc $(GVIMRC)
-install-vim-indent:
- mkdir -p -- $(VIMDIR)/indent
- cp -p -- vim/indent/*.vim $(VIMDIR)/indent
-
-install-vim-plugin: install-vim-autoload
- mkdir -p -- $(VIMDIR)/plugin
- cp -p -- vim/plugin/*.vim $(VIMDIR)/plugin
-
-install-vim-syntax:
- mkdir -p -- $(VIMDIR)/syntax
- cp -p -- vim/syntax/*.vim $(VIMDIR)/syntax
-
-install-vim-thesaurus:
- mkdir -p -- $(VIMDIR)/ref
- curl 'https://sanctum.geek.nz/ref/thesaurus.txt' \
- > $(VIMDIR)/ref/thesaurus.txt
-
install-vint:
cp -p -- vint/vintrc.yaml $(HOME)/.vintrc.yaml
-install-wget:
- cp -p -- wget/wgetrc $(HOME)/.wgetrc
+install-wget: install-sh
+ cp -p -- wget/profile.d/wget.sh $(HOME)/.profile.d
+ mkdir -p -- $(XDG_CACHE_HOME)/wget $(XDG_CONFIG_HOME)/wget
+ cp -p -- wget/wgetrc $(XDG_CONFIG_HOME)/wget/wgetrc
-install-x: check-xinit
- mkdir -p -- \
- $(HOME)/.config \
- $(HOME)/.config/sxhkd \
- $(HOME)/.xinitrc.d \
- $(HOME)/.Xresources.d
- cp -p -- X/redshift.conf $(HOME)/.config
- cp -p -- X/sxhkdrc $(HOME)/.config/sxhkd
- cp -p -- X/xinitrc $(HOME)/.xinitrc
- cp -p -- X/xinitrc.d/* $(HOME)/.xinitrc.d
- cp -p -- X/Xresources $(HOME)/.Xresources
- cp -p -- X/Xresources.d/* $(HOME)/.Xresources.d
+install-x: check-x install-logrotate install-sh
+ cp -p -- x/Xresources $(HOME)/.Xresources
+ cp -p -- x/shrc.d/x.sh $(HOME)/.shrc.d
+ mkdir -p -- $(HOME)/.xsession.d
+
+install-xsession: x/xsession check-xsession install-x
+ cp -p -- x/xsession $(HOME)/.xsession
+ mkdir -p -- $(XDG_CONFIG_HOME)/log/xsession
+ cp -p -- x/logrotate/config.d/xsession $(XDG_CONFIG_HOME)/logrotate/config.d
install-zsh: check-zsh install-sh
- mkdir -p -- $(HOME)/.profile.d $(HOME)/.zshrc.d
- cp -p -- zsh/profile.d/* $(HOME)/.profile.d
+ mkdir -p -- $(HOME)/.zshrc.d
+ cp -p -- zsh/profile.d/zsh.sh $(HOME)/.profile.d
cp -p -- zsh/zprofile $(HOME)/.zprofile
cp -p -- zsh/zshrc $(HOME)/.zshrc
- cp -p -- zsh/zshrc.d/* $(HOME)/.zshrc.d
+ cp -p -- zsh/zshrc.d/*.zsh $(HOME)/.zshrc.d
check: check-bin \
check-git-template-hooks \
@@ -669,7 +677,7 @@ check: check-bin \
check-man \
check-sh
-check-bash:
+check-bash: bin/han
sh check/bash.sh
check-bin: $(BINS)
@@ -693,11 +701,11 @@ check-login-shell:
check-sh:
sh check/sh.sh
-check-urxvt: urxvt/ext/select
- sh check/urxvt.sh
+check-x:
+ sh check/x.sh
-check-xinit:
- sh check/xinit.sh
+check-xsession: x/xsession
+ sh check/xsession.sh
check-zsh:
sh check/zsh.sh
@@ -708,9 +716,8 @@ lint: lint-bash \
lint-git-template-hooks \
lint-ksh \
lint-sh \
- lint-urxvt \
lint-vim \
- lint-xinit
+ lint-x
lint-bash: check-bash
sh lint/bash.sh
@@ -730,11 +737,11 @@ lint-ksh: check-ksh
lint-sh: check-sh
sh lint/sh.sh
-lint-urxvt: check-urxvt
- sh lint/urxvt.sh
-
lint-vim:
sh lint/vim.sh
-lint-xinit: check-xinit
- sh lint/xinit.sh
+lint-x: check-x
+ sh lint/x.sh
+
+lint-xsession: x/xsession check-xsession
+ sh lint/xsession.sh
diff --git a/README.md b/README.md
index 774031a0..6861776a 100644
--- a/README.md
+++ b/README.md
@@ -5,28 +5,29 @@ This is my personal repository of configuration files and scripts for `$HOME`,
including most of the settings that migrate well between machines.
This repository began as a simple way to share Vim and tmux configuration, but
-over time a lot of scripts and shell configuration have been added, making it
+a lot of scripts and shell configuration have been added over time, making it
into a personal suite of custom Unix tools.
Installation
------------
- $ git clone https://sanctum.geek.nz/code/dotfiles.git ~/.dotfiles
- $ cd ~/.dotfiles
+ $ mkdir -p ~/.local/src
+ $ git clone https://dev.sanctum.geek.nz/code/dotfiles.git ~/.local/src/dotfiles
+ $ cd ~/.local/src/dotfiles
$ git submodule init
$ git submodule update
$ make
- $ make -n install
+ $ make -n install # Check output carefully
$ make install
For the default `all` target, you'll need a POSIX-fearing userland, including
`make(1)` and `m4(1)`.
-The installation `Makefile` will overwrite things standing in the way of its
+The installation `Makefile` overwrites things standing in the way of its
installed files without backing them up, so read the output of `make -n
-install` before running `make install` to make sure you aren't going to lose
-anything unexpected. If you're still not sure, install it in a temporary
-directory so you can explore:
+install` before running `make install` carefully, to make sure you aren't going
+to lose anything unexpected. If you're still not sure, install it in
+a temporary directory first, so you can explore:
$ tmpdir=$(mktemp -d)
$ make install HOME="$tmpdir"
@@ -35,154 +36,162 @@ directory so you can explore:
The default `install` target will install these targets and all their
dependencies:
-* `install-bin`
-* `install-bin-man`
-* `install-curl`
-* `install-ex`
-* `install-git`
-* `install-gnupg`
-* `install-less`
-* `install-login-shell`
-* `install-readline`
-* `install-vim`
-
-The `install-login-shell` looks at your `SHELL` environment variable and tries
-to figure out which shell's configuration files to install, falling back on
-`install-sh`.
+- `install-bin`
+- `install-curl`
+- `install-ex`
+- `install-git`
+- `install-gnupg`
+- `install-less`
+- `install-login-shell`
+- `install-man`
+- `install-readline`
+- `install-vim`
+
+The `install-login-shell` target looks at your `SHELL` environment variable,
+and tries to figure out which shell's configuration files to install, falling
+back on `install-sh`.
The remaining files can be installed with the other `install-*` targets. Try
`awk -f bin/mftl.awk Makefile` in the project's root directory to see a list.
### Configuration
-To save a set of `make` targets useful for a specific user or host, you can
-save them in a newline-separated file `~/.dotfiles.conf`, and install using
-that with the special `install-conf` target. This can include variable
-settings, too:
+To keep a set of `make` targets useful for a specific user or host, you can
+list them in a newline-separated file `~/.config/dotfiles/config`, and install
+using that with the special `install-conf` target. This can include macro
+settings for the `Makefile`, too:
$ cd
- $ cat .dotfiles.conf
+ $ cat .config/dotfiles/config
install-bash
install-bin
EMAIL=you@example.com
- $ make -C .dotfiles install-conf
+ $ make -C .local/src/dotfiles install-conf
Tools
-----
Configuration is included for:
-* Bourne-style POSIX shells, sharing a `.profile`, an `ENV` file, and some
+- Bourne-style POSIX shells, sharing a `.profile`, an `ENV` file, and some
helper functions:
- * [GNU Bash](https://www.gnu.org/software/bash/) (3.0 or higher)
- * [Korn shell](http://www.kornshell.com/) (`ksh93`, `pdksh`, `mksh`)
- * [Z shell](https://www.zsh.org/)
-* [Abook](http://abook.sourceforge.net/) -- curses address book program
-* [cURL](https://curl.haxx.se/) -- Command-line tool for transferring data with
+ - [GNU Bash](https://www.gnu.org/software/bash/) (v3.0 or newer)
+ - [Korn shell](http://www.kornshell.com/) (`ksh93`, `pdksh`, `mksh`)
+ - [Z shell](https://www.zsh.org/)
+- [Abook](http://abook.sourceforge.net/)---curses address book program
+- [cURL](https://curl.haxx.se/)---Command-line tool for transferring data with
URL syntax
-* [Dillo](https://www.dillo.org/) -- A lightweight web browser
-* [Dunst](https://dunst-project.org/) -- A lightweight X11 notification daemon
- that works with `libnotify`
-* `finger(1)` -- User information lookup program
-* [Git](https://git-scm.com/) -- Distributed version control system
-* [GNU Emacs](https://www.gnu.org/software/emacs/) -- Extensible text editor
-* [GnuPG](https://www.gnupg.org/) -- GNU Privacy Guard, for private
+- [Dillo](https://www.dillo.org/)---A lightweight web browser
+- `finger(1)`---User information lookup program
+- [Git](https://git-scm.com/)---Distributed version control system
+- [GNU Emacs](https://www.gnu.org/software/emacs/)---Extensible text editor
+- [GnuPG](https://www.gnupg.org/)---GNU Privacy Guard, for private
communication and file encryption
-* [GTK+](https://www.gtk.org/) -- GIMP Toolkit, for graphical user interface
- elements
-* [i3](https://i3wm.org/) -- Tiling window manager
-* [less](https://www.gnu.org/software/less/) -- Terminal pager
-* [mpv](https://mpv.io/) -- Media player
-* [Mutt](http://www.mutt.org/) -- Terminal mail user agent
-* [`mysql(1)`](https://linux.die.net/man/1/mysql) -- Command-line MySQL client
-* [Ncmpcpp](https://rybczak.net/ncmpcpp/) -- ncurses music player client
-* [Newsboat](https://newsboat.org/) -- Terminal RSS/Atom feed reader
-* [`psql(1)`](https://linux.die.net/man/1/psql) -- Command-line PostgreSQL
+- [i3](https://i3wm.org/)---Tiling window manager
+- [less](https://www.gnu.org/software/less/)---Terminal pager
+- [mpv](https://mpv.io/)---Media player
+- [Mutt](http://www.mutt.org/)---Terminal mail user agent
+- [`mysql(1)`](https://linux.die.net/man/1/mysql)---Command-line MySQL client
+- [ncmpcpp](https://rybczak.net/ncmpcpp/)---ncurses based MPD client inspired
+ by ncmpc
+- [Newsboat](https://newsboat.org/)---Terminal RSS/Atom feed reader
+- [`psql(1)`](https://linux.die.net/man/1/psql)---Command-line PostgreSQL
client
-* [Perl::Critic](http://perlcritic.com/) -- static source code analysis engine
+- [Parcellite](http://parcellite.sourceforge.net/)---clipboard manager for X
+- [Perl::Critic](http://perlcritic.com/)---static source code analysis engine
for Perl
-* [Perl::Tidy](http://perltidy.sourceforge.net/) -- Perl source code
- reformatter
-* [Readline](https://tiswww.case.edu/php/chet/readline/rltop.html) -- GNU
+- [Perl::Tidy](http://perltidy.sourceforge.net/)---reformats Perl source code
+- [Readline](https://tiswww.case.edu/php/chet/readline/rltop.html)---GNU
library for user input used by Bash, MySQL, and others
-* [rxvt-unicode](http://software.schmorp.de/pkg/rxvt-unicode.html) -- Fork of
- the rxvt terminal emulator with Unicode support
-* [Subversion](https://subversion.apache.org/) -- Apache Subversion, a version
+- [Subversion](https://subversion.apache.org/)---Apache Subversion, a version
control system
-* [tidy](http://www.html-tidy.org/) -- HTML/XHTML linter and tidier
-* [tmux](https://tmux.github.io/) -- Terminal multiplexer similar to GNU Screen
-* [Vim](https://www.vim.org/) -- Vi IMproved, a text editor
-* [X11](https://www.x.org/wiki/) -- Windowing system with network transparency
+- [tidy](http://www.html-tidy.org/)---HTML/XHTML linter and tidier
+- [tmux](https://tmux.github.io/)---Terminal multiplexer similar to GNU Screen
+- [Vim](https://www.vim.org/)---Vi IMproved, a text editor
+- [X11](https://www.x.org/wiki/)---Windowing system with network transparency
for Unix
-The configurations for shells, GnuPG, Mutt, tmux, and Vim are the most
-expansive, and most likely to be of interest. The i3 configuration is mostly
-changed to make window switching behave like Vim windows and tmux panes do, and
-there's a fair few resources defined for rxvt-unicode.
+There is also some slightly customized support for multi-version environment
+management for three major scripting languages:
+
+- [plenv](https://github.com/tokuhirom/plenv)---Perl
+- [pyenv](https://github.com/pyenv/pyenv)---Python
+- [rbenv](https://github.com/rbenv/rbenv)---Ruby
+
+The configurations for shells, Mutt, tmux, and Vim are the most likely to be of
+interest. The i3 configuration is limited mainly to changing window switching
+key bindings to match Vim's.
### Shell
-My `.profile` and other files in `sh` are written in POSIX shell script, so
-they should work in most `sh(1)` implementations. Individual scripts called by
-`.profile` are saved in `.profile.d` and iterated on login for ease of
-management. Most of these boil down to exporting variables appropriate to the
-system and the software it has available.
+On GNU/Linux, I use Bash; on \*BSD, I use some variant of Korn Shell,
+preferably `ksh93` if it's available.
+
+#### POSIX core
+
+My `~/.profile` and other files in `sh` are written in POSIX shell script, so
+they *should* work in most POSIX-conforming `sh(1)` implementations. Please
+email me if you find a case where they don't!
-Configuration that should be sourced for all POSIX-fearing interactive shells
-is kept in `~/.shrc`, with subscripts read from `~/.shrc.d`. There's a shim in
-`~/.shinit` to act as `ENV`. I make an effort to target POSIX for my functions
-and scripts where I can so that the same files can be loaded for all shells.
+Further shell snippets to run on login are sourced from `~/.profile.d` by
+`~/.profile`. Most of these boil down to exporting variables appropriate to
+the system and the software it has available.
-On GNU/Linux I use Bash, on BSD I use some variant of Korn Shell, preferably
-`ksh93` if it's available.
+Configuration that should be sourced for all conforming *interactive* shells is
+kept in `~/.shrc`, with subscripts read from `~/.shrc.d`. There's
+a `~/.shinit` shim to act as `ENV`.
-My Bash is written to work with [any version 3.0 or
+#### GNU Bash
+
+My Bash scripts are written to work with GNU Bash [v3.0 or
newer](https://wiki.bash-hackers.org/scripting/bashchanges). This is why I use
older syntax for certain things such as appending items to arrays:
array[${#array[@]}]=$item
-Compare this to the much nicer syntax available since 3.1-alpha1, which
-actually works for arrays with sparse indices, unlike the above syntax:
+This doesn't work for arrays with sparse indices; compare this to the much
+nicer syntax available since 3.1-alpha1, which does:
array+=("$item")
-Where I do use features that are only available in versions of Bash newer than
-3.0, such as newer `shopt` options or `PROMPT_DIRTRIM`, they are only run after
-testing `BASH_VERSINFO` appropriately.
+I do use some features that are only available in versions after v3.0, such as
+newer `shopt` options like `dirspell`, or variables like `PROMPT_DIRTRIM`.
+These are set only after testing `BASH_VERSINFO` appropriately.
#### Prompt
A terminal session with my prompt looks something like this:
~$ ssh remote
- remote:~$ cd .dotfiles
- remote:~/.dotfiles(master+!)$ git status
+ remote:~$ cd .local/src/dotfiles
+ remote:~/.local/src/dotfiles(master+!)$ git status
M README.md
M bash/bashrc.d/prompt.bash
A init
- remote:~/.dotfiles(master+!)$ foobar
+ remote:~/.local/src/dotfiles(master+!)$ foobar
foobar: command not found
- remote:~/.dotfiles(master+!)<127>$ sleep 5 &
+ remote:~/.local/src/dotfiles(master+!)<127>$ sleep 5 &
[1] 28937
- remote:~/.dotfiles(master+!){1}$
+ remote:~/.local/src/dotfiles(master+!){1}$
The hostname is elided if not connected via SSH. The working directory with
tilde abbreviation for `$HOME` is always shown. The rest of the prompt expands
-based on context to include these elements in this order:
+based on context to include these elements, in this order:
+
+- Whether in a Git repository if applicable,
-* Whether in a Git repository if applicable, and punctuation to show repository
- status including reference to upstreams at a glance. Subversion support can
- also be enabled (I need it at work), in which case a `git:` or `svn:` prefix
- is added appropriately.
-* The number of running background jobs, if non-zero.
-* The exit status of the last command, if non-zero.
+- The current version control branch, tag, or commit/revision if applicable,
+ and punctuation to show repository status including reference to upstreams at
+ a glance. Subversion support can also be enabled, in which case a `git:` or
+ `svn:` prefix is added appropriately for disambiguation.
+- The number of running background jobs, if non-zero.
+- The exit status of the last command, if non-zero.
You can set `PROMPT_COLOR`, `PROMPT_PREFIX`, and `PROMPT_SUFFIX` too, which all
do about what you'd expect.
-If you start up Bash, Korn shell, or Z shell, and it detects that it's not your
-login shell, the prompt will display an appropriate prefix.
+If you start up GNU Bash, Korn shell, or Z shell, and that doesn't match your
+login shell, the prompt should display an appropriate prefix.
This is all managed within the `prompt` function. There's some mildly hacky
logic on `tput` codes included such that it should work correctly for most
@@ -195,60 +204,59 @@ terminals.
If a function can be written in POSIX `sh` without too much hackery, I put it
in `sh/shrc.d` to be loaded by any POSIX interactive shell. Those include:
-* Four functions for using a "marked" directory, which I find a more manageable
+- Four functions for using a "marked" directory, which I find a more manageable
concept than the `pushd`/`popd` directory stack:
- * `md()` marks a given (or the current) directory.
- * `gd()` goes to the marked directory.
- * `pmd()` prints the marked directory.
- * `xd()` swaps the current and marked directories.
-* Ten other directory management and navigation functions:
- * `bd()` changes into a named ancestor of the current directory.
- * `gt()` changes into a directory or into a file's directory.
- * `lgt()` runs `gt()` on the first result from a `loc(1df)` search.
- * `mkcd()` creates a directory and changes into it.
- * `pd()` changes to the argument's parent directory.
- * `rd()` replaces the first instance of its first argument with its second
+ - `md()` marks a given (or the current) directory.
+ - `gd()` goes to the marked directory.
+ - `pmd()` prints the marked directory.
+ - `xd()` swaps the current and marked directories.
+- Ten other directory management and navigation functions:
+ - `bd()` changes into a named ancestor of the current directory.
+ - `gt()` changes into a directory or into a file's directory.
+ - `lgt()` runs `gt()` on the first result from a `loc(1df)` search.
+ - `mkcd()` creates a directory and changes into it.
+ - `pd()` changes to the argument's parent directory.
+ - `rd()` replaces the first instance of its first argument with its second
argument in `$PWD`, emulating a feature of the Zsh `cd` builtin that I
like.
- * `scr()` creates a temporary directory and changes into it.
- * `sd()` changes into a sibling of the current directory.
- * `ud()` changes into an indexed ancestor of a directory.
- * `vr()` tries to change to the root directory of a source control
+ - `scr()` creates a temporary directory and changes into it.
+ - `sd()` changes into a sibling of the current directory.
+ - `ud()` changes into an indexed ancestor of a directory.
+ - `vr()` tries to change to the root directory of a source control
repository.
-* Two editor wrapper functions:
- * `e()` invokes `$EDITOR`, or `ed(1)` if not set.
- * `v()` invokes `$VISUAL`, or `vi(1)` if not set.
-* `bc()` silences startup messages from GNU `bc(1)`.
-* `ed()` tries to get verbose error messages, a prompt, and a Readline
+- Two editor wrapper functions:
+ - `e()` invokes `$EDITOR`, or `ed(1)` if not set.
+ - `v()` invokes `$VISUAL`, or `vi(1)` if not set.
+- `bc()` silences startup messages from GNU `bc(1)`.
+- `ed()` tries to get verbose error messages, a prompt, and a Readline
environment for `ed(1)`.
-* `gdb()` silences startup messages from `gdb(1)`.
-* `grep()` tries to apply color and other options good for interactive use if
+- `gdb()` silences startup messages from `gdb(1)`.
+- `grep()` tries to apply color and other options good for interactive use if
available.
-* `hgrep()` allows searching `$HISTFILE`.
-* `keychain()` keeps `$GPG_TTY` up to date if a GnuPG agent is available.
-* `ls()` tries to apply color and other options good for interactive use if
+- `hgrep()` allows searching `$HISTFILE`.
+- `ls()` tries to apply color and other options good for interactive use if
available.
- * `la()` runs `ls -A` if it can, or `ls -a` otherwise.
- * `ll()` runs `ls -Al` if it can, or `ls -al` otherwise.
-* `path()` manages the contents of `PATH` conveniently.
-* `scp()` tries to detect forgotten hostnames in `scp(1)` command calls.
-* `sudo()` forces `-H` for `sudo(8)` calls so that `$HOME` is never preserved;
- I hate having `root`-owned files in my home directory.
-* `tree()` colorizes GNU `tree(1)` output if possible (without having
+ - `la()` runs `ls -A` if it can, or `ls -a` otherwise.
+ - `ll()` runs `ls -Al` if it can, or `ls -al` otherwise.
+- `path()` manages the contents of `PATH` conveniently.
+- `scp()` tries to detect forgotten hostnames in `scp(1)` command calls.
+- `tor()` is just a terse shortcut for using Torsocks to anonymize TCP
+ connections from the current shell.
+- `tree()` colorizes GNU `tree(1)` output if possible (without having
`LS_COLORS` set).
-* `x()` is a one-key shortcut for `exec startx`.
+- `x()` is a one-key shortcut for `exec startx`.
There are a few other little tricks defined for other shells providing
non-POSIX features, as compatibility allows:
-* `keep()` stores ad-hoc shell functions and variables (Bash, Korn Shell 93, Z
+- `keep()` stores ad-hoc shell functions and variables (Bash, Korn Shell 93, Z
shell).
-* `prompt()` sets up my interactive prompt (Bash, Korn Shell, Z shell).
-* `pushd()` adds a default destination of `$HOME` to the `pushd` builtin
+- `prompt()` sets up my interactive prompt (Bash, Korn Shell, Z shell).
+- `pushd()` adds a default destination of `$HOME` to the `pushd` builtin
(Bash).
-* `vared()` allows interactively editing a variable with Readline, emulating a
- Zsh function I like by the same name (Bash).
-* `ver()` prints the current shell's version information (Bash, Korn Shell, Z
+- `vared()` allows interactively editing a variable with Readline, emulating a
+ Z shell function I like by the same name (Bash).
+- `ver()` prints the current shell's version information (Bash, Korn Shell, Z
shell).
#### Completion
@@ -258,16 +266,16 @@ off using a stub file installed in `~/.config/bash_completion`. The majority
of the time I just want to complete paths anyway, and this makes for a quicker
startup without a lot of junk functions in my Bash namespace.
-I do make some exceptions with completions defined in `.bash_completion.d`
-files, for things I really do get tired of typing repeatedly:
+I do make some exceptions with completions defined in files in
+`~/.bash_completion.d` for things I really do get tired of typing repeatedly:
-* Bash builtins: commands, help topics, shell options, variables, etc.
-* `find(1)`'s more portable options
-* `gpg(1)` long options
-* `make(1)` targets read from a `Makefile`
-* `man(1)` page titles
-* `pass(1)` entries
-* `ssh(1)` hostnames from `~/.ssh/config`
+- Bash builtins: commands, help topics, shell options, variables, etc.
+- `find(1)`'s more portable options
+- `gpg(1)` long options
+- `make(1)` targets read from a `Makefile`
+- `man(1)` page titles
+- `pass(1)` entries
+- `ssh(1)` hostnames from `~/.ssh/config`
For commands that pretty much always want to operate on text, such as text file
or stream editors, I exclude special file types and extensions I know are
@@ -290,19 +298,11 @@ These are experimental; I do not like Z shell much at the moment. The files
started as a joke (`exec bash`). `zsh` shells default to having a prompt
colored cyan.
-### GnuPG
-
-The configuration for GnuPG is intended to follow [RiseUp's OpenPGP best
-practices](https://riseup.net/en/security/message-security/openpgp/best-practices).
-The configuration file is rebuilt using `mi5(1df)` and `make(1)` because it
-requires hard-coding a path to the SKS keyserver certificate authority, and
-neither tilde nor `$HOME` expansion works for this.
-
### Mutt
-My mail is kept in individual Maildirs under `~/Mail`, with `inbox` being where
-most unfiltered mail is sent. I use
-[Getmail](http://pyropus.ca/software/getmail/),
+My mail is kept in individual Maildir-format directories under `~/mail`, with
+the system mail spool in e.g. `/var/mail/tejr` being where most unfiltered new
+mail is spooled. I use [Getmail](http://pyropus.ca/software/getmail/),
[maildrop](https://www.courier-mta.org/maildrop/), and
[msmtp](https://marlam.de/msmtp/); the configurations for these are not
included here. I sign whenever I have some indication that the recipient might
@@ -310,28 +310,18 @@ be using a PGP implementation, and I encrypt whenever I have a public key
available for them. The GnuPG and S/MIME interfacing is done with
[GPGme](https://www.gnupg.org/related_software/gpgme/), rather than defining
commands for each crypto operation. I wrote [an article about this
-setup](https://sanctum.geek.nz/arabesque/gnu-linux-crypto-email/) if it sounds
+setup](https://blog.sanctum.geek.nz/gnu-linux-crypto-email/) if it sounds
appealing.
You'll need Abook installed if you want to use the `query_command` I have
defined, and msmtp for the `sendmail` command.
-### rxvt-unicode
-
-I've butchered the URxvt Perl extensions `selection-to-clipboard` and
-`selection` into a single `select` extension in `~/.urxvt/ext`, which is the
-only extension I define in `~/.Xresources`.
-
-The included `.Xresources` file assumes that `urxvt` can use 256 colors and
-Perl extensions. If you're missing functionality, try changing
-`perl-ext-common` to `default`.
-
### tmux
-These are just generally vi-friendly settings, not much out of the ordinary.
-Note that the configuration presently uses a hard-coded 256-color color scheme,
-and uses non-login shells, with an attempt to control the environment to stop
-shells thinking they have access to an X display.
+These are just generally vi-friendly settings, and there isn't much out of the
+ordinary. Note that the configuration presently uses a hard-coded 256-color
+color scheme, and uses non-login shells, with an attempt to control the
+environment to stop shells thinking they have access to an X display.
The shell scripts in `bin` include `tm(1df)`, a shortcut to make `attach` into
the default command if no arguments are given and sessions do already exist.
@@ -341,9 +331,19 @@ key combination to detach.
### Vim
The majority of the Vim configuration is just setting options, with a fair few
-mappings and remappings, both global and buffer-local. I try not to deviate
-too much from the Vim defaults behavior in terms of interactive behavior and
-keybindings. It's extensively commented.
+mappings and remappings, both global and buffer-local. It's extensively
+commented.
+
+#### XDG Basedirs
+
+The [XDG Base Directory
+Specification](https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html)'s
+environment variables are checked on startup, and appropriate directories are
+added to the start and end of `'runtimepath'`. I use these separate
+directories for machine-local configuration, usually in `~/.config/vim`, while
+all the files that this suite installs land in `~/.vim`. Backups, swap files,
+persistent undo data, saved views, and the `viminfo` file all live under
+`XDG_CACHE_HOME`, normally `~/.cache/vim`.
#### Filetypes
@@ -355,293 +355,290 @@ filetypes in custom `ftdetect` rules.
#### Plugins
If the logic for doing something involves more than a few lines or any
-structures like functions, I like to implement it as a plugin in
-`~/.vim/plugin` and/or `~/.vim/autoload`, with documentation for each in
-`~/.vim/doc`.
+structures like functions that can be decoupled from `$MYVIMRC`, I like to
+implement it as a plugin in `~/.vim/plugin` and/or `~/.vim/autoload`, with
+documentation for each in `~/.vim/doc`.
They eventually get either discarded if I stop using them, or spun off into
-their own repositories if I don't, and added to this repository as submodules
-under `vim/bundle` instead. Some of them I upload to
+their own repositories and added to this repository as submodules under
+`vim/bundle` if I don't. Some of them I upload to
[vim.org](https://www.vim.org/account/profile.php?user_id=73687).
#### Filetype plugins
I apply some replacement or supplementary configuration specific to file types
I often edit in `~/.vim` and `~/.vim/after`, in the `ftplugin`, `indent`, and
-`syntax` subdirectories. Some of these filetype plugins or extensions will
-also eventually be removed to be separately distributed, and installed via
+`syntax` subdirectories. Some of these filetype plugins or extensions may also
+eventually be removed to be separately distributed, and installed via
submodules instead.
#### Compilers
I define a few of my own `:compiler` scripts for `~/.vim/compiler` to check and
-lint appropriate filetypes. I bind checking--"does it run?"--and linting--"is
-it good?"--with separate local leader maps; for example, for `perl` filetypes,
+lint appropriate filetypes. I bind checking---"does it run?"---and linting---"is
+it good?"---with separate local leader maps; for example, for `perl` filetypes,
`<LocalLeader>c` switches `makeprg` to `perl -c` for checking, and
`<LocalLeader>l` to `perlcritic` for linting.
#### No Neovim support
The configuration doesn't explicitly support Neovim, although most of it will
-probably work.
+probably work; you would probably just comment out the settings for a few of
+the removed options.
Scripts
-------
Where practical, I make short scripts into POSIX (but not Bourne) `sh(1)`,
`awk(1)`, or `sed(1)` scripts in `~/.local/bin`. I try to use shell functions
-only when I actually need to, which tends to be when I need to tinker with the
-namespace of the user's current shell.
+only when I actually need to, which tends to be when I need to change the state
+of the user's current shell, or to limit a change in behavior only to
+interactive shells.
-Installed by the `install-bin` target:
+These scripts are installed by the `install-bin` target:
-* Three SSH-related scripts:
- * `sls(1df)` prints hostnames read from a `ssh_config(5)` file. It uses
+- Three SSH-related scripts:
+ - `sls(1df)` prints hostnames read from `ssh_config(5)` files. It uses
`slsf(1df)` to read each one.
- * `sra(1df)` runs a command on multiple hosts read from `sls(1df)` and
+ - `sra(1df)` runs a command on multiple hosts read from `sls(1df)` and
prints output.
- * `sta(1df)` runs a command on multiple hosts read from `sls(1df)` and
+ - `sta(1df)` runs a command on multiple hosts read from `sls(1df)` and
prints the hostname if the command returns zero.
-* Five URL-related shortcut scripts:
- * `hurl(1df)` extracts values of `href` attributes of `<a>` tags, sorts
+- Five URL-related shortcut scripts:
+ - `hurl(1df)` extracts values of `href` attributes of `<a>` tags, sorts
them uniquely, and writes them to `stdout`; it requires
[pup](https://github.com/ericchiang/pup).
- * `murl(1df)` converts Markdown documents to HTML with `pandoc(1)` and runs
+ - `murl(1df)` converts Markdown documents to HTML with `pandoc(1)` and runs
the output through `hurl(1df)`.
- * `urlc(1df)` accepts a list of URLs on `stdin` and writes error messages
+ - `urlc(1df)` accepts a list of URLs on `stdin` and writes error messages
to `stderr` if any of the URLs are broken, redirecting, or are insecure
and have working secure versions; requires `curl(1)`.
- * `urlh(1df)` prints the values for a given HTTP header from a HEAD
+ - `urlh(1df)` prints the values for a given HTTP header from a HEAD
response.
- * `urlmt(1df)` prints the MIME type from the `Content-Type` header as
+ - `urlmt(1df)` prints the MIME type from the `Content-Type` header as
retrieved by `urlh(1df)`.
-* Three RFC-related shortcut scripts:
- * `rfcf(1df)` fetches ASCII RFCs from the IETF website.
- * `rfct(1df)` formats ASCII RFCs.
- * `rfcr(1df)` does both, displaying in a pager if appropriate, like a
+- Three RFC-related shortcut scripts:
+ - `rfcf(1df)` fetches ASCII RFCs from the IETF website.
+ - `rfct(1df)` formats ASCII RFCs.
+ - `rfcr(1df)` does both, displaying in a pager if appropriate, like a
`man(1)` reader for RFCs.
-* Five toy random-number scripts (not for sensitive/dead-serious use):
- * `rndi(1df)` gets a random integer within two bounds.
- * `rnds(1df)` attempts to get an optional random seed for `rndi(1df)`.
- * `rnda(1df)` uses `rndi(1df)` to choose a random argument.
- * `rndf(1df)` uses `rnda(1df)` to choose a random file from a directory.
- * `rndl(1df)` uses `rndi(1df)` to choose a random line from files.
-* Four file formatting scripts:
- * `d2u(1df)` converts DOS line endings in files to UNIX ones.
- * `u2d(1df)` converts UNIX line endings in files to DOS ones.
- * `stbl(1df)` strips a trailing blank line from the files in its arguments.
- * `stws(1df)` strips trailing spaces from the ends of lines of the files in
+- Five toy random-number scripts (not for sensitive/dead-serious use):
+ - `rndi(1df)` gets a random integer within two bounds.
+ - `rnds(1df)` attempts to get an optional random seed for `rndi(1df)`.
+ - `rnda(1df)` uses `rndi(1df)` to choose a random argument.
+ - `rndf(1df)` uses `rnda(1df)` to choose a random file from a directory.
+ - `rndl(1df)` uses `rndi(1df)` to choose a random line from files.
+- Four file formatting scripts:
+ - `d2u(1df)` converts DOS line endings in files to UNIX ones.
+ - `u2d(1df)` converts UNIX line endings in files to DOS ones.
+ - `stbl(1df)` strips a trailing blank line from the files in its arguments.
+ - `stws(1df)` strips trailing spaces from the ends of lines of the files in
its arguments.
-* Seven stream formatting scripts:
- * `sd2u(1df)` converts DOS line endings in streams to UNIX ones.
- * `su2d(1df)` converts UNIX line endings in streams to DOS ones.
- * `slow(1df)` converts uppercase to lowercase.
- * `supp(1df)` converts lowercase to uppercase.
- * `tl(1df)` tags input lines with a prefix or suffix, basically a `sed(1)`
+- Seven stream formatting scripts:
+ - `sd2u(1df)` converts DOS line endings in streams to UNIX ones.
+ - `su2d(1df)` converts UNIX line endings in streams to DOS ones.
+ - `slow(1df)` converts uppercase to lowercase.
+ - `supp(1df)` converts lowercase to uppercase.
+ - `tl(1df)` tags input lines with a prefix or suffix, basically a `sed(1)`
shortcut.
- * `tlcs(1df)` executes a command and uses `tl(1df)` to tag standard output
+ - `tlcs(1df)` executes a command and uses `tl(1df)` to tag standard output
and standard error lines, and color them if you want.
- * `unf(1df)` joins lines with leading spaces to the previous line.
+ - `unf(1df)` joins lines with leading spaces to the previous line.
Intended for unfolding HTTP headers, but it should work for most RFC 822
formats.
-* Six simple aggregate scripts for numbers:
- * `max(1df)` prints the maximum.
- * `mean(1df)` prints the mean.
- * `med(1df)` prints the median.
- * `min(1df)` prints the minimum.
- * `mode(1df)` prints the first encountered mode.
- * `tot(1df)` totals the set.
-* Three quick-and-dirty HTML tools:
- * `htenc(1df)` encodes.
- * `htdec(1df)` decodes.
- * `htrec(1df)` wraps `a` tags around URLs.
-* Two internet message quoting tools:
- * `quo(1df)` indents with quoting right angle-brackets.
- * `wro(1df)` adds a quote attribution header to its input.
-* Six Git-related tools:
- * `fgscr(1df)` finds Git repositories in a directory root and scrubs them
+- Six simple aggregate scripts for numbers:
+ - `max(1df)` prints the maximum.
+ - `mean(1df)` prints the mean.
+ - `med(1df)` prints the median.
+ - `min(1df)` prints the minimum.
+ - `mode(1df)` prints the first encountered mode.
+ - `tot(1df)` totals the set.
+- Three quick-and-dirty HTML tools:
+ - `htenc(1df)` encodes.
+ - `htdec(1df)` decodes.
+ - `htrec(1df)` wraps `a` tags around URLs.
+- Two internet message quoting tools:
+ - `quo(1df)` indents with quoting right angle-brackets.
+ - `wro(1df)` adds a quote attribution header to its input.
+- Six Git-related tools:
+ - `fgscr(1df)` finds Git repositories in a directory root and scrubs them
with `gscr(1df)`.
- * `grc(1df)` quietly tests whether the given directory appears to be a Git
+ - `grc(1df)` quietly tests whether the given directory appears to be a Git
repository with pending changes.
- * `gscr(1df)` scrubs Git repositories.
- * `isgr(1df)` quietly tests whether the given directory appears to be a Git
+ - `gscr(1df)` scrubs Git repositories.
+ - `isgr(1df)` quietly tests whether the given directory appears to be a Git
repository.
- * `jfc(1df)` adds and commits lazily to a Git repository.
- * `jfcd(1df)` watches a directory for changes and runs `jfc(1df)` if it
+ - `jfc(1df)` adds and commits lazily to a Git repository.
+ - `jfcd(1df)` watches a directory for changes and runs `jfc(1df)` if it
sees any.
-* Two time duration functions:
- * `hms(1df)` converts seconds to `hh:mm:ss` or `mm:ss` timestamps.
- * `sec(1df)` converts `hh:mm:ss` or `mm:ss` timestamps to seconds.
-* Three pipe interaction tools:
- * `pst(1df)` runs an interactive program on data before passing it along a
+- Two time duration functions:
+ - `hms(1df)` converts seconds to `hh:mm:ss` or `mm:ss` timestamps.
+ - `sec(1df)` converts `hh:mm:ss` or `mm:ss` timestamps to seconds.
+- Three pipe interaction tools:
+ - `pst(1df)` runs an interactive program on data before passing it along a
pipeline.
- * `ped(1df)` runs `pst(1df)` with `$EDITOR` or `ed(1)`.
- * `pvi(1df)` runs `pvi(1df)` with `$VISUAL` or `vi(1)`.
-* Two editor wrapper tools:
- * `mked(1df)` creates paths to all its arguments before invoking `$EDITOR`.
- * `mkvi(1df)` creates paths to all its arguments before invoking `$VISUAL`.
-* `ap(1df)` reads arguments for a given command from the standard input,
+ - `ped(1df)` runs `pst(1df)` with `$EDITOR` or `ed(1)`.
+ - `pvi(1df)` runs `pvi(1df)` with `$VISUAL` or `vi(1)`.
+- Two editor wrapper tools:
+ - `mked(1df)` creates paths to all its arguments before invoking `$EDITOR`.
+ - `mkvi(1df)` creates paths to all its arguments before invoking `$VISUAL`.
+- `ap(1df)` reads arguments for a given command from the standard input,
prompting if appropriate.
-* `apf(1df)` inserts arguments to a command with ones read from a file,
+- `apf(1df)` inserts arguments to a command with ones read from a file,
intended as a framework for shell wrappers or functions.
-* `ax(1df)` evaluates an AWK expression given on the command line; this is
+- `ax(1df)` evaluates an AWK expression given on the command line; this is
intended as a quick way to test how AWK would interpret a given expression.
-* `bcq(1df)` runs `bc(1)`, quieting it down if need be.
-* `bel(1df)` prints a terminal bell character.
-* `bl(1df)` generates a given number of blank lines.
-* `bp(1df)` runs `br(1df)` after prompting for an URL.
-* `br(1df)` launches `$BROWSER`.
-* `ca(1df)` prints a count of its given arguments.
-* `cf(1df)` prints a count of entries in a given directory.
-* `cfr(1df)` does the same as `cf(1df)`, but recurses into subdirectories as
+- `bcq(1df)` runs `bc(1)`, quieting it down if need be.
+- `bel(1df)` prints a terminal bell character.
+- `bl(1df)` generates a given number of blank lines.
+- `bp(1df)` runs `br(1df)` after prompting for an URL.
+- `br(1df)` launches `$BROWSER`.
+- `ca(1df)` prints a count of its given arguments.
+- `cf(1df)` prints a count of entries in a given directory.
+- `cfr(1df)` does the same as `cf(1df)`, but recurses into subdirectories as
well.
-* `chc(1df)` caches the output of a command.
-* `chn(1df)` runs a filter over its input a given number of times.
-* `clog(1df)` is a tiny timestamped log system.
-* `clrd(1df)` sets up a per-line file read, clearing the screen first.
-* `clwr(1df)` sets up a per-line file write, clearing the screen before each
+- `chc(1df)` caches the output of a command.
+- `chn(1df)` runs a filter over its input a given number of times.
+- `clog(1df)` is a tiny timestamped log system.
+- `clrd(1df)` sets up a per-line file read, clearing the screen first.
+- `clwr(1df)` sets up a per-line file write, clearing the screen before each
line.
-* `csmw(1df)` prints an English list of monospace-quoted words read from the
+- `csmw(1df)` prints an English list of monospace-quoted words read from the
input.
-* `dam(1df)` buffers all its input before emitting it as output.
-* `ddup(1df)` removes duplicate lines from unsorted input.
-* `defang(1df)` prevents dangerous URLs from being made into clickable links.
-* `dmp(1df)` copies a pass(1) entry selected by `dmenu(1)` to the X CLIPBOARD.
-* `dub(1df)` lists the biggest entries in a directory.
-* `edda(1df)` provides a means to run `ed(1)` over a set of files preserving
+- `dam(1df)` buffers all its input before emitting it as output.
+- `ddup(1df)` removes duplicate lines from unsorted input.
+- `defang(1df)` prevents dangerous URLs from being made into clickable links.
+- `dub(1df)` lists the biggest entries in a directory.
+- `edda(1df)` provides a means to run `ed(1)` over a set of files preserving
any options, mostly useful for scripts.
-* `eds(1df)` edits executable script files in `EDSPATH`, defaulting to
+- `eds(1df)` edits executable script files in `EDSPATH`, defaulting to
`~/.local/bin`, for personal scripting snippets.
-* `exm(1df)` works around a screen-clearing quirk of Vim's `ex` mode.
-* `finc(1df)` counts the number of results returned from a set of given
+- `exm(1df)` works around a screen-clearing quirk of Vim's `ex` mode.
+- `finc(1df)` counts the number of results returned from a set of given
`find(1)` conditions.
-* `fnl(1df)` runs a command and saves its output and error into temporary
+- `fnl(1df)` runs a command and saves its output and error into temporary
files, printing their paths and line counts.
-* `fnp(1df)` prints the given files to standard output, each with a plain text
+- `fnp(1df)` prints the given files to standard output, each with a plain text
heading with the filename in it.
-* `gms(1df)` runs a set of `getmailrc` files; does much the same thing as the
+- `gms(1df)` runs a set of `getmailrc` files; does much the same thing as the
script `getmails` in the `getmail` suite, but runs the requests in parallel
and does up to three silent retries using `try(1df)`.
-* `grec(1df)` is a more logically-named `grep -c`.
-* `gred(1df)` is a more logically-named `grep -v`.
-* `gwp(1df)` searches for alphanumeric words in a similar way to `grep(1)`.
-* `han(1df)` provides a `keywordprg` for Vim's Bash script file type that will
+- `grec(1df)` is a more logically-named `grep -c`.
+- `gred(1df)` is a more logically-named `grep -v`.
+- `gwp(1df)` searches for alphanumeric words in a similar way to `grep(1)`.
+- `han(1df)` provides a `keywordprg` for Vim's Bash script file type that will
look for `help` topics. You could use it from the shell too.
-* `igex(1df)` wraps around a command to allow you to ignore error conditions
+- `igex(1df)` wraps around a command to allow you to ignore error conditions
that don't actually worry you, exiting with 0 anyway.
-* `ix(1df)` posts its input to the `ix.io` pastebin.
-* `jfp(1df)` prints its input, excluding any shebang on the first line only.
-* `loc(1df)` is a quick-search wrapped around `find(1)`.
-* `maybe(1df)` is like `true(1)` or `false(1)`; given a probability of success,
+- `ix(1df)` posts its input to the `ix.io` pastebin.
+- `jfp(1df)` prints its input, excluding any shebang on the first line only.
+- `loc(1df)` is a quick-search wrapped around `find(1)`.
+- `maybe(1df)` is like `true(1)` or `false(1)`; given a probability of success,
it exits with success or failure. Good for quick tests.
-* `mex(1df)` makes given filenames in `$PATH` executable.
-* `mi5(1df)` is a crude preprocessor for `m4`.
-* `mim(1df)` starts an interactive Mutt message with its input.
-* `mftl(1df)` finds usable-looking targets in Makefiles.
-* `mkcp(1df)` creates a directory and copies preceding arguments into it.
-* `mkmv(1df)` creates a directory and moves preceding arguments into it.
-* `motd(1df)` shows the system MOTD.
-* `mw(1df)` prints alphabetic space-delimited words from the input one per
+- `mex(1df)` makes given filenames in `$PATH` executable.
+- `mi5(1df)` is a crude preprocessor for `m4`.
+- `mim(1df)` starts an interactive Mutt message with its input.
+- `mftl(1df)` finds usable-looking targets in Makefiles.
+- `mkcp(1df)` creates a directory and copies preceding arguments into it.
+- `mkmv(1df)` creates a directory and moves preceding arguments into it.
+- `motd(1df)` shows the system MOTD.
+- `msc(1df)` crudely counts messages in an mbox.
+- `mw(1df)` prints alphabetic space-delimited words from the input one per
line.
-* `oii(1df)` runs a command on input only if there is any.
-* `onl(1df)` crunches input down to one printable line.
-* `osc(1df)` implements a `netcat(1)`-like wrapper for `openssl(1)`'s
+- `oii(1df)` runs a command on input only if there is any.
+- `onl(1df)` crunches input down to one printable line.
+- `osc(1df)` implements a `netcat(1)`-like wrapper for `openssl(1)`'s
`s_client` sub-command.
-* `p(1df)` prints concatenated standard input; `cat(1)` as it should always
+- `p(1df)` prints concatenated standard input; `cat(1)` as it should always
have been.
-* `pa(1df)` prints its arguments, one per line.
-* `phpcsff(1df)` wraps around
+- `pa(1df)` prints its arguments, one per line.
+- `phpcsff(1df)` wraps around
[PHP-CS-Fixer](https://github.com/FriendsOfPHP/PHP-CS-Fixer) to make it
a source code filter suitable for use as an `equalprg` in Vim.
-* `pp(1df)` prints the full path of each argument using `$PWD`.
-* `pph(1df)` runs `pp(1df)` and includes a leading `$HOSTNAME:`.
-* `paz(1df)` print its arguments terminated by NULL chars.
-* `pit(1df)` runs its input through a pager if its standard output looks like a
+- `pp(1df)` prints the full path of each argument using `$PWD`.
+- `pph(1df)` runs `pp(1df)` and includes a leading `$HOSTNAME:`.
+- `paz(1df)` print its arguments terminated by NULL chars.
+- `pit(1df)` runs its input through a pager if its standard output looks like a
terminal.
-* `plmu(1df)` retrieves a list of installed modules from
- [`plenv`](https://github.com/tokuhirom/plenv), filters out any modules in
- `~/.plenv/non-cpan-modules`, and updates them all.
-* `pwg(1df)` generates just one decent password with `pwgen(1)`.
-* `rep(1df)` repeats a command a given number of times.
-* `rgl(1df)` is a very crude interactive `grep(1)` loop.
-* `shb(1df)` attempts to build shebang lines for scripts from the system paths.
-* `sqs(1df)` chops off query strings from filenames, usually downloads.
-* `sshi(1df)` prints human-readable SSH connection details.
-* `stex(1df)` strips extensions from filenames.
-* `sue(8df)` execs `sudoedit(8)` as the owner of all the file arguments given,
+- `pwg(1df)` generates just one decent password with `pwgen(1)`.
+- `qat(1df)` disables `stty echo` for the duration of a paste.
+- `rep(1df)` repeats a command a given number of times.
+- `rgl(1df)` is a very crude interactive `grep(1)` loop.
+- `shb(1df)` attempts to build shebang lines for scripts from the system paths.
+- `sqs(1df)` chops off query strings from filenames, usually downloads.
+- `sshi(1df)` prints human-readable SSH connection details.
+- `stex(1df)` strips extensions from filenames.
+- `sue(8df)` execs `sudoedit(8)` as the owner of all the file arguments given,
perhaps in cases where you may not necessarily have `root` `sudo(8)`
privileges.
-* `swr(1df)` allows you to run commands locally specifying remote files in
+- `swr(1df)` allows you to run commands locally specifying remote files in
`scp(1)`'s HOST:PATH format.
-* `td(1df)` manages a to-do file for you with `$EDITOR` and `git(1)`; I used to
+- `td(1df)` manages a to-do file for you with `$EDITOR` and `git(1)`; I used to
use Taskwarrior, but found it too complex and buggy.
-* `tm(1df)` runs `tmux(1)` with `attach-session -d` if a session exists, and
+- `tm(1df)` runs `tmux(1)` with `attach-session -d` if a session exists, and
`new-session` if it doesn't.
-* `trs(1df)` replaces strings (not regular expression) in its input.
-* `try(1df)` repeats a command up to a given number of times until it succeeds,
+- `trs(1df)` replaces strings (not regular expression) in its input.
+- `try(1df)` repeats a command up to a given number of times until it succeeds,
only printing error output if all three attempts failed. Good for tolerating
blips or temporary failures in `cron(8)` scripts.
-* `umake(1df)` iterates upwards through the directory tree from `$PWD` until it
+- `umake(1df)` iterates upwards through the directory tree from `$PWD` until it
finds a Makefile for which to run `make(1)` with the given arguments.
-* `uts(1df)` gets the current UNIX timestamp in an unorthodox way that should
+- `uts(1df)` gets the current UNIX timestamp in an unorthodox way that should
work on all POSIX-compliant operating systems.
-* `vest(1df)` runs `test(1)` but fails with explicit output via `vex(1df)`.
-* `vex(1df)` runs a command and prints `true` or `false` explicitly to `stdout`
+- `vest(1df)` runs `test(1)` but fails with explicit output via `vex(1df)`.
+- `vex(1df)` runs a command and prints `true` or `false` explicitly to `stdout`
based on the exit value.
-* `vic(1df)` tries to run a POSIX-compliant `vi(1)`.
-* `xrbg(1df)` applies the same randomly-selected background to each X screen.
-* `xrq(1df)` gets the values of specific resources out of `xrdb -query` output.
+- `vic(1df)` tries to run a POSIX-compliant `vi(1)`.
+- `xrbg(1df)` applies the same randomly-selected background to each X screen.
+- `xrq(1df)` gets the values of specific resources out of `xrdb -query` output.
There's some silly stuff in `install-games`:
-* `aaf(6df)` gets a random [ASCII Art Farts](http://www.asciiartfarts.com/)
+- `aaf(6df)` gets a random [ASCII Art Farts](http://www.asciiartfarts.com/)
comic.
-* `acq(6df)` allows you to interrogate AC, the interplanetary computer.
-* `aesth(6df)` converts English letters to their full width CJK analogues,
+- `acq(6df)` allows you to interrogate AC, the interplanetary computer.
+- `aesth(6df)` converts English letters to their full width CJK analogues,
for aesthetic purposes.
-* `squ(6df)` makes a reduced Latin square out of each line of input.
-* `kvlt(6df)` translates input to emulate a style of typing unique to black
+- `squ(6df)` makes a reduced Latin square out of each line of input.
+- `kvlt(6df)` translates input to emulate a style of typing unique to black
metal communities on the internet.
-* `philsay(6df)` shows a picture to accompany `pks(6df)` output.
-* `pks(6df)` laughs at a randomly selected word.
-* `rndn(6df)` implements an esoteric random number generation algorithm.
-* `strik(6df)` outputs s̶t̶r̶i̶k̶e̶d̶ ̶o̶u̶t̶ struck out text.
-* `rot13(6df)` rotates the Latin letters in its input.
-* `uuu(6df)` uuuuu uuuu uu uuuuuu uuuuuuu u uuu uuuuu.
-* `xyzzy(6df)` teleports to a marked location on the filesystem.
-* `zs(6df)` prefixes "z" case-appropriately to every occurrence of "s" in the
+- `philsay(6df)` shows a picture to accompany `pks(6df)` output.
+- `pks(6df)` laughs at a randomly selected word.
+- `rndn(6df)` implements an esoteric random number generation algorithm.
+- `strik(6df)` outputs s̶t̶r̶i̶k̶e̶d̶ ̶o̶u̶t̶ struck out text.
+- `rot13(6df)` rotates the Latin letters in its input.
+- `uuu(6df)` uuuuu uuuu uu uuuuuu uuuuuuu u uuu uuuuu.
+- `xyzzy(6df)` teleports to a marked location on the filesystem.
+- `zs(6df)` prefixes "z" case-appropriately to every occurrence of "s" in the
text on its standard input.
Manuals
-------
-The `install-bin` and `install-games` targets install manuals for each script
-they install. If you want to use the manuals, you may need to add
-`~/.local/share/man` to your `~/.manpath` or `/etc/manpath` configuration,
-depending on your system.
+The `install-bin` and `install-games` targets install manuals for each script.
+If you want to read the manuals, you may need to add `~/.local/share/man` to
+your `~/.manpath` or `/etc/manpath` configuration, depending on your system.
Testing
-------
You can check that both sets of shell scripts are syntactically correct with
-`make check-bash`, `make check-sh`, or `make check` for everything including
+`make check-bash` or `make check-sh`, or `make check` for everything including
the scripts in `bin` and `games`. There's no proper test suite for the actual
functionality (yet).
There are also optional `lint` targets, if you have the appropriate tools
available to run them:
-* [ShellCheck](https://www.shellcheck.net/):
- * `lint-bash`
- * `lint-bin`
- * `lint-games`
- * `lint-ksh`
- * `lint-sh`
- * `lint-xinit`
-* Perl::Critic:
- * `lint-urxvt`
-* [Vint](https://github.com/Kuniwak/vint):
- * `lint-vim`
+- [ShellCheck](https://www.shellcheck.net/):
+ - `lint-bash`
+ - `lint-bin`
+ - `lint-games`
+ - `lint-ksh`
+ - `lint-sh`
+ - `lint-x`
+- [Vint](https://github.com/Kuniwak/vint):
+ - `lint-vim`
Future development
------------------
@@ -661,7 +658,7 @@ simple scripts, so do whatever you like with it if any of it's useful to you.
If you're feeling generous, please join and/or donate to a free software
advocacy group, and let me know you did it because of this project:
-* [Free Software Foundation](https://www.fsf.org/)
-* [Software in the Public Interest](https://www.spi-inc.org/)
-* [FreeBSD Foundation](https://www.freebsdfoundation.org/)
-* [OpenBSD Foundation](https://www.openbsdfoundation.org/)
+- [Free Software Foundation](https://www.fsf.org/)
+- [Software in the Public Interest](https://www.spi-inc.org/)
+- [FreeBSD Foundation](https://www.freebsdfoundation.org/)
+- [OpenBSD Foundation](https://www.openbsdfoundation.org/)
diff --git a/TABS.md b/TABS.md
deleted file mode 100644
index 105d89d4..00000000
--- a/TABS.md
+++ /dev/null
@@ -1,26 +0,0 @@
-Spaces to tabs
-==============
-
-If you prefer tabs to spaces, the following recipe seems to convert everything
-pretty nicely:
-
- $ find . -name .git -prune -o -name vim -prune -o -type f \
- -exec sh -c \
- 'for f;do unexpand -t4 "$f">"$f".tmp;mv "$f" "$f".tmp;done' \
- _ {} +
-
- $ find vim -name bundle -prune -o -type f \
- -exec sh -c \
- 'for f;do unexpand -t2 "$f">"$f".tmp;mv "$f" "$f".tmp;done' \
- _ {} +
-
-If you have GNU `unexpand(1)` and can add `--first-only` to each of those
-calls, the results seem perfect.
-
-You can configure Vim to accommodate this by removing the settings in
-vim/vimrc.vim for:
-
-* `'expandtab'`
-* `'shiftwidth'`
-* `'smarttab'`
-* `'softtabstop'`
diff --git a/VERSION b/VERSION
index 9375bb0b..f677da70 100644
--- a/VERSION
+++ b/VERSION
@@ -1,2 +1,2 @@
-tejr dotfiles v8.13.0
-Sun, 16 Feb 2020 03:09:30 +0000
+tejr dotfiles v12.41.0
+Wed, 02 Aug 2023 21:39:23 +0000
diff --git a/X/Xresources b/X/Xresources
deleted file mode 100644
index 3f586a87..00000000
--- a/X/Xresources
+++ /dev/null
@@ -1,2 +0,0 @@
-#include ".Xresources.d/URxvt"
-#include ".Xresources.d/XTerm"
diff --git a/X/Xresources.d/URxvt b/X/Xresources.d/URxvt
deleted file mode 100644
index f4c30d54..00000000
--- a/X/Xresources.d/URxvt
+++ /dev/null
@@ -1,32 +0,0 @@
-! URxvt
-URxvt.cursorBlink: on
-URxvt.cutchars: <>│
-URxvt.internalBorder: 0
-URxvt.iso14755: false
-URxvt.iso14755_52: false
-URxvt.perl-ext-common: select
-URxvt.pointerBlank: true
-URxvt.saveLines: 10000
-URxvt.scrollBar: false
-URxvt.scrollTTyKeypress: true
-URxvt.scrollTTyOutput: false
-URxvt.secondaryScroll: true
-URxvt.urgentOnBell: true
-URxvt.background: #030303
-URxvt.foreground: #E0E0E0
-URxvt.color0: #030303
-URxvt.color1: #CC0000
-URxvt.color2: #3EAA06
-URxvt.color3: #C4A000
-URxvt.color4: #3465A4
-URxvt.color5: #75507B
-URxvt.color6: #06989A
-URxvt.color7: #D3D7CF
-URxvt.color8: #303030
-URxvt.color9: #EF2929
-URxvt.color10: #7AF234
-URxvt.color11: #FCE94F
-URxvt.color12: #729FCF
-URxvt.color13: #AD7FA8
-URxvt.color14: #34E2E2
-URxvt.color15: #EEEEEC
diff --git a/X/Xresources.d/XTerm b/X/Xresources.d/XTerm
deleted file mode 100644
index f991ec91..00000000
--- a/X/Xresources.d/XTerm
+++ /dev/null
@@ -1,24 +0,0 @@
-! XTerm
-XTerm.termName: xterm-256color
-XTerm.vt100.bellIsUrgent: true
-XTerm.vt100.internalBorder: 0
-XTerm.vt100.eightBitInput: false
-XTerm.vt100.metaSendsEscape: true
-XTerm.vt100.background: #030303
-XTerm.vt100.foreground: #E0E0E0
-XTerm.vt100.color0: #030303
-XTerm.vt100.color1: #CC0000
-XTerm.vt100.color2: #3EAA06
-XTerm.vt100.color3: #C4A000
-XTerm.vt100.color4: #3465A4
-XTerm.vt100.color5: #75507B
-XTerm.vt100.color6: #06989A
-XTerm.vt100.color7: #D3D7CF
-XTerm.vt100.color8: #303030
-XTerm.vt100.color9: #EF2929
-XTerm.vt100.color10: #7AF234
-XTerm.vt100.color11: #FCE94F
-XTerm.vt100.color12: #729FCF
-XTerm.vt100.color13: #AD7FA8
-XTerm.vt100.color14: #34E2E2
-XTerm.vt101.color15: #EEEEEC
diff --git a/X/redshift.conf b/X/redshift.conf
deleted file mode 100644
index 1e1de4ee..00000000
--- a/X/redshift.conf
+++ /dev/null
@@ -1,10 +0,0 @@
-[redshift]
-adjustment-method=randr
-location-provider=manual
-temp-day=5700
-temp-night=3500
-transition=1
-
-[manual]
-lat=-40.352306
-lon=175.608215
diff --git a/X/sxhkdrc b/X/sxhkdrc
deleted file mode 100644
index 7816208f..00000000
--- a/X/sxhkdrc
+++ /dev/null
@@ -1,47 +0,0 @@
-super + Return
- urxvtcd
-
-super + control + Return
- urxvtcd -e sh
-
-super + shift + Return
- urxvtcd -e ksh
-
-super + alt + Return
- urxvtcd -e zsh
-
-super + b
- br
-
-super + d
- dmenu_run
-
-super + g
- xgoc
-
-super + i
- gimp
-
-super + m
- urxvtcd -e tm
-
-super + p
- dmp
-
-super + v
- urxvtcd -e "$VISUAL"
-
-super + slash
- i3lock --color=#000000 --image ~/.i3/lock.png --nofork
-
-XF86AudioMute
- amixer -q sset Master toggle
-
-XF86AudioRaiseVolume
- amixer -q sset Master 5%+ unmute
-
-XF86AudioLowerVolume
- amixer -q sset Master 5%- unmute
-
-XF86Calculator
- urxvtcd -e bcq
diff --git a/X/xinitrc b/X/xinitrc
deleted file mode 100644
index e86cac4d..00000000
--- a/X/xinitrc
+++ /dev/null
@@ -1,17 +0,0 @@
-# If a file ~/.xrandrrc exists for monitor setup, source that first
-[ -e "$HOME"/.xrandrrc ] && . "$HOME"/.xrandrrc
-
-# Read X resources
-xrdb "$HOME"/.Xresources
-
-# Faster mouse acceleration with a natural threshold
-xset mouse 5/2 0
-
-# Load all supplementary scripts in ~/.xinitrc.d
-for sh in "$HOME"/.xinitrc.d/*.sh ; do
- [ -e "$sh" ] && . "$sh"
-done
-unset -v sh
-
-# Start window manager
-exec i3
diff --git a/X/xinitrc.d/browser.sh b/X/xinitrc.d/browser.sh
deleted file mode 100644
index 0153fba9..00000000
--- a/X/xinitrc.d/browser.sh
+++ /dev/null
@@ -1,24 +0,0 @@
-# Choose a GUI browser with some rough heuristics
-
-# If Firefox is available, start by assuming that
-if command -v firefox >/dev/null 2>&1 ; then
- BROWSER=firefox
-fi
-
-# Consider a switch to Dillo...
-if (
- # No output, please
- exec >/dev/null 2>&1
- # Don't switch if it's not there
- command -v dillo || exit
- # Switch if Firefox isn't there
- command -v firefox || exit 0
- # Switch if procfs says we have less than 2GB of RAM
- awk '$1=="MemTotal:"&&$2<2^20{m++}END{exit!m}' < /proc/meminfo
-) ; then
- BROWSER=dillo
-fi
-
-# Export our choice of browser, if it isn't empty
-[ -n "$BROWSER" ] || return
-export BROWSER
diff --git a/X/xinitrc.d/dunst.sh b/X/xinitrc.d/dunst.sh
deleted file mode 100644
index bddaa1fe..00000000
--- a/X/xinitrc.d/dunst.sh
+++ /dev/null
@@ -1,3 +0,0 @@
-# Start dunst(1) to display libnotify messages
-command -v dunst >/dev/null 2>&1 || return
-dunst &
diff --git a/X/xinitrc.d/redshift.sh b/X/xinitrc.d/redshift.sh
deleted file mode 100644
index d5d58d8a..00000000
--- a/X/xinitrc.d/redshift.sh
+++ /dev/null
@@ -1,3 +0,0 @@
-# Start redshift(1)
-command -v redshift >/dev/null 2>&1 || return
-redshift &
diff --git a/X/xinitrc.d/ssh.sh b/X/xinitrc.d/ssh.sh
deleted file mode 100644
index 005743fe..00000000
--- a/X/xinitrc.d/ssh.sh
+++ /dev/null
@@ -1,4 +0,0 @@
-# Set SSH_ASKPASS if we can find one
-command -v ssh-askpass >/dev/null 2>&1 || return
-SSH_ASKPASS=$(command -v ssh-askpass)
-export SSH_ASKPASS
diff --git a/X/xinitrc.d/sxhkd.sh b/X/xinitrc.d/sxhkd.sh
deleted file mode 100644
index 132d8f8a..00000000
--- a/X/xinitrc.d/sxhkd.sh
+++ /dev/null
@@ -1,3 +0,0 @@
-# Start sxhkd(1)
-command -v sxhkd >/dev/null 2>&1 || return
-sxhkd &
diff --git a/X/xinitrc.d/urxvt.sh b/X/xinitrc.d/urxvt.sh
deleted file mode 100644
index a5eb0940..00000000
--- a/X/xinitrc.d/urxvt.sh
+++ /dev/null
@@ -1,3 +0,0 @@
-# Start urxvtd(1)
-command -v urxvtd >/dev/null 2>&1 || return
-urxvtd -o -q &
diff --git a/X/xinitrc.d/xkb.sh b/X/xinitrc.d/xkb.sh
deleted file mode 100644
index a5142398..00000000
--- a/X/xinitrc.d/xkb.sh
+++ /dev/null
@@ -1,5 +0,0 @@
-# Map Caps Lock as a Ctrl key, use right alt as Compose, kill X server with
-# Ctrl+Alt+Backspace
-# <https://en.wikipedia.org/wiki/Compose_key#Common_compose_combinations>
-command -v setxkbmap >/dev/null 2>&1 || return
-setxkbmap -option compose:ralt,ctrl:nocaps,terminate:ctrl_alt_bksp
diff --git a/X/xinitrc.d/xrbg.sh b/X/xinitrc.d/xrbg.sh
deleted file mode 100644
index 0e4ec278..00000000
--- a/X/xinitrc.d/xrbg.sh
+++ /dev/null
@@ -1,2 +0,0 @@
-# Apply a random background image
-xrbg
diff --git a/bash/bash_completion.d/_ssh_config_hosts.bash b/bash/bash_completion.d/_ssh_config_hosts.bash
index 0959f52b..16265e8a 100644
--- a/bash/bash_completion.d/_ssh_config_hosts.bash
+++ b/bash/bash_completion.d/_ssh_config_hosts.bash
@@ -3,23 +3,28 @@ _ssh_config_hosts() {
# Iterate through SSH client config paths
local config
- for config in "$HOME"/.ssh/config /etc/ssh/ssh_config ; do
+ for config in /etc/ssh/ssh_config.d/*.conf /etc/ssh/ssh_config \
+ "$HOME"/.ssh/config.d/*.conf "$HOME"/.ssh/config ; do
[[ -e $config ]] || continue
- # Read 'Host' options and their first value from file
- local option value ci
- while read -r option value _ ; do
+ # Read 'Host' options and their patterns from file
+ local option value patterns pattern ci
+ while read -r option value ; do
[[ $option == Host ]] || continue
+ read -a patterns -r \
+ < <(printf '%s\n' "$value")
# Check host value
- case $value in
- # No empties
- '') ;;
- # No wildcards
- *'*'*) ;;
- # Found a match; print it
- "$2"*) COMPREPLY[ci++]=$value ;;
- esac
+ for pattern in "${patterns[@]}" ; do
+ case $pattern in
+ # No empties
+ '') ;;
+ # No wildcards
+ *'*'*) ;;
+ # Found a match; print it
+ "$2"*) COMPREPLY[ci++]=$pattern ;;
+ esac
+ done
done < "$config"
done
diff --git a/bash/bash_completion.d/keep.bash b/bash/bash_completion.d/keep.bash
index 4b479eca..8bb4615f 100644
--- a/bash/bash_completion.d/keep.bash
+++ b/bash/bash_completion.d/keep.bash
@@ -44,7 +44,7 @@ _keep() {
fi
# Build list of kept names
- bashkeep=${BASHKEEP:-"$HOME"/.bashkeep.d}
+ bashkeep=${XDG_DATA_HOME:-"$HOME"/.local/share}/bashkeep
for keep in "$bashkeep"/"$2"*.bash ; do
# Skip directories
! [[ -d $keep ]] || continue
diff --git a/bash/bash_completion.d/mosh.bash b/bash/bash_completion.d/mosh.bash
new file mode 100644
index 00000000..17d72ca1
--- /dev/null
+++ b/bash/bash_completion.d/mosh.bash
@@ -0,0 +1,5 @@
+# Completion for mosh(1) with ssh_config(5) hostnames
+if ! declare -F _ssh_config_hosts >/dev/null ; then
+ source "$HOME"/.bash_completion.d/_ssh_config_hosts.bash
+fi
+complete -F _ssh_config_hosts -o bashdefault -o default mosh
diff --git a/bash/bash_completion.d/path.bash b/bash/bash_completion.d/path.bash
index 9224506a..9234f132 100644
--- a/bash/bash_completion.d/path.bash
+++ b/bash/bash_completion.d/path.bash
@@ -62,6 +62,7 @@ _path() {
fi
# Break PATH into parts
+ declare -a paths
IFS=: read -a paths -d '' -r \
< <(printf '%s\0' "$PATH")
diff --git a/bash/bashrc b/bash/bashrc
index 6e4c31a9..5d3a7bbc 100644
--- a/bash/bashrc
+++ b/bash/bashrc
@@ -28,8 +28,8 @@ fi
# Clear away command_not_found_handle if a system bashrc file set it up
unset -f command_not_found_handle
-# Keep around 32K lines of history in file
-HISTFILESIZE=$((1 << 15))
+# Keep around 128K lines of history in file
+HISTFILESIZE=131072
# Ignore duplicate commands
HISTCONTROL=ignoredups
diff --git a/bash/bashrc.d/keep.bash b/bash/bashrc.d/keep.bash
index 6796aae7..26a84f5b 100644
--- a/bash/bashrc.d/keep.bash
+++ b/bash/bashrc.d/keep.bash
@@ -29,7 +29,7 @@ keep() {
# Figure out the directory to which we're reading and writing these scripts
local bashkeep
- bashkeep=${BASHKEEP:-"$HOME"/.bashkeep.d}
+ bashkeep=${XDG_DATA_HOME:-"$HOME"/.local/share}/bashkeep
mkdir -p -- "$bashkeep" || return
# Parse options
@@ -89,8 +89,8 @@ EOF
case $name in
# NAME must start with letters or an underscore, and contain no
- # characters besides letters, numbers, or underscores
- *[!a-zA-Z0-9_]*|[!a-zA-Z_]*)
+ # characters besides letters, numbers, underscores, or dashes
+ [!a-zA-Z_]*|*[!a-zA-Z0-9_-]*)
printf 'bash: %s: %s not a valid NAME\n' \
"${FUNCNAME[0]}" "$name" >&2
((errors++))
@@ -140,7 +140,7 @@ EOF
}
# Load any existing scripts in bashkeep
-for bashkeep in "${BASHKEEP:-"$HOME"/.bashkeep.d}"/*.bash ; do
+for bashkeep in "${XDG_DATA_HOME:-"$HOME"/.local/share}"/bashkeep/*.bash ; do
[[ -e $bashkeep ]] || continue
source "$bashkeep"
done
diff --git a/bash/bashrc.d/prompt.bash b/bash/bashrc.d/prompt.bash
index f9678f20..e0a03438 100644
--- a/bash/bashrc.d/prompt.bash
+++ b/bash/bashrc.d/prompt.bash
@@ -7,29 +7,32 @@ prompt() {
# Turn complex, colored PS1 and debugging PS4 prompts on
on)
# Set up pre-prompt command
- PROMPT_COMMAND='history -a'
+ PROMPT_COMMAND='PROMPT_RETURN=$?;history -a'
# If Bash 4.0 is available, trim very long paths in prompt
if ((BASH_VERSINFO[0] >= 4)) ; then
PROMPT_DIRTRIM=4
fi
- # Basic prompt shape depends on whether we're in SSH or not
+ # Prompt has hostname via SSH outside of screen/tmux
PS1=
- if [[ -n $SSH_CLIENT || -n $SSH_CONNECTION ]] ; then
+ if [[ -n $SSH_CLIENT && -z $STY && -z $TMUX ]] ; then
PS1=$PS1'\h:'
fi
PS1=$PS1'\w'
- # Add sub-commands; VCS, job, and return status checks
- PS1=$PS1'$(ret=$?;prompt vcs;prompt job;prompt ret)'
-
# Add a helpful prefix if this shell appears to be exotic
case ${SHELL##*/} in
(bash) ;;
(*) PS1=bash:$PS1 ;;
esac
+ # Add sub-commands:
+ ## Preload libraries as prefix
+ PS1='$(prompt preload)'$PS1
+ ## VCS, job, and return status checks as suffixes
+ PS1=$PS1'$(prompt vcs;prompt job;prompt ret)'
+
# Add prefix and suffix
PS1='${PROMPT_PREFIX}'$PS1'${PROMPT_SUFFIX}'
@@ -92,6 +95,21 @@ prompt() {
fi
;;
+ # Analyze LD_PRELOAD to see if we should report anything loaded
+ preload)
+ printf '%s:' "$LD_PRELOAD" |
+ while read -d : -r ; do
+ case $REPLY in
+ (*/libip2unix.so)
+ printf '[IP2Unix]'
+ ;;
+ (*/libtorsocks.so)
+ printf '[Tor]'
+ ;;
+ esac
+ done
+ ;;
+
# Git prompt function
git)
@@ -249,8 +267,8 @@ prompt() {
# Show return status of previous command in angle brackets, if not zero
ret)
# shellcheck disable=SC2154
- ((ret)) || return
- printf '<%u>' "${ret//\\/\\\\}"
+ ((PROMPT_RETURN)) || return
+ printf '<%u>' "${PROMPT_RETURN//\\/\\\\}"
;;
# Show the count of background jobs in curly brackets, if not zero
diff --git a/bin/clog.sh b/bin/clog.sh
index 3269c508..a5c777e8 100644
--- a/bin/clog.sh
+++ b/bin/clog.sh
@@ -3,7 +3,8 @@
# Build the cat(1) command we'll run, wrapping it in rlwrap(1) if available and
# applicable.
if [ "$#" -eq 0 ] && [ -t 0 ] && command -v rlwrap >/dev/null 2>&1 ; then
- set -- rlwrap --history-filename=/dev/null cat -- "${@:--}"
+ set -- rlwrap --history-filename=/dev/null --no-warnings \
+ cat -- "${@:--}"
else
set -- cat -- "${@:--}"
fi
diff --git a/bin/dmp.sh b/bin/dmp.sh
deleted file mode 100644
index ab09c20e..00000000
--- a/bin/dmp.sh
+++ /dev/null
@@ -1,31 +0,0 @@
-# Pick a pass(1) password with dmenu(1)
-
-# Get the password store directory, bail if we can't
-pwsd=${PASSWORD_STORE_DIR:-"$HOME"/.password-store}
-pwsd=${pwsd%/}
-[ -n "$pwsd" ] || exit
-
-# Get the password; get all the names from find(1)
-# shellcheck disable=SC2016
-pw=$(
- cd -- "$pwsd" || exit
- # Get all the names from find(1)
- find ./ -name \*.gpg |
- # Sort them
- sort |
- # Strip the leading directory and the trailing .gpg
- sed 's_^\./__;s_\.gpg$__' |
- # Use dmenu(1) to prompt the user to select one
- dmenu
-) || exit
-
-# Bail if we don't have a password
-[ -n "$pw" ] || exit
-
-# Pump the first line of the password into the clipboard
-pass show "$pw" | sed 1q | xsel -ib || exit
-
-# If we have notify-send(1), alert that the password has been copied
-if command -v notify-send >/dev/null >&2 ; then
- notify-send "$(printf '%s in clipboard' "$pw")"
-fi
diff --git a/bin/gscr.sh b/bin/gscr.sh
index 2fbee05a..26eafb12 100644
--- a/bin/gscr.sh
+++ b/bin/gscr.sh
@@ -16,11 +16,16 @@ for arg in "${@:-.}" ; do (
;;
esac
+ # Remove any original refs from a prior rewrite
+ if [ -e refs/original ] ; then
+ rm -r -- refs/original || exit
+ fi
+
# Check for bad references or other integrity/sanity problems
- git fsck || exit
+ git fsck --full --no-reflogs || exit
# Expire dangling references
- git reflog expire --expire=now || exit
+ git reflog expire --all --expire=now --expire-unreachable=now || exit
# Remove dangling references
git gc --prune=now --aggressive || exit
diff --git a/bin/han.bash b/bin/han.bash
index 6ab0b3e7..5e5d67c2 100644
--- a/bin/han.bash
+++ b/bin/han.bash
@@ -1,5 +1,4 @@
# Abstract calls to Bash help vs man(1)
-self=han
# Ensure we're using at least version 3.0
# shellcheck disable=SC2128
@@ -13,22 +12,6 @@ if ((BASH_VERSINFO[0] >= 4)) ; then
helpopts=(-m)
fi
-# Create a temporary directory with name in $td, and a trap to remove it when
-# the script exits
-td=
-cleanup() {
- [[ -n $td ]] && rm -fr -- "$td"
-}
-trap cleanup EXIT
-td=$(mktd "$self") || exit
-
-# If we have exactly one argument and a call to the help builtin with that
-# argument succeeds, display its output with `pager -s`
-if (($# == 1)) &&
- help "${helpopts[@]}" "$1" >"$td"/"$1".help 2>/dev/null ; then
- (cd -- "$td" && "$PAGER" -s -- "$1".help)
-
-# Otherwise, just pass all the arguments to man(1)
-else
- man "$@"
-fi
+# Call `help`, with the `-m` flag if available; if it errors out (discard
+# stderr), run `man` instead
+help "${helpopts[@]}" -- "$@" 2>/dev/null || man -- "$@"
diff --git a/bin/mked.sh b/bin/mked.sh
index 93e21573..24a61de8 100644
--- a/bin/mked.sh
+++ b/bin/mked.sh
@@ -1,4 +1,3 @@
-#!/bin/sh
# Create paths to all files before invoking editor
for file do
mkdir -p -- "${file%/*}" || exit
diff --git a/bin/mktd.sh b/bin/mktd.sh
index 72375873..c2ba2ee2 100644
--- a/bin/mktd.sh
+++ b/bin/mktd.sh
@@ -2,7 +2,7 @@
# Build the intended directory name, with the last element a random integer
# from 1..2^31
-lim=$((2 << 31))
+lim=2147483648
dn=${TMPDIR:-/tmp}/${1:-mktd}.$$.$(rndi 1 "$lim")
# Create the directory and print its name if successful
diff --git a/bin/mkvi.sh b/bin/mkvi.sh
index c5974383..ac5c6229 100644
--- a/bin/mkvi.sh
+++ b/bin/mkvi.sh
@@ -1,4 +1,3 @@
-#!/bin/sh
# Create paths to all files before invoking editor
for file do
mkdir -p -- "${file%/*}" || exit
diff --git a/bin/msc.sh b/bin/msc.sh
new file mode 100644
index 00000000..051f104a
--- /dev/null
+++ b/bin/msc.sh
@@ -0,0 +1,12 @@
+# Crudely but quickly count mail in the user's inbox, if we can find it
+username=$(id -nu)
+if [ "$#" -eq 0 ] ; then
+ set -- "$MAIL" /var/mail/"$username" /var/spool/mail/"$username"
+fi
+for path do
+ [ -e "$path" ] || continue
+ grep -ch -- '^From ' "$path"
+ exit
+done
+printf >&2 'Couldn'\''t find user mail spool; provide it as an argument...?\n'
+exit 1
diff --git a/bin/osc.sh b/bin/osc.sh
index 5def12ff..2853f1a5 100644
--- a/bin/osc.sh
+++ b/bin/osc.sh
@@ -17,7 +17,7 @@ serv=${2:-https}
set --
## If we have rlwrap, use it, but don't complain if we don't
if command -v rlwrap >/dev/null 2>&1 ; then
- set -- "$@" rlwrap --history-filename=/dev/null
+ set -- "$@" rlwrap --history-filename=/dev/null --no-warnings
fi
## The actual openssl(1ssl) and subcommand call
set -- "$@" openssl s_client
diff --git a/bin/phpcsff.mi5 b/bin/phpcsff.mi5
index 49f00759..49f00759 100755..100644
--- a/bin/phpcsff.mi5
+++ b/bin/phpcsff.mi5
diff --git a/bin/plmu.sh b/bin/plmu.sh
deleted file mode 100644
index 3f237ae2..00000000
--- a/bin/plmu.sh
+++ /dev/null
@@ -1,27 +0,0 @@
-# Upgrade plenv modules with cpanm(1)
-
-# Set up exceptions file if it exists
-def="$HOME"/.plenv/non-cpanm-modules
-if [ -e "$def" ] ; then
- ef=$def
-else
- ef=/dev/null
-fi
-
-# Check that exceptions file is sorted
-if ! LC_COLLATE=C sort -c -- "$ef" ; then
- printf >&2 '%s not sorted\n' "$ef"
- exit 1
-fi
-
-# Get the list of modules; sort them in case our current locale disagrees on
-# the existing sorting
-plenv list-modules | LC_COLLATE=C sort |
-
-# Exclude any modules in ~/.plenv/non-cpanm-modules if it exists
-LC_COLLATE=C comm -23 -- - "$ef" |
-
-# Read that list of modules to upgrade and upgrade them one by one
-while read -r module ; do
- cpanm --notest --quiet -- "$module"
-done
diff --git a/bin/qat.sh b/bin/qat.sh
new file mode 100644
index 00000000..19acbf5a
--- /dev/null
+++ b/bin/qat.sh
@@ -0,0 +1,11 @@
+restore() {
+ if [ -n "$stty" ] ; then
+ stty "$stty"
+ fi
+}
+trap restore EXIT
+if [ -t 0 ] ; then
+ stty=$(stty -g)
+ stty -echo
+fi
+cat
diff --git a/bin/rndi.awk b/bin/rndi.awk
index 7d9c640b..44989d11 100644
--- a/bin/rndi.awk
+++ b/bin/rndi.awk
@@ -30,9 +30,6 @@ BEGIN {
# Print a random integer bounded by the first and second arguments
print int(lower + rand() * (upper - lower + 1))
-
- # Bail before processing any lines
- exit
}
# Bailout function
diff --git a/bin/sls.sh b/bin/sls.sh
index 55c1dfc7..9741144a 100644
--- a/bin/sls.sh
+++ b/bin/sls.sh
@@ -3,7 +3,8 @@
# If we weren't given a file explicitly, we'll try to read both /etc/ssh_config
# and ~/.ssh_config in that order if they exist
if [ "$#" -eq 0 ] ; then
- for cfg in /etc/ssh_config "$HOME"/.ssh/config ; do
+ for cfg in /etc/ssh_config.d/*.conf /etc/ssh_config \
+ "$HOME"/.ssh/config.d/*.conf "$HOME"/.ssh/config ; do
[ -e "$cfg" ] || continue
set -- "$@" "$cfg"
done
diff --git a/bin/slsf.awk b/bin/slsf.awk
index 3d5c190f..75efe7a4 100644
--- a/bin/slsf.awk
+++ b/bin/slsf.awk
@@ -1,9 +1,28 @@
-# Print the first non-glob "Host" name from each line of ssh_config(5) files
+# Print all the hosts from ssh_config(1) files
# Manage the processing flag (starts set in each file)
-FNR == 1 || /### sls/ { sls = 1 }
+BEGIN { sls = 1 }
+FNR == 1 { sls = 1 }
+/### sls/ { sls = 1 }
/### nosls/ { sls = 0 }
-# If processing flag set, directive is "Host", and hostname has no wildcards,
-# then print it
-sls && $1 == "Host" && $2 !~ /\*/ { print $2 }
+# Skip if we're ignoring hosts
+!sls { next }
+# Skip if this isn't a host line
+$1 != "Host" { next }
+
+# Add all the patterns after the keyword that don't have wildcards
+{
+ for (i = 2; i <= NF; i++) {
+ if ($i !~ /[?*]/) {
+ hosts[$i]++
+ }
+ }
+}
+
+# Print the complete list of hosts, sorted
+END {
+ for (host in hosts) {
+ print host | "sort"
+ }
+}
diff --git a/bin/td.sh b/bin/td.sh
index a5a4ab30..6dfbebc0 100644
--- a/bin/td.sh
+++ b/bin/td.sh
@@ -1,7 +1,7 @@
# Manage to-do files with just $EDITOR and git(1)
# Specify the path and file
-dir=${TODO_DIR:-"$HOME"/Todo}
+dir=${TODO_DIR:-"$HOME"/todo}
# If the directory doesn't exist, create it
[ -d "$dir" ] || mkdir -p -- "$dir" || exit
diff --git a/bin/tm.sh b/bin/tm.sh
index d5422869..6bdce20b 100644
--- a/bin/tm.sh
+++ b/bin/tm.sh
@@ -1,5 +1,10 @@
# Attach to existing tmux session rather than create a new one if possible
+# Source config if it exists (just the session name, really)
+if [ -e "${XDG_CONFIG_HOME:-"$HOME"/.config}"/tm/config ] ; then
+ . "${XDG_CONFIG_HOME:-"$HOME"/.config}"/tm/config || exit
+fi
+
# If given any arguments, just use them as they are
if [ "$#" -gt 0 ] ; then
:
@@ -10,8 +15,8 @@ elif tmux has-session 2>/dev/null ; then
# Create a new session with an appropriate name
else
- set -- new-session -s "${TMUX_SESSION:-default}"
+ set -- new-session -s "${default_session_name:-default}"
fi
# Execute with concluded arguments
-tmux "$@"
+exec tmux "$@"
diff --git a/bin/urlmt.sh b/bin/urlmt.sh
index cd71b0fd..69bef5f7 100644
--- a/bin/urlmt.sh
+++ b/bin/urlmt.sh
@@ -1,8 +1,10 @@
# Get the MIME type for a given URL
-urlh "$1" Content-Type |
-
-# Use last line only, remove any charset suffix
-sed '
-$!d
-s/;.*//
-'
+self=urlmt
+if [ "$#" -ne 1 ] || [ -z "$1" ] ; then
+ printf >&2 '%s: Need a single URL\n' \
+ "$self"
+ exit 2
+fi
+url=$1
+curl --head --output /dev/null --write-out '%{content_type}\n' "$url" |
+ awk -F\; '{print $1}'
diff --git a/bin/uts.awk b/bin/uts.awk
index 3aaec2ab..a7b3ef5d 100644
--- a/bin/uts.awk
+++ b/bin/uts.awk
@@ -2,5 +2,4 @@
BEGIN {
srand()
print srand()
- exit
}
diff --git a/bin/xgo.sh b/bin/xgo.sh
index 6d6586ef..c59409a5 100644
--- a/bin/xgo.sh
+++ b/bin/xgo.sh
@@ -39,7 +39,7 @@ for url do (
# mpv(1)
(*[/.]youtube.com/watch*[?\&]t=) ;;
(*[/.]youtube.com/watch*)
- exec mpv -- "$url"
+ exec mpv --force-window --no-terminal -- "$url"
;;
esac
@@ -59,14 +59,15 @@ for url do (
)
;;
- # Open audio and video in mpv(1); force a window even for audio so I
- # can control it
+ # Open audio and video in mpv(1)
(audio/*|video/*)
- exec mpv --force-window -- "$url"
+ exec mpv --force-window --no-terminal -- "$url"
;;
- # If the MIME type is an image that is not a GIF, load it in feh(1)
- (image/gif) ;;
+ # Open GIFs with a looping mpv(1), and all other images with feh(1)
+ (image/gif)
+ exec mpv --force-window --loop=inf --no-terminal -- "$url"
+ ;;
(image/*)
exec curl -- "$url" | feh -
;;
@@ -74,7 +75,7 @@ for url do (
# Open plain text in a terminal view(1)
(text/plain)
# shellcheck disable=SC2016
- exec urxvt -e sh -c 'curl -- "$1" | view -' _ "$url"
+ exec x-terminal-emulator -e sh -c 'curl -- "$1" | view -' _ "$url"
;;
# Otherwise, just pass it to br(1df)
diff --git a/bin/xsnap.sh b/bin/xsnap.sh
new file mode 100644
index 00000000..7a9d0c38
--- /dev/null
+++ b/bin/xsnap.sh
@@ -0,0 +1,24 @@
+# Wrapper for scrot(1) for use in recording screenshots
+date=$(date +%Y/%m/%d) || exit
+dir=${XDG_DATA_HOME:-"$HOME"/.local/share}/scrot/screenshots/$date
+mkdir -p -- "$dir" || exit
+cd -- "$dir" || exit
+for ent in * ; do
+ [ -e "$ent" ] || continue
+ case $ent in
+ *.png) ;;
+ *) continue ;;
+ esac
+ basename=${ent%.png}
+ case $basename in
+ *[!0-9]*) continue ;;
+ esac
+ last=$basename
+done
+number=$(printf '%s' "$last" | sed 's/^0*//') # Avoid octal
+id=$((number + 1))
+name=$(printf '%05d' "$id").png
+path=$dir/$name
+scrot --file="$path" --overwrite "$@" || exit
+xclip -selection clipboard -target image/png "$path" || exit
+notify-send "Saved: $date/$name"
diff --git a/cabal/cabal.sh b/cabal/cabal.sh
new file mode 100644
index 00000000..b5730916
--- /dev/null
+++ b/cabal/cabal.sh
@@ -0,0 +1,3 @@
+# Include user-built Haskell programs if the dir exists
+[ -d "$HOME"/.cabal/bin ] || return
+PATH=$HOME/.cabal/bin:$PATH
diff --git a/cabal/profile.d/cabal.sh b/cabal/profile.d/cabal.sh
new file mode 100644
index 00000000..638f8d04
--- /dev/null
+++ b/cabal/profile.d/cabal.sh
@@ -0,0 +1,2 @@
+# Include user-built Haskell programs
+PATH=$HOME/.cabal/bin:$PATH
diff --git a/cargo/profile.d/cargo.sh b/cargo/profile.d/cargo.sh
new file mode 100644
index 00000000..89bcd524
--- /dev/null
+++ b/cargo/profile.d/cargo.sh
@@ -0,0 +1,2 @@
+# Include user-built Rust programs
+PATH=$HOME/.cargo/bin:$PATH
diff --git a/check/sh.sh b/check/sh.sh
index 4e816337..c3ff856a 100644
--- a/check/sh.sh
+++ b/check/sh.sh
@@ -1,9 +1,9 @@
set \
sh/profile \
- sh/profile.d/*.sh \
sh/shinit \
sh/shrc \
- sh/shrc.d/*.sh
+ */profile.d/*.sh \
+ */shrc.d/*.sh
for sh do
sh -n -- "$sh" || exit
done
diff --git a/check/urxvt.sh b/check/urxvt.sh
deleted file mode 100644
index e64ba1e5..00000000
--- a/check/urxvt.sh
+++ /dev/null
@@ -1,3 +0,0 @@
-for perl in urxvt/ext/*.pl ; do
- perl -c "${perl%.pl}" || exit
-done
diff --git a/check/x.sh b/check/x.sh
new file mode 100644
index 00000000..f88f11a1
--- /dev/null
+++ b/check/x.sh
@@ -0,0 +1 @@
+sh -n -- x/xsessionrc x/shrc.d/*.sh
diff --git a/check/xinit.sh b/check/xinit.sh
deleted file mode 100644
index a354422a..00000000
--- a/check/xinit.sh
+++ /dev/null
@@ -1,6 +0,0 @@
-set \
- X/xinitrc \
- X/xinitrc.d/*.sh
-for xinit do
- sh -n -- "$xinit" || exit
-done
diff --git a/check/xsession.sh b/check/xsession.sh
new file mode 100644
index 00000000..0b72d8a6
--- /dev/null
+++ b/check/xsession.sh
@@ -0,0 +1 @@
+sh -n -- x/xsession
diff --git a/cpanm/profile.d/cpanm.sh b/cpanm/profile.d/cpanm.sh
new file mode 100644
index 00000000..a860162e
--- /dev/null
+++ b/cpanm/profile.d/cpanm.sh
@@ -0,0 +1,3 @@
+# Set home directory for cpanm files to be XDG-conformant
+PERL_CPANM_HOME=${XDG_CACHE_HOME:-$HOME/.cache}/cpanm
+export PERL_CPANM_HOME
diff --git a/dunst/dunstrc b/dunst/dunstrc
deleted file mode 100644
index e3e3e43f..00000000
--- a/dunst/dunstrc
+++ /dev/null
@@ -1,46 +0,0 @@
-[global]
-galignment = left
-gallow_markup = no
-gbounce_freq = 0
-gdmenu = dmenu -p dunst:
-gfollow = mouse
-gformat = "%s %b"
-ggeometry = "350x5-0-17"
-ghistory_length = 20
-ghorizontal_padding = 8
-gicon_position = off
-gidle_threshold = 0
-gignore_newline = no
-gindicate_hidden = no
-gline_height = 0
-gmonitor = 0
-gpadding = 8
-gseparator_color = frame
-gseparator_height = 0
-gshow_age_threshold = -1
-gshow_indicators = no
-gshrink = no
-gsort = yes
-gstartup_notification = false
-gsticky_history = yes
-gtransparency = 0
-gword_wrap = yes
-
-[frame]
-gwidth = 1
-gcolor = "#333333"
-
-[urgency_low]
-gbackground = "#222222"
-gforeground = "#bbbbbb"
-gtimeout = 10
-
-[urgency_normal]
-gbackground = "#285577"
-gforeground = "#ffffff"
-gtimeout = 10
-
-[urgency_critical]
-gbackground = "#900000"
-gforeground = "#ffffff"
-gtimeout = 0
diff --git a/finger/pgpkey b/finger/pgpkey
index 1f62c961..f9569c8f 100644
--- a/finger/pgpkey
+++ b/finger/pgpkey
@@ -1,4 +1,4 @@
-pub rsa4096 2013-03-12 [SC] [expires: 2020-05-16]
+pub rsa4096 2013-03-12 [SC] [expires: 2024-06-16]
FA09 C06E 1B67 0CD0 B2F5 DE60 C142 86EA 77BB 8872
uid [ultimate] Thomas Ryder (tyrmored, tejr) <tom@sanctum.geek.nz>
uid [ultimate] Thomas Ryder <tejr@echo-n.nz>
@@ -6,9 +6,6 @@ uid [ultimate] Thomas Ryder <secretary@plug.org.nz>
uid [ultimate] Thomas Ryder (TEJR) <tejr@cpan.org>
uid [ultimate] Thomas Ryder <tyrmored@inspire.net.nz>
uid [ultimate] Thomas Ryder <tej.ryder@gmail.com>
-sub rsa4096 2013-03-12 [E] [expires: 2020-05-16]
- 9DF1 A89F F8D9 70AF 3265 C882 96C2 CD91 E67A C61D
-sub rsa4096 2013-03-12 [S] [expires: 2020-05-16]
- 3179 90A1 4597 A1FC F82D 953A B5AF 5F89 2592 6609
-sub rsa4096 2019-08-06 [A] [expires: 2020-05-16]
- 42AE 569D 6162 7C52 03B0 74ED D58F F1F0 7E90 9B49
+sub rsa4096 2013-03-12 [E] [expires: 2024-06-16]
+sub rsa4096 2013-03-12 [S] [expires: 2024-06-16]
+sub rsa4096 2019-08-06 [A] [expires: 2024-06-16]
diff --git a/finger/plan b/finger/plan
index e882c433..ec8a1d3d 100644
--- a/finger/plan
+++ b/finger/plan
@@ -1,3 +1,3 @@
-"I am his Highness' dog at Kew.
- Pray tell me, Sir: whose dog are you?"
- -- Pope
+> I am his Highness' dog at Kew.
+> Pray tell me, Sir: whose dog are you?
+ ---Pope
diff --git a/games/xyzzy.sh b/games/xyzzy.sh
index 5cc03278..ebf3959a 100644
--- a/games/xyzzy.sh
+++ b/games/xyzzy.sh
@@ -1,6 +1,11 @@
# ADVENTURE
-if [ -e "$HOME"/.xyzzy ] ; then
- printf >&2 '%s\n' 'Nothing happens.'
- exit 1
+dir=${XDG_CONFIG_HOME:-$HOME/.config}/xyzzy
+if ! [ -d "$dir" ] ; then
+ mkdir -- "$dir" || exit
fi
-printf '%s\n' 'I see no cave here.' > "$HOME"/.xyzzy
+if [ -e "$dir"/dest ] ; then
+ printf >&2 'Nothing happens.\n'
+else
+ printf 'I see no cave here.\n' > "$dir"/dest
+fi
+exit 1
diff --git a/git/gitconfig.mi5 b/git/config.mi5
index 11b815d1..efdbc277 100644
--- a/git/gitconfig.mi5
+++ b/git/config.mi5
@@ -4,15 +4,15 @@
[diff]
algorithm = patience
-[fetch]
- output = compact
+[format]
+ pretty = fuller
[init]
- templateDir = ~/.git-template
+ defaultBranch = master
+ templateDir = <% XDG_DATA_HOME %>/git/template
[log]
date = local
- decorate = short
[merge]
ff = false
@@ -26,12 +26,14 @@
[sendemail]
confirm = compose
- smtpServer = <% SENDMAIL %>
[status]
short = true
+[tag]
+ sort = -taggerdate
+
[user]
name = <% NAME %>
email = <% EMAIL %>
- signingKey = <% KEY %>
+ signingKey = <% GPG_KEYID %>
diff --git a/gnupg/gpg.conf b/gnupg/gpg.conf
deleted file mode 100644
index 97c1ca77..00000000
--- a/gnupg/gpg.conf
+++ /dev/null
@@ -1,14 +0,0 @@
-# Assume I mean to encrypt to myself if no recipient is specified
-default-recipient-self
-
-# Don't use key IDs in listings, just show full fingerprints
-keyid-format none
-
-# Suppress the copyright message
-no-greeting
-
-# Don't sign pictures or other binary UID data
-only-sign-text-ids
-
-# Show fingerprints where they might not otherwise appear
-with-fingerprint
diff --git a/gnupg/profile.d/gnupg.sh.mi5 b/gnupg/profile.d/gnupg.sh.mi5
new file mode 100644
index 00000000..33a57dd0
--- /dev/null
+++ b/gnupg/profile.d/gnupg.sh.mi5
@@ -0,0 +1,3 @@
+# GPG key details
+GPG_KEYID=<% GPG_KEYID %>
+export GPG_KEYID
diff --git a/gtk/gtk-3.0/settings.ini b/gtk/gtk-3.0/settings.ini
deleted file mode 100644
index 4f93dfe4..00000000
--- a/gtk/gtk-3.0/settings.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-[Settings]
-gtk-theme-name = Clearlooks-Phenix
diff --git a/gtk/gtkrc-2.0 b/gtk/gtkrc-2.0
deleted file mode 100644
index 99fb22e2..00000000
--- a/gtk/gtkrc-2.0
+++ /dev/null
@@ -1 +0,0 @@
-gtk-theme-name = "Clearlooks-Phenix"
diff --git a/i3/config b/i3/config
index be00e590..1e641b9f 100644
--- a/i3/config
+++ b/i3/config
@@ -4,8 +4,8 @@ set $mod Mod4
# Use Mouse+$mod to drag floating windows to their wanted position
floating_modifier $mod
-# No title bar
-new_window 1pixel
+# Use a nice Unicode-aware condensed font
+font pango:Noto Sans 10
# Mod+Shift+r restarts i3wm
bindsym $mod+Shift+r restart
@@ -50,22 +50,22 @@ bindsym $mod+a focus parent
bindsym $mod+z focus child
# Mod+<n> switches to a workspace
-bindsym $mod+1 workspace 1:main
-bindsym $mod+2 workspace 2:home
-bindsym $mod+3 workspace 3:work
-bindsym $mod+4 workspace 4:soc
-bindsym $mod+5 workspace 5:tor
+bindsym $mod+1 workspace 1
+bindsym $mod+2 workspace 2
+bindsym $mod+3 workspace 3
+bindsym $mod+4 workspace 4
+bindsym $mod+5 workspace 5
bindsym $mod+6 workspace 6
bindsym $mod+7 workspace 7
bindsym $mod+8 workspace 8
bindsym $mod+9 workspace 9
# Mod+Shift+<n> moves a container to a workspace
-bindsym $mod+Shift+1 move container to workspace 1:main
-bindsym $mod+Shift+2 move container to workspace 2:home
-bindsym $mod+Shift+3 move container to workspace 3:work
-bindsym $mod+Shift+4 move container to workspace 4:soc
-bindsym $mod+Shift+5 move container to workspace 5:tor
+bindsym $mod+Shift+1 move container to workspace 1
+bindsym $mod+Shift+2 move container to workspace 2
+bindsym $mod+Shift+3 move container to workspace 3
+bindsym $mod+Shift+4 move container to workspace 4
+bindsym $mod+Shift+5 move container to workspace 5
bindsym $mod+Shift+6 move container to workspace 6
bindsym $mod+Shift+7 move container to workspace 7
bindsym $mod+Shift+8 move container to workspace 8
@@ -74,27 +74,20 @@ bindsym $mod+Shift+9 move container to workspace 9
# Mod+r resizes a container
bindsym $mod+r mode "resize"
mode "resize" {
- bindsym h resize shrink width 10 px or 10 ppt
- bindsym j resize grow height 10 px or 10 ppt
- bindsym k resize shrink height 10 px or 10 ppt
- bindsym l resize grow width 10 px or 10 ppt
- bindsym Return mode "default"
- bindsym Escape mode "default"
+ bindsym h resize shrink width 10 px or 10 ppt
+ bindsym j resize grow height 10 px or 10 ppt
+ bindsym k resize shrink height 10 px or 10 ppt
+ bindsym l resize grow width 10 px or 10 ppt
+ bindsym Return mode "default"
+ bindsym Escape mode "default"
}
# i3bar at bottom of screen
bar {
- position bottom
- status_command i3status --config ~/.i3/status
- workspace_buttons yes
-
- colors {
- background #111111
- statusline #eeeeee
-
- focused_workspace #ffffff #285577
- active_workspace #ffffff #333333
- inactive_workspace #888888 #222222
- urgent_workspace #ffffff #900000
- }
+ separator_symbol "—"
+ status_command i3status
+ tray_padding 0
+ colors {
+ background #111111
+ }
}
diff --git a/i3/status b/i3/status
index 87cf9df8..534b1f8f 100644
--- a/i3/status
+++ b/i3/status
@@ -2,16 +2,10 @@
order += "load"
order += "tztime local"
-order += "battery 0"
load {
- format = "%1min/%5min/%15min"
+ format = "%1min/%5min/%15min"
}
tztime local {
- format = "%Y-%m-%d %H:%M:%S"
-}
-battery 0 {
- format = "%status %percentage %remaining %emptytime"
- path = "/sys/class/power_supply/BAT%d/uevent"
- low_threshold = 15
+ format = "%Y-%m-%d %H:%M:%S"
}
diff --git a/install/conf.sh b/install/conf.sh
index f50cde73..1634f0cb 100644
--- a/install/conf.sh
+++ b/install/conf.sh
@@ -1,10 +1,11 @@
-# Read extra targets from an optional ~/.dotfiles.conf file
-if [ -e "$HOME"/.dotfiles.conf ] ; then
+# Read extra targets from an optional configuration file
+conf=${XDG_CONFIG_HOME:-"$HOME"/.config}/dotfiles/config
+if [ -e "$conf" ] ; then
while read -r line ; do
case $line in
'#'*|'') ;;
*) set -- "$@" "$line" ;;
esac
- done < "$HOME"/.dotfiles.conf
+ done < $conf
fi
make install "$@"
diff --git a/install/helptags.vim b/install/helptags.vim
new file mode 100644
index 00000000..865f32db
--- /dev/null
+++ b/install/helptags.vim
@@ -0,0 +1,2 @@
+helptags $HOME/.vim/doc
+quit
diff --git a/irssi/aliases b/irssi/aliases
index 65e80c13..ecedc21a 100644
--- a/irssi/aliases
+++ b/irssi/aliases
@@ -1,11 +1,13 @@
#
# I don't think irssi lets you specify include files for configuration, and
# you're not really supposed to edit it manually, but here are some commands to
-# create aliases to use the text files for tools in section 6.
+# create aliases.
#
-# I'd love to know if there's a better way to do these; maybe I should make a
-# proper plugin?
+# I'd love to know if there's a better way to do this. Maybe I should make
+# a proper irssi script?
#
+
+# Text filters via games/tools in section 6df
alias aesth exec - -out printf %s "$*" | aesth
alias drakon exec - -out printf %s "$*" | drakon
alias kvlt exec - -out printf %s "$*" | kvlt
@@ -13,3 +15,21 @@ alias rot13 exec - -out printf %s "$*" | rot13
alias squ exec - -out printf %s "$*" | squ
alias strik exec - -out printf %s "$*" | strik
alias zs exec - -out printf %s "$*" | zs
+
+# More generic aliases
+alias apt msg * Bro I just `apt install $x` and it works lol
+alias bully msg * $0: I feel offended by your recent action(s). Please read https://stop-irc-bullying.info/stop
+alias ch me chuckle
+alias hic msg * here it comes
+alias tig msg * there it goes
+alias hryk msg * ^ He's right you know
+alias lenny msg * ( ͡° ͜ʖ ͡°)
+alias lol msg * WHATA FUCK MAN xD i just fall of my chair cuz i couldnt and i CANT stop laugh xDXDXDXDXDDDDDDDDDDDDXXXXXXXXXXXXXXXXXXXDDDDDDDDDDDDDDDDDDD OMGOSH DDDDDXXXXXXXXXXXXXXXXXXXXXXXDDDDDDDDDDDDDDDDDDDDDDDDDDDD DDDDDD LOOOOOOOOOLLLLL THIS IS A SHIT XDDDDDDDDDDDDDDDDDDDDXDDDDDDDDDDDDDDDDDDDDD A BIG ONE XDDDDDDDD A GRAT ONE XXXXXXDDDD CONGRATS MAN XD
+alias n names
+alias q query
+alias sb scrollback
+alias shrug msg * ¯\\_(ツ)_/¯
+alias tyvc msg * Thank you $0, very cool
+alias w window goto
+alias wl window last
+alias wls window list
diff --git a/keychain/profile.d/keychain.sh b/keychain/profile.d/keychain.sh
deleted file mode 100644
index 63eb613a..00000000
--- a/keychain/profile.d/keychain.sh
+++ /dev/null
@@ -1,5 +0,0 @@
-# keychain setup
-command -v keychain >/dev/null 2>&1 || return
-eval "$(TERM=${TERM:-ansi} keychain \
- --eval --ignore-missing --quick --quiet \
- id_dsa id_rsa id_ecdsa id_ed25519)"
diff --git a/keychain/shrc.d/keychain.sh b/keychain/shrc.d/keychain.sh
deleted file mode 100644
index 1c0e780e..00000000
--- a/keychain/shrc.d/keychain.sh
+++ /dev/null
@@ -1,3 +0,0 @@
-# Update GPG_TTY for clean use of pinentry(1) etc
-GPG_TTY=$(command -p tty) || return
-export GPG_TTY
diff --git a/ksh/kshrc.d/keep.ksh b/ksh/kshrc.d/keep.ksh
index c1546deb..861e1b2b 100644
--- a/ksh/kshrc.d/keep.ksh
+++ b/ksh/kshrc.d/keep.ksh
@@ -40,7 +40,7 @@ function keep {
# Figure out the directory to which we're reading and writing these scripts
typeset kshkeep
- kshkeep=${KSHKEEP:-"$HOME"/.kshkeep.d}
+ kshkeep=${XDG_DATA_HOME:-"$HOME"/.local/share}/kshkeep
mkdir -p -- "$kshkeep" || return
# Parse options
@@ -100,8 +100,8 @@ EOF
case $name in
# NAME must start with letters or an underscore, and contain no
- # characters besides letters, numbers, or underscores
- *[!a-zA-Z0-9_]*|[!a-zA-Z_]*)
+ # characters besides letters, numbers, underscores, or dashes
+ [!a-zA-Z_]*|*[!a-zA-Z0-9_-]*)
printf 'ksh: %s: %s not a valid NAME\n' \
"$self" "$name" >&2
((errors++))
@@ -152,7 +152,7 @@ EOF
}
# Load any existing scripts in kshkeep
-for kshkeep in "${KSHKEEP:-"$HOME"/.kshkeep.d}"/*.ksh ; do
+for kshkeep in "${XDG_DATA_HOME:-"$HOME"/.local/share}"/kshkeep/*.ksh ; do
[[ -e $kshkeep ]] || continue
source "$kshkeep"
done
diff --git a/ksh/kshrc.d/prompt.ksh b/ksh/kshrc.d/prompt.ksh
index 64e22e8e..99d999de 100644
--- a/ksh/kshrc.d/prompt.ksh
+++ b/ksh/kshrc.d/prompt.ksh
@@ -12,16 +12,12 @@ function prompt {
# Turn complex, colored PS1 and debugging PS4 prompts on
on)
- # Basic prompt shape depends on whether we're in SSH or not
+ # Prompt has hostname via SSH outside of screen/tmux
PS1=
- if [[ -n $SSH_CLIENT || -n $SSH_CONNECTION ]] ; then
+ if [[ -n $SSH_CLIENT && -z $STY && -z $TMUX ]] ; then
PS1=$PS1'${HOSTNAME%%.*}:'
fi
- # Add sub-commands; working directory with ~ abbreviation, VCS, job
- # count, and previous command return value
- PS1=$PS1'$(ret=$?;jobc=$(jobs -p|sed -n '\''$='\'');prompt pwd;prompt vcs;prompt job;prompt ret;:)'
-
# Add a helpful prefix if this shell appears to be exotic
typeset ksh
case $KSH_VERSION in
@@ -34,6 +30,10 @@ function prompt {
(*) PS1=$ksh:$PS1 ;;
esac
+ # Add sub-commands:
+ ## VCS, job, and return status checks as suffixes
+ PS1=$PS1'$(ret=$?;jobc=$(jobs -p|sed -n '\''$='\'');prompt pwd;prompt vcs;prompt job;prompt ret;:)'
+
# Add prefix and suffix
PS1='${PROMPT_PREFIX}'$PS1'${PROMPT_SUFFIX}'
diff --git a/ksh/shrc.d/ksh.sh b/ksh/shrc.d/ksh.sh
index 9e032756..f074c832 100644
--- a/ksh/shrc.d/ksh.sh
+++ b/ksh/shrc.d/ksh.sh
@@ -21,10 +21,11 @@ if [ -z "$KSH_VERSION" ] ; then
# Test whether we have content in the .sh.version variable. Suppress
# errors and run it in a subshell to work around parsing error precedence.
- # shellcheck disable=SC2234
+ # shellcheck disable=SC2234,SC2296
( test -n "${.sh.version}" ) 2>/dev/null || return
# If that peculiarly named variable was set, then that's our KSH_VERSION
+ # shellcheck disable=SC2296
KSH_VERSION=${.sh.version}
fi
diff --git a/less/profile.d/less.sh b/less/profile.d/less.sh
new file mode 100644
index 00000000..75fd1bf0
--- /dev/null
+++ b/less/profile.d/less.sh
@@ -0,0 +1,2 @@
+LESSKEY=${XDG_CONFIG_HOME:-$HOME/.config}/less/key
+export LESSKEY
diff --git a/lint/bash.sh b/lint/bash.sh
index 13754a3f..2b6342ae 100644
--- a/lint/bash.sh
+++ b/lint/bash.sh
@@ -5,4 +5,4 @@ set \
bash/bash_profile \
bash/bashrc \
bash/bashrc.d/*.bash
-shellcheck -e SC1090 -s bash -- "$@" || exit
+shellcheck -e SC1090 -e SC1091 -s bash -- "$@" || exit
diff --git a/lint/bin.sh b/lint/bin.sh
index a98c6a73..f80f44d2 100644
--- a/lint/bin.sh
+++ b/lint/bin.sh
@@ -3,7 +3,7 @@ set --
for bin in bin/*.sh ; do
set -- "$@" "${bin%.sh}"
done
-shellcheck -e SC1090 -- "$@" || exit
+shellcheck -e SC1090 -e SC1091 -- "$@" || exit
# GNU Bash
if command -v bash >/dev/null 2>&1 ; then
@@ -11,5 +11,5 @@ if command -v bash >/dev/null 2>&1 ; then
for bin in bin/*.bash ; do
set -- "$@" "${bin%.bash}"
done
- shellcheck -e SC1090 -- "$@" || exit
+ shellcheck -e SC1090 -e SC1091 -- "$@" || exit
fi
diff --git a/lint/games.sh b/lint/games.sh
index e9690d8d..aa680035 100644
--- a/lint/games.sh
+++ b/lint/games.sh
@@ -3,4 +3,4 @@ set --
for game in games/*.sh ; do
set -- "$@" "${game%.sh}"
done
-shellcheck -e SC1090 -- "$@" || exit
+shellcheck -e SC1090 -e SC1091 -- "$@" || exit
diff --git a/lint/git-template-hooks.sh b/lint/git-template-hooks.sh
index 74f20fc6..a0f7ef1a 100644
--- a/lint/git-template-hooks.sh
+++ b/lint/git-template-hooks.sh
@@ -2,4 +2,4 @@ set --
for bin in git/template/hooks/*.sh ; do
set -- "$@" "${bin%.sh}"
done
-shellcheck -e SC1090 -- "$@" || exit
+shellcheck -e SC1090 -e SC1091 -- "$@" || exit
diff --git a/lint/ksh.sh b/lint/ksh.sh
index 117909b3..164c4672 100644
--- a/lint/ksh.sh
+++ b/lint/ksh.sh
@@ -1,5 +1,5 @@
set \
ksh/kshrc \
ksh/kshrc.d/*.ksh
-shellcheck -e SC1090 -s ksh -- "$@" || exit
-shellcheck -e SC1090 -s sh -- ksh/shrc.d/ksh.sh || exit
+shellcheck -e SC1090 -e SC1091 -s ksh -- "$@" || exit
+shellcheck -e SC1090 -e SC1091 -s sh -- ksh/shrc.d/ksh.sh || exit
diff --git a/lint/sh.sh b/lint/sh.sh
index b0d28e5d..e15b5504 100644
--- a/lint/sh.sh
+++ b/lint/sh.sh
@@ -1,7 +1,7 @@
set \
sh/profile \
- sh/profile.d/*.sh \
sh/shinit \
sh/shrc \
- sh/shrc.d/*.sh
-shellcheck -e SC1090 -s sh -- "$@" || exit
+ */profile.d/*.sh \
+ */shrc.d/*.sh
+shellcheck -e SC1090 -e SC1091 -s sh -- "$@" || exit
diff --git a/lint/urxvt.sh b/lint/urxvt.sh
deleted file mode 100644
index 6e5fb503..00000000
--- a/lint/urxvt.sh
+++ /dev/null
@@ -1,5 +0,0 @@
-set --
-for pl in urxvt/ext/*.pl ; do
- set -- "$@" "${pl%.pl}"
-done
-perlcritic --brutal -- "${pl%.pl}"
diff --git a/lint/x.sh b/lint/x.sh
new file mode 100644
index 00000000..0625369b
--- /dev/null
+++ b/lint/x.sh
@@ -0,0 +1 @@
+shellcheck -e SC1090 -e SC1091 -s sh -- x/xsessionrc x/shrc.d/*.sh
diff --git a/lint/xinit.sh b/lint/xinit.sh
deleted file mode 100644
index 0fab84d2..00000000
--- a/lint/xinit.sh
+++ /dev/null
@@ -1,4 +0,0 @@
-set \
- X/xinitrc \
- X/xinitrc.d/*.sh
-shellcheck -e SC1090 -s sh -- "$@"
diff --git a/lint/xsession.sh b/lint/xsession.sh
new file mode 100644
index 00000000..5544e1be
--- /dev/null
+++ b/lint/xsession.sh
@@ -0,0 +1 @@
+shellcheck -e SC1090 -e SC1091 -s sh -- x/xsession
diff --git a/logrotate/config b/logrotate/config
new file mode 100644
index 00000000..5a703a46
--- /dev/null
+++ b/logrotate/config
@@ -0,0 +1,5 @@
+compress
+create 0600
+delaycompress
+
+include ~/.config/logrotate/config.d
diff --git a/logrotate/systemd/user/logrotate.service b/logrotate/systemd/user/logrotate.service
new file mode 100644
index 00000000..0193d5be
--- /dev/null
+++ b/logrotate/systemd/user/logrotate.service
@@ -0,0 +1,10 @@
+[Unit]
+Description=user log rotation
+
+[Service]
+Type=oneshot
+ConfigurationDirectory=%p %p/config.d
+StateDirectory=%p
+ExecStartPre=/bin/mkdir -pv -- %h/.local/state/%p
+ExecStart=/usr/sbin/logrotate --state=%h/.local/state/%p/status -- %E/%p/config
+TimeoutStartSec=20m
diff --git a/logrotate/systemd/user/logrotate.timer b/logrotate/systemd/user/logrotate.timer
new file mode 100644
index 00000000..077aeac9
--- /dev/null
+++ b/logrotate/systemd/user/logrotate.timer
@@ -0,0 +1,10 @@
+[Unit]
+Description=user log rotation schedule
+
+[Timer]
+OnBootSec=1h
+OnUnitActiveSec=6h
+RandomizedDelaySec=5m
+
+[Install]
+WantedBy=timers.target
diff --git a/man/man1/bp.1df b/man/man1/bp.1df
index 93f08f74..835ffaf6 100644
--- a/man/man1/bp.1df
+++ b/man/man1/bp.1df
@@ -5,7 +5,7 @@
.SH SYNOPSIS
.B bp
.br
-BROWSER=firefox
+BROWSER=librewolf
.B bp
.SH DESCRIPTION
.B bp
diff --git a/man/man1/br.1df b/man/man1/br.1df
index a84a55d3..1690af5c 100644
--- a/man/man1/br.1df
+++ b/man/man1/br.1df
@@ -8,7 +8,7 @@
.B br
http://www.example.com/
.br
-BROWSER=firefox
+BROWSER=librewolf
.B br
.SH DESCRIPTION
.B br
diff --git a/man/man1/dmp.1df b/man/man1/dmp.1df
deleted file mode 100644
index d663e3d0..00000000
--- a/man/man1/dmp.1df
+++ /dev/null
@@ -1,17 +0,0 @@
-.TH DMP 1df "August 2016" "Manual page for dmp"
-.SH NAME
-.B dmp
-\- pick a pass(1) password with dmenu(1)
-.SH SYNOPSIS
-.B dmp
-.SH DESCRIPTION
-.B dmp
-applies dmenu(1) to pick a password entry from a pass(1) store and put it into
-the X CLIPBOARD for a period of time.
-.P
-If notify-send(1) is installed, a notification with the default priority will
-be written when the password is successfully clipped.
-.SH SEE ALSO
-dmenu(1), notify-send(1), pass(1), xsel(1)
-.SH AUTHOR
-Tom Ryder <tom@sanctum.geek.nz>
diff --git a/man/man1/msc.1df b/man/man1/msc.1df
new file mode 100644
index 00000000..b8aadb11
--- /dev/null
+++ b/man/man1/msc.1df
@@ -0,0 +1,12 @@
+.TH MSC 1df "May 2020" "Manual page for msc"
+.SH NAME
+.B msc
+\- count the messages in a user's mail spool or other mbox
+.SH SYNOPSIS
+.B msc
+.SH DESCRIPTION
+.B msc
+counts the messages in the given mailboxes, or the user mail spool if not
+provided and it can be found in the MAIL env var or at common paths.
+.SH AUTHOR
+Tom Ryder <tom@sanctum.geek.nz>
diff --git a/man/man1/phpcsff.1df b/man/man1/phpcsff.1df
new file mode 100644
index 00000000..a6364367
--- /dev/null
+++ b/man/man1/phpcsff.1df
@@ -0,0 +1,21 @@
+.TH PHPCSFF 1df "April 2020" "Manual page for phpcsff"
+.SH NAME
+.B phpcsff
+\- use php-cs-fixed as a source filter
+.SH SYNOPSIS
+.B phpcsff
+source.php
+.br
+.B phpcsff
+\< source.php
+.br
+.B phpcsff
+source.php > source.fixed.php
+.br
+.SH DESCRIPTION
+.B phpcsff
+allows the use of PHP linter php-cs-fixer as a stream filter, to work around its fixed edit-in-place behaviour using temporary files. It's intended for use as an 'equalprg' in Vim, but it might be useful in other circumstances too.
+.SH SEE ALSO
+<https://github.com/FriendsOfPHP/PHP-CS-Fixer>
+.SH AUTHOR
+Tom Ryder <tom@sanctum.geek.nz>
diff --git a/man/man1/plmu.1df b/man/man1/plmu.1df
deleted file mode 100644
index 92e0a550..00000000
--- a/man/man1/plmu.1df
+++ /dev/null
@@ -1,19 +0,0 @@
-.TH PLMU 1df "June 2016" "Manual page for plmu"
-.SH NAME
-.B plmu
-\- upgrade plenv[1] modules with cpanm(1)
-.SH SYNOPSIS
-.B plmu
-.SH DESCRIPTION
-.B plmu
-iterates through a list of the modules installed in the current plenv(1)
-version of Perl, excluding any defined in ~/.plenv/non-cpanm-modules, and
-attempts to upgrade each of them, reporting any errors. It does not run any
-tests, so it's just a shortcut for your personal Perl installation tinkerings,
-and not for any production deployment of plenv[1].
-.SH SEE ALSO
-[1] plenv: https://github.com/tokuhirom/plenv
-.br
-cpanm(1)
-.SH AUTHOR
-Tom Ryder <tom@sanctum.geek.nz>
diff --git a/man/man1/qat.1df b/man/man1/qat.1df
new file mode 100644
index 00000000..d7466b3a
--- /dev/null
+++ b/man/man1/qat.1df
@@ -0,0 +1,19 @@
+.TH QAT 1df "May 2020" "Manual page for qat"
+.SH NAME
+.B qat
+\- quiet cat for terminal pastes
+.SH SYNOPSIS
+.B qat
+| wc -l
+.br
+.B qat
+| grep pattern
+.SH DESCRIPTION
+.B qat
+switches the echo feature for stty(1) off for the duration of a cat(1). You
+can use this to paste stuff into a pipeline without the terminal echoing it
+back at you.
+.SH SEE ALSO
+stty(1)
+.SH AUTHOR
+Tom Ryder <tom@sanctum.geek.nz>
diff --git a/man/man1/sls.1df b/man/man1/sls.1df
index 83c13201..dde8e622 100644
--- a/man/man1/sls.1df
+++ b/man/man1/sls.1df
@@ -1,4 +1,4 @@
-.TH SLS 1df "May 2014" "Manual page for sls"
+.TH SLS 1df "August 2022" "Manual page for sls"
.SH NAME
.B sls
\- list the first hostname on each line of an ssh_config(5) file
@@ -10,9 +10,9 @@ ssh_config_alt1 ssh_config_alt2
.SH DESCRIPTION
.B sls
runs slsf(1df) on the given set of ssh_config(5) files to print the first
-non-wildcard hostname on each "Host" line, defaulting to /etc/ssh/ssh_config
-and ~/.ssh/config if they exist. Suitable for use in batch scripts like
-sra(1df).
+non-wildcard hostname on each "Host" line, defaulting to
+/etc/ssh/ssh_config.d/*.conf, /etc/ssh/ssh_config, ~/.ssh/config.d/*.conf, and
+~/.ssh/config if they exist. Suitable for use in batch scripts like sra(1df).
.SH SEE ALSO
slsf(1df), sra(1df), sta(1df), ssh(1), ssh_config(5)
.SH AUTHOR
diff --git a/man/man1/slsf.1df b/man/man1/slsf.1df
index 31453dca..6d59ba3d 100644
--- a/man/man1/slsf.1df
+++ b/man/man1/slsf.1df
@@ -1,4 +1,4 @@
-.TH SLSF 1df "July 2016" "Manual page for slsf"
+.TH SLSF 1df "August 2022" "Manual page for slsf"
.SH NAME
.B slsf
\- list the first hostname on each line of ssh_config(5) files
@@ -10,9 +10,9 @@ cat ~/.ssh_config |
.br
.SH DESCRIPTION
.B slsf
-iterates through the ssh_config(5) files given as its input and prints the
-first name given on each "Host" line, as long as it contains no wildcards.
-Most users will probably want the sls(1df) frontend.
+iterates through the ssh_config(5) files given as its input and prints a unique
+list of the patterns given on each "Host" line containing no wildcards. Most
+users will probably want the sls(1df) frontend instead.
.P
Within the file, a comment "### nosls" on its own line will exclude all
following output unless an "### sls" comment is read to resume it again:
diff --git a/man/man1/xrbg.1df b/man/man1/xrbg.1df
index 14bfbc7d..9c067ff9 100644
--- a/man/man1/xrbg.1df
+++ b/man/man1/xrbg.1df
@@ -11,8 +11,8 @@ XBACKGROUNDS=/path/to/images
.B xrbg
searches for images in the directory named in the XBACKGROUNDS environment
variable (defaults to ~/.xbackgrounds), chooses a random one with rndf(1df),
-and applies it with feh(1). It's designed for use in ~/.xinitrc, but it seems
-to work when called manually from within an X session too.
+and applies it with feh(1). It's designed for use in X startup files, but it
+seems to work when called manually from within an X session too.
.SH SEE ALSO
feh(1), rndf(1df)
.SH AUTHOR
diff --git a/man/man1/xrq.1df b/man/man1/xrq.1df
index 9dd7f0d1..184aa186 100644
--- a/man/man1/xrq.1df
+++ b/man/man1/xrq.1df
@@ -1,4 +1,4 @@
-.TH XRQ 1df "January 2017" "Manual page for xrq"
+.TH XRQ 1df "February 2023" "Manual page for xrq"
.SH NAME
.B xrq
\- query X resource values
@@ -7,7 +7,7 @@
Xft.hintstyle
.br
.B xrq
-URxvt.color0 URxvt.color9
+XTerm.vt100.color0 XTerm.vt100.color9
.SH DESCRIPTION
.B xrq
runs xrdb(1) with the -query option and filters for the values of the named
diff --git a/man/man1/xsnap.1df b/man/man1/xsnap.1df
new file mode 100644
index 00000000..276e27b3
--- /dev/null
+++ b/man/man1/xsnap.1df
@@ -0,0 +1,16 @@
+.TH XSNAP 1df "May 2022" "Manual page for xsnap"
+.SH NAME
+.B xsnap
+\- wrapper around scrot(1) for serialized recorded screenshots
+.SH SYNOPSIS
+.B xsnap
+.br
+.B xsnap
+\--select
+.SH DESCRIPTION
+.B xsnap
+takes a PNG screenshot with scrot(1), passing any options thereto, saving the
+image into a date-stamped path ~/.local/share/scrot/screenshots/YYYY-MM-DD,
+with increasing integer filenames for that day.
+.SH AUTHOR
+Tom Ryder <tom@sanctum.geek.nz>
diff --git a/man/man6/pks.6df b/man/man6/pks.6df
index 8de04491..b0f15d24 100644
--- a/man/man6/pks.6df
+++ b/man/man6/pks.6df
@@ -1,4 +1,4 @@
-.TH PKS 6df "July 2017" "Manual page for pks"
+.TH PKS 6df "March 2021" "Manual page for pks"
.SH NAME
.B pks
\- select and laugh at a random word from a system dictionary or fileset
@@ -24,6 +24,6 @@ A hyphen character "-" can be given as an argument to select standard input.
.SH SEE ALSO
philsay(6df)
.br
-<https://www.youtube.com/watch?v=F8ID1KJQxB8>
+<https://www.youtube.com/watch?v=FKmHtw0vDrs>
.SH AUTHOR
Tom Ryder <tom@sanctum.geek.nz>
diff --git a/man/man6/xyzzy.6df b/man/man6/xyzzy.6df
index 7270b95d..0d928b45 100644
--- a/man/man6/xyzzy.6df
+++ b/man/man6/xyzzy.6df
@@ -8,7 +8,7 @@
Invoking
.B xyzzy
in a directory will tag that directory as a target for teleportation, writing
-its name to the file ~/.xyzzy. Typing it again at any given point will then
-change into that marked directory.
+its name to the file $XDG_CONFIG_HOME/xyzzy/dest. Typing it again at any given
+point will then change into that marked directory.
.SH AUTHOR
Tom Ryder <tom@sanctum.geek.nz>
diff --git a/man/man7/dotfiles.7df b/man/man7/dotfiles.7df
index 3e70c142..83616552 100644
--- a/man/man7/dotfiles.7df
+++ b/man/man7/dotfiles.7df
@@ -1,448 +1,466 @@
-.\" Automatically generated by Pandoc 2.2.1
+.\" Automatically generated by Pandoc 2.17.1.1
.\"
-.TH "DOTFILES" "7" "October 2017" "Tom Ryder's personal scripts and configuration" ""
+.\" Define V font for inline verbatim, using C font in formats
+.\" that render this, and otherwise B font.
+.ie "\f[CB]x\f[]"x" \{\
+. ftr V B
+. ftr VI BI
+. ftr VB B
+. ftr VBI BI
+.\}
+.el \{\
+. ftr V CR
+. ftr VI CI
+. ftr VB CB
+. ftr VBI CBI
+.\}
+.TH "DOTFILES" "7" "October 2017" "Tom Ryder\[cq]s personal scripts and configuration" ""
.hy
.SH Dotfiles (Tom Ryder)
.PP
This is my personal repository of configuration files and scripts for
-\f[C]$HOME\f[], including most of the settings that migrate well between
-machines.
+\f[V]$HOME\f[R], including most of the settings that migrate well
+between machines.
.PP
This repository began as a simple way to share Vim and tmux
-configuration, but over time a lot of scripts and shell configuration
-have been added, making it into a personal suite of custom Unix tools.
+configuration, but a lot of scripts and shell configuration have been
+added over time, making it into a personal suite of custom Unix tools.
.SS Installation
.IP
.nf
\f[C]
-$\ git\ clone\ https://sanctum.geek.nz/code/dotfiles.git\ ~/.dotfiles
-$\ cd\ ~/.dotfiles
-$\ git\ submodule\ init
-$\ git\ submodule\ update
-$\ make
-$\ make\ \-n\ install
-$\ make\ install
-\f[]
+$ mkdir -p \[ti]/.local/src
+$ git clone https://dev.sanctum.geek.nz/code/dotfiles.git \[ti]/.local/src/dotfiles
+$ cd \[ti]/.local/src/dotfiles
+$ git submodule init
+$ git submodule update
+$ make
+$ make -n install # Check output carefully
+$ make install
+\f[R]
.fi
.PP
-For the default \f[C]all\f[] target, you'll need a POSIX\-fearing
-userland, including \f[C]make(1)\f[] and \f[C]m4(1)\f[].
+For the default \f[V]all\f[R] target, you\[cq]ll need a POSIX-fearing
+userland, including \f[V]make(1)\f[R] and \f[V]m4(1)\f[R].
.PP
-The installation \f[C]Makefile\f[] will overwrite things standing in the
+The installation \f[V]Makefile\f[R] overwrites things standing in the
way of its installed files without backing them up, so read the output
-of \f[C]make\ \-n\ install\f[] before running \f[C]make\ install\f[] to
-make sure you aren't going to lose anything unexpected.
-If you're still not sure, install it in a temporary directory so you can
-explore:
+of \f[V]make -n install\f[R] before running \f[V]make install\f[R]
+carefully, to make sure you aren\[cq]t going to lose anything
+unexpected.
+If you\[cq]re still not sure, install it in a temporary directory first,
+so you can explore:
.IP
.nf
\f[C]
-$\ tmpdir=$(mktemp\ \-d)
-$\ make\ install\ HOME="$tmpdir"
-$\ env\ \-i\ HOME="$tmpdir"\ TERM="$TERM"\ "$SHELL"\ \-l
-\f[]
+$ tmpdir=$(mktemp -d)
+$ make install HOME=\[dq]$tmpdir\[dq]
+$ env -i HOME=\[dq]$tmpdir\[dq] TERM=\[dq]$TERM\[dq] \[dq]$SHELL\[dq] -l
+\f[R]
.fi
.PP
-The default \f[C]install\f[] target will install these targets and all
+The default \f[V]install\f[R] target will install these targets and all
their dependencies:
.IP \[bu] 2
-\f[C]install\-bin\f[]
+\f[V]install-bin\f[R]
.IP \[bu] 2
-\f[C]install\-bin\-man\f[]
+\f[V]install-curl\f[R]
.IP \[bu] 2
-\f[C]install\-curl\f[]
+\f[V]install-ex\f[R]
.IP \[bu] 2
-\f[C]install\-ex\f[]
+\f[V]install-git\f[R]
.IP \[bu] 2
-\f[C]install\-git\f[]
+\f[V]install-gnupg\f[R]
.IP \[bu] 2
-\f[C]install\-gnupg\f[]
+\f[V]install-less\f[R]
.IP \[bu] 2
-\f[C]install\-less\f[]
+\f[V]install-login-shell\f[R]
.IP \[bu] 2
-\f[C]install\-login\-shell\f[]
+\f[V]install-man\f[R]
.IP \[bu] 2
-\f[C]install\-readline\f[]
+\f[V]install-readline\f[R]
.IP \[bu] 2
-\f[C]install\-vim\f[]
+\f[V]install-vim\f[R]
.PP
-The \f[C]install\-login\-shell\f[] looks at your \f[C]SHELL\f[]
-environment variable and tries to figure out which shell's configuration
-files to install, falling back on \f[C]install\-sh\f[].
+The \f[V]install-login-shell\f[R] target looks at your \f[V]SHELL\f[R]
+environment variable, and tries to figure out which shell\[cq]s
+configuration files to install, falling back on \f[V]install-sh\f[R].
.PP
-The remaining files can be installed with the other \f[C]install\-*\f[]
+The remaining files can be installed with the other \f[V]install-*\f[R]
targets.
-Try \f[C]awk\ \-f\ bin/mftl.awk\ Makefile\f[] in the project's root
+Try \f[V]awk -f bin/mftl.awk Makefile\f[R] in the project\[cq]s root
directory to see a list.
.SS Configuration
.PP
-To save a set of \f[C]make\f[] targets useful for a specific user or
-host, you can save them in a newline\-separated file
-\f[C]~/.dotfiles.conf\f[], and install using that with the special
-\f[C]install\-conf\f[] target.
-This can include variable settings, too:
+To keep a set of \f[V]make\f[R] targets useful for a specific user or
+host, you can list them in a newline-separated file
+\f[V]\[ti]/.config/dotfiles/config\f[R], and install using that with the
+special \f[V]install-conf\f[R] target.
+This can include macro settings for the \f[V]Makefile\f[R], too:
.IP
.nf
\f[C]
-$\ cd
-$\ cat\ .dotfiles.conf
-install\-bash
-install\-bin
-EMAIL=you\@example.com
-$\ make\ \-C\ .dotfiles\ install\-conf
-\f[]
+$ cd
+$ cat .config/dotfiles/config
+install-bash
+install-bin
+EMAIL=you\[at]example.com
+$ make -C .local/src/dotfiles install-conf
+\f[R]
.fi
.SS Tools
.PP
Configuration is included for:
.IP \[bu] 2
-Bourne\-style POSIX shells, sharing a \f[C]\&.profile\f[], an
-\f[C]ENV\f[] file, and some helper functions:
+Bourne-style POSIX shells, sharing a \f[V].profile\f[R], an
+\f[V]ENV\f[R] file, and some helper functions:
.RS 2
.IP \[bu] 2
-GNU Bash (https://www.gnu.org/software/bash/) (3.0 or higher)
+GNU Bash (https://www.gnu.org/software/bash/) (v3.0 or newer)
.IP \[bu] 2
-Korn shell (http://www.kornshell.com/) (\f[C]ksh93\f[], \f[C]pdksh\f[],
-\f[C]mksh\f[])
+Korn shell (http://www.kornshell.com/) (\f[V]ksh93\f[R],
+\f[V]pdksh\f[R], \f[V]mksh\f[R])
.IP \[bu] 2
Z shell (https://www.zsh.org/)
.RE
.IP \[bu] 2
-Abook (http://abook.sourceforge.net/) \[en] curses address book program
+Abook (http://abook.sourceforge.net/)\[em]curses address book program
.IP \[bu] 2
-cURL (https://curl.haxx.se/) \[en] Command\-line tool for transferring
-data with URL syntax
+cURL (https://curl.haxx.se/)\[em]Command-line tool for transferring data
+with URL syntax
.IP \[bu] 2
-Dillo (https://www.dillo.org/) \[en] A lightweight web browser
+Dillo (https://www.dillo.org/)\[em]A lightweight web browser
.IP \[bu] 2
-Dunst (https://dunst-project.org/) \[en] A lightweight X11 notification
-daemon that works with \f[C]libnotify\f[]
+\f[V]finger(1)\f[R]\[em]User information lookup program
.IP \[bu] 2
-\f[C]finger(1)\f[] \[en] User information lookup program
+Git (https://git-scm.com/)\[em]Distributed version control system
.IP \[bu] 2
-Git (https://git-scm.com/) \[en] Distributed version control system
-.IP \[bu] 2
-GNU Emacs (https://www.gnu.org/software/emacs/) \[en] Extensible text
+GNU Emacs (https://www.gnu.org/software/emacs/)\[em]Extensible text
editor
.IP \[bu] 2
-GnuPG (https://www.gnupg.org/) \[en] GNU Privacy Guard, for private
+GnuPG (https://www.gnupg.org/)\[em]GNU Privacy Guard, for private
communication and file encryption
.IP \[bu] 2
-GTK+ (https://www.gtk.org/) \[en] GIMP Toolkit, for graphical user
-interface elements
-.IP \[bu] 2
-i3 (https://i3wm.org/) \[en] Tiling window manager
+i3 (https://i3wm.org/)\[em]Tiling window manager
.IP \[bu] 2
-less (https://www.gnu.org/software/less/) \[en] Terminal pager
+less (https://www.gnu.org/software/less/)\[em]Terminal pager
.IP \[bu] 2
-mpv (https://mpv.io/) \[en] Media player
+mpv (https://mpv.io/)\[em]Media player
.IP \[bu] 2
-Mutt (http://www.mutt.org/) \[en] Terminal mail user agent
+Mutt (http://www.mutt.org/)\[em]Terminal mail user agent
.IP \[bu] 2
-\f[C]mysql(1)\f[] (https://linux.die.net/man/1/mysql) \[en]
-Command\-line MySQL client
+\f[V]mysql(1)\f[R] (https://linux.die.net/man/1/mysql)\[em]Command-line
+MySQL client
.IP \[bu] 2
-Ncmpcpp (https://rybczak.net/ncmpcpp/) \[en] ncurses music player client
+ncmpcpp (https://rybczak.net/ncmpcpp/)\[em]ncurses based MPD client
+inspired by ncmpc
.IP \[bu] 2
-Newsboat (https://newsboat.org/) \[en] Terminal RSS/Atom feed reader
+Newsboat (https://newsboat.org/)\[em]Terminal RSS/Atom feed reader
.IP \[bu] 2
-\f[C]psql(1)\f[] (https://linux.die.net/man/1/psql) \[en] Command\-line
+\f[V]psql(1)\f[R] (https://linux.die.net/man/1/psql)\[em]Command-line
PostgreSQL client
.IP \[bu] 2
-Perl::Critic (http://perlcritic.com/) \[en] static source code analysis
-engine for Perl
+Parcellite (http://parcellite.sourceforge.net/)\[em]clipboard manager
+for X
.IP \[bu] 2
-Perl::Tidy (http://perltidy.sourceforge.net/) \[en] Perl source code
-reformatter
+Perl::Critic (http://perlcritic.com/)\[em]static source code analysis
+engine for Perl
.IP \[bu] 2
-Readline (https://tiswww.case.edu/php/chet/readline/rltop.html) \[en]
-GNU library for user input used by Bash, MySQL, and others
+Perl::Tidy (http://perltidy.sourceforge.net/)\[em]reformats Perl source
+code
.IP \[bu] 2
-rxvt\-unicode (http://software.schmorp.de/pkg/rxvt-unicode.html) \[en]
-Fork of the rxvt terminal emulator with Unicode support
+Readline (https://tiswww.case.edu/php/chet/readline/rltop.html)\[em]GNU
+library for user input used by Bash, MySQL, and others
.IP \[bu] 2
-Subversion (https://subversion.apache.org/) \[en] Apache Subversion, a
+Subversion (https://subversion.apache.org/)\[em]Apache Subversion, a
version control system
.IP \[bu] 2
-tidy (http://www.html-tidy.org/) \[en] HTML/XHTML linter and tidier
+tidy (http://www.html-tidy.org/)\[em]HTML/XHTML linter and tidier
.IP \[bu] 2
-tmux (https://tmux.github.io/) \[en] Terminal multiplexer similar to GNU
+tmux (https://tmux.github.io/)\[em]Terminal multiplexer similar to GNU
Screen
.IP \[bu] 2
-Vim (https://www.vim.org/) \[en] Vi IMproved, a text editor
+Vim (https://www.vim.org/)\[em]Vi IMproved, a text editor
.IP \[bu] 2
-X11 (https://www.x.org/wiki/) \[en] Windowing system with network
+X11 (https://www.x.org/wiki/)\[em]Windowing system with network
transparency for Unix
.PP
-The configurations for shells, GnuPG, Mutt, tmux, and Vim are the most
-expansive, and most likely to be of interest.
-The i3 configuration is mostly changed to make window switching behave
-like Vim windows and tmux panes do, and there's a fair few resources
-defined for rxvt\-unicode.
+There is also some slightly customized support for multi-version
+environment management for three major scripting languages:
+.IP \[bu] 2
+plenv (https://github.com/tokuhirom/plenv)\[em]Perl
+.IP \[bu] 2
+pyenv (https://github.com/pyenv/pyenv)\[em]Python
+.IP \[bu] 2
+rbenv (https://github.com/rbenv/rbenv)\[em]Ruby
+.PP
+The configurations for shells, Mutt, tmux, and Vim are the most likely
+to be of interest.
+The i3 configuration is limited mainly to changing window switching key
+bindings to match Vim\[cq]s.
.SS Shell
.PP
-My \f[C]\&.profile\f[] and other files in \f[C]sh\f[] are written in
-POSIX shell script, so they should work in most \f[C]sh(1)\f[]
-implementations.
-Individual scripts called by \f[C]\&.profile\f[] are saved in
-\f[C]\&.profile.d\f[] and iterated on login for ease of management.
+On GNU/Linux, I use Bash; on *BSD, I use some variant of Korn Shell,
+preferably \f[V]ksh93\f[R] if it\[cq]s available.
+.SS POSIX core
+.PP
+My \f[V]\[ti]/.profile\f[R] and other files in \f[V]sh\f[R] are written
+in POSIX shell script, so they \f[I]should\f[R] work in most
+POSIX-conforming \f[V]sh(1)\f[R] implementations.
+Please email me if you find a case where they don\[cq]t!
+.PP
+Further shell snippets to run on login are sourced from
+\f[V]\[ti]/.profile.d\f[R] by \f[V]\[ti]/.profile\f[R].
Most of these boil down to exporting variables appropriate to the system
and the software it has available.
.PP
-Configuration that should be sourced for all POSIX\-fearing interactive
-shells is kept in \f[C]~/.shrc\f[], with subscripts read from
-\f[C]~/.shrc.d\f[].
-There's a shim in \f[C]~/.shinit\f[] to act as \f[C]ENV\f[].
-I make an effort to target POSIX for my functions and scripts where I
-can so that the same files can be loaded for all shells.
+Configuration that should be sourced for all conforming
+\f[I]interactive\f[R] shells is kept in \f[V]\[ti]/.shrc\f[R], with
+subscripts read from \f[V]\[ti]/.shrc.d\f[R].
+There\[cq]s a \f[V]\[ti]/.shinit\f[R] shim to act as \f[V]ENV\f[R].
+.SS GNU Bash
.PP
-On GNU/Linux I use Bash, on BSD I use some variant of Korn Shell,
-preferably \f[C]ksh93\f[] if it's available.
-.PP
-My Bash is written to work with any version 3.0 or
+My Bash scripts are written to work with GNU Bash v3.0 or
newer (https://wiki.bash-hackers.org/scripting/bashchanges).
This is why I use older syntax for certain things such as appending
items to arrays:
.IP
.nf
\f[C]
-array[${#array[\@]}]=$item
-\f[]
+array[${#array[\[at]]}]=$item
+\f[R]
.fi
.PP
-Compare this to the much nicer syntax available since 3.1\-alpha1, which
-actually works for arrays with sparse indices, unlike the above syntax:
+This doesn\[cq]t work for arrays with sparse indices; compare this to
+the much nicer syntax available since 3.1-alpha1, which does:
.IP
.nf
\f[C]
-array+=("$item")
-\f[]
+array+=(\[dq]$item\[dq])
+\f[R]
.fi
.PP
-Where I do use features that are only available in versions of Bash
-newer than 3.0, such as newer \f[C]shopt\f[] options or
-\f[C]PROMPT_DIRTRIM\f[], they are only run after testing
-\f[C]BASH_VERSINFO\f[] appropriately.
+I do use some features that are only available in versions after v3.0,
+such as newer \f[V]shopt\f[R] options like \f[V]dirspell\f[R], or
+variables like \f[V]PROMPT_DIRTRIM\f[R].
+These are set only after testing \f[V]BASH_VERSINFO\f[R] appropriately.
.SS Prompt
.PP
A terminal session with my prompt looks something like this:
.IP
.nf
\f[C]
-~$\ ssh\ remote
-remote:~$\ cd\ .dotfiles
-remote:~/.dotfiles(master+!)$\ git\ status
-\ M\ README.md
-M\ \ bash/bashrc.d/prompt.bash
-A\ \ init
-remote:~/.dotfiles(master+!)$\ foobar
-foobar:\ command\ not\ found
-remote:~/.dotfiles(master+!)<127>$\ sleep\ 5\ &
-[1]\ 28937
-remote:~/.dotfiles(master+!){1}$
-\f[]
+\[ti]$ ssh remote
+remote:\[ti]$ cd .local/src/dotfiles
+remote:\[ti]/.local/src/dotfiles(master+!)$ git status
+ M README.md
+M bash/bashrc.d/prompt.bash
+A init
+remote:\[ti]/.local/src/dotfiles(master+!)$ foobar
+foobar: command not found
+remote:\[ti]/.local/src/dotfiles(master+!)<127>$ sleep 5 &
+[1] 28937
+remote:\[ti]/.local/src/dotfiles(master+!){1}$
+\f[R]
.fi
.PP
The hostname is elided if not connected via SSH.
-The working directory with tilde abbreviation for \f[C]$HOME\f[] is
+The working directory with tilde abbreviation for \f[V]$HOME\f[R] is
always shown.
The rest of the prompt expands based on context to include these
-elements in this order:
+elements, in this order:
+.IP \[bu] 2
+Whether in a Git repository if applicable,
.IP \[bu] 2
-Whether in a Git repository if applicable, and punctuation to show
-repository status including reference to upstreams at a glance.
-Subversion support can also be enabled (I need it at work), in which
-case a \f[C]git:\f[] or \f[C]svn:\f[] prefix is added appropriately.
+The current version control branch, tag, or commit/revision if
+applicable, and punctuation to show repository status including
+reference to upstreams at a glance.
+Subversion support can also be enabled, in which case a \f[V]git:\f[R]
+or \f[V]svn:\f[R] prefix is added appropriately for disambiguation.
.IP \[bu] 2
-The number of running background jobs, if non\-zero.
+The number of running background jobs, if non-zero.
.IP \[bu] 2
-The exit status of the last command, if non\-zero.
+The exit status of the last command, if non-zero.
.PP
-You can set \f[C]PROMPT_COLOR\f[], \f[C]PROMPT_PREFIX\f[], and
-\f[C]PROMPT_SUFFIX\f[] too, which all do about what you'd expect.
+You can set \f[V]PROMPT_COLOR\f[R], \f[V]PROMPT_PREFIX\f[R], and
+\f[V]PROMPT_SUFFIX\f[R] too, which all do about what you\[cq]d expect.
.PP
-If you start up Bash, Korn shell, or Z shell, and it detects that it's
-not your login shell, the prompt will display an appropriate prefix.
+If you start up GNU Bash, Korn shell, or Z shell, and that doesn\[cq]t
+match your login shell, the prompt should display an appropriate prefix.
.PP
-This is all managed within the \f[C]prompt\f[] function.
-There's some mildly hacky logic on \f[C]tput\f[] codes included such
-that it should work correctly for most common terminals using both
-\f[C]termcap(5)\f[] and \f[C]terminfo(5)\f[], including *BSD systems.
-It's also designed to degrade gracefully for eight\-color and no\-color
-terminals.
+This is all managed within the \f[V]prompt\f[R] function.
+There\[cq]s some mildly hacky logic on \f[V]tput\f[R] codes included
+such that it should work correctly for most common terminals using both
+\f[V]termcap(5)\f[R] and \f[V]terminfo(5)\f[R], including *BSD systems.
+It\[cq]s also designed to degrade gracefully for eight-color and
+no-color terminals.
.SS Functions
.PP
-If a function can be written in POSIX \f[C]sh\f[] without too much
-hackery, I put it in \f[C]sh/shrc.d\f[] to be loaded by any POSIX
+If a function can be written in POSIX \f[V]sh\f[R] without too much
+hackery, I put it in \f[V]sh/shrc.d\f[R] to be loaded by any POSIX
interactive shell.
Those include:
.IP \[bu] 2
Four functions for using a \[lq]marked\[rq] directory, which I find a
-more manageable concept than the \f[C]pushd\f[]/\f[C]popd\f[] directory
-stack:
+more manageable concept than the \f[V]pushd\f[R]/\f[V]popd\f[R]
+directory stack:
.RS 2
.IP \[bu] 2
-\f[C]md()\f[] marks a given (or the current) directory.
+\f[V]md()\f[R] marks a given (or the current) directory.
.IP \[bu] 2
-\f[C]gd()\f[] goes to the marked directory.
+\f[V]gd()\f[R] goes to the marked directory.
.IP \[bu] 2
-\f[C]pmd()\f[] prints the marked directory.
+\f[V]pmd()\f[R] prints the marked directory.
.IP \[bu] 2
-\f[C]xd()\f[] swaps the current and marked directories.
+\f[V]xd()\f[R] swaps the current and marked directories.
.RE
.IP \[bu] 2
Ten other directory management and navigation functions:
.RS 2
.IP \[bu] 2
-\f[C]bd()\f[] changes into a named ancestor of the current directory.
+\f[V]bd()\f[R] changes into a named ancestor of the current directory.
.IP \[bu] 2
-\f[C]gt()\f[] changes into a directory or into a file's directory.
+\f[V]gt()\f[R] changes into a directory or into a file\[cq]s directory.
.IP \[bu] 2
-\f[C]lgt()\f[] runs \f[C]gt()\f[] on the first result from a
-\f[C]loc(1df)\f[] search.
+\f[V]lgt()\f[R] runs \f[V]gt()\f[R] on the first result from a
+\f[V]loc(1df)\f[R] search.
.IP \[bu] 2
-\f[C]mkcd()\f[] creates a directory and changes into it.
+\f[V]mkcd()\f[R] creates a directory and changes into it.
.IP \[bu] 2
-\f[C]pd()\f[] changes to the argument's parent directory.
+\f[V]pd()\f[R] changes to the argument\[cq]s parent directory.
.IP \[bu] 2
-\f[C]rd()\f[] replaces the first instance of its first argument with its
-second argument in \f[C]$PWD\f[], emulating a feature of the Zsh
-\f[C]cd\f[] builtin that I like.
+\f[V]rd()\f[R] replaces the first instance of its first argument with
+its second argument in \f[V]$PWD\f[R], emulating a feature of the Zsh
+\f[V]cd\f[R] builtin that I like.
.IP \[bu] 2
-\f[C]scr()\f[] creates a temporary directory and changes into it.
+\f[V]scr()\f[R] creates a temporary directory and changes into it.
.IP \[bu] 2
-\f[C]sd()\f[] changes into a sibling of the current directory.
+\f[V]sd()\f[R] changes into a sibling of the current directory.
.IP \[bu] 2
-\f[C]ud()\f[] changes into an indexed ancestor of a directory.
+\f[V]ud()\f[R] changes into an indexed ancestor of a directory.
.IP \[bu] 2
-\f[C]vr()\f[] tries to change to the root directory of a source control
+\f[V]vr()\f[R] tries to change to the root directory of a source control
repository.
.RE
.IP \[bu] 2
Two editor wrapper functions:
.RS 2
.IP \[bu] 2
-\f[C]e()\f[] invokes \f[C]$EDITOR\f[], or \f[C]ed(1)\f[] if not set.
+\f[V]e()\f[R] invokes \f[V]$EDITOR\f[R], or \f[V]ed(1)\f[R] if not set.
.IP \[bu] 2
-\f[C]v()\f[] invokes \f[C]$VISUAL\f[], or \f[C]vi(1)\f[] if not set.
+\f[V]v()\f[R] invokes \f[V]$VISUAL\f[R], or \f[V]vi(1)\f[R] if not set.
.RE
.IP \[bu] 2
-\f[C]bc()\f[] silences startup messages from GNU \f[C]bc(1)\f[].
+\f[V]bc()\f[R] silences startup messages from GNU \f[V]bc(1)\f[R].
.IP \[bu] 2
-\f[C]ed()\f[] tries to get verbose error messages, a prompt, and a
-Readline environment for \f[C]ed(1)\f[].
+\f[V]ed()\f[R] tries to get verbose error messages, a prompt, and a
+Readline environment for \f[V]ed(1)\f[R].
.IP \[bu] 2
-\f[C]gdb()\f[] silences startup messages from \f[C]gdb(1)\f[].
+\f[V]gdb()\f[R] silences startup messages from \f[V]gdb(1)\f[R].
.IP \[bu] 2
-\f[C]grep()\f[] tries to apply color and other options good for
+\f[V]grep()\f[R] tries to apply color and other options good for
interactive use if available.
.IP \[bu] 2
-\f[C]hgrep()\f[] allows searching \f[C]$HISTFILE\f[].
-.IP \[bu] 2
-\f[C]keychain()\f[] keeps \f[C]$GPG_TTY\f[] up to date if a GnuPG agent
-is available.
+\f[V]hgrep()\f[R] allows searching \f[V]$HISTFILE\f[R].
.IP \[bu] 2
-\f[C]ls()\f[] tries to apply color and other options good for
+\f[V]ls()\f[R] tries to apply color and other options good for
interactive use if available.
.RS 2
.IP \[bu] 2
-\f[C]la()\f[] runs \f[C]ls\ \-A\f[] if it can, or \f[C]ls\ \-a\f[]
+\f[V]la()\f[R] runs \f[V]ls -A\f[R] if it can, or \f[V]ls -a\f[R]
otherwise.
.IP \[bu] 2
-\f[C]ll()\f[] runs \f[C]ls\ \-Al\f[] if it can, or \f[C]ls\ \-al\f[]
+\f[V]ll()\f[R] runs \f[V]ls -Al\f[R] if it can, or \f[V]ls -al\f[R]
otherwise.
.RE
.IP \[bu] 2
-\f[C]path()\f[] manages the contents of \f[C]PATH\f[] conveniently.
+\f[V]path()\f[R] manages the contents of \f[V]PATH\f[R] conveniently.
.IP \[bu] 2
-\f[C]scp()\f[] tries to detect forgotten hostnames in \f[C]scp(1)\f[]
+\f[V]scp()\f[R] tries to detect forgotten hostnames in \f[V]scp(1)\f[R]
command calls.
.IP \[bu] 2
-\f[C]sudo()\f[] forces \f[C]\-H\f[] for \f[C]sudo(8)\f[] calls so that
-\f[C]$HOME\f[] is never preserved; I hate having \f[C]root\f[]\-owned
+\f[V]sudo()\f[R] forces \f[V]-H\f[R] for \f[V]sudo(8)\f[R] calls so that
+\f[V]$HOME\f[R] is never preserved; I hate having \f[V]root\f[R]-owned
files in my home directory.
.IP \[bu] 2
-\f[C]tree()\f[] colorizes GNU \f[C]tree(1)\f[] output if possible
-(without having \f[C]LS_COLORS\f[] set).
+\f[V]tor()\f[R] is just a terse shortcut for using Torsocks to anonymize
+TCP connections from the current shell.
.IP \[bu] 2
-\f[C]x()\f[] is a one\-key shortcut for \f[C]exec\ startx\f[].
+\f[V]tree()\f[R] colorizes GNU \f[V]tree(1)\f[R] output if possible
+(without having \f[V]LS_COLORS\f[R] set).
+.IP \[bu] 2
+\f[V]x()\f[R] is a one-key shortcut for \f[V]exec startx\f[R].
.PP
There are a few other little tricks defined for other shells providing
-non\-POSIX features, as compatibility allows:
+non-POSIX features, as compatibility allows:
.IP \[bu] 2
-\f[C]keep()\f[] stores ad\-hoc shell functions and variables (Bash, Korn
+\f[V]keep()\f[R] stores ad-hoc shell functions and variables (Bash, Korn
Shell 93, Z shell).
.IP \[bu] 2
-\f[C]prompt()\f[] sets up my interactive prompt (Bash, Korn Shell, Z
+\f[V]prompt()\f[R] sets up my interactive prompt (Bash, Korn Shell, Z
shell).
.IP \[bu] 2
-\f[C]pushd()\f[] adds a default destination of \f[C]$HOME\f[] to the
-\f[C]pushd\f[] builtin (Bash).
+\f[V]pushd()\f[R] adds a default destination of \f[V]$HOME\f[R] to the
+\f[V]pushd\f[R] builtin (Bash).
.IP \[bu] 2
-\f[C]vared()\f[] allows interactively editing a variable with Readline,
-emulating a Zsh function I like by the same name (Bash).
+\f[V]vared()\f[R] allows interactively editing a variable with Readline,
+emulating a Z shell function I like by the same name (Bash).
.IP \[bu] 2
-\f[C]ver()\f[] prints the current shell's version information (Bash,
-Korn Shell, Z shell).
+\f[V]ver()\f[R] prints the current shell\[cq]s version information
+(Bash, Korn Shell, Z shell).
.SS Completion
.PP
-I find the \f[C]bash\-completion\f[] package a bit too heavy for my
+I find the \f[V]bash-completion\f[R] package a bit too heavy for my
tastes, and turn it off using a stub file installed in
-\f[C]~/.config/bash_completion\f[].
+\f[V]\[ti]/.config/bash_completion\f[R].
The majority of the time I just want to complete paths anyway, and this
makes for a quicker startup without a lot of junk functions in my Bash
namespace.
.PP
-I do make some exceptions with completions defined in
-\f[C]\&.bash_completion.d\f[] files, for things I really do get tired of
+I do make some exceptions with completions defined in files in
+\f[V]\[ti]/.bash_completion.d\f[R] for things I really do get tired of
typing repeatedly:
.IP \[bu] 2
Bash builtins: commands, help topics, shell options, variables, etc.
.IP \[bu] 2
-\f[C]find(1)\f[]'s more portable options
+\f[V]find(1)\f[R]\[cq]s more portable options
.IP \[bu] 2
-\f[C]gpg(1)\f[] long options
+\f[V]gpg(1)\f[R] long options
.IP \[bu] 2
-\f[C]make(1)\f[] targets read from a \f[C]Makefile\f[]
+\f[V]make(1)\f[R] targets read from a \f[V]Makefile\f[R]
.IP \[bu] 2
-\f[C]man(1)\f[] page titles
+\f[V]man(1)\f[R] page titles
.IP \[bu] 2
-\f[C]pass(1)\f[] entries
+\f[V]pass(1)\f[R] entries
.IP \[bu] 2
-\f[C]ssh(1)\f[] hostnames from \f[C]~/.ssh/config\f[]
+\f[V]ssh(1)\f[R] hostnames from \f[V]\[ti]/.ssh/config\f[R]
.PP
For commands that pretty much always want to operate on text, such as
text file or stream editors, I exclude special file types and extensions
I know are binary.
-I don't actually read the file, so this is more of a heuristic thing,
-and sometimes it will get things wrong.
+I don\[cq]t actually read the file, so this is more of a heuristic
+thing, and sometimes it will get things wrong.
.PP
I also add completions for my own scripts and functions where useful.
The completions are dynamically loaded if Bash is version 4.0 or
greater.
-Otherwise, they're all loaded on startup.
+Otherwise, they\[cq]re all loaded on startup.
.SS Korn shell
.PP
These are experimental; they are mostly used to tinker with MirBSD
-\f[C]mksh\f[], AT&T \f[C]ksh93\f[], and OpenBSD \f[C]pdksh\f[].
+\f[V]mksh\f[R], AT&T \f[V]ksh93\f[R], and OpenBSD \f[V]pdksh\f[R].
All shells in this family default to a yellow prompt if detected.
.SS Z shell
.PP
These are experimental; I do not like Z shell much at the moment.
-The files started as a joke (\f[C]exec\ bash\f[]).
-\f[C]zsh\f[] shells default to having a prompt colored cyan.
-.SS GnuPG
-.PP
-The configuration for GnuPG is intended to follow RiseUp's OpenPGP best
-practices (https://riseup.net/en/security/message-security/openpgp/best-practices).
-The configuration file is rebuilt using \f[C]mi5(1df)\f[] and
-\f[C]make(1)\f[] because it requires hard\-coding a path to the SKS
-keyserver certificate authority, and neither tilde nor \f[C]$HOME\f[]
-expansion works for this.
+The files started as a joke (\f[V]exec bash\f[R]).
+\f[V]zsh\f[R] shells default to having a prompt colored cyan.
.SS Mutt
.PP
-My mail is kept in individual Maildirs under \f[C]~/Mail\f[], with
-\f[C]inbox\f[] being where most unfiltered mail is sent.
+My mail is kept in individual Maildir-format directories under
+\f[V]\[ti]/mail\f[R], with the system mail spool in
+e.g.\ \f[V]/var/mail/tejr\f[R] being where most unfiltered new mail is
+spooled.
I use Getmail (http://pyropus.ca/software/getmail/),
maildrop (https://www.courier-mta.org/maildrop/), and
msmtp (https://marlam.de/msmtp/); the configurations for these are not
@@ -454,190 +472,194 @@ The GnuPG and S/MIME interfacing is done with
GPGme (https://www.gnupg.org/related_software/gpgme/), rather than
defining commands for each crypto operation.
I wrote an article about this
-setup (https://sanctum.geek.nz/arabesque/gnu-linux-crypto-email/) if it
+setup (https://blog.sanctum.geek.nz/gnu-linux-crypto-email/) if it
sounds appealing.
.PP
-You'll need Abook installed if you want to use the
-\f[C]query_command\f[] I have defined, and msmtp for the
-\f[C]sendmail\f[] command.
-.SS rxvt\-unicode
-.PP
-I've butchered the URxvt Perl extensions
-\f[C]selection\-to\-clipboard\f[] and \f[C]selection\f[] into a single
-\f[C]select\f[] extension in \f[C]~/.urxvt/ext\f[], which is the only
-extension I define in \f[C]~/.Xresources\f[].
-.PP
-The included \f[C]\&.Xresources\f[] file assumes that \f[C]urxvt\f[] can
-use 256 colors and Perl extensions.
-If you're missing functionality, try changing \f[C]perl\-ext\-common\f[]
-to \f[C]default\f[].
+You\[cq]ll need Abook installed if you want to use the
+\f[V]query_command\f[R] I have defined, and msmtp for the
+\f[V]sendmail\f[R] command.
.SS tmux
.PP
-These are just generally vi\-friendly settings, not much out of the
-ordinary.
-Note that the configuration presently uses a hard\-coded 256\-color
-color scheme, and uses non\-login shells, with an attempt to control the
+These are just generally vi-friendly settings, and there isn\[cq]t much
+out of the ordinary.
+Note that the configuration presently uses a hard-coded 256-color color
+scheme, and uses non-login shells, with an attempt to control the
environment to stop shells thinking they have access to an X display.
.PP
-The shell scripts in \f[C]bin\f[] include \f[C]tm(1df)\f[], a shortcut
-to make \f[C]attach\f[] into the default command if no arguments are
+The shell scripts in \f[V]bin\f[R] include \f[V]tm(1df)\f[R], a shortcut
+to make \f[V]attach\f[R] into the default command if no arguments are
given and sessions do already exist.
-My \f[C]~/.inputrc\f[] file binds Alt+M to run that, and Tmux in turn
-binds the same key combination to detach.
+My \f[V]\[ti]/.inputrc\f[R] file binds Alt+M to run that, and Tmux in
+turn binds the same key combination to detach.
.SS Vim
.PP
The majority of the Vim configuration is just setting options, with a
-fair few mappings and remappings, both global and buffer\-local.
-I try not to deviate too much from the Vim defaults behavior in terms of
-interactive behavior and keybindings.
-It's extensively commented.
+fair few mappings and remappings, both global and buffer-local.
+It\[cq]s extensively commented.
+.SS XDG Basedirs
+.PP
+The XDG Base Directory
+Specification (https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html)\[cq]s
+environment variables are checked on startup, and appropriate
+directories are added to the start and end of
+\f[V]\[aq]runtimepath\[aq]\f[R].
+I use these separate directories for machine-local configuration,
+usually in \f[V]\[ti]/.config/vim\f[R], while all the files that this
+suite installs land in \f[V]\[ti]/.vim\f[R].
+Backups, swap files, persistent undo data, saved views, and the
+\f[V]viminfo\f[R] file all live under \f[V]XDG_CACHE_HOME\f[R], normally
+\f[V]\[ti]/.cache/vim\f[R].
.SS Filetypes
.PP
-I define my own \f[C]filetype.vim\f[] and \f[C]scripts.vim\f[], so that
-filetype detection works in a way I like, and loads quickly.
+I define my own \f[V]filetype.vim\f[R] and \f[V]scripts.vim\f[R], so
+that filetype detection works in a way I like, and loads quickly.
They are unlikely to suit you as they are, but if you want to use it,
you can extend them with your favorite filetypes in custom
-\f[C]ftdetect\f[] rules.
+\f[V]ftdetect\f[R] rules.
.SS Plugins
.PP
If the logic for doing something involves more than a few lines or any
-structures like functions, I like to implement it as a plugin in
-\f[C]~/.vim/plugin\f[] and/or \f[C]~/.vim/autoload\f[], with
-documentation for each in \f[C]~/.vim/doc\f[].
+structures like functions that can be decoupled from \f[V]$MYVIMRC\f[R],
+I like to implement it as a plugin in \f[V]\[ti]/.vim/plugin\f[R] and/or
+\f[V]\[ti]/.vim/autoload\f[R], with documentation for each in
+\f[V]\[ti]/.vim/doc\f[R].
.PP
They eventually get either discarded if I stop using them, or spun off
-into their own repositories if I don't, and added to this repository as
-submodules under \f[C]vim/bundle\f[] instead.
+into their own repositories and added to this repository as submodules
+under \f[V]vim/bundle\f[R] if I don\[cq]t.
Some of them I upload to
vim.org (https://www.vim.org/account/profile.php?user_id=73687).
.SS Filetype plugins
.PP
I apply some replacement or supplementary configuration specific to file
-types I often edit in \f[C]~/.vim\f[] and \f[C]~/.vim/after\f[], in the
-\f[C]ftplugin\f[], \f[C]indent\f[], and \f[C]syntax\f[] subdirectories.
-Some of these filetype plugins or extensions will also eventually be
+types I often edit in \f[V]\[ti]/.vim\f[R] and
+\f[V]\[ti]/.vim/after\f[R], in the \f[V]ftplugin\f[R], \f[V]indent\f[R],
+and \f[V]syntax\f[R] subdirectories.
+Some of these filetype plugins or extensions may also eventually be
removed to be separately distributed, and installed via submodules
instead.
.SS Compilers
.PP
-I define a few of my own \f[C]:compiler\f[] scripts for
-\f[C]~/.vim/compiler\f[] to check and lint appropriate filetypes.
-I bind checking\[en]\[lq]does it run?\[rq]\[en]and linting\[en]\[lq]is
-it good?\[rq]\[en]with separate local leader maps; for example, for
-\f[C]perl\f[] filetypes, \f[C]<LocalLeader>c\f[] switches
-\f[C]makeprg\f[] to \f[C]perl\ \-c\f[] for checking, and
-\f[C]<LocalLeader>l\f[] to \f[C]perlcritic\f[] for linting.
+I define a few of my own \f[V]:compiler\f[R] scripts for
+\f[V]\[ti]/.vim/compiler\f[R] to check and lint appropriate filetypes.
+I bind checking\[em]\[lq]does it run?\[rq]\[em]and linting\[em]\[lq]is
+it good?\[rq]\[em]with separate local leader maps; for example, for
+\f[V]perl\f[R] filetypes, \f[V]<LocalLeader>c\f[R] switches
+\f[V]makeprg\f[R] to \f[V]perl -c\f[R] for checking, and
+\f[V]<LocalLeader>l\f[R] to \f[V]perlcritic\f[R] for linting.
.SS No Neovim support
.PP
-The configuration doesn't explicitly support Neovim, although most of it
-will probably work.
+The configuration doesn\[cq]t explicitly support Neovim, although most
+of it will probably work; you would probably just comment out the
+settings for a few of the removed options.
.SS Scripts
.PP
Where practical, I make short scripts into POSIX (but not Bourne)
-\f[C]sh(1)\f[], \f[C]awk(1)\f[], or \f[C]sed(1)\f[] scripts in
-\f[C]~/.local/bin\f[].
+\f[V]sh(1)\f[R], \f[V]awk(1)\f[R], or \f[V]sed(1)\f[R] scripts in
+\f[V]\[ti]/.local/bin\f[R].
I try to use shell functions only when I actually need to, which tends
-to be when I need to tinker with the namespace of the user's current
-shell.
+to be when I need to change the state of the user\[cq]s current shell,
+or to limit a change in behavior only to interactive shells.
.PP
-Installed by the \f[C]install\-bin\f[] target:
+These scripts are installed by the \f[V]install-bin\f[R] target:
.IP \[bu] 2
-Three SSH\-related scripts:
+Three SSH-related scripts:
.RS 2
.IP \[bu] 2
-\f[C]sls(1df)\f[] prints hostnames read from a \f[C]ssh_config(5)\f[]
-file.
-It uses \f[C]slsf(1df)\f[] to read each one.
+\f[V]sls(1df)\f[R] prints hostnames read from \f[V]ssh_config(5)\f[R]
+files.
+It uses \f[V]slsf(1df)\f[R] to read each one.
.IP \[bu] 2
-\f[C]sra(1df)\f[] runs a command on multiple hosts read from
-\f[C]sls(1df)\f[] and prints output.
+\f[V]sra(1df)\f[R] runs a command on multiple hosts read from
+\f[V]sls(1df)\f[R] and prints output.
.IP \[bu] 2
-\f[C]sta(1df)\f[] runs a command on multiple hosts read from
-\f[C]sls(1df)\f[] and prints the hostname if the command returns zero.
+\f[V]sta(1df)\f[R] runs a command on multiple hosts read from
+\f[V]sls(1df)\f[R] and prints the hostname if the command returns zero.
.RE
.IP \[bu] 2
-Five URL\-related shortcut scripts:
+Five URL-related shortcut scripts:
.RS 2
.IP \[bu] 2
-\f[C]hurl(1df)\f[] extracts values of \f[C]href\f[] attributes of
-\f[C]<a>\f[] tags, sorts them uniquely, and writes them to
-\f[C]stdout\f[]; it requires pup (https://github.com/ericchiang/pup).
+\f[V]hurl(1df)\f[R] extracts values of \f[V]href\f[R] attributes of
+\f[V]<a>\f[R] tags, sorts them uniquely, and writes them to
+\f[V]stdout\f[R]; it requires pup (https://github.com/ericchiang/pup).
.IP \[bu] 2
-\f[C]murl(1df)\f[] converts Markdown documents to HTML with
-\f[C]pandoc(1)\f[] and runs the output through \f[C]hurl(1df)\f[].
+\f[V]murl(1df)\f[R] converts Markdown documents to HTML with
+\f[V]pandoc(1)\f[R] and runs the output through \f[V]hurl(1df)\f[R].
.IP \[bu] 2
-\f[C]urlc(1df)\f[] accepts a list of URLs on \f[C]stdin\f[] and writes
-error messages to \f[C]stderr\f[] if any of the URLs are broken,
+\f[V]urlc(1df)\f[R] accepts a list of URLs on \f[V]stdin\f[R] and writes
+error messages to \f[V]stderr\f[R] if any of the URLs are broken,
redirecting, or are insecure and have working secure versions; requires
-\f[C]curl(1)\f[].
+\f[V]curl(1)\f[R].
.IP \[bu] 2
-\f[C]urlh(1df)\f[] prints the values for a given HTTP header from a HEAD
-response.
+\f[V]urlh(1df)\f[R] prints the values for a given HTTP header from a
+HEAD response.
.IP \[bu] 2
-\f[C]urlmt(1df)\f[] prints the MIME type from the \f[C]Content\-Type\f[]
-header as retrieved by \f[C]urlh(1df)\f[].
+\f[V]urlmt(1df)\f[R] prints the MIME type from the
+\f[V]Content-Type\f[R] header as retrieved by \f[V]urlh(1df)\f[R].
.RE
.IP \[bu] 2
-Three RFC\-related shortcut scripts:
+Three RFC-related shortcut scripts:
.RS 2
.IP \[bu] 2
-\f[C]rfcf(1df)\f[] fetches ASCII RFCs from the IETF website.
+\f[V]rfcf(1df)\f[R] fetches ASCII RFCs from the IETF website.
.IP \[bu] 2
-\f[C]rfct(1df)\f[] formats ASCII RFCs.
+\f[V]rfct(1df)\f[R] formats ASCII RFCs.
.IP \[bu] 2
-\f[C]rfcr(1df)\f[] does both, displaying in a pager if appropriate, like
-a \f[C]man(1)\f[] reader for RFCs.
+\f[V]rfcr(1df)\f[R] does both, displaying in a pager if appropriate,
+like a \f[V]man(1)\f[R] reader for RFCs.
.RE
.IP \[bu] 2
-Five toy random\-number scripts (not for sensitive/dead\-serious use):
+Five toy random-number scripts (not for sensitive/dead-serious use):
.RS 2
.IP \[bu] 2
-\f[C]rndi(1df)\f[] gets a random integer within two bounds.
+\f[V]rndi(1df)\f[R] gets a random integer within two bounds.
.IP \[bu] 2
-\f[C]rnds(1df)\f[] attempts to get an optional random seed for
-\f[C]rndi(1df)\f[].
+\f[V]rnds(1df)\f[R] attempts to get an optional random seed for
+\f[V]rndi(1df)\f[R].
.IP \[bu] 2
-\f[C]rnda(1df)\f[] uses \f[C]rndi(1df)\f[] to choose a random argument.
+\f[V]rnda(1df)\f[R] uses \f[V]rndi(1df)\f[R] to choose a random
+argument.
.IP \[bu] 2
-\f[C]rndf(1df)\f[] uses \f[C]rnda(1df)\f[] to choose a random file from
-a directory.
+\f[V]rndf(1df)\f[R] uses \f[V]rnda(1df)\f[R] to choose a random file
+from a directory.
.IP \[bu] 2
-\f[C]rndl(1df)\f[] uses \f[C]rndi(1df)\f[] to choose a random line from
-files.
+\f[V]rndl(1df)\f[R] uses \f[V]rndi(1df)\f[R] to choose a random line
+from files.
.RE
.IP \[bu] 2
Four file formatting scripts:
.RS 2
.IP \[bu] 2
-\f[C]d2u(1df)\f[] converts DOS line endings in files to UNIX ones.
+\f[V]d2u(1df)\f[R] converts DOS line endings in files to UNIX ones.
.IP \[bu] 2
-\f[C]u2d(1df)\f[] converts UNIX line endings in files to DOS ones.
+\f[V]u2d(1df)\f[R] converts UNIX line endings in files to DOS ones.
.IP \[bu] 2
-\f[C]stbl(1df)\f[] strips a trailing blank line from the files in its
+\f[V]stbl(1df)\f[R] strips a trailing blank line from the files in its
arguments.
.IP \[bu] 2
-\f[C]stws(1df)\f[] strips trailing spaces from the ends of lines of the
+\f[V]stws(1df)\f[R] strips trailing spaces from the ends of lines of the
files in its arguments.
.RE
.IP \[bu] 2
Seven stream formatting scripts:
.RS 2
.IP \[bu] 2
-\f[C]sd2u(1df)\f[] converts DOS line endings in streams to UNIX ones.
+\f[V]sd2u(1df)\f[R] converts DOS line endings in streams to UNIX ones.
.IP \[bu] 2
-\f[C]su2d(1df)\f[] converts UNIX line endings in streams to DOS ones.
+\f[V]su2d(1df)\f[R] converts UNIX line endings in streams to DOS ones.
.IP \[bu] 2
-\f[C]slow(1df)\f[] converts uppercase to lowercase.
+\f[V]slow(1df)\f[R] converts uppercase to lowercase.
.IP \[bu] 2
-\f[C]supp(1df)\f[] converts lowercase to uppercase.
+\f[V]supp(1df)\f[R] converts lowercase to uppercase.
.IP \[bu] 2
-\f[C]tl(1df)\f[] tags input lines with a prefix or suffix, basically a
-\f[C]sed(1)\f[] shortcut.
+\f[V]tl(1df)\f[R] tags input lines with a prefix or suffix, basically a
+\f[V]sed(1)\f[R] shortcut.
.IP \[bu] 2
-\f[C]tlcs(1df)\f[] executes a command and uses \f[C]tl(1df)\f[] to tag
+\f[V]tlcs(1df)\f[R] executes a command and uses \f[V]tl(1df)\f[R] to tag
standard output and standard error lines, and color them if you want.
.IP \[bu] 2
-\f[C]unf(1df)\f[] joins lines with leading spaces to the previous line.
+\f[V]unf(1df)\f[R] joins lines with leading spaces to the previous line.
Intended for unfolding HTTP headers, but it should work for most RFC 822
formats.
.RE
@@ -645,382 +667,379 @@ formats.
Six simple aggregate scripts for numbers:
.RS 2
.IP \[bu] 2
-\f[C]max(1df)\f[] prints the maximum.
+\f[V]max(1df)\f[R] prints the maximum.
.IP \[bu] 2
-\f[C]mean(1df)\f[] prints the mean.
+\f[V]mean(1df)\f[R] prints the mean.
.IP \[bu] 2
-\f[C]med(1df)\f[] prints the median.
+\f[V]med(1df)\f[R] prints the median.
.IP \[bu] 2
-\f[C]min(1df)\f[] prints the minimum.
+\f[V]min(1df)\f[R] prints the minimum.
.IP \[bu] 2
-\f[C]mode(1df)\f[] prints the first encountered mode.
+\f[V]mode(1df)\f[R] prints the first encountered mode.
.IP \[bu] 2
-\f[C]tot(1df)\f[] totals the set.
+\f[V]tot(1df)\f[R] totals the set.
.RE
.IP \[bu] 2
-Three quick\-and\-dirty HTML tools:
+Three quick-and-dirty HTML tools:
.RS 2
.IP \[bu] 2
-\f[C]htenc(1df)\f[] encodes.
+\f[V]htenc(1df)\f[R] encodes.
.IP \[bu] 2
-\f[C]htdec(1df)\f[] decodes.
+\f[V]htdec(1df)\f[R] decodes.
.IP \[bu] 2
-\f[C]htrec(1df)\f[] wraps \f[C]a\f[] tags around URLs.
+\f[V]htrec(1df)\f[R] wraps \f[V]a\f[R] tags around URLs.
.RE
.IP \[bu] 2
Two internet message quoting tools:
.RS 2
.IP \[bu] 2
-\f[C]quo(1df)\f[] indents with quoting right angle\-brackets.
+\f[V]quo(1df)\f[R] indents with quoting right angle-brackets.
.IP \[bu] 2
-\f[C]wro(1df)\f[] adds a quote attribution header to its input.
+\f[V]wro(1df)\f[R] adds a quote attribution header to its input.
.RE
.IP \[bu] 2
-Six Git\-related tools:
+Six Git-related tools:
.RS 2
.IP \[bu] 2
-\f[C]fgscr(1df)\f[] finds Git repositories in a directory root and
-scrubs them with \f[C]gscr(1df)\f[].
+\f[V]fgscr(1df)\f[R] finds Git repositories in a directory root and
+scrubs them with \f[V]gscr(1df)\f[R].
.IP \[bu] 2
-\f[C]grc(1df)\f[] quietly tests whether the given directory appears to
+\f[V]grc(1df)\f[R] quietly tests whether the given directory appears to
be a Git repository with pending changes.
.IP \[bu] 2
-\f[C]gscr(1df)\f[] scrubs Git repositories.
+\f[V]gscr(1df)\f[R] scrubs Git repositories.
.IP \[bu] 2
-\f[C]isgr(1df)\f[] quietly tests whether the given directory appears to
+\f[V]isgr(1df)\f[R] quietly tests whether the given directory appears to
be a Git repository.
.IP \[bu] 2
-\f[C]jfc(1df)\f[] adds and commits lazily to a Git repository.
+\f[V]jfc(1df)\f[R] adds and commits lazily to a Git repository.
.IP \[bu] 2
-\f[C]jfcd(1df)\f[] watches a directory for changes and runs
-\f[C]jfc(1df)\f[] if it sees any.
+\f[V]jfcd(1df)\f[R] watches a directory for changes and runs
+\f[V]jfc(1df)\f[R] if it sees any.
.RE
.IP \[bu] 2
Two time duration functions:
.RS 2
.IP \[bu] 2
-\f[C]hms(1df)\f[] converts seconds to \f[C]hh:mm:ss\f[] or
-\f[C]mm:ss\f[] timestamps.
+\f[V]hms(1df)\f[R] converts seconds to \f[V]hh:mm:ss\f[R] or
+\f[V]mm:ss\f[R] timestamps.
.IP \[bu] 2
-\f[C]sec(1df)\f[] converts \f[C]hh:mm:ss\f[] or \f[C]mm:ss\f[]
+\f[V]sec(1df)\f[R] converts \f[V]hh:mm:ss\f[R] or \f[V]mm:ss\f[R]
timestamps to seconds.
.RE
.IP \[bu] 2
Three pipe interaction tools:
.RS 2
.IP \[bu] 2
-\f[C]pst(1df)\f[] runs an interactive program on data before passing it
+\f[V]pst(1df)\f[R] runs an interactive program on data before passing it
along a pipeline.
.IP \[bu] 2
-\f[C]ped(1df)\f[] runs \f[C]pst(1df)\f[] with \f[C]$EDITOR\f[] or
-\f[C]ed(1)\f[].
+\f[V]ped(1df)\f[R] runs \f[V]pst(1df)\f[R] with \f[V]$EDITOR\f[R] or
+\f[V]ed(1)\f[R].
.IP \[bu] 2
-\f[C]pvi(1df)\f[] runs \f[C]pvi(1df)\f[] with \f[C]$VISUAL\f[] or
-\f[C]vi(1)\f[].
+\f[V]pvi(1df)\f[R] runs \f[V]pvi(1df)\f[R] with \f[V]$VISUAL\f[R] or
+\f[V]vi(1)\f[R].
.RE
.IP \[bu] 2
Two editor wrapper tools:
.RS 2
.IP \[bu] 2
-\f[C]mked(1df)\f[] creates paths to all its arguments before invoking
-\f[C]$EDITOR\f[].
+\f[V]mked(1df)\f[R] creates paths to all its arguments before invoking
+\f[V]$EDITOR\f[R].
.IP \[bu] 2
-\f[C]mkvi(1df)\f[] creates paths to all its arguments before invoking
-\f[C]$VISUAL\f[].
+\f[V]mkvi(1df)\f[R] creates paths to all its arguments before invoking
+\f[V]$VISUAL\f[R].
.RE
.IP \[bu] 2
-\f[C]ap(1df)\f[] reads arguments for a given command from the standard
+\f[V]ap(1df)\f[R] reads arguments for a given command from the standard
input, prompting if appropriate.
.IP \[bu] 2
-\f[C]apf(1df)\f[] inserts arguments to a command with ones read from a
+\f[V]apf(1df)\f[R] inserts arguments to a command with ones read from a
file, intended as a framework for shell wrappers or functions.
.IP \[bu] 2
-\f[C]ax(1df)\f[] evaluates an AWK expression given on the command line;
+\f[V]ax(1df)\f[R] evaluates an AWK expression given on the command line;
this is intended as a quick way to test how AWK would interpret a given
expression.
.IP \[bu] 2
-\f[C]bcq(1df)\f[] runs \f[C]bc(1)\f[], quieting it down if need be.
+\f[V]bcq(1df)\f[R] runs \f[V]bc(1)\f[R], quieting it down if need be.
.IP \[bu] 2
-\f[C]bel(1df)\f[] prints a terminal bell character.
+\f[V]bel(1df)\f[R] prints a terminal bell character.
.IP \[bu] 2
-\f[C]bl(1df)\f[] generates a given number of blank lines.
+\f[V]bl(1df)\f[R] generates a given number of blank lines.
.IP \[bu] 2
-\f[C]bp(1df)\f[] runs \f[C]br(1df)\f[] after prompting for an URL.
+\f[V]bp(1df)\f[R] runs \f[V]br(1df)\f[R] after prompting for an URL.
.IP \[bu] 2
-\f[C]br(1df)\f[] launches \f[C]$BROWSER\f[].
+\f[V]br(1df)\f[R] launches \f[V]$BROWSER\f[R].
.IP \[bu] 2
-\f[C]ca(1df)\f[] prints a count of its given arguments.
+\f[V]ca(1df)\f[R] prints a count of its given arguments.
.IP \[bu] 2
-\f[C]cf(1df)\f[] prints a count of entries in a given directory.
+\f[V]cf(1df)\f[R] prints a count of entries in a given directory.
.IP \[bu] 2
-\f[C]cfr(1df)\f[] does the same as \f[C]cf(1df)\f[], but recurses into
+\f[V]cfr(1df)\f[R] does the same as \f[V]cf(1df)\f[R], but recurses into
subdirectories as well.
.IP \[bu] 2
-\f[C]chc(1df)\f[] caches the output of a command.
+\f[V]chc(1df)\f[R] caches the output of a command.
.IP \[bu] 2
-\f[C]chn(1df)\f[] runs a filter over its input a given number of times.
+\f[V]chn(1df)\f[R] runs a filter over its input a given number of times.
.IP \[bu] 2
-\f[C]clog(1df)\f[] is a tiny timestamped log system.
+\f[V]clog(1df)\f[R] is a tiny timestamped log system.
.IP \[bu] 2
-\f[C]clrd(1df)\f[] sets up a per\-line file read, clearing the screen
+\f[V]clrd(1df)\f[R] sets up a per-line file read, clearing the screen
first.
.IP \[bu] 2
-\f[C]clwr(1df)\f[] sets up a per\-line file write, clearing the screen
+\f[V]clwr(1df)\f[R] sets up a per-line file write, clearing the screen
before each line.
.IP \[bu] 2
-\f[C]csmw(1df)\f[] prints an English list of monospace\-quoted words
+\f[V]csmw(1df)\f[R] prints an English list of monospace-quoted words
read from the input.
.IP \[bu] 2
-\f[C]dam(1df)\f[] buffers all its input before emitting it as output.
+\f[V]dam(1df)\f[R] buffers all its input before emitting it as output.
.IP \[bu] 2
-\f[C]ddup(1df)\f[] removes duplicate lines from unsorted input.
+\f[V]ddup(1df)\f[R] removes duplicate lines from unsorted input.
.IP \[bu] 2
-\f[C]defang(1df)\f[] prevents dangerous URLs from being made into
+\f[V]defang(1df)\f[R] prevents dangerous URLs from being made into
clickable links.
.IP \[bu] 2
-\f[C]dmp(1df)\f[] copies a pass(1) entry selected by \f[C]dmenu(1)\f[]
-to the X CLIPBOARD.
+\f[V]dub(1df)\f[R] lists the biggest entries in a directory.
.IP \[bu] 2
-\f[C]dub(1df)\f[] lists the biggest entries in a directory.
+\f[V]edda(1df)\f[R] provides a means to run \f[V]ed(1)\f[R] over a set
+of files preserving any options, mostly useful for scripts.
.IP \[bu] 2
-\f[C]edda(1df)\f[] provides a means to run \f[C]ed(1)\f[] over a set of
-files preserving any options, mostly useful for scripts.
+\f[V]eds(1df)\f[R] edits executable script files in \f[V]EDSPATH\f[R],
+defaulting to \f[V]\[ti]/.local/bin\f[R], for personal scripting
+snippets.
.IP \[bu] 2
-\f[C]eds(1df)\f[] edits executable script files in \f[C]EDSPATH\f[],
-defaulting to \f[C]~/.local/bin\f[], for personal scripting snippets.
+\f[V]exm(1df)\f[R] works around a screen-clearing quirk of Vim\[cq]s
+\f[V]ex\f[R] mode.
.IP \[bu] 2
-\f[C]exm(1df)\f[] works around a screen\-clearing quirk of Vim's
-\f[C]ex\f[] mode.
+\f[V]finc(1df)\f[R] counts the number of results returned from a set of
+given \f[V]find(1)\f[R] conditions.
.IP \[bu] 2
-\f[C]finc(1df)\f[] counts the number of results returned from a set of
-given \f[C]find(1)\f[] conditions.
-.IP \[bu] 2
-\f[C]fnl(1df)\f[] runs a command and saves its output and error into
+\f[V]fnl(1df)\f[R] runs a command and saves its output and error into
temporary files, printing their paths and line counts.
.IP \[bu] 2
-\f[C]fnp(1df)\f[] prints the given files to standard output, each with a
-plain text heading with the filename in it.
+\f[V]fnp(1df)\f[R] prints the given files to standard output, each with
+a plain text heading with the filename in it.
.IP \[bu] 2
-\f[C]gms(1df)\f[] runs a set of \f[C]getmailrc\f[] files; does much the
-same thing as the script \f[C]getmails\f[] in the \f[C]getmail\f[]
+\f[V]gms(1df)\f[R] runs a set of \f[V]getmailrc\f[R] files; does much
+the same thing as the script \f[V]getmails\f[R] in the \f[V]getmail\f[R]
suite, but runs the requests in parallel and does up to three silent
-retries using \f[C]try(1df)\f[].
+retries using \f[V]try(1df)\f[R].
.IP \[bu] 2
-\f[C]grec(1df)\f[] is a more logically\-named \f[C]grep\ \-c\f[].
+\f[V]grec(1df)\f[R] is a more logically-named \f[V]grep -c\f[R].
.IP \[bu] 2
-\f[C]gred(1df)\f[] is a more logically\-named \f[C]grep\ \-v\f[].
+\f[V]gred(1df)\f[R] is a more logically-named \f[V]grep -v\f[R].
.IP \[bu] 2
-\f[C]gwp(1df)\f[] searches for alphanumeric words in a similar way to
-\f[C]grep(1)\f[].
+\f[V]gwp(1df)\f[R] searches for alphanumeric words in a similar way to
+\f[V]grep(1)\f[R].
.IP \[bu] 2
-\f[C]han(1df)\f[] provides a \f[C]keywordprg\f[] for Vim's Bash script
-file type that will look for \f[C]help\f[] topics.
+\f[V]han(1df)\f[R] provides a \f[V]keywordprg\f[R] for Vim\[cq]s Bash
+script file type that will look for \f[V]help\f[R] topics.
You could use it from the shell too.
.IP \[bu] 2
-\f[C]igex(1df)\f[] wraps around a command to allow you to ignore error
-conditions that don't actually worry you, exiting with 0 anyway.
+\f[V]igex(1df)\f[R] wraps around a command to allow you to ignore error
+conditions that don\[cq]t actually worry you, exiting with 0 anyway.
.IP \[bu] 2
-\f[C]ix(1df)\f[] posts its input to the \f[C]ix.io\f[] pastebin.
+\f[V]ix(1df)\f[R] posts its input to the \f[V]ix.io\f[R] pastebin.
.IP \[bu] 2
-\f[C]jfp(1df)\f[] prints its input, excluding any shebang on the first
+\f[V]jfp(1df)\f[R] prints its input, excluding any shebang on the first
line only.
.IP \[bu] 2
-\f[C]loc(1df)\f[] is a quick\-search wrapped around \f[C]find(1)\f[].
+\f[V]loc(1df)\f[R] is a quick-search wrapped around \f[V]find(1)\f[R].
.IP \[bu] 2
-\f[C]maybe(1df)\f[] is like \f[C]true(1)\f[] or \f[C]false(1)\f[]; given
-a probability of success, it exits with success or failure.
+\f[V]maybe(1df)\f[R] is like \f[V]true(1)\f[R] or \f[V]false(1)\f[R];
+given a probability of success, it exits with success or failure.
Good for quick tests.
.IP \[bu] 2
-\f[C]mex(1df)\f[] makes given filenames in \f[C]$PATH\f[] executable.
+\f[V]mex(1df)\f[R] makes given filenames in \f[V]$PATH\f[R] executable.
.IP \[bu] 2
-\f[C]mi5(1df)\f[] is a crude preprocessor for \f[C]m4\f[].
+\f[V]mi5(1df)\f[R] is a crude preprocessor for \f[V]m4\f[R].
.IP \[bu] 2
-\f[C]mim(1df)\f[] starts an interactive Mutt message with its input.
+\f[V]mim(1df)\f[R] starts an interactive Mutt message with its input.
.IP \[bu] 2
-\f[C]mftl(1df)\f[] finds usable\-looking targets in Makefiles.
+\f[V]mftl(1df)\f[R] finds usable-looking targets in Makefiles.
.IP \[bu] 2
-\f[C]mkcp(1df)\f[] creates a directory and copies preceding arguments
+\f[V]mkcp(1df)\f[R] creates a directory and copies preceding arguments
into it.
.IP \[bu] 2
-\f[C]mkmv(1df)\f[] creates a directory and moves preceding arguments
+\f[V]mkmv(1df)\f[R] creates a directory and moves preceding arguments
into it.
.IP \[bu] 2
-\f[C]motd(1df)\f[] shows the system MOTD.
+\f[V]motd(1df)\f[R] shows the system MOTD.
+.IP \[bu] 2
+\f[V]msc(1df)\f[R] crudely counts messages in an mbox.
.IP \[bu] 2
-\f[C]mw(1df)\f[] prints alphabetic space\-delimited words from the input
+\f[V]mw(1df)\f[R] prints alphabetic space-delimited words from the input
one per line.
.IP \[bu] 2
-\f[C]oii(1df)\f[] runs a command on input only if there is any.
+\f[V]oii(1df)\f[R] runs a command on input only if there is any.
.IP \[bu] 2
-\f[C]onl(1df)\f[] crunches input down to one printable line.
+\f[V]onl(1df)\f[R] crunches input down to one printable line.
.IP \[bu] 2
-\f[C]osc(1df)\f[] implements a \f[C]netcat(1)\f[]\-like wrapper for
-\f[C]openssl(1)\f[]'s \f[C]s_client\f[] sub\-command.
+\f[V]osc(1df)\f[R] implements a \f[V]netcat(1)\f[R]-like wrapper for
+\f[V]openssl(1)\f[R]\[cq]s \f[V]s_client\f[R] sub-command.
.IP \[bu] 2
-\f[C]p(1df)\f[] prints concatenated standard input; \f[C]cat(1)\f[] as
+\f[V]p(1df)\f[R] prints concatenated standard input; \f[V]cat(1)\f[R] as
it should always have been.
.IP \[bu] 2
-\f[C]pa(1df)\f[] prints its arguments, one per line.
+\f[V]pa(1df)\f[R] prints its arguments, one per line.
.IP \[bu] 2
-\f[C]phpcsff(1df)\f[] wraps around
-PHP\-CS\-Fixer (https://github.com/FriendsOfPHP/PHP-CS-Fixer) to make it
-a source code filter suitable for use as an \f[C]equalprg\f[] in Vim.
+\f[V]phpcsff(1df)\f[R] wraps around
+PHP-CS-Fixer (https://github.com/FriendsOfPHP/PHP-CS-Fixer) to make it a
+source code filter suitable for use as an \f[V]equalprg\f[R] in Vim.
.IP \[bu] 2
-\f[C]pp(1df)\f[] prints the full path of each argument using
-\f[C]$PWD\f[].
+\f[V]pp(1df)\f[R] prints the full path of each argument using
+\f[V]$PWD\f[R].
.IP \[bu] 2
-\f[C]pph(1df)\f[] runs \f[C]pp(1df)\f[] and includes a leading
-\f[C]$HOSTNAME:\f[].
+\f[V]pph(1df)\f[R] runs \f[V]pp(1df)\f[R] and includes a leading
+\f[V]$HOSTNAME:\f[R].
.IP \[bu] 2
-\f[C]paz(1df)\f[] print its arguments terminated by NULL chars.
+\f[V]paz(1df)\f[R] print its arguments terminated by NULL chars.
.IP \[bu] 2
-\f[C]pit(1df)\f[] runs its input through a pager if its standard output
+\f[V]pit(1df)\f[R] runs its input through a pager if its standard output
looks like a terminal.
.IP \[bu] 2
-\f[C]plmu(1df)\f[] retrieves a list of installed modules from
-\f[C]plenv\f[] (https://github.com/tokuhirom/plenv), filters out any
-modules in \f[C]~/.plenv/non\-cpan\-modules\f[], and updates them all.
+\f[V]pwg(1df)\f[R] generates just one decent password with
+\f[V]pwgen(1)\f[R].
.IP \[bu] 2
-\f[C]pwg(1df)\f[] generates just one decent password with
-\f[C]pwgen(1)\f[].
+\f[V]qat(1df)\f[R] disables \f[V]stty echo\f[R] for the duration of a
+paste.
.IP \[bu] 2
-\f[C]rep(1df)\f[] repeats a command a given number of times.
+\f[V]rep(1df)\f[R] repeats a command a given number of times.
.IP \[bu] 2
-\f[C]rgl(1df)\f[] is a very crude interactive \f[C]grep(1)\f[] loop.
+\f[V]rgl(1df)\f[R] is a very crude interactive \f[V]grep(1)\f[R] loop.
.IP \[bu] 2
-\f[C]shb(1df)\f[] attempts to build shebang lines for scripts from the
+\f[V]shb(1df)\f[R] attempts to build shebang lines for scripts from the
system paths.
.IP \[bu] 2
-\f[C]sqs(1df)\f[] chops off query strings from filenames, usually
+\f[V]sqs(1df)\f[R] chops off query strings from filenames, usually
downloads.
.IP \[bu] 2
-\f[C]sshi(1df)\f[] prints human\-readable SSH connection details.
+\f[V]sshi(1df)\f[R] prints human-readable SSH connection details.
.IP \[bu] 2
-\f[C]stex(1df)\f[] strips extensions from filenames.
+\f[V]stex(1df)\f[R] strips extensions from filenames.
.IP \[bu] 2
-\f[C]sue(8df)\f[] execs \f[C]sudoedit(8)\f[] as the owner of all the
+\f[V]sue(8df)\f[R] execs \f[V]sudoedit(8)\f[R] as the owner of all the
file arguments given, perhaps in cases where you may not necessarily
-have \f[C]root\f[] \f[C]sudo(8)\f[] privileges.
+have \f[V]root\f[R] \f[V]sudo(8)\f[R] privileges.
.IP \[bu] 2
-\f[C]swr(1df)\f[] allows you to run commands locally specifying remote
-files in \f[C]scp(1)\f[]'s HOST:PATH format.
+\f[V]swr(1df)\f[R] allows you to run commands locally specifying remote
+files in \f[V]scp(1)\f[R]\[cq]s HOST:PATH format.
.IP \[bu] 2
-\f[C]td(1df)\f[] manages a to\-do file for you with \f[C]$EDITOR\f[] and
-\f[C]git(1)\f[]; I used to use Taskwarrior, but found it too complex and
-buggy.
+\f[V]td(1df)\f[R] manages a to-do file for you with \f[V]$EDITOR\f[R]
+and \f[V]git(1)\f[R]; I used to use Taskwarrior, but found it too
+complex and buggy.
.IP \[bu] 2
-\f[C]tm(1df)\f[] runs \f[C]tmux(1)\f[] with
-\f[C]attach\-session\ \-d\f[] if a session exists, and
-\f[C]new\-session\f[] if it doesn't.
+\f[V]tm(1df)\f[R] runs \f[V]tmux(1)\f[R] with
+\f[V]attach-session -d\f[R] if a session exists, and
+\f[V]new-session\f[R] if it doesn\[cq]t.
.IP \[bu] 2
-\f[C]trs(1df)\f[] replaces strings (not regular expression) in its
+\f[V]trs(1df)\f[R] replaces strings (not regular expression) in its
input.
.IP \[bu] 2
-\f[C]try(1df)\f[] repeats a command up to a given number of times until
+\f[V]try(1df)\f[R] repeats a command up to a given number of times until
it succeeds, only printing error output if all three attempts failed.
-Good for tolerating blips or temporary failures in \f[C]cron(8)\f[]
+Good for tolerating blips or temporary failures in \f[V]cron(8)\f[R]
scripts.
.IP \[bu] 2
-\f[C]umake(1df)\f[] iterates upwards through the directory tree from
-\f[C]$PWD\f[] until it finds a Makefile for which to run
-\f[C]make(1)\f[] with the given arguments.
+\f[V]umake(1df)\f[R] iterates upwards through the directory tree from
+\f[V]$PWD\f[R] until it finds a Makefile for which to run
+\f[V]make(1)\f[R] with the given arguments.
.IP \[bu] 2
-\f[C]uts(1df)\f[] gets the current UNIX timestamp in an unorthodox way
-that should work on all POSIX\-compliant operating systems.
+\f[V]uts(1df)\f[R] gets the current UNIX timestamp in an unorthodox way
+that should work on all POSIX-compliant operating systems.
.IP \[bu] 2
-\f[C]vest(1df)\f[] runs \f[C]test(1)\f[] but fails with explicit output
-via \f[C]vex(1df)\f[].
+\f[V]vest(1df)\f[R] runs \f[V]test(1)\f[R] but fails with explicit
+output via \f[V]vex(1df)\f[R].
.IP \[bu] 2
-\f[C]vex(1df)\f[] runs a command and prints \f[C]true\f[] or
-\f[C]false\f[] explicitly to \f[C]stdout\f[] based on the exit value.
+\f[V]vex(1df)\f[R] runs a command and prints \f[V]true\f[R] or
+\f[V]false\f[R] explicitly to \f[V]stdout\f[R] based on the exit value.
.IP \[bu] 2
-\f[C]vic(1df)\f[] tries to run a POSIX\-compliant \f[C]vi(1)\f[].
+\f[V]vic(1df)\f[R] tries to run a POSIX-compliant \f[V]vi(1)\f[R].
.IP \[bu] 2
-\f[C]xrbg(1df)\f[] applies the same randomly\-selected background to
+\f[V]xrbg(1df)\f[R] applies the same randomly-selected background to
each X screen.
.IP \[bu] 2
-\f[C]xrq(1df)\f[] gets the values of specific resources out of
-\f[C]xrdb\ \-query\f[] output.
+\f[V]xrq(1df)\f[R] gets the values of specific resources out of
+\f[V]xrdb -query\f[R] output.
.PP
-There's some silly stuff in \f[C]install\-games\f[]:
+There\[cq]s some silly stuff in \f[V]install-games\f[R]:
.IP \[bu] 2
-\f[C]aaf(6df)\f[] gets a random ASCII Art
+\f[V]aaf(6df)\f[R] gets a random ASCII Art
Farts (http://www.asciiartfarts.com/) comic.
.IP \[bu] 2
-\f[C]acq(6df)\f[] allows you to interrogate AC, the interplanetary
+\f[V]acq(6df)\f[R] allows you to interrogate AC, the interplanetary
computer.
.IP \[bu] 2
-\f[C]aesth(6df)\f[] converts English letters to their full width CJK
-analogues, for aesthetic purposes.
+\f[V]aesth(6df)\f[R] converts English letters to their full width CJK
+analogues, for
+\[uFF41]\[uFF45]\[uFF53]\[uFF54]\[uFF48]\[uFF45]\[uFF54]\[uFF49]\[uFF43]
+purposes.
.IP \[bu] 2
-\f[C]squ(6df)\f[] makes a reduced Latin square out of each line of
+\f[V]squ(6df)\f[R] makes a reduced Latin square out of each line of
input.
.IP \[bu] 2
-\f[C]kvlt(6df)\f[] translates input to emulate a style of typing unique
+\f[V]kvlt(6df)\f[R] translates input to emulate a style of typing unique
to black metal communities on the internet.
.IP \[bu] 2
-\f[C]philsay(6df)\f[] shows a picture to accompany \f[C]pks(6df)\f[]
+\f[V]philsay(6df)\f[R] shows a picture to accompany \f[V]pks(6df)\f[R]
output.
.IP \[bu] 2
-\f[C]pks(6df)\f[] laughs at a randomly selected word.
+\f[V]pks(6df)\f[R] laughs at a randomly selected word.
.IP \[bu] 2
-\f[C]rndn(6df)\f[] implements an esoteric random number generation
+\f[V]rndn(6df)\f[R] implements an esoteric random number generation
algorithm.
.IP \[bu] 2
-\f[C]strik(6df)\f[] outputs s̶t̶r̶i̶k̶e̶d̶ ̶o̶u̶t̶ struck out text.
+\f[V]strik(6df)\f[R] outputs
+s\[u0336]t\[u0336]r\[u0336]i\[u0336]k\[u0336]e\[u0336]d\[u0336]
+\[u0336]o\[u0336]u\[u0336]t\[u0336] struck out text.
.IP \[bu] 2
-\f[C]rot13(6df)\f[] rotates the Latin letters in its input.
+\f[V]rot13(6df)\f[R] rotates the Latin letters in its input.
.IP \[bu] 2
-\f[C]uuu(6df)\f[] uuuuu uuuu uu uuuuuu uuuuuuu u uuu uuuuu.
+\f[V]uuu(6df)\f[R] uuuuu uuuu uu uuuuuu uuuuuuu u uuu uuuuu.
.IP \[bu] 2
-\f[C]xyzzy(6df)\f[] teleports to a marked location on the filesystem.
+\f[V]xyzzy(6df)\f[R] teleports to a marked location on the filesystem.
.IP \[bu] 2
-\f[C]zs(6df)\f[] prefixes \[lq]z\[rq] case\-appropriately to every
+\f[V]zs(6df)\f[R] prefixes \[lq]z\[rq] case-appropriately to every
occurrence of \[lq]s\[rq] in the text on its standard input.
.SS Manuals
.PP
-The \f[C]install\-bin\f[] and \f[C]install\-games\f[] targets install
-manuals for each script they install.
-If you want to use the manuals, you may need to add
-\f[C]~/.local/share/man\f[] to your \f[C]~/.manpath\f[] or
-\f[C]/etc/manpath\f[] configuration, depending on your system.
+The \f[V]install-bin\f[R] and \f[V]install-games\f[R] targets install
+manuals for each script.
+If you want to read the manuals, you may need to add
+\f[V]\[ti]/.local/share/man\f[R] to your \f[V]\[ti]/.manpath\f[R] or
+\f[V]/etc/manpath\f[R] configuration, depending on your system.
.SS Testing
.PP
You can check that both sets of shell scripts are syntactically correct
-with \f[C]make\ check\-bash\f[], \f[C]make\ check\-sh\f[], or
-\f[C]make\ check\f[] for everything including the scripts in
-\f[C]bin\f[] and \f[C]games\f[].
-There's no proper test suite for the actual functionality (yet).
+with \f[V]make check-bash\f[R] or \f[V]make check-sh\f[R], or
+\f[V]make check\f[R] for everything including the scripts in
+\f[V]bin\f[R] and \f[V]games\f[R].
+There\[cq]s no proper test suite for the actual functionality (yet).
.PP
-There are also optional \f[C]lint\f[] targets, if you have the
+There are also optional \f[V]lint\f[R] targets, if you have the
appropriate tools available to run them:
.IP \[bu] 2
ShellCheck (https://www.shellcheck.net/):
.RS 2
.IP \[bu] 2
-\f[C]lint\-bash\f[]
-.IP \[bu] 2
-\f[C]lint\-bin\f[]
+\f[V]lint-bash\f[R]
.IP \[bu] 2
-\f[C]lint\-games\f[]
+\f[V]lint-bin\f[R]
.IP \[bu] 2
-\f[C]lint\-ksh\f[]
+\f[V]lint-games\f[R]
.IP \[bu] 2
-\f[C]lint\-sh\f[]
+\f[V]lint-ksh\f[R]
.IP \[bu] 2
-\f[C]lint\-xinit\f[]
-.RE
-.IP \[bu] 2
-Perl::Critic:
-.RS 2
+\f[V]lint-sh\f[R]
.IP \[bu] 2
-\f[C]lint\-urxvt\f[]
+\f[V]lint-x\f[R]
.RE
.IP \[bu] 2
Vint (https://github.com/Kuniwak/vint):
.RS 2
.IP \[bu] 2
-\f[C]lint\-vim\f[]
+\f[V]lint-vim\f[R]
.RE
.SS Future development
.PP
@@ -1030,11 +1049,12 @@ See IDEAS.md.
See ISSUES.md.
.SS License
.PP
-Public domain; see the included \f[C]UNLICENSE\f[] file.
-It's just configuration and simple scripts, so do whatever you like with
-it if any of it's useful to you.
-If you're feeling generous, please join and/or donate to a free software
-advocacy group, and let me know you did it because of this project:
+Public domain; see the included \f[V]UNLICENSE\f[R] file.
+It\[cq]s just configuration and simple scripts, so do whatever you like
+with it if any of it\[cq]s useful to you.
+If you\[cq]re feeling generous, please join and/or donate to a free
+software advocacy group, and let me know you did it because of this
+project:
.IP \[bu] 2
Free Software Foundation (https://www.fsf.org/)
.IP \[bu] 2
diff --git a/mpd/mpdconf b/mpd/mpdconf
deleted file mode 100644
index e8bad4cc..00000000
--- a/mpd/mpdconf
+++ /dev/null
@@ -1,15 +0,0 @@
-bind_to_address "~/.mpd/socket"
-
-db_file "~/.mpd/database"
-log_file "~/.mpd/log"
-
-music_directory "/mnt/media/shares/music"
-playlist_directory "~/.mpd/playlists"
-pid_file "~/.mpd/pid"
-state_file "~/.mpd/state"
-sticker_file "~/.mpd/sticker.sql"
-
-audio_output {
- type "pulse"
- name "PulseAudio"
-}
diff --git a/mpd/profile.d/mpd.sh b/mpd/profile.d/mpd.sh
deleted file mode 100644
index 5a14aef2..00000000
--- a/mpd/profile.d/mpd.sh
+++ /dev/null
@@ -1,3 +0,0 @@
-# Start an mpd process if one isn't already running
-command -v mpd >/dev/null 2>&1 || return
-[ -s "$HOME"/.mpd/pid ] || mpd
diff --git a/mpv/mpv.conf b/mpv/mpv.conf
index 5a2a05c4..553d73b7 100644
--- a/mpv/mpv.conf
+++ b/mpv/mpv.conf
@@ -1,2 +1,34 @@
# Don't try to show me album covers when I play FLAC
no-audio-display
+
+# Use yt-dlp instead of youtube-dl, as the latter project appears to have been
+# abandonded for some time as at 2022-05-08.
+#
+# * <https://github.com/ytdl-org/youtube-dl/issues/29965>
+# * <https://web.archive.org/web/20220212025407/https://github.com/ytdl-org/youtube-dl/issues/29965>
+#
+script-opts-append="ytdl_hook-ytdl_path=yt-dlp"
+
+# Save screenshot images into XDG-respecting location
+screenshot-directory="~/.local/share/mpv/screenshots"
+
+# Use PNG (lossless) for screenshots rather than the default JPEG
+screenshot-format="png"
+
+# Keep the screenshots in directories named after the media file, with the
+# screenshot filename including the media filename, the timestamp within it,
+# and a numeric suffix to guarantee uniqueness. Full paths look like this:
+#
+# ~/.local/share/mpv/screenshots/Red Dwarf S01E01.mkv/mpv_Red Dwarf S01E01.mkv_00:08:20.461_0001.png
+#
+screenshot-template="%f/mpv_%f_%P_%04n"
+
+# Don't try to find external subtitles for me; I'll specify if I want them.
+sub-auto=no
+
+# Get somewhat lower-resolution (<=640kps), lower-bitrate (<=500kbps) videos,
+# so that they come down quicker and slower systems are less likely to stutter
+# while playing them at busy times; if I want archival quality, I'll just
+# invoke yt-dlp directly.
+#
+ytdl-format="[height<=?640][tbr<=?500]"
diff --git a/mutt/filters/markdown-to-html.sh b/mutt/filters/markdown-to-html.sh
new file mode 100644
index 00000000..5fe28560
--- /dev/null
+++ b/mutt/filters/markdown-to-html.sh
@@ -0,0 +1,8 @@
+printf 'text/html\n\n'
+sed 's/ $/ /;/[^ ]$/s/$/ /;s/^-- $/-- /' |
+pandoc \
+ --from markdown_strict+smart \
+ --metadata=pagetitle:HTML \
+ --standalone \
+ --to html4 |
+sed '/[—–][—–]/{s/—/---/g;s/–/--/g}'
diff --git a/mutt/mailcap b/mutt/mailcap
new file mode 100644
index 00000000..b8fd5b03
--- /dev/null
+++ b/mutt/mailcap
@@ -0,0 +1,11 @@
+# Simple mailcap for a terminal-only Mutt; I generally download everything
+# anyway and deal with it on a shell, or pass it to a GUI machine.
+#
+text/html; lynx -dump -nomargins -force_html -width 1024 %s; \
+ copiousoutput; \
+ description=HTML; \
+ nametemplate=%s.html
+application/pdf; pdftotext -layout -nopgbrk -q %s -; \
+ copiousoutput; \
+ description=PDF; \
+ nametemplate=%s.pdf
diff --git a/mutt/muttrc b/mutt/muttrc
index b61b4af6..aba87363 100644
--- a/mutt/muttrc
+++ b/mutt/muttrc
@@ -1,141 +1,329 @@
-# Addresses
-set query_command = 'abook --mutt-query %s'
-set reverse_name = yes
-set use_domain = yes
-set use_from = yes
-
-# Alerts
-set beep_new = yes
-
-# Attachments
-attachments +A */.*
-attachments -A text/x-vcard application/pgp.*
-attachments -A application/x-pkcs7-.*
-attachments +I text/plain
-attachments -A message/external-body
-attachments -I message/external-body
-
-# Caching
-set header_cache = '~/.cache/mutt/headers'
-
-# Colors
-color attachment brightyellow default
-color hdrdefault cyan default
-color indicator black white
-color markers brightred default
-color normal default default
-color quoted green default
-color signature cyan default
-color status default color22
-color tilde brightblack default
-color tree default default
-
-# Completion
-bind editor <Tab> complete-query
-bind editor ^T complete
-
-# Files
-set delete = ask-yes
-set move = no
-
-# Flags
-set mark_old = no
-
-# Headers
-ignore *
-unignore Date From: To Cc Subject
-hdr_order Date From: To Cc Subject
-set edit_headers = yes
+# If an outgoing message looks like I meant to attach something, and there
+# isn't an attachment, prompt me to make sure I haven't forgotten it.
+# I normally don't like this sort of nagging, but I'm making an exception in
+# this case, as I really do trip up on this a lot. The default pattern of just
+# 'attach' is a bit too aggressive, so I write a slightly softer one that
+# reflects the usual way I refer to attachments.
+#
+set abort_noattach = ask-no
+set abort_noattach_regexp = "attached (are|is)|(find|i have|i've|see) attached"
+
+# Don't assume I don't want to continue editing a message if I didn't change
+# anything to it; if I want to send a message with just my signature, that's my
+# right.
+#
+unset abort_unmodified
+
+# Put the alias file in a nice XDG location, distinct from the muttrc, so that
+# we don't end up losing them each time the dotfiles are reinstalled; `man
+# 5 muttrc` points out that this file needs to be explicitly sourced, too.
+#
+set alias_file \
+ = ~/.config/mutt/aliases
+source $alias_file
+
+# Don't send terminal bells on errors, but do send them when new mail arrives,
+# because that should light up either my terminal emulator window or my tmux
+# window label.
+#
+unset beep
+set beep_new
+
+# Don't prompt me for confirmation if I move messages into an existing mailbox;
+# just do it.
+#
+unset confirmappend
+
+# Switch to a subject format for forwarded messages that's more familiar to
+# most mail users.
+#
+set forward_format = 'Fw: %s'
+
+# Cache message headers for speed; this really helps.
+#
+set header_cache \
+ = ~/.cache/mutt/headers
+
+# Save command history; this saves other kinds of history as well, but all
+# I really want is to be able to run the same commands again even after I quit
+# Mutt. We can afford to keep 2^8 of these, since it's the future and all.
+#
+set history_file \
+ = ~/.cache/mutt/history
+set history = 256
+set save_history = $history
-# Index
-set index_format = '%4C %Z %{%b %d %Y} %-15.15L (%?l?%4l&%4c?) %s'
+# Always put a quoted copy of the whole message in a reply text for me to chop
+# up and respond to in Vim--no need to prompt me (the default does that).
+#
+set include
+
+# Tweak the index format to include spam tagging information, if any, with the
+# %H format string
+#
+set index_format = '%4C %Z %{%b %d %Y} %-15.15L (%?l?%4l&%4c?) %?H?[%H] ?%s'
+
+# Set a custom mailcap, rather than leaning on the system's
+#
+set mailcap_path \
+ = ~/.config/mutt/mailcap
+
+# When displaying messages with multiple alternatives for display, prefer any
+# plain text one, but failing that, fall back to enriched text (hey, it could
+# happen...)
+#
+alternative_order \
+ text/plain \
+ text/enriched \
+ text/html \
+ application/pdf \
+ *
+
+# Decode any text/html and application/pdf parts with .mailcap's specified
+# programs.
+#
+auto_view \
+ text/html \
+ application/pdf
+
+# Don't show any nasty little markers at the start of wrapped lines. That's
+# the sort of thing Vim cares about, if need be.
+#
+unset markers
+
+# Created mailboxes are in Maildir format everywhere I deploy this, so I may as
+# well set it in here rather than get annoyed when Mutt starts dropping files
+# in mbox format everywhere if I leave it out of muttrc.d/*.rc.
+#
+set mbox_type = Maildir
+
+# Show a few messages of the index when in pager mode to give a little context
+# around the message. I should have been doing this years ago. Oh well.
+#
+set pager_index_lines = 6
+
+# Don't move on to the next message if we're at the end of the current one just
+# because I executed <next-page>.
+#
+set pager_stop
+
+# Use the abook program for finding and completing addresses with ^T. I do use
+# the aliases system for regular correspondents, too.
+#
+set query_command = 'abook --mutt-query %s'
-# Interaction
-set abort_unmodified = no
-set confirmappend = no
-set wait_key = no
+# Check with me whether I really want to quit, just in case I've hit "q" too
+# many times trying to get out of e.g. the aliases menu.
+#
set quit = ask-yes
-# Intervals
-set mail_check = 5
+# I prefer a slightly stricter pattern to match what is and isn't a quote; this
+# avoids flagging things like closing braces on new lines in code blocks as
+# quotes.
+#
+set quote_regexp = '^(>[ \t]*)+'
+
+# Don't offer to resume a postponed message when I hit <mail>; I'll use
+# <recall-message> for that.
+#
+unset recall
+
+# If I have an alias configured for someone, use that in the index display, in
+# preference to whatever the From: line actually says.
+#
+set reverse_alias
+
+# Don't delay on switching or altering mailboxes so that I see the messages;
+# just do it straight away.
+#
set sleep_time = 0
-# Mailboxes
-set confirmcreate = yes
+# Only use the headers with proper references to link messages in a thread;
+# don't try to use pattern matches on subjects, which might be rubbish like
+# "hi". If I need to link a thread together because it's been broken somehow,
+# I'll do that manually.
+#
+set strict_threads
-# Menus
-set menu_context = 1
+# Use format=flowed, continuing paragraphs for lines that end with a single
+# space, and use that wrapping information to use the full width of the
+# terminal for the wrapping display.
+#
+set text_flowed
+set reflow_wrap = 0
-# MIME
-mime_lookup application/octet-stream
+# Don't wait for me to press a key after running a command if it exited
+# successfully; this still warns me if something failed, though.
+#
+unset wait_key
-# Pager
-set pager_context = 1
-set pager_format = '%4C %Z %[!%b %e at %I:%M %p] %.20n %s%* -- (%P)'
-set pager_stop = yes
+# Use the GPGME library for PGP; sign replies to messages that are themselves
+# signed (whether encrypted or not), and encrypt when we have a key for every
+# recipient (opportunistic).
+#
+set crypt_use_gpgme
+set crypt_opportunistic_encrypt
+set crypt_replysign
+set crypt_replysignencrypted
-# Presentation/formatting
-set markers = no
-set smart_wrap = yes
-set text_flowed = yes
-set tilde = yes
-alternative_order text/plain text/html *
-auto_view text/html
+# Use a default key for self-encrypting both sent and draft messages so that
+# they're protected but legible. This defaults to the $GPG_KEYID environment
+# variable, so be careful to set that lest you send useless OpenPGP headers!
+# My kingdom for muttrc(5) conditionals...
+#
+set pgp_default_key = $GPG_KEYID
+set postpone_encrypt
-# Quoting
-set quote_regexp = '^(>[ \t]*)+'
+# Always include OpenPGP header with the selected default key, regardless of
+# whether the message is protected or not:
+#
+# <https://datatracker.ietf.org/doc/draft-josefsson-openpgp-mailnews-header/>
+#
+# This RFC has expired and doesn't seem to have seen widespread adoption, but
+# it looks like Thunderbird's Enigmail extension is still sending key IDs with
+# it, and it doesn't do any harm.
+#
+my_hdr OpenPGP: id=$pgp_default_key\; \
+preference=signencrypt\; \
+url=https://keys.openpgp.org/vks/v1/by-fingerprint/$pgp_default_key
-# Responses
-set fast_reply = yes
-set forward_attachments = yes
-set forward_format = 'Fw: %s'
-set include = yes
-set use_envelope_from = yes
-
-# Searching/sorting
-set sort = 'threads'
-set sort_aux = 'last-date-received'
-set strict_threads = yes
-set thorough_search = yes
-
-# SSH
-set time_inc = 250
-
-# Encryption settings
-set crypt_protected_headers_write = yes
-set crypt_replysign = yes
-set crypt_replyencrypt = yes
-set crypt_replysignencrypted = yes
-set crypt_use_gpgme = yes
-set crypt_use_pka = yes
-set crypt_verify_sig = yes
-
-# Do decode classic PGP messages, though we'll never write them
-set pgp_auto_decode = yes
-
-# Vim-ish bindings
-bind index gg first-entry
-bind index G last-entry
-bind pager gg top
-bind pager G bottom
-bind index,pager \Cu half-up
-bind index,pager \Cd half-down
-bind generic,index,browser,pager \Cf next-page
-bind generic,index,browser,pager \Cb previous-page
-
-# Turn off annoying mailbox lock feature
-bind index '%' noop
-
-# Blindly save message to whatever box is suggested
-macro index,pager S 's<enter>' 'Save message blindly'
-
-# Run gms to retrieve all mail
-macro generic,index,browser,pager gm '!gms --quiet &<enter>' 'Run gms(1df)'
+# Reset whatever ignore/unignore settings we've been passed by the system
+# config, and use our own basic set, excluding User-Agent and other generally
+# uninteresting fields.
+#
+ignore *
+unignore date: from: to: cc: subject:
+
+# Also show List-Archive and X-List-Archive headers, both to show the source
+# list, and to provide me with a web link to it to pass on to anyone
+# interested.
+#
+unignore list-archive: x-list-archive:
+
+# Because I (personally) never want to encrypt mail without signing it, add in
+# a hook for sending or changing a message that forces a signature if it's
+# encrypted but not signed. This may not suit anyone else reading.
+#
+send-hook '~G !~g' \
+ 'push <pgp-menu>s'
+send2-hook '~G !~g' \
+ 'push <pgp-menu>s'
+
+# Because of the order in which opportunistic encryption is applied, we queue
+# up a no-op change by opening the PGP menu and then doing nothing (pressing
+# Enter), to trigger send2-hooks to run and turn signatures on if opportunistic
+# encryption happens to have decided to switch encryption on.
+#
+send-hook '!~G !~g' \
+ 'push <pgp-menu><enter>'
+
+# Failing all of the above, maybe autocrypt will passively give us a key to
+# use, but don't store its keys in our primary keyring.
+#
+set autocrypt
+set autocrypt_dir \
+ = ~/.local/share/mutt/autocrypt
+
+# Set custom filter to generate an HTML part for plain-text messages in
+# Markdown style; defaults to off, per God's will and common decency.
+#
+set send_multipart_alternative_filter \
+ = ~/.local/libexec/mutt/filters/markdown-to-html
+
+# Toggle multipart sending option manually and display the new setting
+macro generic,index,browser,pager \\h '\
+<enter-command>toggle send_multipart_alternative<enter>\
+<enter-command>set ?send_multipart_alternative<enter>' \
+ 'Toggle multipart/alternative sending'
+
+# Shortcuts to jump to mailboxes
+macro generic,index,browser,pager \\b \
+ '<change-folder>-<enter>' \
+ 'Change to previous'
+macro generic,index,browser,pager \\i \
+ '<change-folder>!<enter>' \
+ 'Change to inbox'
+macro generic,index,browser,pager \\r \
+ '<change-folder><<enter>' \
+ 'Change to sent'
+
+# Shortcuts to save to mailboxes
+macro generic,index,browser,pager \\\Cb \
+ '<save-message>-<enter>' \
+ 'Move message to previous'
+macro generic,index,browser,pager \\\Ci \
+ '<save-message>!<enter>' \
+ 'Move message to inbox'
+macro generic,index,browser,pager \\\Cr \
+ '<save-message><<enter>' \
+ 'Move message to sent'
# Shortcut to add addresses to abook
-macro index,pager A \
- '<pipe-message>abook --add-email-quiet<enter>' \
- 'Add sender address to abook'
+macro index,pager \\a \
+ '<pipe-message>abook --add-email-quiet<enter>' \
+ 'Add sender address to abook'
+
+# Janky notmuch-mutt search macro, cleaned up a little
+macro index \\l '\
+<enter-command>set \
+ my_pipe_decode=$pipe_decode \
+ my_wait_key=$wait_key \
+ nopipe_decode \
+ nowait_key<enter>\
+<shell-escape>notmuch-mutt --prompt search --remove-dups<enter>\
+<change-folder-readonly>~/.cache/notmuch/mutt/results<enter>\
+<enter-command>set \
+ pipe_decode=$my_pipe_decode \
+ wait_key=$my_wait_key<enter>' \
+ 'notmuch: search mail'
+
+# Shortcut to reload configuration
+set my_muttrc \
+ = ~/.config/mutt/muttrc
+macro generic,index,browser,pager \\R '\
+<enter-command>unhook *<enter>\
+<enter-command>source $my_muttrc<enter>\
+<enter-command>echo "Reloaded $my_muttrc"<enter>' \
+ "Clear hooks and reload"
+
+# I often want thread display when having to keep track of multiple
+# conversations at once with multiple people replying to one another, as is
+# regularly the case when reading mailing lists, but for my personal mail it's
+# generally nicer to sort the messages simply by date. This macro uses
+# user-defined variables to toggle $sort between "threads" (default) and
+# "date".
+#
+set sort = threads
+set my_sort_alt = date-received
+macro index \\t '\
+<enter-command>set my_sort_tmp = $sort<enter>\
+<enter-command>set sort = $my_sort_alt<enter>\
+<enter-command>set my_sort_alt = $my_sort_tmp<enter>\
+<enter-command>unset my_sort_tmp<enter>\
+<enter-command>set ?sort<enter>' \
+ "Toggle thread display"
+
+# When threads are on, sort them by the date the most recent message within
+# them was received.
+#
+set sort_aux = last-date-received
+
+# Set a few simple colors just for a quick visual cue of which tool I'm looking
+# at and for some visual distinction between text, signature, and quote. The
+# navigation bar is a nice dark green.
+#
+color attachment \
+ brightyellow default
+color hdrdefault \
+ brightcyan default
+color quoted \
+ brightgreen default
+color signature \
+ cyan default
+color status \
+ default color22
-# Machine or account specific settings
-source ~/.muttrc.d/src|
+# Load machine-specific or account-specific settings from the helper script in
+# muttrc.d, and we're done.
+#
+source ~/.config/mutt/muttrc.d/src|
diff --git a/mutt/muttrc.d/src b/mutt/muttrc.d/src
deleted file mode 100755
index cc2eb4ef..00000000
--- a/mutt/muttrc.d/src
+++ /dev/null
@@ -1,13 +0,0 @@
-#!/bin/sh
-# Helper script to emit the source all muttrc subfiles, in LC_COLLATE order
-for rc in "$HOME"/.muttrc.d/*.rc ; do
- [ -e "$rc" ] || continue
- cat -- "$rc"
-done
-
-# Special case: if using GNU Emacs, emit a line to disable edit_headers, just
-# because at the moment I haven't worked out how to make this work sanely with
-# messages-are-flowing in message-mode.
-case $VISUAL in
- emacs|emacsclient) printf 'set edit_headers = no\n' ;;
-esac
diff --git a/mutt/muttrc.d/src.sh b/mutt/muttrc.d/src.sh
new file mode 100644
index 00000000..60e0c566
--- /dev/null
+++ b/mutt/muttrc.d/src.sh
@@ -0,0 +1,24 @@
+# Build groups from address lists
+for rc in "$HOME"/.config/mutt/muttrc.d/groups/*.list ; do
+ [ -e "$rc" ] || continue
+ group=$rc
+ group=${group##*/}
+ group=${group%.list}
+ while read -r member ; do
+ printf 'group -group %s -addr %s\n' \
+ "$group" "$member"
+ done < "$rc"
+done
+
+# Emit the source all muttrc subfiles, in LC_COLLATE order
+for rc in "$HOME"/.config/mutt/muttrc.d/*.rc ; do
+ [ -e "$rc" ] || continue
+ cat -- "$rc"
+done
+
+# Special case: if using GNU Emacs, emit a line to disable edit_headers, just
+# because at the moment I haven't worked out how to make this work sanely with
+# messages-are-flowing in message-mode.
+case $VISUAL in
+ emacs|emacsclient) printf 'unset edit_headers\n' ;;
+esac
diff --git a/ncmpcpp/config b/ncmpcpp/config
index 7e865a8f..48f5137a 100644
--- a/ncmpcpp/config
+++ b/ncmpcpp/config
@@ -1,8 +1 @@
-# Configuration directory
-ncmpcpp_directory = "~/.ncmpcpp"
-
-# Server specifics
-mpd_host = "~/.mpd/socket"
-
-# No mouse, it confuses tmux/urxvt, and I never use it anyway
-mouse_support = "no"
+enable_window_title = no
diff --git a/newsboat/config b/newsboat/config
index d7caf12d..78577adf 100644
--- a/newsboat/config
+++ b/newsboat/config
@@ -1,14 +1,23 @@
-auto-reload yes
confirm-exit yes
-keep-articles-days 180
-reload-threads 5
-reload-time 30
+
+auto-reload yes
+reload-time 10
+
+use-proxy yes
+proxy-type socks5h
+proxy localhost:9050
+
+download-retries 4
+download-timeout 60
bind-key j next
bind-key k prev
bind-key J next-feed
bind-key K prev-feed
+articlelist-format "%4i %f %D %?T?|%-17T| ?%t"
+datetime-format "%F %T"
+
color article default default
color background default default
color info white color52
diff --git a/newsboat/systemd/user/newsboat.service b/newsboat/systemd/user/newsboat.service
new file mode 100644
index 00000000..020ba328
--- /dev/null
+++ b/newsboat/systemd/user/newsboat.service
@@ -0,0 +1,10 @@
+[Unit]
+Description=Newsboat news reader
+
+[Service]
+Environment=TERM=screen-256color
+ExecStart=/usr/bin/dtach -N %t/newsboat.socket /usr/bin/newsboat --log-file=%L/newsboat/%p.log --log-level=2
+Restart=always
+
+[Install]
+WantedBy=default.target
diff --git a/parcellite/parcelliterc b/parcellite/parcelliterc
new file mode 100644
index 00000000..fad0493e
--- /dev/null
+++ b/parcellite/parcelliterc
@@ -0,0 +1,41 @@
+[rc]
+RCVersion=1
+use_copy=true
+use_primary=true
+synchronize=false
+save_history=true
+history_pos=false
+history_x=1
+history_y=1
+history_limit=64
+data_size=0
+item_size=8
+automatic_paste=false
+auto_key=false
+auto_mouse=true
+key_input=false
+restore_empty=true
+rc_edit=false
+type_search=false
+case_search=false
+ignore_whiteonly=false
+trim_wspace_begend=false
+trim_newline=false
+hyperlinks_only=false
+confirm_clear=true
+current_on_top=true
+single_line=true
+reverse_history=true
+item_length=50
+persistent_history=false
+persistent_separate=false
+persistent_on_top=false
+persistent_delim=\\n
+nonprint_disp=false
+ellipsize=2
+multi_user=true
+icon_name=parcellite
+menu_key=
+history_key=
+phistory_key=
+actions_key=
diff --git a/parcellite/xsession.d/parcellite.sh b/parcellite/xsession.d/parcellite.sh
new file mode 100644
index 00000000..39fb6c4e
--- /dev/null
+++ b/parcellite/xsession.d/parcellite.sh
@@ -0,0 +1,2 @@
+# Start X clipboard manager
+parcellite &
diff --git a/perlcritic/perlcriticrc b/perlcritic/perlcriticrc
index 0bd59c98..37f033fe 100644
--- a/perlcritic/perlcriticrc
+++ b/perlcritic/perlcriticrc
@@ -20,6 +20,11 @@ add_exceptions = inet4 inet6 ipv4 ipv6
# Cool story, bro
[-Editor::RequireEmacsFileVariables]
+# Postfix dereferencing like $foo->@* causes false positives for this policy,
+# a known bug; it's not fixed yet, so we'll just block this policy in the
+# meantime: <https://github.com/Perl-Critic/Perl-Critic/issues/578>
+[-References::ProhibitDoubleSigils]
+
# Soften this rather harsh policy a fair bit; tolerate negative one, all the
# single-digit integers as literals, three powers of 10 (for percentages,
# milliseconds etc), 60 (for angles and clocks), and 1900 (for localtime)
diff --git a/perlcritic/profile.d/perlcritic.sh b/perlcritic/profile.d/perlcritic.sh
new file mode 100644
index 00000000..bb404c45
--- /dev/null
+++ b/perlcritic/profile.d/perlcritic.sh
@@ -0,0 +1,2 @@
+PERLCRITIC=${XDG_CONFIG_HOME:-$HOME/.config}/perlcritic/perlcriticrc
+export PERLCRITIC
diff --git a/perltidy/profile.d/perltidy.sh b/perltidy/profile.d/perltidy.sh
new file mode 100644
index 00000000..03ed0754
--- /dev/null
+++ b/perltidy/profile.d/perltidy.sh
@@ -0,0 +1,2 @@
+PERLTIDY=${XDG_CONFIG_HOME:-$HOME/.config}/perltidy/perltidyrc
+export PERLTIDY
diff --git a/plenv/profile.d/plenv.sh b/plenv/profile.d/plenv.sh
index b2b491e1..5bfc2d24 100644
--- a/plenv/profile.d/plenv.sh
+++ b/plenv/profile.d/plenv.sh
@@ -1,5 +1,2 @@
-# Add plenv to PATH and MANPATH if it appears to be in use
-[ -d "$HOME"/.plenv ] || return
-PATH=$HOME/.plenv/shims:$HOME/.plenv/bin:$PATH
-MANPATH=$HOME/.plenv/versions/$(perl -e 'print substr($^V,1)')/man:$MANPATH
-export MANPATH
+# Add plenv bindir and shims to PATH
+PATH=$HOME/.plenv/bin:$HOME/.plenv/shims:$PATH
diff --git a/plenv/shrc.d/plenv.sh b/plenv/shrc.d/plenv.sh
index 6e03618e..938bcbf6 100644
--- a/plenv/shrc.d/plenv.sh
+++ b/plenv/shrc.d/plenv.sh
@@ -1,17 +1,20 @@
# POSIX-compatible version of the plenv Bash shell wrapper
-[ -d "$HOME"/.plenv ] || return
plenv() {
case $1 in
rehash)
shift
eval "$(plenv sh-rehash "$@")"
;;
+ sh-rehash)
+ command plenv "$@"
+ ;;
shell)
shift
eval "$(plenv sh-shell "$@")"
;;
*)
command plenv "$@"
+ plenv rehash
;;
esac
}
diff --git a/pyenv/profile.d/pyenv.sh b/pyenv/profile.d/pyenv.sh
new file mode 100644
index 00000000..ea2455fb
--- /dev/null
+++ b/pyenv/profile.d/pyenv.sh
@@ -0,0 +1,2 @@
+# Add pyenv bindir and shims to PATH
+PATH=$HOME/.pyenv/bin:$HOME/.pyenv/shims:$PATH
diff --git a/pyenv/shrc.d/pyenv.sh b/pyenv/shrc.d/pyenv.sh
new file mode 100644
index 00000000..60ed8ac7
--- /dev/null
+++ b/pyenv/shrc.d/pyenv.sh
@@ -0,0 +1,20 @@
+# POSIX-compatible version of the pyenv Bash shell wrapper
+pyenv() {
+ case $1 in
+ rehash)
+ shift
+ eval "$(pyenv sh-rehash "$@")"
+ ;;
+ sh-rehash)
+ command pyenv "$@"
+ ;;
+ shell)
+ shift
+ eval "$(pyenv sh-shell "$@")"
+ ;;
+ *)
+ command pyenv "$@"
+ pyenv rehash
+ ;;
+ esac
+}
diff --git a/rbenv/profile.d/rbenv.sh b/rbenv/profile.d/rbenv.sh
new file mode 100644
index 00000000..5295584c
--- /dev/null
+++ b/rbenv/profile.d/rbenv.sh
@@ -0,0 +1,2 @@
+# Add rbenv bindir and shims to PATH
+PATH=$HOME/.rbenv/bin:$HOME/.rbenv/shims:$PATH
diff --git a/rbenv/shrc.d/rbenv.sh b/rbenv/shrc.d/rbenv.sh
new file mode 100644
index 00000000..14403680
--- /dev/null
+++ b/rbenv/shrc.d/rbenv.sh
@@ -0,0 +1,20 @@
+# POSIX-compatible version of the rbenv Bash shell wrapper
+rbenv() {
+ case $1 in
+ rehash)
+ shift
+ eval "$(rbenv sh-rehash "$@")"
+ ;;
+ sh-rehash)
+ command rbenv "$@"
+ ;;
+ shell)
+ shift
+ eval "$(rbenv sh-shell "$@")"
+ ;;
+ *)
+ command rbenv "$@"
+ rbenv rehash
+ ;;
+ esac
+}
diff --git a/readline/inputrc b/readline/inputrc
index 87abcd49..90c53633 100644
--- a/readline/inputrc
+++ b/readline/inputrc
@@ -1,12 +1,8 @@
-# Don't mess with the eighth bit of characters
-set input-meta on
-set output-meta on
-
# Never ring any sort of bell during line reading
set bell-style none
-# Let readline do stuff like word killing, not stty(1)
-set bind-tty-special-chars off
+# Color files by type in the same way as `ls`
+set colored-stats on
# Ignore case when matching and completing paths
set completion-ignore-case on
@@ -17,9 +13,16 @@ set completion-map-case on
# Show me up to 5,000 completion items, don't be shy
set completion-query-items 5000
+# When completing, put the matched completion prefix in a different color
+set colored-completion-prefix on
+set menu-complete-display-prefix on
+
# Don't display control characters like ^C if I input them
set echo-control-characters off
+# Detect terminal pastes and don't treat the characters like keyboard input
+set enable-bracketed-paste on
+
# Expand tilde to full path on completion
set expand-tilde on
@@ -48,56 +51,59 @@ set show-all-if-ambiguous on
# Don't re-complete already completed text in the middle of a word
set skip-completed-text on
+# Append characters to indicate completion filetype
+set visible-stats on
+
# Bash macros
$if Bash
- # Expand ! history with a spacebar press
- # Note that this makes your shell unusable if your Bash doesn't have
- # magic-space. It's had this feature since 2.02.
- Space: magic-space
-
- # Tab does traditional blocking completion
- Tab: complete
- # Alt+A cycles through completion options
- "\ea": menu-complete
-
- # Special completion keys for git(1)
- ## Branches
- "\C-xb": complete
- ## Tags
- "\C-xt": complete
-
- # Ctrl-Alt-L to clear screen; more ksh-like
- "\e\C-l": clear-screen
-
- # Alt-E (for exec) to prepend "exec " to a command and return to the end of
- # the line
- "\ee": "\C-aexec \C-e"
- # Alt-P (for procedure) to wrap current command in () { ... ; } and go to
- # the start of the line
- "\ep": "\C-a() { \C-e ; }\C-a"
- # Alt-S (for set) to wrap current command in (set -x ; ...)
- "\es": "\C-a(set -x ; \C-e)\C-b"
-
- # Alt-M (for muxer) to run tm(1df)
- "\em": "\C-utm\C-j\C-y"
-
- # Alt-' for escaped single-quote: 'don'\''t fear the reaper'
- "\e'": "'\\''"
-
- # Ctrl-Alt-B to move backward a shell-quoted word
- "\e\C-b": shell-backward-word
- # Ctrl-Alt-F to move forward a shell-quoted word
- "\e\C-f": shell-forward-word
- # Ctrl-Alt-W to delete a previous shell-quoted word
- "\e\C-w": shell-backward-kill-word
+ # Expand ! history with a spacebar press
+ # Note that this makes your shell unusable if your Bash doesn't have
+ # magic-space. It's had this feature since 2.02.
+ Space: magic-space
+
+ # Tab does traditional blocking completion
+ Tab: complete
+ # Alt+A cycles through completion options
+ "\ea": menu-complete
+
+ # Special completion keys for git(1)
+ ## Branches
+ "\C-xb": complete
+ ## Tags
+ "\C-xt": complete
+
+ # Ctrl-Alt-L to clear screen; more ksh-like
+ "\e\C-l": clear-screen
+
+ # Alt-E (for exec) to prepend "exec " to a command and return to the end of
+ # the line
+ "\ee": "\C-aexec \C-e"
+ # Alt-P (for procedure) to wrap current command in () { ... ; } and go to
+ # the start of the line
+ "\ep": "\C-a() { \C-e ; }\C-a"
+ # Alt-S (for set) to wrap current command in (set -x ; ...)
+ "\es": "\C-a(set -x ; \C-e)\C-b"
+
+ # Alt-M (for muxer) to run tm(1df)
+ "\em": "\C-utm\C-j\C-y"
+
+ # Alt-' for escaped single-quote: 'don'\''t fear the reaper'
+ "\e'": "'\\''"
+
+ # Ctrl-Alt-B to move backward a shell-quoted word
+ "\e\C-b": shell-backward-word
+ # Ctrl-Alt-F to move forward a shell-quoted word
+ "\e\C-f": shell-forward-word
+ # Ctrl-Alt-W to delete a previous shell-quoted word
+ "\e\C-w": shell-backward-kill-word
$endif
# bc macros
$if bc
- # Don't let bc complete filenames (!?)
- Tab:
+ # Don't let bc complete filenames (!?)
+ Tab:
$endif
diff --git a/redshift/redshift.conf b/redshift/redshift.conf
new file mode 100644
index 00000000..0c2f5cfb
--- /dev/null
+++ b/redshift/redshift.conf
@@ -0,0 +1,6 @@
+[redshift]
+location-provider=manual
+
+[manual]
+lat=-36.8487484
+lon=174.7600435
diff --git a/redshift/xsession.d/redshift.sh b/redshift/xsession.d/redshift.sh
new file mode 100644
index 00000000..503877dc
--- /dev/null
+++ b/redshift/xsession.d/redshift.sh
@@ -0,0 +1,2 @@
+# Start X color temperature manager
+redshift &
diff --git a/rofi/bin/rofi_pass.sh b/rofi/bin/rofi_pass.sh
new file mode 100644
index 00000000..fb31a454
--- /dev/null
+++ b/rofi/bin/rofi_pass.sh
@@ -0,0 +1,92 @@
+# Pick password from local or remote password-store with rofi's dmenu emulation
+# mode, and write it to the active X11 window. Optionally, prefix it with the
+# username, being the last part of the slash-delimited password's name, and
+# a TAB press to move to the next field in a form.
+#
+self=rofi_pass
+
+# Abstraction to handle running shell commands (args or stdin) in either
+# a remote or local shell. If the environment variable PASSWORD_STORE_HOST is
+# set, it's used as the destination SSH hostname to the password store.
+#
+pass_shell() {
+ [ "$#" -le 1 ] || return
+ if [ -n "$PASSWORD_STORE_HOST" ] ; then
+ ssh -o StrictHostKeyChecking=yes -T -X -- \
+ "$PASSWORD_STORE_HOST" "$@"
+ elif [ "$#" -eq 1 ] ; then
+ "${SHELL:-/bin/sh}" -c "$1"
+ else
+ "${SHELL:-/bin/sh}" -s
+ fi
+}
+
+# Get a list of all the password paths, relative to the password store root,
+# including leading dot-slash and trailing .gpg extension.
+#
+get_paths() {
+ pass_shell <<-'EOF'
+ dir=${PASSWORD_STORE_DIR:-"$HOME"/.password-store}
+ cd -- "$dir" || exit
+ find . -name \*.gpg -type f || exit
+ EOF
+}
+
+# Get a list of all the password names, bytewise-sorted, with leading dot-slash
+# and trailing .gpg extension removed.
+#
+get_names() {
+ get_paths |
+ sed -e 's_^[.]/__' -e 's_[.]gpg$__' |
+ LC_COLLATE=C sort -f
+}
+
+# Write a password name to a shell to retrieve it, and read its first line;
+# write the name safely to the shell's input rather than as an argument.
+#
+get_password() {
+ name=$1
+ [ -n "$name" ] || return
+ printf '%s\n' "$name" |
+ pass_shell 'IFS= read -r name ; pass show "$name"' |
+ head -n 1
+}
+
+# Check for --login/-l option to paste a username-password combo, not just the
+# password (defaults to the latter).
+#
+login=0
+case $1 in
+ --login|-l) login=1 ;;
+esac
+
+# Apply rofi -dmenu to pick a password name. Use case-insensitive matching,
+# and don't accept arbitrary input.
+#
+name=$(get_names | rofi -dmenu -i -no-lazy-grab -only_match -p pass) || exit
+[ -n "$name" ] || exit
+
+# Retrieve the username for the chosen password, and then the secret itself;
+# check that we actually got more than an empty string back in both cases.
+#
+username=${name##*/}
+[ -n "$username" ] || exit
+password=$(get_password "$name") || exit
+[ -n "$password" ] || exit
+
+# Have xdotool type either the username-TAB-password, or just the password;
+# receiving it on its standard input rather than its arguments, for security.
+#
+if [ "$login" -eq 1 ] ; then
+ printf '%s\t%s' \
+ "$username" "$password"
+else
+ printf '%s' \
+ "$password"
+fi | xdotool type --clearmodifiers --delay=0 --file - || exit
+
+# Tell the user we wrote the password out, in case they're typing a password
+# into a field with echo turned off.
+#
+notify-send --app-name="$self" --icon=gcr-password -- \
+ 'Password typed' "$name"
diff --git a/sh/profile b/sh/profile
index 7f16cb32..5b835458 100644
--- a/sh/profile
+++ b/sh/profile
@@ -1,17 +1,38 @@
-# Add ~/.local/bin to PATH if it exists
-if [ -d "$HOME"/.local/bin ] ; then
- PATH=$HOME/.local/bin:$PATH
-fi
+# Use lynx as our terminal browser
+BROWSER=lynx
+export BROWSER
-# Load all supplementary scripts in ~/.profile.d
+# Use ed as our line editor and vi as our visual editor
+EDITOR=ed
+VISUAL=vi
+export EDITOR VISUAL
+
+# Set the POSIX interactive startup file to ~/.shinit
+ENV=$HOME/.shinit
+export ENV
+
+# Use NZ English, but bytewise sorting
+LANG=en_NZ.UTF-8
+LANGUAGE=en_NZ:en
+LC_COLLATE=C
+export LANG LANGUAGE LC_COLLATE
+
+# Use less as my pager
+PAGER=less
+export PAGER
+
+# Assume I'm at home unless something overrides it
+TZ=Pacific/Auckland
+export TZ
+
+# Source all scripts in ~/.profile.d; many of them will be modifying $PATH, so
+# we'll get that sorted out first
for sh in "$HOME"/.profile.d/*.sh ; do
[ -e "$sh" ] || continue
. "$sh"
done
unset -v sh
-# If ~/.shinit exists, set ENV to that
-if [ -f "$HOME"/.shinit ] ; then
- ENV=$HOME/.shinit
- export ENV
-fi
+# Add ~/.local/bin and ~/.local/games to the very front of PATH, so that it
+# overrides everything else
+PATH=$HOME/.local/bin:$HOME/.local/games:$PATH
diff --git a/sh/profile.d/browser.sh b/sh/profile.d/browser.sh
deleted file mode 100644
index 2c724505..00000000
--- a/sh/profile.d/browser.sh
+++ /dev/null
@@ -1,4 +0,0 @@
-# Set command-line browser to lynx; ~/.xinitrc will change this to something
-# graphical instead
-BROWSER=lynx
-export BROWSER
diff --git a/sh/profile.d/downloads.sh b/sh/profile.d/downloads.sh
deleted file mode 100644
index 1a89bc3f..00000000
--- a/sh/profile.d/downloads.sh
+++ /dev/null
@@ -1,33 +0,0 @@
-# Only if shell is interactive
-case $- in
- *i*) ;;
- *) return ;;
-esac
-
-# Only if not in a tmux window
-[ -z "$TMUX" ] || return
-
-# Not if ~/.hushlogin exists
-! [ -e "$HOME"/.hushlogin ] || return
-
-# Not if ~/.downloads doesn't
-[ -f "$HOME"/.downloads ] || return
-
-# Count files in each directory, report if greater than zero
-(
- lc=0
- while IFS= read -r dir ; do
- case $dir in
- '#'*) continue ;;
- esac
- [ -d "$dir" ] || continue
- set -- "$dir"/*
- [ -e "$1" ] || shift
- [ "$#" -gt 0 ] || continue
- printf 'You have %u unsorted files in %s.\n' "$#" "$dir"
- lc=$((lc+1))
- done < "$HOME"/.downloads
- if [ "$lc" -gt 0 ] ; then
- printf '\n'
- fi
-)
diff --git a/sh/profile.d/editor.sh b/sh/profile.d/editor.sh
deleted file mode 100644
index 37146fb9..00000000
--- a/sh/profile.d/editor.sh
+++ /dev/null
@@ -1,25 +0,0 @@
-# Ideally, we'd use plain old ed(1), but many Linux distributions don't install
-# it by default
-if command -v ed >/dev/null 2>&1 ; then
- EDITOR='ed'
-
-# Failing that, if the system's implementation of ex(1) looks like Vim and we
-# have exm(1df) in our $PATH, use the latter to work around Vim's ex mode
-# screen-clearing
-elif (
- command -v ex >/dev/null 2>&1 || exit 1
- command -v exm >/dev/null 2>&1 || exit 1
- ver=$(ex --version 2>/dev/null | awk '{print $1;exit}')
- case $ver in
- (VIM) exit 0 ;;
- (*) exit 1 ;;
- esac
-) >/dev/null 2>&1 ; then
- EDITOR='exm'
-
-# Otherwise, we can just call ex(1) directly
-else
- EDITOR='ex'
-fi
-
-export EDITOR
diff --git a/sh/profile.d/games.sh b/sh/profile.d/games.sh
deleted file mode 100644
index 956d1de1..00000000
--- a/sh/profile.d/games.sh
+++ /dev/null
@@ -1,3 +0,0 @@
-# Add ~/.local/games to PATH if it exists
-[ -d "$HOME"/.local/games ] || return
-PATH=$PATH:$HOME/.local/games
diff --git a/sh/profile.d/lang.sh b/sh/profile.d/lang.sh
deleted file mode 100644
index 21f67d5b..00000000
--- a/sh/profile.d/lang.sh
+++ /dev/null
@@ -1,4 +0,0 @@
-# Always use bytewise sorting if not already set
-[ -z "$LC_COLLATE" ] || return
-LC_COLLATE=C
-export LC_COLLATE
diff --git a/sh/profile.d/options.sh b/sh/profile.d/options.sh
index ad9d43ab..f9dc3c79 100644
--- a/sh/profile.d/options.sh
+++ b/sh/profile.d/options.sh
@@ -52,5 +52,6 @@ options ls \
block-size \
color \
human-readable \
+ quoting-style \
time-style
)
diff --git a/sh/profile.d/os.sh b/sh/profile.d/os.sh
deleted file mode 100644
index f9d5a79b..00000000
--- a/sh/profile.d/os.sh
+++ /dev/null
@@ -1,3 +0,0 @@
-# Store the operating system in an environment variable
-OS=$(uname)
-export OS
diff --git a/sh/profile.d/pager.sh b/sh/profile.d/pager.sh
deleted file mode 100644
index f0c4fab4..00000000
--- a/sh/profile.d/pager.sh
+++ /dev/null
@@ -1,7 +0,0 @@
-# If we don't have less(1), we'll just use whatever pager the application or
-# system deems fit
-command -v less >/dev/null 2>&1 || return
-
-# Use less(1) as my PAGER
-PAGER=less
-export PAGER
diff --git a/sh/profile.d/timezone.sh b/sh/profile.d/timezone.sh
deleted file mode 100644
index cbd33539..00000000
--- a/sh/profile.d/timezone.sh
+++ /dev/null
@@ -1,3 +0,0 @@
-# Timezone
-TZ=Pacific/Auckland
-export TZ
diff --git a/sh/profile.d/visual.sh b/sh/profile.d/visual.sh
deleted file mode 100644
index 50b8b423..00000000
--- a/sh/profile.d/visual.sh
+++ /dev/null
@@ -1,3 +0,0 @@
-# For a visual editor, use whichever kind of vi we get when we invoke 'vi'
-VISUAL='vi'
-export VISUAL
diff --git a/sh/profile.d/welcome.sh b/sh/profile.d/welcome.sh
deleted file mode 100644
index 22cdde93..00000000
--- a/sh/profile.d/welcome.sh
+++ /dev/null
@@ -1,49 +0,0 @@
-# Only if shell is interactive
-case $- in
- *i*) ;;
- *) return ;;
-esac
-
-# Only if not in a tmux window
-[ -z "$TMUX" ] || return
-
-# Not if ~/.hushlogin exists
-[ -e "$HOME"/.hushlogin ] && return
-
-# Run all of this in a subshell to clear it away afterwards
-(
- # Temporary helper function
- welcome() {
- [ -e "$HOME"/.welcome/"$1" ] || return
- command -v "$1" >/dev/null 2>&1 || return
- }
-
- # Show a fortune
- if welcome fortune ; then
- if [ -z "$FORTUNE_PATH" ] &&
- [ -d "$HOME"/.local/share/games/fortunes ] ; then
- FORTUNE_PATH=$HOME/.local/share/games/fortunes
- fi
- fortune -s "$FORTUNE_PATH"
- printf '\n'
- fi
-
- # Print today's reminders with asterisks
- if welcome rem ; then
- rem -hq | sed 's/^/* /'
- printf '\n'
- fi
-
- # Run verse(1) if we haven't seen it already today
- if welcome verse ; then
- if [ -f "$HOME"/.verse ] ; then
- read -r last <"$HOME"/.verse
- fi
- now=$(date +%Y%m%d)
- if [ "$now" -gt "${last:-0}" ] ; then
- verse
- printf '\n'
- printf '%s\n' "$now" >"$HOME"/.verse
- fi
- fi
-)
diff --git a/sh/shrc b/sh/shrc
index 26f69c0c..353120f5 100644
--- a/sh/shrc
+++ b/sh/shrc
@@ -4,8 +4,8 @@ command -p mesg n 2>/dev/null
# Turn off flow control and control character echo
command -p stty -ixon -ctlecho 2>/dev/null
-# Keep around 4K lines of history in memory
-HISTSIZE=$((1 << 12))
+# Keep around 16K lines of history in memory
+HISTSIZE=16384
# If HOSTNAME isn't set by this shell, we'll do it
if [ -z "$HOSTNAME" ] ; then
diff --git a/sh/shrc.d/ed.sh b/sh/shrc.d/ed.sh
index dc8433f6..0591e18d 100644
--- a/sh/shrc.d/ed.sh
+++ b/sh/shrc.d/ed.sh
@@ -22,7 +22,7 @@ ed() {
# Run in rlwrap(1) if available
set -- ed "$@"
if command -v rlwrap >/dev/null 2>&1 ; then
- set -- rlwrap --history-filename=/dev/null "$@"
+ set -- rlwrap --history-filename=/dev/null --no-warnings "$@"
fi
# Run determined command
diff --git a/sh/shrc.d/gdb.sh b/sh/shrc.d/gdb.sh
index ec9d4137..4fb459cb 100644
--- a/sh/shrc.d/gdb.sh
+++ b/sh/shrc.d/gdb.sh
@@ -1,4 +1,4 @@
# Don't print the GDB copyright message on every invocation
gdb() {
- command gdb -q "$@"
+ command gdb --quiet "$@"
}
diff --git a/sh/shrc.d/ls.sh b/sh/shrc.d/ls.sh
index 203a734f..6fbfbf61 100644
--- a/sh/shrc.d/ls.sh
+++ b/sh/shrc.d/ls.sh
@@ -31,22 +31,16 @@ ls() {
[ "$(exec 2>/dev/null;tput colors||tput Co||echo 0)" -ge 8 ] ; then
set -- --color=auto "$@"
fi
+ ## Force the new entry quoting off
+ if [ -e "$HOME"/.cache/sh/opt/ls/quoting-style ] ; then
+ set -- --quoting-style=literal "$@"
+ fi
## Add --time-style='+%Y-%m-%d %H:%M:%S' to show the date in my preferred
## (fixed) format
if [ -e "$HOME"/.cache/sh/opt/ls/time-style ] ; then
set -- --time-style='+%Y-%m-%d %H:%M:%S' "$@"
fi
- # If the operating system is FreeBSD, there are some specific options we
- # can add that might mean different things to e.g. GNU ls(1)
- case $OS in
- FreeBSD)
- # -D: Timestamp format
- # -G: Use color
- set -- -D '%Y-%m-%d %H:%M:%S' -G "$@"
- ;;
- esac
-
# Run ls(1) with the concluded arguments
command ls "$@"
}
diff --git a/sh/shrc.d/path.sh b/sh/shrc.d/path.sh
index a854e148..812f5f0f 100644
--- a/sh/shrc.d/path.sh
+++ b/sh/shrc.d/path.sh
@@ -130,7 +130,7 @@ path(): Manage contents of PATH variable
USAGE:
path [list]
- Print the current directories in PATH, one per line (default command)
+ Print the current directories in PATH, one per line (default)
path insert [DIR]
Add directory DIR (default $PWD) to the front of PATH
path append [DIR]
@@ -142,7 +142,7 @@ USAGE:
path pop
Remove the last directory from PATH
path check [DIR]
- Return whether directory DIR (default $PWD) is a component of PATH
+ Return whether directory DIR (default $PWD) is in PATH
path help
Print this help message
EOF
@@ -150,7 +150,9 @@ EOF
# Command not found
*)
- printf >&2 'path(): %s: Unknown command (try "help")\n' "$1"
+ printf >&2 \
+ 'path(): %s: Unknown command (try "help")\n' \
+ "$1"
return 2
;;
esac
diff --git a/sh/shrc.d/pd.sh b/sh/shrc.d/pd.sh
index 77f6bae9..e99049d3 100644
--- a/sh/shrc.d/pd.sh
+++ b/sh/shrc.d/pd.sh
@@ -2,8 +2,6 @@
# use when you've got a file path in a variable, or in history, or in Alt+.,
# and want to quickly move to its containing directory. In the absence of an
# argument, this just shifts up a directory, i.e. `cd ..`
-#
-# Note this is equivalent to `ud 1`.
pd() {
# Check arguments; default to $PWD
diff --git a/sh/shrc.d/prompt.sh b/sh/shrc.d/prompt.sh
index cb32c113..72cf59b6 100644
--- a/sh/shrc.d/prompt.sh
+++ b/sh/shrc.d/prompt.sh
@@ -11,8 +11,7 @@ PS3='? '
unset PS4
PS4='+ '
-# If we have an SSH_CLIENT or SSH_CONNECTION environment variable, put the
-# hostname in PS1 too.
-if [ -n "$SSH_CLIENT" ] || [ -n "$SSH_CONNECTION" ] ; then
- PS1=$(hostname -s)'$ '
+# Prompt has hostname via SSH outside of screen/tmux
+if [ -n "$SSH_CLIENT" ] && [ -z "$STY" ] && [ -z "$TMUX" ] ; then
+ PS1=$(hostname -s)$PS1
fi
diff --git a/sh/shrc.d/rd.sh b/sh/shrc.d/rd.sh
index e6d761a6..3e1b4d9c 100644
--- a/sh/shrc.d/rd.sh
+++ b/sh/shrc.d/rd.sh
@@ -11,6 +11,7 @@
# $ rd usr opt
# $ pwd
# /opt/bin
+#
rd() {
# Check argument count
diff --git a/sh/shrc.d/sd.sh b/sh/shrc.d/sd.sh
index 10597832..1fe748c4 100644
--- a/sh/shrc.d/sd.sh
+++ b/sh/shrc.d/sd.sh
@@ -30,6 +30,7 @@
# /tmp/tmp.ZSunna5Eup/a
#
# Seems to work for symbolic links.
+#
sd() {
# Check argument count
diff --git a/sh/shrc.d/sudo.sh b/sh/shrc.d/sudo.sh
deleted file mode 100644
index d9e30bc4..00000000
--- a/sh/shrc.d/sudo.sh
+++ /dev/null
@@ -1,8 +0,0 @@
-# Add the -H parameter to sudo(8) calls, always use the target user's $HOME
-sudo() {
- case $1 in
- -v) ;;
- *) set -- -H "$@" ;;
- esac
- command sudo "$@"
-}
diff --git a/sh/shrc.d/tor.sh b/sh/shrc.d/tor.sh
new file mode 100644
index 00000000..e6e31341
--- /dev/null
+++ b/sh/shrc.d/tor.sh
@@ -0,0 +1,33 @@
+# Manage Torsocks for the current shell
+tor() {
+
+ # Check first argument to figure out operation
+ case $1 in
+
+ # Show whether Torsocks
+ show|'')
+ case $LD_PRELOAD: in
+ (*/libtorsocks.so:*)
+ printf 'on\n'
+ ;;
+ (*)
+ printf 'off\n'
+ ;;
+ esac
+ ;;
+
+ # Turn Torsocks on or off
+ on|off)
+ command -v torsocks >/dev/null 2>&1 || return
+ . "$(command -v torsocks)"
+ ;;
+
+ # Command not found
+ *)
+ printf >&2 \
+ 'tor(): %s: Unknown command (try "help")\n' \
+ "$1"
+ return 2
+ ;;
+ esac
+}
diff --git a/sh/shrc.d/which.sh b/sh/shrc.d/which.sh
index 9d8c899a..528e5048 100644
--- a/sh/shrc.d/which.sh
+++ b/sh/shrc.d/which.sh
@@ -1,3 +1,5 @@
+# Try to stop me using the non-standard `which`:
+# <http://mywiki.wooledge.org/BadUtils#which>
which() {
printf >&2 'Whichcraft detected! Did you mean: command -v %s\n' "$*"
return 2
diff --git a/sxhkd/sxhkdrc b/sxhkd/sxhkdrc
new file mode 100644
index 00000000..b4f823b6
--- /dev/null
+++ b/sxhkd/sxhkdrc
@@ -0,0 +1,53 @@
+super + Return
+ exec x-terminal-emulator
+
+super + {control,shift,alt} + Return
+ exec x-terminal-emulator -e {sh,ksh,zsh}
+
+super + b
+ exec x-www-browser
+
+super + d
+ exec rofi -modi drun -show drun
+
+super + g
+ exec xgoc
+
+super + i
+ exec gimp
+
+super + m
+ exec x-terminal-emulator -title tm -e tm
+
+super + p
+ exec rofi_pass
+
+super + shift + p
+ exec rofi_pass --login
+
+super + t
+ exec thunar
+
+super + v
+ exec x-terminal-emulator -title "$VISUAL" -e "$VISUAL"
+
+Print
+ exec xsnap
+
+control + Print
+ exec xsnap --freeze --select
+
+super + Print
+ exec xsnap --focused
+
+Pause
+ exec xlock
+
+XF86AudioMute
+ exec pactl set-sink-mute @DEFAULT_SINK@ toggle
+
+XF86Audio{Lower,Raise}Volume
+ exec pactl set-sink-volume @DEFAULT_SINK@ {-5%,+5%}
+
+XF86Calculator
+ exec x-terminal-emulator -title bcq -e bcq
diff --git a/sxhkd/xsession.d/sxhkd.sh b/sxhkd/xsession.d/sxhkd.sh
new file mode 100644
index 00000000..ca0e27e3
--- /dev/null
+++ b/sxhkd/xsession.d/sxhkd.sh
@@ -0,0 +1,2 @@
+# Start X hotkey daemon
+sxhkd &
diff --git a/systemd/parcimonie.service b/systemd/parcimonie.service
deleted file mode 100644
index a823b216..00000000
--- a/systemd/parcimonie.service
+++ /dev/null
@@ -1,8 +0,0 @@
-[Service]
-ExecStart=/home/tom/.local/bin/parcimonie
-Restart=always
-PrivateTmp=true
-NoNewPrivileges=true
-
-[Install]
-WantedBy=default.target
diff --git a/systemd/profile.d/systemd.sh b/systemd/profile.d/systemd.sh
new file mode 100644
index 00000000..b5f05c24
--- /dev/null
+++ b/systemd/profile.d/systemd.sh
@@ -0,0 +1,3 @@
+# Use $VISUAL for editing systemd unit files, not $EDITOR
+SYSTEMD_EDITOR=$VISUAL
+export SYSTEMD_EDITOR
diff --git a/systemd/user/notify-email@.service b/systemd/user/notify-email@.service
new file mode 100644
index 00000000..2d356c79
--- /dev/null
+++ b/systemd/user/notify-email@.service
@@ -0,0 +1,7 @@
+[Unit]
+Description=unit status mailer service for %i
+
+[Service]
+Type=oneshot
+ExecStart=sh -c 'systemctl --user status --full %i | mail -a "X-systemd: %H %m %b" -s "[systemd] %i failure" %u'
+TimeoutStartSec=1m
diff --git a/systemd/user/notify-email@.service.d/50-notify-email.conf b/systemd/user/notify-email@.service.d/50-notify-email.conf
new file mode 100644
index 00000000..dc548c73
--- /dev/null
+++ b/systemd/user/notify-email@.service.d/50-notify-email.conf
@@ -0,0 +1,2 @@
+[Unit]
+OnFailure=
diff --git a/systemd/user/run-.service.d/50-notify-email.conf b/systemd/user/run-.service.d/50-notify-email.conf
new file mode 100644
index 00000000..e5a45b8c
--- /dev/null
+++ b/systemd/user/run-.service.d/50-notify-email.conf
@@ -0,0 +1,5 @@
+[Unit]
+OnFailure=
+
+[Service]
+ExecStopPost=sh -c 'systemctl --user status --full %n | mail -a "X-systemd: %H %m %b" -s "[systemd] %n completed" %u'
diff --git a/systemd/user/service.d/50-notify-email.conf b/systemd/user/service.d/50-notify-email.conf
new file mode 100644
index 00000000..11b8b2f2
--- /dev/null
+++ b/systemd/user/service.d/50-notify-email.conf
@@ -0,0 +1,2 @@
+[Unit]
+OnFailure=notify-email@%N.service
diff --git a/terminfo/putty-256color.ti b/terminfo/putty-256color.ti
deleted file mode 100644
index 81d2b3f1..00000000
--- a/terminfo/putty-256color.ti
+++ /dev/null
@@ -1,7 +0,0 @@
-putty-256color| PuTTY with 256 colors,
- use=putty,
- colors#256,
- initc@,
- pairs#32767,
- setab=\E[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e48;5;%p1%d%;m,
- setaf=\E[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m,
diff --git a/terminfo/putty.ti b/terminfo/putty.ti
deleted file mode 100644
index 6c3bd69e..00000000
--- a/terminfo/putty.ti
+++ /dev/null
@@ -1,128 +0,0 @@
-putty| PuTTY,
- acsc=``aaffggjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~,
- am,
- bce,
- bel=^G,
- blink=\E[5m,
- bold=\E[1m,
- bw,
- cbt=\E[Z,
- ccc,
- civis=\E[?25l,
- clear=\E[H\E[J,
- cnorm=\E[?25h,
- colors#8,
- cr=^M,
- csr=\E[%i%p1%d;%p2%dr,
- cub1=^H,
- cub=\E[%p1%dD,
- cud1=\ED,
- cud=\E[%p1%dB,
- cuf1=\E[C,
- cuf=\E[%p1%dC,
- cup=\E[%i%p1%d;%p2%dH,
- cuu1=\EM,
- cuu=\E[%p1%dA,
- dch1=\E[P,
- dch=\E[%p1%dP,
- dispc=%?%p1%{8}%=%t\E%%G\342\227\230\E%%@%e%p1%{10}%=%t\E%%G\342\227\231\E%%@%e%p1%{12}%=%t\E%%G\342\231\0\E%%@%e%p1%{13}%=%t\E%%G\342\231\252\E%%@%e%p1%{14}%=%t\E%%G\342\231\253\E%%@%e%p1%{15}%=%t\E%%G\342\230\274\E%%@%e%p1%{27}%=%t\E%%G\342\206\220\E%%@%e%p1%{155}%=%t\E%%G\340\202\242\E%%@%e%p1%c%;,
- dl1=\E[M,
- dl=\E[%p1%dM,
- dsl=\E]0;\007,
- ech=\E[%p1%dX,
- ed=\E[J,
- el1=\E[1K,
- el=\E[K,
- enacs=\E(B\E)0,
- flash=\E[?5h\E[?5l,
- fsl=^G,
- home=\E[H,
- hpa=\E[%i%p1%dG,
- hs,
- ht=^I,
- hts=\EH,
- il1=\E[L,
- il=\E[%p1%dL,
- ind=^J,
- indn=\E[%p1%dS,
- initc=\E]P%p1%x%p2%{255}%*%{1000}%/%02x%p3%{255}%*%{1000}%/%02x%p4%{255}%*%{1000}%/%02x,
- is2=\E7\E[r\E[m\E[?7h\E[?1;4;6l\E[4l\E8\E>\E]R,
- it#8,
- kb2=\E[G,
- kbs=\177,
- kcbt=\E[Z,
- kcub1=\E[D,
- kcud1=\E[B,
- kcuf1=\E[C,
- kcuu1=\E[A,
- kdch1=\E[3~,
- kend=\E[4~,
- kf10=\E[21~,
- kf11=\E[23~,
- kf12=\E[24~,
- kf13=\E[25~,
- kf14=\E[26~,
- kf15=\E[28~,
- kf16=\E[29~,
- kf17=\E[31~,
- kf18=\E[32~,
- kf19=\E[33~,
- kf1=\E[11~,
- kf20=\E[34~,
- kf2=\E[12~,
- kf3=\E[13~,
- kf4=\E[14~,
- kf5=\E[15~,
- kf6=\E[17~,
- kf7=\E[18~,
- kf8=\E[19~,
- kf9=\E[20~,
- khome=\E[1~,
- kich1=\E[2~,
- kmous=\E[M,
- knp=\E[6~,
- kpp=\E[5~,
- kspd=^Z,
- mir,
- msgr,
- ncv#22,
- nel=^M^J,
- oc=\E]R,
- op=\E[39;49m,
- pairs#64,
- rc=\E8,
- rev=\E[7m,
- ri=\EM,
- rin=\E[%p1%dT,
- rmacs=^O,
- rmam=\E[?7l,
- rmcup=\E[2J\E[?47l,
- rmir=\E[4l,
- rmpch=\E[10m,
- rmso=\E[27m,
- rmul=\E[24m,
- rs2=\E<\E["p\E[50;6"p\Ec\E[?3l\E]R\E[?1000l,
- s0ds=\E[10m,
- s1ds=\E[11m,
- s2ds=\E[12m,
- sc=\E7,
- setab=\E[4%p1%dm,
- setaf=\E[3%p1%dm,
- sgr0=\E[m\017,
- sgr=\E[0%?%p1%p6%|%t;1%;%?%p2%t;4%;%?%p1%p3%|%t;7%;%?%p4%t;5%;m%?%p9%t\016%e\017%;,
- smacs=^N,
- smam=\E[?7h,
- smcup=\E[?47h,
- smir=\E[4h,
- smpch=\E[11m,
- smso=\E[7m,
- smul=\E[4m,
- tbc=\E[3g,
- tsl=\E]0;,
- u6=\E[%i%d;%dR,
- u7=\E[6n,
- u8=\E[?6c,
- u9=\E[c,
- vpa=\E[%i%p1%dd,
- xenl,
- xon,
diff --git a/terminfo/rxvt-256color.ti b/terminfo/rxvt-256color.ti
deleted file mode 100644
index 19057b84..00000000
--- a/terminfo/rxvt-256color.ti
+++ /dev/null
@@ -1,8 +0,0 @@
-rxvt-256color| rxvt with 256 colors,
- use=rxvt,
- ccc,
- colors#256,
- initc=\E]4;%p1%d;rgb\:%p2%{255}%*%{1000}%/%2.2X/%p3%{255}%*%{1000}%/%2.2X/%p4%{255}%*%{1000}%/%2.2X\E\\,
- pairs#32767,
- setab=\E[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e48;5;%p1%d%;m,
- setaf=\E[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m,
diff --git a/terminfo/rxvt-unicode-256color.ti b/terminfo/rxvt-unicode-256color.ti
deleted file mode 100644
index 62e6c021..00000000
--- a/terminfo/rxvt-unicode-256color.ti
+++ /dev/null
@@ -1,4 +0,0 @@
-rxvt-unicode-256color| rxvt-unicode with 256 colors,
- use=rxvt-unicode,
- colors#256,
- pairs#32767,
diff --git a/terminfo/rxvt-unicode.ti b/terminfo/rxvt-unicode.ti
deleted file mode 100644
index 3c4e0479..00000000
--- a/terminfo/rxvt-unicode.ti
+++ /dev/null
@@ -1,160 +0,0 @@
-rxvt-unicode| rxvt-unicode,
- acsc=+C\,D-A.B0E``aaffgghFiGjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~,
- am,
- bce,
- bel=^G,
- blink=\E[5m,
- bold=\E[1m,
- btns#5,
- bw,
- ccc,
- civis=\E[?25l,
- clear=\E[H\E[2J,
- cnorm=\E[?25h,
- colors#88,
- cols#80,
- cr=^M,
- csr=\E[%i%p1%d;%p2%dr,
- cub1=^H,
- cub=\E[%p1%dD,
- cud1=^J,
- cud=\E[%p1%dB,
- cuf1=\E[C,
- cuf=\E[%p1%dC,
- cup=\E[%i%p1%d;%p2%dH,
- cuu1=\E[A,
- cuu=\E[%p1%dA,
- cvvis=\E[?25h,
- dch1=\E[P,
- dch=\E[%p1%dP,
- dl1=\E[M,
- dl=\E[%p1%dM,
- dsl=\E]2;\007,
- ech=\E[%p1%dX,
- ed=\E[J,
- el1=\E[1K,
- el=\E[K,
- enacs=,
- eo,
- flash=\E[?5h$<20/>\E[?5l,
- fsl=^G,
- home=\E[H,
- hpa=\E[%i%p1%dG,
- hs,
- ht=^I,
- hts=\EH,
- ich1=\E[@,
- ich=\E[%p1%d@,
- il1=\E[L,
- il=\E[%p1%dL,
- ind=^J,
- indn=\E[%p1%dS,
- initc=\E]4;%p1%d;rgb\:%p2%{65535}%*%{1000}%/%4.4X/%p3%{65535}%*%{1000}%/%4.4X/%p4%{65535}%*%{1000}%/%4.4X\E\\,
- is1=\E[!p,
- is2=\E[r\E[m\E[2J\E[?7;25h\E[?1;3;4;5;6;9;66;1000;1001;1049l\E[4l,
- it#8,
- kDC=\E[3$,
- kEND=\E[8$,
- kHOM=\E[7$,
- kIC=\E[2$,
- kLFT=\E[d,
- kNXT=\E[6$,
- kPRV=\E[5$,
- kRIT=\E[c,
- ka1=\EOw,
- ka3=\EOy,
- kb2=\EOu,
- kbs=\177,
- kc1=\EOq,
- kc3=\EOs,
- kcbt=\E[Z,
- kcub1=\E[D,
- kcud1=\E[B,
- kcuf1=\E[C,
- kcuu1=\E[A,
- kdch1=\E[3~,
- kel=\E[8\^,
- kend=\E[8~,
- kent=\EOM,
- kf10=\E[21~,
- kf11=\E[23~,
- kf12=\E[24~,
- kf13=\E[25~,
- kf14=\E[26~,
- kf15=\E[28~,
- kf16=\E[29~,
- kf17=\E[31~,
- kf18=\E[32~,
- kf19=\E[33~,
- kf1=\E[11~,
- kf20=\E[34~,
- kf2=\E[12~,
- kf3=\E[13~,
- kf4=\E[14~,
- kf5=\E[15~,
- kf6=\E[17~,
- kf7=\E[18~,
- kf8=\E[19~,
- kf9=\E[20~,
- kfnd=\E[1~,
- khome=\E[7~,
- kich1=\E[2~,
- km,
- kmous=\E[M,
- knp=\E[6~,
- kpp=\E[5~,
- kslt=\E[4~,
- lines#24,
- lm#0,
- mc0=\E[i,
- mc4=\E[4i,
- mc5=\E[5i,
- mc5i,
- mir,
- msgr,
- ncv#0,
- npc,
- op=\E[39;49m,
- pairs#7744,
- rc=\E8,
- rev=\E[7m,
- ri=\EM,
- rin=\E[%p1%dT,
- ritm=\E[23m,
- rmacs=\E(B,
- rmam=\E[?7l,
- rmcup=\E[r\E[?1049l,
- rmir=\E[4l,
- rmkx=\E>,
- rmso=\E[27m,
- rmul=\E[24m,
- rs1=\Ec,
- rs2=\E[r\E[m\E[?7;25h\E[?1;3;4;5;6;9;66;1000;1001;1049l\E[4l,
- s0ds=\E(B,
- s1ds=\E(0,
- s2ds=\E*B,
- s3ds=\E+B,
- sc=\E7,
- setab=\E[48;5;%p1%dm,
- setaf=\E[38;5;%p1%dm,
- setb=%?%p1%{7}%>%t\E[48;5;%p1%dm%e\E[4%?%p1%{1}%=%t4%e%p1%{3}%=%t6%e%p1%{4}%=%t1%e%p1%{6}%=%t3%e%p1%d%;m%;,
- setf=%?%p1%{7}%>%t\E[38;5;%p1%dm%e\E[3%?%p1%{1}%=%t4%e%p1%{3}%=%t6%e%p1%{4}%=%t1%e%p1%{6}%=%t3%e%p1%d%;m%;,
- sgr0=\E[m\E(B,
- sgr=\E[0%?%p6%t;1%;%?%p2%t;4%;%?%p1%p3%|%t;7%;%?%p4%t;5%;%?%p7%t;8%;m%?%p9%t\E(0%e\E(B%;,
- sitm=\E[3m,
- smacs=\E(0,
- smam=\E[?7h,
- smcup=\E[?1049h,
- smir=\E[4h,
- smkx=\E=,
- smso=\E[7m,
- smul=\E[4m,
- tbc=\E[3g,
- tsl=\E]2;,
- u6=\E[%i%d;%dR,
- u7=\E[6n,
- u8=\E[?1;2c,
- u9=\E[c,
- vpa=\E[%i%p1%dd,
- xenl,
- xon,
diff --git a/terminfo/rxvt.ti b/terminfo/rxvt.ti
deleted file mode 100644
index 41cafa39..00000000
--- a/terminfo/rxvt.ti
+++ /dev/null
@@ -1,151 +0,0 @@
-rxvt| rxvt,
- acsc=``aaffggjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~,
- am,
- bce,
- bel=^G,
- blink=\E[5m,
- bold=\E[1m,
- civis=\E[?25l,
- clear=\E[H\E[2J,
- cnorm=\E[?25h,
- colors#8,
- cols#80,
- cr=^M,
- csr=\E[%i%p1%d;%p2%dr,
- cub1=^H,
- cub=\E[%p1%dD,
- cud1=^J,
- cud=\E[%p1%dB,
- cuf1=\E[C,
- cuf=\E[%p1%dC,
- cup=\E[%i%p1%d;%p2%dH,
- cuu1=\E[A,
- cuu=\E[%p1%dA,
- dl1=\E[M,
- dl=\E[%p1%dM,
- ed=\E[J,
- el1=\E[1K,
- el=\E[K,
- enacs=\E(B\E)0,
- eo,
- flash=\E[?5h\E[?5l,
- home=\E[H,
- hpa=\E[%i%p1%dG,
- ht=^I,
- hts=\EH,
- ich1=\E[@,
- ich=\E[%p1%d@,
- il1=\E[L,
- il=\E[%p1%dL,
- ind=^J,
- is1=\E[?47l\E=\E[?1l,
- is2=\E[r\E[m\E[2J\E[H\E[?7h\E[?1;3;4;6l\E[4l,
- it#8,
- kDC=\E[3$,
- kEND=\E[8$,
- kHOM=\E[7$,
- kLFT=\E[d,
- kNXT=\E[6$,
- kPRV=\E[5$,
- kRIT=\E[c,
- ka1=\EOw,
- ka3=\EOy,
- kb2=\EOu,
- kbs=\177,
- kc1=\EOq,
- kc3=\EOs,
- kcbt=\E[Z,
- kcub1=\E[D,
- kcud1=\E[B,
- kcuf1=\E[C,
- kcuu1=\E[A,
- kdch1=\E[3~,
- kel=\E[8\^,
- kend=\E[8~,
- kent=\EOM,
- kf10=\E[21~,
- kf11=\E[23~,
- kf12=\E[24~,
- kf13=\E[25~,
- kf14=\E[26~,
- kf15=\E[28~,
- kf16=\E[29~,
- kf17=\E[31~,
- kf18=\E[32~,
- kf19=\E[33~,
- kf1=\E[11~,
- kf20=\E[34~,
- kf21=\E[23$,
- kf22=\E[24$,
- kf23=\E[11\^,
- kf24=\E[12\^,
- kf25=\E[13\^,
- kf26=\E[14\^,
- kf27=\E[15\^,
- kf28=\E[17\^,
- kf29=\E[18\^,
- kf2=\E[12~,
- kf30=\E[19\^,
- kf31=\E[20\^,
- kf32=\E[21\^,
- kf33=\E[23\^,
- kf34=\E[24\^,
- kf35=\E[25\^,
- kf36=\E[26\^,
- kf37=\E[28\^,
- kf38=\E[29\^,
- kf39=\E[31\^,
- kf3=\E[13~,
- kf40=\E[32\^,
- kf41=\E[33\^,
- kf42=\E[34\^,
- kf43=\E[23@,
- kf44=\E[24@,
- kf4=\E[14~,
- kf5=\E[15~,
- kf6=\E[17~,
- kf7=\E[18~,
- kf8=\E[19~,
- kf9=\E[20~,
- kfnd=\E[1~,
- khome=\E[7~,
- kich1=\E[2~,
- km,
- kmous=\E[M,
- knp=\E[6~,
- kpp=\E[5~,
- kslt=\E[4~,
- lines#24,
- mir,
- msgr,
- ncv@,
- op=\E[39;49m,
- pairs#64,
- rc=\E8,
- rev=\E[7m,
- ri=\EM,
- rmacs=^O,
- rmcup=\E[2J\E[?47l\E8,
- rmir=\E[4l,
- rmkx=\E>,
- rmso=\E[27m,
- rmul=\E[24m,
- rs1=\E>\E[1;3;4;5;6l\E[?7h\E[m\E[r\E[2J\E[H,
- rs2=\E[r\E[m\E[2J\E[H\E[?7h\E[?1;3;4;6l\E[4l\E=\E[?1000l\E[?25h,
- s0ds=\E(B,
- s1ds=\E(0,
- sc=\E7,
- setab=\E[4%p1%dm,
- setaf=\E[3%p1%dm,
- sgr0=\E[m\017,
- sgr=\E[0%?%p6%t;1%;%?%p2%t;4%;%?%p1%p3%|%t;7%;%?%p4%t;5%;m%?%p9%t\016%e\017%;,
- smacs=^N,
- smcup=\E7\E[?47h,
- smir=\E[4h,
- smkx=\E=,
- smso=\E[7m,
- smul=\E[4m,
- tbc=\E[3g,
- vpa=\E[%i%p1%dd,
- xenl,
- xon,
diff --git a/terminfo/screen-256color.ti b/terminfo/screen-256color.ti
deleted file mode 100644
index 1cfabaf9..00000000
--- a/terminfo/screen-256color.ti
+++ /dev/null
@@ -1,7 +0,0 @@
-screen-256color| GNU Screen or tmux with 256 colors,
- use=screen,
- colors#256,
- initc@,
- pairs#32767,
- setab=\E[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e48;5;%p1%d%;m,
- setaf=\E[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m,
diff --git a/terminfo/screen.ti b/terminfo/screen.ti
deleted file mode 100644
index 3f51e9fd..00000000
--- a/terminfo/screen.ti
+++ /dev/null
@@ -1,100 +0,0 @@
-screen| GNU Screen or tmux,
- acsc=++\,\,--..00``aaffgghhiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~,
- am,
- bel=^G,
- blink=\E[5m,
- bold=\E[1m,
- cbt=\E[Z,
- civis=\E[?25l,
- clear=\E[H\E[J,
- cnorm=\E[34h\E[?25h,
- colors#8,
- cols#80,
- cr=^M,
- csr=\E[%i%p1%d;%p2%dr,
- cub1=^H,
- cub=\E[%p1%dD,
- cud1=^J,
- cud=\E[%p1%dB,
- cuf1=\E[C,
- cuf=\E[%p1%dC,
- cup=\E[%i%p1%d;%p2%dH,
- cuu1=\EM,
- cuu=\E[%p1%dA,
- cvvis=\E[34l,
- dch1=\E[P,
- dch=\E[%p1%dP,
- dl1=\E[M,
- dl=\E[%p1%dM,
- ed=\E[J,
- el1=\E[1K,
- el=\E[K,
- enacs=\E(B\E)0,
- flash=\Eg,
- home=\E[H,
- ht=^I,
- hts=\EH,
- ich=\E[%p1%d@,
- il1=\E[L,
- il=\E[%p1%dL,
- ind=^J,
- is2=\E)0,
- it#8,
- kbs=\177,
- kcbt=\E[Z,
- kcub1=\EOD,
- kcud1=\EOB,
- kcuf1=\EOC,
- kcuu1=\EOA,
- kdch1=\E[3~,
- kend=\E[4~,
- kf10=\E[21~,
- kf11=\E[23~,
- kf12=\E[24~,
- kf1=\EOP,
- kf2=\EOQ,
- kf3=\EOR,
- kf4=\EOS,
- kf5=\E[15~,
- kf6=\E[17~,
- kf7=\E[18~,
- kf8=\E[19~,
- kf9=\E[20~,
- khome=\E[1~,
- kich1=\E[2~,
- km,
- kmous=\E[M,
- knp=\E[6~,
- kpp=\E[5~,
- lines#24,
- mir,
- msgr,
- ncv@,
- nel=\EE,
- op=\E[39;49m,
- pairs#64,
- rc=\E8,
- rev=\E[7m,
- ri=\EM,
- ritm=\E[23m,
- rmacs=^O,
- rmcup=\E[?1049l,
- rmir=\E[4l,
- rmkx=\E[?1l\E>,
- rmso=\E[27m,
- rmul=\E[24m,
- rs2=\Ec\E[?1000l\E[?25h,
- sc=\E7,
- setab=\E[4%p1%dm,
- setaf=\E[3%p1%dm,
- sgr0=\E[m\017,
- sgr=\E[0%?%p6%t;1%;%?%p1%t;7%;%?%p2%t;4%;%?%p3%t;7%;%?%p4%t;5%;m%?%p9%t\016%e\017%;,
- sitm=\E[3m,
- smacs=^N,
- smcup=\E[?1049h,
- smir=\E[4h,
- smkx=\E[?1h\E=,
- smso=\E[7m,
- smul=\E[4m,
- tbc=\E[3g,
- xenl,
diff --git a/terminfo/tmux-256color.ti b/terminfo/tmux-256color.ti
deleted file mode 100644
index a242b7c1..00000000
--- a/terminfo/tmux-256color.ti
+++ /dev/null
@@ -1,6 +0,0 @@
-tmux-256color| tmux with 256 colors,
- use=tmux,
- colors#256,
- pairs#32767,
- setab=\E[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e48;5;%p1%d%;m,
- setaf=\E[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m,
diff --git a/terminfo/tmux.ti b/terminfo/tmux.ti
deleted file mode 100644
index fc86d773..00000000
--- a/terminfo/tmux.ti
+++ /dev/null
@@ -1,104 +0,0 @@
-tmux| tmux terminal multiplexer,
- acsc=++\,\,--..00``aaffgghhiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~,
- am,
- bel=^G,
- blink=\E[5m,
- bold=\E[1m,
- cbt=\E[Z,
- civis=\E[?25l,
- clear=\E[H\E[J,
- cnorm=\E[34h\E[?25h,
- colors#8,
- cols#80,
- cr=^M,
- csr=\E[%i%p1%d;%p2%dr,
- cub1=^H,
- cub=\E[%p1%dD,
- cud1=^J,
- cud=\E[%p1%dB,
- cuf1=\E[C,
- cuf=\E[%p1%dC,
- cup=\E[%i%p1%d;%p2%dH,
- cuu1=\EM,
- cuu=\E[%p1%dA,
- cvvis=\E[34l,
- dch1=\E[P,
- dch=\E[%p1%dP,
- dim=\E[2m,
- dl1=\E[M,
- dl=\E[%p1%dM,
- dsl=\E]0;\007,
- ed=\E[J,
- el1=\E[1K,
- el=\E[K,
- enacs=\E(B\E)0,
- flash=\Eg,
- fsl=^G,
- home=\E[H,
- hs,
- ht=^I,
- hts=\EH,
- ich=\E[%p1%d@,
- il1=\E[L,
- il=\E[%p1%dL,
- ind=^J,
- is2=\E)0,
- it#8,
- kbs=\177,
- kcbt=\E[Z,
- kcub1=\EOD,
- kcud1=\EOB,
- kcuf1=\EOC,
- kcuu1=\EOA,
- kdch1=\E[3~,
- kend=\E[4~,
- kf10=\E[21~,
- kf11=\E[23~,
- kf12=\E[24~,
- kf1=\EOP,
- kf2=\EOQ,
- kf3=\EOR,
- kf4=\EOS,
- kf5=\E[15~,
- kf6=\E[17~,
- kf7=\E[18~,
- kf8=\E[19~,
- kf9=\E[20~,
- khome=\E[1~,
- kich1=\E[2~,
- km,
- kmous=\E[M,
- knp=\E[6~,
- kpp=\E[5~,
- lines#24,
- mir,
- msgr,
- nel=\EE,
- op=\E[39;49m,
- pairs#64,
- rc=\E8,
- rev=\E[7m,
- ri=\EM,
- ritm=\E[23m,
- rmacs=^O,
- rmcup=\E[?1049l,
- rmir=\E[4l,
- rmkx=\E[?1l\E>,
- rmso=\E[27m,
- rmul=\E[24m,
- rs2=\Ec\E[?1000l\E[?25h,
- sc=\E7,
- setab=\E[4%p1%dm,
- setaf=\E[3%p1%dm,
- sgr0=\E[m\017,
- sgr=\E[0%?%p6%t;1%;%?%p1%t;3%;%?%p2%t;4%;%?%p3%t;7%;%?%p4%t;5%;%?%p5%t;2%;m%?%p9%t\016%e\017%;,
- sitm=\E[3m,
- smacs=^N,
- smcup=\E[?1049h,
- smir=\E[4h,
- smkx=\E[?1h\E=,
- smso=\E[7m,
- smul=\E[4m,
- tbc=\E[3g,
- tsl=\E]0;,
- xenl,
diff --git a/tidy/profile.d/tidy.sh b/tidy/profile.d/tidy.sh
index 177a8124..664a6536 100644
--- a/tidy/profile.d/tidy.sh
+++ b/tidy/profile.d/tidy.sh
@@ -1,3 +1,3 @@
# Set a configuration file path for tidy(1)
-HTML_TIDY=$HOME/.tidyrc
+HTML_TIDY=${XDG_CONFIG_HOME:-$HOME/.config}/tidy/tidyrc
export HTML_TIDY
diff --git a/tmux/bin/tmux.sh b/tmux/bin/tmux.sh
new file mode 100644
index 00000000..bbe11636
--- /dev/null
+++ b/tmux/bin/tmux.sh
@@ -0,0 +1,11 @@
+#
+# Simple wrapper to force acting only as client; can't do anything if the
+# server isn't actually running. The correct way to do this is of course
+# socket activation, but Debian's version doesn't have --enable-systemd yet.
+# This will do fine in the meantime.
+#
+if ! systemctl --user is-active --quiet tmux.service ; then
+ printf >&2 'tmux: server not running\n'
+ exit
+fi
+exec /usr/bin/tmux "$@"
diff --git a/tmux/profile.d/tmux.sh b/tmux/profile.d/tmux.sh
new file mode 100644
index 00000000..15ba00ff
--- /dev/null
+++ b/tmux/profile.d/tmux.sh
@@ -0,0 +1,4 @@
+# Encourage tmux to put its sockets into XDG_RUNTIME_DIR rather than /tmp
+[ -n "$XDG_RUNTIME_DIR" ] || return
+TMUX_TMPDIR=$XDG_RUNTIME_DIR
+export TMUX_TMPDIR
diff --git a/tmux/systemd/user/tmux.service b/tmux/systemd/user/tmux.service
new file mode 100644
index 00000000..404f1888
--- /dev/null
+++ b/tmux/systemd/user/tmux.service
@@ -0,0 +1,11 @@
+[Unit]
+Description=tmux server
+Documentation=man:tmux(1)
+
+[Service]
+ExecStart=/bin/sh -lc 'exec /usr/bin/tmux start-server \\; set-option -s exit-empty off'
+KillMode=mixed
+Type=forking
+
+[Install]
+WantedBy=default.target
diff --git a/tmux/tmux.conf b/tmux/tmux.conf
index 257cee5f..ad420528 100644
--- a/tmux/tmux.conf
+++ b/tmux/tmux.conf
@@ -1,20 +1,8 @@
-# Strip out a lot of machine and X11 dependent crap from the initial
-# environment
-set-environment -gru DISPLAY
-set-environment -gru SSH_CLIENT
-set-environment -gru SSH_CONNECTION
-set-environment -gru SSH_TTY
-set-environment -gru WINDOWID
-
-# Otherwise, use the environment we had when we started; don't touch it during
-# a session unless I specifically ask
-set-option -g update-environment 'COLORFGBG COLORTERM'
+# Don't update the environment from anywhere; too confusing
+set-option -g update-environment ''
# Setting this makes each new pane a non-login shell, which suits me better
-set-option -g default-command "$SHELL"
-
-# Expect a 256-color terminal
-set-option -g default-terminal 'tmux-256color'
+set-option -g default-command "exec $SHELL"
# Change the prefix to ^A rather than the default of ^B, because I'm a godless
# GNU Screen refugee, and also I like using ^B in my shell and in Vim more
@@ -69,7 +57,7 @@ bind-key s choose-session
set-option -g status-left '[#S] '
# Username, hostname, and the current date on the right side of the status bar
-set-option -g status-right ' [#H] %F %T'
+set-option -g status-right ' (mail:#(msc)) [#h] %F %T'
# Update the status bar every second
set-option -g status-interval 1
@@ -81,9 +69,6 @@ set-option -g base-index 1
# meta and prefer things to be snappier
set-option -g escape-time 0
-# Keep plenty of history
-set-option -g history-limit 100000
-
# Don't interfere with my system clipboard
set-option -g set-clipboard off
diff --git a/urxvt/ext/select.pl b/urxvt/ext/select.pl
deleted file mode 100644
index 90b13960..00000000
--- a/urxvt/ext/select.pl
+++ /dev/null
@@ -1,93 +0,0 @@
-# Tom Ryder's choice of selection behaviours for urxvt, butchered from included
-# URxvt extension scripts.
-
-# Force me to write this properly
-use strict;
-use warnings;
-use utf8;
-
-# Require at least this version of Perl
-use 5.006;
-
-# Use plain-English variable names
-use English qw(-no_match_vars);
-
-# Set version of this extension
-our $VERSION = 1.0;
-
-# On creation, read all of cutchars into a list of regex-quoted patterns
-sub on_init {
- my ($self) = @_;
- if ( defined( my $res = $self->resource('cutchars') ) ) {
- $res = $self->locale_decode($res);
- push @{ $self->{patterns} },
- qr{\G [\Q$res\E[:space:]]* ([^\Q$res\E[:space:]]+) }msx;
- }
- return ();
-}
-
-# Handle multiple-clicking selection extension
-sub on_sel_extend {
- my ($self) = @_;
-
- # Get attributes of the current selection
- my ( $row, $col ) = $self->selection_mark;
- my $line = $self->line($row);
- my $text = $line->t;
- my $markofs = $line->offset_of( $row, $col );
- my $curlen =
- $line->offset_of( $self->selection_end ) -
- $line->offset_of( $self->selection_beg );
-
- # Find all the possible matches
- my @matches;
- if ( $markofs < $line->l ) {
-
- # `perldoc -f study` says this does nothing useful anymore since
- # version 5.16
- study $text;
-
- for my $regex ( @{ $self->{patterns} } ) {
- while ( $text =~ m{$regex}gmsx ) {
- if ( $LAST_MATCH_START[1] <= $markofs
- and $markofs <= $LAST_MATCH_END[1] )
- {
- my $ofs = $LAST_MATCH_START[1];
- my $match = $1;
-
- push @matches, [ $ofs, length $match ];
- }
- }
- }
- }
-
- # If no more clever patterns matched, just snarf the whole line
- push @matches, [ 0, ( $line->end - $line->beg + 1 ) * $self->ncol ];
-
- # Iterate over the matches to choose the shortest one
- MATCH:
- for (
- sort { ## no critic (ProhibitReverseSortBlock)
- $a->[1] <=> $b->[1]
- or $b->[0] <=> $a->[0]
- } @matches
- )
- {
- my ( $ofs, $len ) = @{$_};
- next MATCH if $len <= $curlen;
- $self->selection_beg( $line->coord_of($ofs) );
- $self->selection_end( $line->coord_of( $ofs + $len ) );
- return 1;
- }
-
- # Done
- return ();
-}
-
-# Copy selections to CLIPBOARD as well as PRIMARY.
-sub on_sel_grab {
- my ( $self, $time ) = @_;
- $self->selection( $self->selection, 1 );
- $self->selection_grab( $time, 1 );
- return ();
-}
diff --git a/vim/after/ftplugin/gitcommit.vim b/vim/after/ftplugin/gitcommit.vim
index 4a1c3814..093dc5f5 100644
--- a/vim/after/ftplugin/gitcommit.vim
+++ b/vim/after/ftplugin/gitcommit.vim
@@ -4,13 +4,15 @@ setlocal formatoptions+=coqr
let b:undo_ftplugin .= '|setlocal comments< formatoptions<'
" Choose the color column depending on non-comment line count
-augroup gitcommit_cursorcolumn
- autocmd CursorMoved,CursorMovedI <buffer>
- \ let &l:colorcolumn = gitcommit#CursorColumn()
-augroup END
-let b:undo_ftplugin .= '|execute ''autocmd! gitcommit_cursorcolumn'''
- \ . '|augroup! gitcommit_cursorcolumn'
- \ . '|setlocal colorcolumn<'
+if exists('&colorcolumn')
+ augroup gitcommit_cursorcolumn
+ autocmd CursorMoved,CursorMovedI <buffer>
+ \ let &l:colorcolumn = gitcommit#CursorColumn()
+ augroup END
+ let b:undo_ftplugin .= '|execute ''autocmd! gitcommit_cursorcolumn'''
+ \ . '|augroup! gitcommit_cursorcolumn'
+ \ . '|setlocal colorcolumn<'
+endif
" Stop here if the user doesn't want ftplugin mappings
if exists('no_plugin_maps') || exists('no_gitcommit_maps')
diff --git a/vim/after/ftplugin/html.vim b/vim/after/ftplugin/html.vim
index 7e2ba439..21a84a42 100644
--- a/vim/after/ftplugin/html.vim
+++ b/vim/after/ftplugin/html.vim
@@ -4,7 +4,7 @@ if &filetype !=# 'html'
finish
endif
-" Spellcheck documents we're actually editing (not just viewing)
+" Check the spelling of documents we're actually editing (not just viewing)
if &modifiable && !&readonly
setlocal spell
let b:undo_ftplugin .= '|setlocal spell<'
diff --git a/vim/after/ftplugin/mail.vim b/vim/after/ftplugin/mail.vim
index 738f17ec..4c07bac3 100644
--- a/vim/after/ftplugin/mail.vim
+++ b/vim/after/ftplugin/mail.vim
@@ -1,3 +1,13 @@
+" Restore global value for no_mail_maps that we set in
+" ~/.vim/ftplugin/mail.vim to work around the bad maps set in
+" $VIMRUNTIME/ftplugin/mail.vim
+"
+if exists('b:no_mail_maps')
+ let no_mail_maps = b:no_mail_maps
+elseif exists('no_mail_maps')
+ unlet no_mail_maps
+endif
+
" Don't append spaces after quote chars, for strict compliance with
" format=flowed
let b:quote_space = 0
@@ -8,7 +18,7 @@ command -bar -buffer SuggestStart
let b:undo_ftplugin .= '|delcommand SuggestStart'
SuggestStart
-" Normalise quoting
+" Normalize quoting
command -bar -buffer -range=% StrictQuote
\ call mail#StrictQuote(<q-line1>, <q-line2>)
let b:undo_ftplugin .= '|delcommand StrictQuote'
@@ -66,9 +76,9 @@ let b:undo_ftplugin .= '|nunmap <buffer> <LocalLeader>Q'
\ . '|xunmap <buffer> <LocalLeader>Q'
" Mappings for enforcing strict quoting
-nnoremap <LocalLeader>s
+nnoremap <buffer> <LocalLeader>s
\ :StrictQuote<CR>
-xnoremap <LocalLeader>s
+xnoremap <buffer> <LocalLeader>s
\ :StrictQuote<CR>
let b:undo_ftplugin .= '|nunmap <buffer> <LocalLeader>s'
\ . '|xunmap <buffer> <LocalLeader>s'
diff --git a/vim/after/ftplugin/python.vim b/vim/after/ftplugin/python.vim
new file mode 100644
index 00000000..2ca1ae89
--- /dev/null
+++ b/vim/after/ftplugin/python.vim
@@ -0,0 +1,35 @@
+" The Python runtime files didn't define b:undo_ftplugin until Vim v8.1.1048;
+" if it's not set yet, set it here (to something innoccuous) so that the
+" appending :let commands in the rest of this file don't break.
+"
+if !exists('b:undo_ftplugin')
+ let b:undo_ftplugin = 'setlocal tabstop<'
+endif
+
+" Use pyflakes for syntax checking and autopep8 for tidying
+compiler pyflakes
+if executable('autopep8')
+ setlocal equalprg=autopep8\ -aaa\ --\ -
+ let b:undo_ftplugin .= '|setlocal equalprg<'
+endif
+
+" Stop here if the user doesn't want ftplugin mappings
+if exists('no_plugin_maps') || exists('no_python_maps')
+ finish
+endif
+
+" Mappings to choose compiler
+nnoremap <buffer> <LocalLeader>c
+ \ :<C-U>compiler pyflakes<CR>
+nnoremap <buffer> <LocalLeader>l
+ \ :<C-U>compiler pylint<CR>
+let b:undo_ftplugin .= '|nunmap <buffer> <LocalLeader>c'
+ \ . '|nunmap <buffer> <LocalLeader>l'
+
+" Mappings to choose 'equalprg'
+nnoremap <buffer> <LocalLeader>t
+ \ :<C-U>setlocal equalprg=autopep8\ -aaa\ --\ -<CR>
+nnoremap <buffer> <LocalLeader>i
+ \ :<C-U>setlocal equalprg<<CR>
+let b:undo_ftplugin .= '|nunmap <buffer> <LocalLeader>t'
+ \ . '|nunmap <buffer> <LocalLeader>i'
diff --git a/vim/after/ftplugin/vim.vim b/vim/after/ftplugin/vim.vim
index 01f971b9..112523da 100644
--- a/vim/after/ftplugin/vim.vim
+++ b/vim/after/ftplugin/vim.vim
@@ -26,9 +26,9 @@ let &l:include = '\<source\>\|\<runtime!\=\>'
" Search runtime paths for included scripts
let &l:path = &runtimepath . ',' . &path
-" Adjust the match words for the matchit plugin; the default filetype plugin
-" matches e.g. an opening "function" with the first "return" within, which I
-" don't like
+" Adjust the match words for the matchit.vim plugin; the default filetype
+" plugin matches e.g. an opening "function" with the first "return" within,
+" which I don't like
if exists('loaded_matchit')
let b:match_words = '\<fu\%[nction]\>:\<endf\%[unction]\>,'
\ . '\<\(wh\%[ile]\|for\)\>:\<end\(w\%[hile]\|fo\%[r]\)\>,'
diff --git a/vim/after/indent/vim.vim b/vim/after/indent/vim.vim
index da34eb75..4300e125 100644
--- a/vim/after/indent/vim.vim
+++ b/vim/after/indent/vim.vim
@@ -1,9 +1,9 @@
-" Use two (not four!) spaces for indentation, per convention
-call indent#Spaces(2)
-
" Remove inapplicable defaults from 'indentkeys'; we should only need to undo
" this if the stock plugin didn't already arrange that (before v7.3.539)
setlocal indentkeys-=0#,0{,0},0),:
if !exists('b:undo_indent')
let b:undo_indent = 'setlocal indentkeys<'
endif
+
+" Use two (not four!) spaces for indentation, per convention
+call indent#Spaces(2)
diff --git a/vim/after/indent/yaml.vim b/vim/after/indent/yaml.vim
new file mode 100644
index 00000000..d0478631
--- /dev/null
+++ b/vim/after/indent/yaml.vim
@@ -0,0 +1,2 @@
+" Use two (not four!) spaces for indentation, per convention
+call indent#Spaces(2)
diff --git a/vim/after/plugin/2html.vim b/vim/after/plugin/2html.vim
new file mode 100644
index 00000000..dd65486d
--- /dev/null
+++ b/vim/after/plugin/2html.vim
@@ -0,0 +1,11 @@
+" Don't make these settings if the base plugin didn't load
+if !exists('g:loaded_2html_plugin')
+ finish
+endif
+
+" Set preferred fonts for the HTML rendering
+let g:html_font = [
+ \ 'DejaVu Sans Mono',
+ \ 'Ubuntu Mono',
+ \ 'Consolas',
+ \]
diff --git a/vim/after/plugin/dist.vim b/vim/after/plugin/dist.vim
index 98574de8..c53ebd2c 100644
--- a/vim/after/plugin/dist.vim
+++ b/vim/after/plugin/dist.vim
@@ -7,3 +7,4 @@ unlet loaded_rrhelper
unlet loaded_spellfile_plugin
unlet loaded_tarPlugin
unlet loaded_zipPlugin
+unlet loaded_manpager_plugin
diff --git a/vim/after/plugin/insert_cancel.vim b/vim/after/plugin/insert_cancel.vim
new file mode 100644
index 00000000..a8abe6ed
--- /dev/null
+++ b/vim/after/plugin/insert_cancel.vim
@@ -0,0 +1,4 @@
+" Set mapping for insert_cancel.vim
+if exists('loaded_insert_cancel')
+ imap <C-C> <Plug>(InsertCancel)
+endif
diff --git a/vim/after/plugin/matchparen.vim b/vim/after/plugin/matchparen.vim
new file mode 100644
index 00000000..b2be8f61
--- /dev/null
+++ b/vim/after/plugin/matchparen.vim
@@ -0,0 +1,4 @@
+" If matchparen.vim didn't load, use 'showmatch' instead
+if !exists('loaded_matchparen')
+ set showmatch matchtime=3
+endif
diff --git a/vim/after/plugin/spellfile_local.vim b/vim/after/plugin/spellfile_local.vim
new file mode 100644
index 00000000..7d805660
--- /dev/null
+++ b/vim/after/plugin/spellfile_local.vim
@@ -0,0 +1,13 @@
+" Don't make these settings if the base plugin didn't load
+if !exists('g:loaded_spellfile_local')
+ finish
+endif
+
+" Use XDG dirs for 'spellfile' if XDG_DATA_HOME is useable
+if xdg#DataHome() !=# ''
+ let g:spellfile_local_dirs = [ xdg#DataHome() ]
+ call extend(
+ \ g:spellfile_local_dirs,
+ \ xdg#DataDirs(),
+ \)
+endif
diff --git a/vim/after/plugin/undofileskip.vim b/vim/after/plugin/undofileskip.vim
new file mode 100644
index 00000000..e7116940
--- /dev/null
+++ b/vim/after/plugin/undofileskip.vim
@@ -0,0 +1,7 @@
+" If undofileskip.vim loaded, add a few applicable paths to its list
+if !exists('g:undofileskip')
+ finish
+endif
+
+" Just split and copy 'backupskip'
+let g:undofileskip = option#Split(&backupskip)
diff --git a/vim/after/syntax/bindzone.vim b/vim/after/syntax/bindzone.vim
index 29d5f4b8..f95aff8f 100644
--- a/vim/after/syntax/bindzone.vim
+++ b/vim/after/syntax/bindzone.vim
@@ -1,5 +1,5 @@
-" Highlight TLSA and SSHFP records correctly
+" Highlight some newer/weirder records correctly
" <https://github.com/vim/vim/issues/220>
syn keyword zoneRRType
- \ contained TLSA SSHFP
+ \ contained CAA SSHFP TLSA
\ nextgroup=zoneRData skipwhite
diff --git a/vim/after/syntax/mail.vim b/vim/after/syntax/mail.vim
new file mode 100644
index 00000000..77c76f00
--- /dev/null
+++ b/vim/after/syntax/mail.vim
@@ -0,0 +1,3 @@
+" Don't spellcheck code in mail messages
+syntax region mailCode start='`' end='`' keepend contains=@NoSpell
+syntax region mailCodeBlock start=' \{4\}' end='$' contains=@NoSpell
diff --git a/vim/after/syntax/resolv.vim b/vim/after/syntax/resolv.vim
new file mode 100644
index 00000000..4c8ec165
--- /dev/null
+++ b/vim/after/syntax/resolv.vim
@@ -0,0 +1,6 @@
+" Over-simple but good-enough `nameserver` rule fix including IPv6
+" Version 1.4 of the syntax file has a more accurate fix
+if !has('patch-8.2.0380')
+ syntax clear resolvIPNameserver
+ syntax match resolvIPNameserver contained /[0-9.a-fA-F:]\+/
+endif
diff --git a/vim/after/syntax/sh.vim b/vim/after/syntax/sh.vim
index af7670d5..d7cf040d 100644
--- a/vim/after/syntax/sh.vim
+++ b/vim/after/syntax/sh.vim
@@ -16,11 +16,11 @@ elseif exists('b:is_posix')
endif
" The syntax highlighter seems to flag '/baz' in '"${foo:-"$bar"/baz}"' as an
-" error, which it isn't, at least in POSIX sh, Bash, and Ksh.
+" error, which it isn't, at least in POSIX sh, Bash, and Korn shell.
syntax clear shDerefWordError
-" The syntax highlighter doesn't match parens for subshells for 'if' tests
-" correctly if they're on separate lines. This happens enough that it's
+" The syntax highlighter doesn't match parentheses for subshells for 'if'
+" tests correctly if they're on separate lines. This happens enough that it's
" probably not worth keeping the error.
syntax clear shParenError
@@ -33,7 +33,7 @@ syntax clear shTestError
if exists('b:is_posix')
" Highlight some commands that are both defined by POSIX and builtin
- " commands in dash, as a rough but useable proxy for 'shell builtins'. This
+ " commands in dash, as a rough but usable proxy for 'shell builtins'. This
" list was mostly wrested from `man 1 dash`. Also include control structure
" keywords like `break`, `continue`, and `return`.
syntax clear shStatement
@@ -76,8 +76,8 @@ if exists('b:is_posix')
" Core syntax/sh.vim puts IFS and other variables that affect shell function
" in another color, but a subset of them actually apply to POSIX shell too
- " (and plain Bourne). These are selected by searching the POSIX manpages. I
- " added NLSPATH too, which wasn't in the original.
+ " (and plain Bourne). These are selected by searching the POSIX man pages.
+ " I added NLSPATH too, which wasn't in the original.
syntax clear shShellVariables
syntax cluster shCommandSubList add=shShellVariables
syntax keyword shShellVariables
diff --git a/vim/after/syntax/vim.vim b/vim/after/syntax/vim.vim
index 438ce596..bd7d8274 100644
--- a/vim/after/syntax/vim.vim
+++ b/vim/after/syntax/vim.vim
@@ -4,7 +4,7 @@ syntax clear vimCommentString
syntax clear vimCommentTitle
" Highlight :CompilerSet commands like :set/:setlocal, but only in compiler
-" scripts in recognisable paths
+" scripts in recognizable paths
if expand('%:p:h:t') ==# 'compiler'
\ && expand('%:e') ==# 'vim'
syntax keyword vimCommand contained
diff --git a/vim/autoload/argument.vim b/vim/autoload/argument.vim
deleted file mode 100644
index 85d75eb1..00000000
--- a/vim/autoload/argument.vim
+++ /dev/null
@@ -1,8 +0,0 @@
-" Escape a single argument for use on an Ex command line; essentially
-" a backport of fnameescape() for versions before v7.1.299
-"
-function! argument#Escape(argument) abort
- return exists('*fnameescape')
- \ ? fnameescape(a:argument)
- \ : escape(a:argument, "\n\r\t".' *?[{`$\%#''"|!<')
-endfunction
diff --git a/vim/autoload/diff.vim b/vim/autoload/diff.vim
index 29389b95..6e87b62a 100644
--- a/vim/autoload/diff.vim
+++ b/vim/autoload/diff.vim
@@ -1,7 +1,7 @@
" Move between diff block headers
function! diff#MoveBlock(count, up, visual) abort
- " Reselect visual selection
+ " Re-select visual selection
if a:visual
normal! gv
endif
diff --git a/vim/autoload/filetype/repeat.vim b/vim/autoload/filetype/repeat.vim
index f681932b..899bbcc4 100644
--- a/vim/autoload/filetype/repeat.vim
+++ b/vim/autoload/filetype/repeat.vim
@@ -53,7 +53,7 @@ function! filetype#repeat#Sudo() abort
elseif fn =~# '/[^/]\+\.\w\{8}$'
let fn = expand('<afile>:r')
- " Unrecognised pattern; return, don't repeat
+ " Unrecognized pattern; return, don't repeat
else
return
endif
diff --git a/vim/autoload/fortune.vim b/vim/autoload/fortune.vim
deleted file mode 100644
index da6e2fa3..00000000
--- a/vim/autoload/fortune.vim
+++ /dev/null
@@ -1,59 +0,0 @@
-" Declare paths to check for fortune files
-let s:paths = [
- \ $HOME.'/.fortunes',
- \ $HOME.'/.local/share/games/fortunes',
- \]
-
-" List of executables for which we need to check
-let s:executables = [
- \ 'fortune',
- \ 'timeout',
- \]
-
-" Entry point for plugin
-function! fortune#() abort
-
- " Check we have all of the executables we need
- for executable in s:executables
- if !executable(executable)
- echoerr 'Missing executable "'.executable.'"'
- endif
- endfor
-
- " Maximum length of fortunes is the width of the screen minus 1; characters
- " wider than one column will break this
- "
- let limit = &columns - 1
-
- " Some implementations of fortune(6) thrash the disk if they can't meet the
- " length limit, so we need to rap this invocation in a timeout(1) call
- let command = [
- \ 'timeout',
- \ '0.3s',
- \ 'fortune',
- \ '-s',
- \ '-n',
- \ limit,
- \]
-
- " Find a path for custom fortunes and add it on to the command if found
- for path in s:paths
- if isdirectory(path)
- call add(command, path)
- break
- endif
- endfor
-
- " Run the command and condense any control or space character groups into
- " just one space
- let fortune = substitute(
- \ system(join(command)),
- \ '[[:cntrl:][:space:]]\+',
- \ ' ',
- \ 'g',
- \)
-
- " Show the fortune message!
- echomsg fortune
-
-endfunction
diff --git a/vim/autoload/has.vim b/vim/autoload/has.vim
deleted file mode 100644
index 162e4929..00000000
--- a/vim/autoload/has.vim
+++ /dev/null
@@ -1,34 +0,0 @@
-" Wrapper to backport the nicer has() syntax for simultaneous version and
-" patch level checking that was introduced in v7.4.236 and fixed in v7.4.237.
-"
-" * <https://github.com/vim/vim/releases/tag/v7.4.236>
-" * <https://github.com/vim/vim/releases/tag/v7.4.237>
-"
-function! has#(feature) abort
-
- " If we're new enough, we can just run the native has()
- if has('patch-7.4.237')
- return has(a:feature)
- endif
-
- " Otherwise, we have to break down the pattern and do manual version and
- " patch level checks; if it doesn't match the patch syntax, just return what
- " the native has() does
- "
- let feature = a:feature
- let pattern = '^patch-\(\d\+\)\.\(\d\+\)\.\(\d\+\)$'
- let matchlist = matchlist(feature, pattern)
- if empty(matchlist)
- return has(a:feature)
- endif
- let [major, minor, patch] = matchlist[1:3]
-
- " The v:version variable looks like e.g. 801 for v8.1
- let l:version = major * 100 + minor
-
- " Compare the version numbers, and then the patch level if they're the same
- return v:version != l:version
- \ ? v:version > l:version
- \ : has('patch-'.patch)
-
-endfunction
diff --git a/vim/autoload/html/timestamp.vim b/vim/autoload/html/timestamp.vim
index 9de19aa0..8f250710 100644
--- a/vim/autoload/html/timestamp.vim
+++ b/vim/autoload/html/timestamp.vim
@@ -34,7 +34,7 @@ function! s:Timestamp(time) abort
endfunction
" Define timestamp prefix string
-let s:prefix = '<strong>Last updated:</strong> '
+let s:prefix = 'Last updated: '
" Define pattern to match date timestamps; no ZALGO, please
let s:pattern = '\m\C'
@@ -69,6 +69,6 @@ function! html#timestamp#Update() abort
" Apply the updated timestamp
let line = getline(lnum)
let line = substitute(line, s:pattern, update, '')
- call setline(lnum, line)
+ keepjumps call setline(lnum, line)
endfunction
diff --git a/vim/autoload/indent.vim b/vim/autoload/indent.vim
index d597653f..19a9f03d 100644
--- a/vim/autoload/indent.vim
+++ b/vim/autoload/indent.vim
@@ -10,7 +10,7 @@ function! indent#Spaces(...) abort
" If we have the patch that supports it, set 'softtabstop' to dynamically
" mirror the value of 'shiftwidth'; failing that, just copy it
- let &l:softtabstop = has#('patch-7.3.693')
+ let &l:softtabstop = patch#('7.3.693')
\ ? -1
\ : &l:shiftwidth
@@ -19,27 +19,17 @@ endfunction
" Set the current buffer to tab indent
function! indent#Tabs() abort
- setlocal noexpandtab
- setlocal shiftwidth< softtabstop<
+ setlocal noexpandtab shiftwidth< softtabstop<
call indent#Undo()
endfunction
" Add commands to b:undo_indent to clean up buffer-local indentation changes
" on a change of filetype
function! indent#Undo() abort
-
- " Check and set a flag so that we only do this once per buffer
- if exists('b:undo_indent_type_set')
- return
- endif
- let b:undo_indent_type_set = 1
-
- " Either set or append relevant commands to b:undo_indent
- let l:undo = 'setlocal expandtab< shiftwidth< softtabstop< tabstop<'
+ let undo = 'setlocal expandtab< shiftwidth< softtabstop<'
if exists('b:undo_indent')
- let b:undo_indent .= '|'.l:undo
+ let b:undo_indent .= '|'.undo
else
- let b:undo_indent = l:undo
+ let b:undo_indent = undo
endif
-
endfunction
diff --git a/vim/autoload/mail.vim b/vim/autoload/mail.vim
index cd585af4..6d4874ca 100644
--- a/vim/autoload/mail.vim
+++ b/vim/autoload/mail.vim
@@ -1,7 +1,7 @@
" Move through quoted paragraphs like normal-mode `{` and `}`
function! mail#NewBlank(count, up, visual) abort
- " Reselect visual selection
+ " Re-select visual selection
if a:visual
normal! gv
endif
@@ -61,7 +61,7 @@ function! mail#StrictQuote(start, end) abort
continue
endif
- " Normalise the quote with no spaces
+ " Normalize the quote with no spaces
let quote = substitute(quote, '[^>]', '', 'g')
" Re-set the line
diff --git a/vim/autoload/mail/header/field.vim b/vim/autoload/mail/header/field.vim
index e27d13c0..db38c09f 100644
--- a/vim/autoload/mail/header/field.vim
+++ b/vim/autoload/mail/header/field.vim
@@ -9,7 +9,7 @@ function! mail#header#field#Add(header, name, body) abort
endfunction
" Set a field in a header, replacing the first one with the same name (if
-" any), and and removing any others
+" any), and removing any others
"
function! mail#header#field#Set(header, name, body) abort
let fields = []
diff --git a/vim/autoload/option.vim b/vim/autoload/option.vim
index 5ff44ced..49fbf1a4 100644
--- a/vim/autoload/option.vim
+++ b/vim/autoload/option.vim
@@ -7,5 +7,11 @@ function! option#Split(expr, ...) abort
endif
let keepempty = a:0 ? a:1 : 0
let parts = split(a:expr, '\\\@<!,[, ]*', keepempty)
- return map(parts, 'substitute(v:val, ''\\,'', '','', ''g'')')
+ return map(copy(parts), 'substitute(v:val, ''\\,'', '','', ''g'')')
+endfunction
+
+" Escape the right-hand side of a :set option value
+"
+function! option#Escape(expr) abort
+ return escape(a:expr, ' |"\')
endfunction
diff --git a/vim/autoload/patch.vim b/vim/autoload/patch.vim
new file mode 100644
index 00000000..3a17ccda
--- /dev/null
+++ b/vim/autoload/patch.vim
@@ -0,0 +1,35 @@
+" Wrapper to emulate the nicer has() syntax for simultaneous version and patch
+" level checking that was introduced in v7.4.236 and fixed in v7.4.237.
+"
+" * <https://github.com/vim/vim/releases/tag/v7.4.236>
+" * <https://github.com/vim/vim/releases/tag/v7.4.237>
+"
+function! patch#(version) abort
+
+ " If the Vim running is new enough for its has() function to support
+ " checking patch levels with version prefixes, we can just add a "patch-"
+ " prefix to the query, and pass it on to has().
+ "
+ if has('patch-7.4.237')
+ return has('patch-'.a:version)
+ endif
+
+ " Failing that, we need to do our own version number and patch number
+ " comparisons; split the queried version on dots.
+ "
+ let [major, minor, patch] = split(a:version, '\.')
+
+ " The internal variable v:version describing the running Vim looks like
+ " e.g. 801 for v8.1; reproduce that logic for the queried version.
+ "
+ let l:version = major * 100 + minor
+
+ " If the running version number is the same as the required one, return
+ " whether we have the specific patch requested; otherwise, return whether
+ " the running version number is greater than the required one.
+ "
+ return v:version == l:version
+ \ ? has('patch-'.patch)
+ \ : v:version > l:version
+
+endfunction
diff --git a/vim/autoload/path.vim b/vim/autoload/path.vim
deleted file mode 100644
index e230cab2..00000000
--- a/vim/autoload/path.vim
+++ /dev/null
@@ -1,14 +0,0 @@
-" Create all the directories needed for a path, with optional flag for
-" owner-only permissions
-function! path#Create(name, ...) abort
- if a:0 > 2
- echoerr 'Too many arguments'
- endif
- if isdirectory(a:name)
- return 1
- endif
- let name = a:name
- let path = 'p'
- let prot = a:0 == 1 && a:1 ? 0700 : 0755
- return mkdir(name, path, prot)
-endfunction
diff --git a/vim/autoload/plugin.vim b/vim/autoload/plugin.vim
deleted file mode 100644
index 629a4367..00000000
--- a/vim/autoload/plugin.vim
+++ /dev/null
@@ -1,7 +0,0 @@
-" Check whether plugins are enabled and a specific named plugin (excluding
-" extension .vim) is available somewhere within 'runtimepath'
-"
-function! plugin#Ready(name) abort
- return &loadplugins
- \ && globpath(&runtimepath, 'plugin/'.a:name.'.vim') !=# ''
-endfunction
diff --git a/vim/autoload/put_date.vim b/vim/autoload/put_date.vim
deleted file mode 100644
index b0b0b548..00000000
--- a/vim/autoload/put_date.vim
+++ /dev/null
@@ -1,24 +0,0 @@
-" RFC2822 format string for strftime()
-let s:rfc_2822 = '%a, %d %b %Y %T %z'
-
-" Write a date to the buffer, UTC or local, in the specified format,
-" defaulting to RFC2822; formats are provided without the leading % signs
-" before each letter, like PHP date()
-"
-function! put_date#(line, utc, format) abort
- let line = a:line
- let utc = a:utc
- let format = strlen(a:format)
- \ ? substitute(a:format, '\a', '%&', 'g')
- \ : s:rfc_2822
- if utc
- if exists('$TZ')
- let tz = $TZ
- endif
- let $TZ = 'UTC'
- endif
- execute line.'put =strftime(format)'
- if exists('tz')
- let $TZ = tz
- endif
-endfunction
diff --git a/vim/autoload/quote.vim b/vim/autoload/quote.vim
index 690ba2db..7574ed71 100644
--- a/vim/autoload/quote.vim
+++ b/vim/autoload/quote.vim
@@ -24,8 +24,8 @@ function! quote#QuoteOpfunc(type) abort
continue
endif
- " If configured to do so, add a a space after the quote character, but
- " only if this line isn't already quoted
+ " If configured to do so, add a space after the quote character, but only
+ " if this line isn't already quoted
let new = char
if space && cur[0] != char
let new .= ' '
diff --git a/vim/autoload/xdg.vim b/vim/autoload/xdg.vim
new file mode 100644
index 00000000..cb7adcf5
--- /dev/null
+++ b/vim/autoload/xdg.vim
@@ -0,0 +1,67 @@
+" <https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html#variables>
+let s:defaults = {
+ \ 'XDG_CACHE_HOME': $HOME.'/.cache',
+ \ 'XDG_CONFIG_HOME': $HOME.'/.config',
+ \ 'XDG_CONFIG_DIRS': '/etc/xdg',
+ \ 'XDG_DATA_HOME': $HOME.'/.local/share',
+ \ 'XDG_DATA_DIRS': '/usr/local/share:/usr/share',
+ \ 'XDG_STATE_HOME': $HOME.'/.local/state',
+ \}
+
+function! s:Get(name) abort
+ let name = a:name
+ if !has_key(s:defaults, name)
+ throw 'Illegal XDG basedirs env var name'
+ endif
+ let value = s:defaults[name]
+ if exists('$'.a:name)
+ execute 'let value = $'.a:name
+ endif
+ return value
+endfunction
+
+function! s:Absolute(path) abort
+ return a:path =~# '^/'
+ \ || a:path =~# '^\~/'
+ \ || a:path ==# '~'
+endfunction
+
+function! s:Home(name) abort
+ let home = s:Get(a:name)
+ if !s:Absolute(home)
+ return ''
+ endif
+ return home.'/vim'
+endfunction
+
+function! s:Dirs(name) abort
+ let dirs = split(s:Get(a:name), ':')
+ return map(
+ \ filter(copy(dirs), 's:Absolute(v:val)')
+ \,'v:val.''/vim'''
+ \)
+endfunction
+
+function! xdg#CacheHome() abort
+ return has('unix') ? s:Home('XDG_CACHE_HOME') : ''
+endfunction
+
+function! xdg#ConfigHome() abort
+ return has('unix') ? s:Home('XDG_CONFIG_HOME') : ''
+endfunction
+
+function! xdg#DataHome() abort
+ return has('unix') ? s:Home('XDG_DATA_HOME') : ''
+endfunction
+
+function! xdg#StateHome() abort
+ return has('unix') ? s:Home('XDG_STATE_HOME') : ''
+endfunction
+
+function! xdg#ConfigDirs() abort
+ return has('unix') ? s:Dirs('XDG_CONFIG_DIRS') : []
+endfunction
+
+function! xdg#DataDirs() abort
+ return has('unix') ? s:Dirs('XDG_DATA_DIRS') : []
+endfunction
diff --git a/vim/bundle/copy_linebreak b/vim/bundle/copy_linebreak
-Subproject 6692eef760ccfc2e1b888d1d604e3e1a156fcbc
+Subproject a0004c18da5f524f62e2da6e19be1a51ce282f3
diff --git a/vim/bundle/cursorline_current b/vim/bundle/cursorline_current
-Subproject 4ab61f5dfa9a2868c529c75a50219dac6619080
+Subproject d1b8db2fe6b06bd556c777c7bd9d4632f12a3a1
diff --git a/vim/bundle/detect_indent b/vim/bundle/detect_indent
new file mode 160000
+Subproject 96f46cae148517e4b8e8a5bbe13b623ddde6b70
diff --git a/vim/bundle/html_spelllang b/vim/bundle/html_spelllang
new file mode 160000
+Subproject 161e47f00cd5a1bdcef61097b7ba100ffd69a48
diff --git a/vim/bundle/paste_insert b/vim/bundle/paste_insert
-Subproject 0365dd11c050f885050cd6dd22405c81aba5f46
+Subproject 1ffcb96611315dd068b734d5aae7ff07fa2b3a2
diff --git a/vim/bundle/put_date b/vim/bundle/put_date
new file mode 160000
+Subproject fa0b0289b80fadbe9af87ca2faa3b5da4512d3f
diff --git a/vim/bundle/redact_pass b/vim/bundle/redact_pass
-Subproject 337e7498e2b483e79c9abb33a2feb670655b23d
+Subproject 403a44dc32533e631384dfcca40d520b9088b0d
diff --git a/vim/bundle/spellfile_local b/vim/bundle/spellfile_local
-Subproject 16dbdc90b39c1ebf43ca1881a493edc816d2d9f
+Subproject 6199ee785c6fb964292ec6e82c5b8a0f79e2606
diff --git a/vim/bundle/squeeze_repeat_blanks b/vim/bundle/squeeze_repeat_blanks
-Subproject 8c849183f8723086e6b61a0644292bdb1ad99c1
+Subproject 27dd1b5858b4839b34249c106d2b3963a3da416
diff --git a/vim/bundle/strip_trailing_whitespace b/vim/bundle/strip_trailing_whitespace
-Subproject 90e60095bcfcfeb60bea60ba7f51bbfac3bf469
+Subproject 03782cdaf9db6329665316e1dc2d1b8270714a3
diff --git a/vim/bundle/undofileskip b/vim/bundle/undofileskip
new file mode 160000
+Subproject 1d0a5cf3aa1bf1f360862819d229d756958df32
diff --git a/vim/compiler/pyflakes.vim b/vim/compiler/pyflakes.vim
new file mode 100644
index 00000000..727fbd76
--- /dev/null
+++ b/vim/compiler/pyflakes.vim
@@ -0,0 +1,9 @@
+" :compiler support for Python syntax checking with pyflakes
+" <https://pypi.org/project/pyflakes/>
+if exists('current_compiler') || &compatible || !has('patch-7.4.191')
+ finish
+endif
+let current_compiler = 'pyflakes'
+
+CompilerSet makeprg=pyflakes\ %:S
+CompilerSet errorformat=%f:%l:%c:\ %m
diff --git a/vim/compiler/pylint.vim b/vim/compiler/pylint.vim
new file mode 100644
index 00000000..589f78e3
--- /dev/null
+++ b/vim/compiler/pylint.vim
@@ -0,0 +1,9 @@
+" :compiler support for Python linting with pylint
+" <https://pypi.org/project/pyflakes/>
+if exists('current_compiler') || &compatible || !has('patch-7.4.191')
+ finish
+endif
+let current_compiler = 'pylint'
+
+CompilerSet makeprg=pylint\ --output-format=parseable\ --score=n\ %:S
+CompilerSet errorformat=%f:%l:\ %m
diff --git a/vim/filetype.vim b/vim/filetype.vim
index 137d1cf5..eea7f1f5 100644
--- a/vim/filetype.vim
+++ b/vim/filetype.vim
@@ -24,6 +24,7 @@ augroup filetypedetect
" Apache config
autocmd BufNewFile,BufRead
\ .htaccess
+ \,htaccess
\,*/apache*/?*.conf
\ setfiletype apache
" Assembly language files
@@ -67,6 +68,16 @@ augroup filetypedetect
autocmd BufNewFile,BufRead
\ ?*.csv
\ setfiletype csv
+ " Debian package sources
+ autocmd BufNewFile,BufRead
+ \ sources.list
+ \,*/etc/apt/sources.list.d/*.list
+ \ setfiletype debsources
+ " Desktop files
+ autocmd BufNewFile,BufRead
+ \ ?*.desktop
+ \,?*.directory
+ \ setfiletype desktop
" Diff and patch files
autocmd BufNewFile,BufRead
\ ?*.diff
@@ -76,6 +87,7 @@ augroup filetypedetect
" INI format files
autocmd BufNewFile,BufRead
\ ?*.ini
+ \,.editorconfig
\,perlcriticrc
\,.perlcriticrc
\ setfiletype dosini
@@ -83,6 +95,10 @@ augroup filetypedetect
autocmd BufNewFile,BufRead
\ ?*.dot
\ setfiletype dot
+ " NFS exports
+ autocmd BufNewFile,BufRead
+ \ exports
+ \ setfiletype exports
" Forth
autocmd BufNewFile,BufRead
\ ?*.fs,?*.ft
@@ -95,11 +111,18 @@ augroup filetypedetect
autocmd BufNewFile,BufRead
\ .gdbinit
\ setfiletype gdb
+ " Gemini markup
+ autocmd BufNewFile,BufRead
+ \ *.gmi
+ \,*.gemini
+ \ setfiletype gemtext
" Git commit messages
autocmd BufNewFile,BufRead
\ COMMIT_EDITMSG
+ \,EDIT_DESCRIPTION
\,MERGE_MSG
\,TAG_EDITMSG
+ \,NOTES_EDITMSG
\ setfiletype gitcommit
" Git config files
autocmd BufNewFile,BufRead
@@ -107,6 +130,7 @@ augroup filetypedetect
\,.gitconfig
\,.gitmodules
\,gitconfig
+ \,*/.config/git/config
\ setfiletype gitconfig
" Git rebase manifests
autocmd BufNewFile,BufRead
@@ -117,26 +141,29 @@ augroup filetypedetect
\ *gnupg/options
\,*gnupg/gpg.conf
\ setfiletype gpg
+ " Golang
+ autocmd BufNewFile,BufRead
+ \ ?*.go
+ \ setfiletype go
" UNIX group file
autocmd BufNewFile,BufRead
- \ /etc/group
- \,/etc/group-
- \,/etc/group.edit
- \,/etc/gshadow
- \,/etc/gshadow-
- \,/etc/gshadow.edit
+ \ */etc/group
+ \,*/etc/group-
+ \,*/etc/group.edit
+ \,*/etc/gshadow
+ \,*/etc/gshadow-
+ \,*/etc/gshadow.edit
\ setfiletype group
" GTK settings files
autocmd BufNewFile,BufRead
- \ .gktrc*,
- \,gktrc*
+ \ .gtkrc*
+ \,gtkrc*
\ setfiletype gtkrc
" Vim help files
autocmd BufNewFile,BufRead
- \ ~/.vim/doc/?*.txt
+ \ */*.vim/doc/?*.txt
\,*/vim-*/doc/?*.txt
\,*/vim/*/doc/?*.txt
- \,*/*.vim/doc/?*.txt
\,$VIMRUNTIME/doc/?*.txt
\ setfiletype help
" HTML files
@@ -146,7 +173,7 @@ augroup filetypedetect
\ setfiletype html
" hosts(5) file
autocmd BufNewFile,BufRead
- \ /etc/hosts
+ \ */etc/hosts
\ setfiletype hostconf
" inittab(5) files
autocmd BufNewFile,BufRead
@@ -157,6 +184,10 @@ augroup filetypedetect
\ ?*.java
\,?*.jav
\ setfiletype java
+ " Jinja2 templates
+ autocmd BufNewFile,BufRead
+ \ ?*.j2
+ \ setfiletype jinja2
" JSON files
autocmd BufNewFile,BufRead
\ ?*.js
@@ -170,6 +201,11 @@ augroup filetypedetect
\ ?*.l
\,?*.lex
\ setfiletype lex
+ " limits.conf(5) files
+ autocmd BufNewFile,BufRead
+ \ limits.conf
+ \,*/limits.d/*.conf
+ \ setfiletype limits
" Lisp
autocmd BufNewFile,BufRead
\ ?*.lisp
@@ -177,10 +213,19 @@ augroup filetypedetect
\,.emacs
\,emacs
\ setfiletype lisp
+ " Login configuration
+ autocmd BufNewFile,BufRead
+ \ */etc/login.defs
+ \ setf logindefs
" Lua files
autocmd BufNewFile,BufRead
\ ?*.lua
\ setfiletype lua
+ " Lynx configuration
+ au BufNewFile,BufRead
+ \ lynx.cfg
+ \,.lynxrc
+ \ setfiletype lynx
" m4 files
autocmd BufNewFile,BufRead
\ ?*.m4
@@ -190,10 +235,15 @@ augroup filetypedetect
\ ?*.msg
\,mutt-*-[0-9]\+-[0-9]\+-[0-9]\+
\ setfiletype mail
- " Mail messages
+ " Mail aliases
autocmd BufNewFile,BufRead
\ aliases
\ setfiletype mailaliases
+ " Mailcap (MIME app reference) files
+ autocmd BufNewFile,BufRead
+ \ mailcap
+ \,.mailcap
+ \ setfiletype mailcap
" Makefiles
autocmd BufNewFile,BufRead
\ Makefile
@@ -205,13 +255,24 @@ augroup filetypedetect
\ ?*.markdown
\,?*.md
\ setfiletype markdown
+ " Meson configuration
+ autocmd BufNewFile,BufRead
+ \ meson.build
+ \,meson_options.txt
+ \ setfiletype meson
+ " SNMP MIB files
+ autocmd BufNewFile,BufRead
+ \ *.mib
+ \,*.my
+ \ setfiletype mib
" Mutt configuration files
autocmd BufNewFile,BufRead
\ Muttrc
- \,*/.muttrc.d/*.rc
+ \,*/.muttrc.d/?*.rc
+ \,*/muttrc.d/?*.rc
\,.muttrc
\,muttrc
- \,/etc/Muttrc.d/*
+ \,*/etc/Muttrc.d/*
\ setfiletype muttrc
" BIND configuration file
autocmd BufNewFile,BufRead
@@ -237,14 +298,18 @@ augroup filetypedetect
\ setfiletype nroff
" UNIX password and shadow files
autocmd BufNewFile,BufRead
- \ /etc/passwd
- \,/etc/passwd-
- \,/etc/passwd.edit
- \,/etc/shadow
- \,/etc/shadow-
- \,/etc/shadow.edit
+ \ */etc/passwd
+ \,*/etc/passwd-
+ \,*/etc/passwd.edit
+ \,*/etc/shadow
+ \,*/etc/shadow-
+ \,*/etc/shadow.edit
\ setfiletype passwd
- " Perl 5 files
+ " Packet capture files
+ autocmd BufNewFile,BufRead
+ \ ?*.pcap
+ \ setfiletype pcap
+ " Perl files
autocmd BufNewFile,BufRead
\ ?*.pl
\,?*.pm
@@ -252,12 +317,6 @@ augroup filetypedetect
\,*/xt/?*.t
\,Makefile.PL
\ setfiletype perl
- " Perl 6 files
- autocmd BufNewFile,BufRead
- \ ?*.p6
- \,?*.pl6
- \,?*.pm6
- \ setfiletype perl6
" PHP files
autocmd BufNewFile,BufRead
\ ?*.php
@@ -270,9 +329,21 @@ augroup filetypedetect
autocmd BufNewFile,BufRead
\ ?*.pod6
\ setfiletype pod6
+ " protocols(5) files
+ autocmd BufNewFile,BufRead
+ \ protocols
+ \ setfiletype protocols
+ " printcap(5) files
+ autocmd BufNewFile,BufRead
+ \ printcap
+ \ let b:ptcap_type = 'print'
+ \|setfiletype ptcap
" Python files
autocmd BufNewFile,BufRead
\ ?*.py
+ \,?*.pyw
+ \,?*.pythonstartup
+ \,?*.pythonrc
\ setfiletype python
" Readline configuration file
autocmd BufNewFile,BufRead
@@ -297,13 +368,27 @@ augroup filetypedetect
autocmd BufNewFile,BufRead
\ ?*.rb
\ setfiletype ruby
+ " Rust
+ autocmd BufNewFile,BufRead
+ \ ?*.rs
+ \ setfiletype rust
+ " Samba config
+ autocmd BufNewFile,BufRead
+ \ smb.conf
+ \ setfiletype samba
+ " Scheme
+ au BufNewFile,BufRead
+ \ ?*.scm
+ \,*.ss
+ \,*.sld
+ \ setfiletype scheme
" sed files
autocmd BufNewFile,BufRead
\ ?*.sed
\ setfiletype sed
" Services files
autocmd BufNewFile,BufRead
- \ /etc/services
+ \ */etc/services
\ setfiletype services
" Bash shell
autocmd BufNewFile,BufRead
@@ -336,12 +421,21 @@ augroup filetypedetect
\,.shinit
\,.shrc
\,.xinitrc
- \,/etc/default/*
+ \,.xprofile
+ \,.xsession
+ \,.xsessionrc
+ \,*/etc/default/*
\,configure
\,profile
\,shinit
\,shrc
\,xinitrc
+ \,xprofile
+ \,xsession
+ \,xsessionrc
+ \,*/etc/X11/xinit
+ \,*/etc/X11/Xreset
+ \,*/etc/X11/Xsession
\ let b:is_posix = 1
\|setfiletype sh
" SQL
@@ -349,22 +443,32 @@ augroup filetypedetect
\ ?*.sql
\ setfiletype sql
" OpenSSH configuration
+ "" client
autocmd BufNewFile,BufRead
- \ ssh_config,*/.ssh/config
+ \ ssh_config
+ \,*/ssh_config.d/*.conf
+ \,*/.ssh/config,
+ \,*/.ssh/config.d/*.conf
\ setfiletype sshconfig
+ "" server
+ autocmd BufNewFile,BufRead
+ \ sshd_config
+ \,*/sshd_config.d/*.conf
+ \ setfiletype sshdconfig
" sudoers(5)
autocmd BufNewFile,BufRead
\ sudoers
\,sudoers.tmp
- \ setfiletype sshdconfig
- " OpenSSH server configuration
- autocmd BufNewFile,BufRead
- \ sshd_config
\ setfiletype sudoers
" Subversion commit
autocmd BufNewFile,BufRead
\ svn-commit*.tmp
\ setfiletype svn
+ " sysctl configuration files
+ autocmd BufNewFile,BufRead
+ \ */etc/sysctl.conf
+ \,*/etc/sysctl.d/*.conf
+ \ setfiletype sysctl
" Systemd unit files
autocmd BufNewFile,BufRead
\ */systemd/*.*
@@ -377,10 +481,6 @@ augroup filetypedetect
autocmd BufNewFile,BufRead
\ ?*.ti
\ setfiletype terminfo
- " TextEditorAnywhere text field
- autocmd BufNewFile,BufRead
- \ TextEditorAnywhere_??_??_??.txt
- \ setfiletype textarea
" Tidy config
autocmd BufNewFile,BufRead
\ .tidyrc
@@ -391,11 +491,15 @@ augroup filetypedetect
\ .tmux.conf
\,tmux.conf
\ setfiletype tmux
+ " TOML configuration files
+ autocmd BufNewFile,BufRead
+ \ ?*.toml
+ \ setfiletype toml
" Tab-separated (TSV) files
autocmd BufNewFile,BufRead
\ ?*.tsv
\ setfiletype tsv
- " VimL files
+ " Vim script files
autocmd BufNewFile,BufRead
\ ?*.vim
\,.exrc
@@ -416,12 +520,10 @@ augroup filetypedetect
\ .wgetrc
\,wgetrc
\ setfiletype wget
- " Add automatic commands to find Xresources subfiles
+ " Add automatic commands to find .Xresources subfiles
autocmd BufNewFile,BufRead
\ .Xresources
- \,*/.Xresources.d/*
\,Xresources
- \,*/Xresources.d/*
\ setfiletype xdefaults
" XHTML files
autocmd BufNewFile,BufRead
@@ -455,8 +557,8 @@ augroup filetypedetect
\,zshrc
\ setfiletype zsh
- " If it's a new file in a bin, libexec, or scripts subdir that has a
- " Makefile.PL sibling, and I'm editing it, it's almost definitely Perl.
+ " If it's a new file in a bin, libexec, or scripts subdirectory that has
+ " a Makefile.PL sibling, and I'm editing it, it's almost definitely Perl.
autocmd BufNewFile
\ ?*/bin/?*
\,?*/libexec/?*
@@ -471,8 +573,8 @@ augroup filetypedetect
" Clumsy attempt at typing files in `sudo -e` if a filename hasn't already
" been found
autocmd BufNewFile,BufRead
- \ /var/tmp/?*????????.*
- \,/var/tmp/?*.????????
+ \ */var/tmp/?*????????.*
+ \,*/var/tmp/?*.????????
\ if !did_filetype()
\| call filetype#repeat#Sudo()
\|endif
@@ -483,14 +585,14 @@ augroup filetypedetect
\,?*.txt
\,INSTALL
\,README
- \,/etc/issue
- \,/etc/motd
+ \,*/etc/issue
+ \,*/etc/motd
\ setfiletype text
autocmd BufNewFile,BufRead
\ ?*.cfg
\,?*.conf
\,?*.config
- \,/etc/*
+ \,*/etc/*
\ setfiletype conf
autocmd BufNewFile,BufRead
\ */log/*
diff --git a/vim/ftplugin/csv.vim b/vim/ftplugin/csv.vim
index 9bd3e86e..68378d62 100644
--- a/vim/ftplugin/csv.vim
+++ b/vim/ftplugin/csv.vim
@@ -4,6 +4,6 @@ if exists('b:did_ftplugin')
endif
let b:did_ftplugin = 1
-" No autoformatting
+" No automatic formatting
setlocal formatoptions=
let b:undo_ftplugin = 'formatoptions<'
diff --git a/vim/ftplugin/mail.vim b/vim/ftplugin/mail.vim
new file mode 100644
index 00000000..bc10a2ec
--- /dev/null
+++ b/vim/ftplugin/mail.vim
@@ -0,0 +1,15 @@
+" Only do this when not yet done for this buffer--but don't set the flag
+" ourselves, either; this is intended to be a prelude to
+" $VIMRUNTIME/ftplugin/mail.vim
+"
+if exists('b:did_ftplugin')
+ finish
+endif
+
+" Force no_mail_maps value on to work around loading bad maps in
+" $VIMRUNTIME/ftplugin/mail.vim
+"
+if exists('no_mail_maps')
+ let b:no_mail_maps = no_mail_maps
+endif
+let no_mail_maps = 1
diff --git a/vim/ftplugin/markdown.vim b/vim/ftplugin/markdown.vim
index 3f41cf8d..ddd88e2c 100644
--- a/vim/ftplugin/markdown.vim
+++ b/vim/ftplugin/markdown.vim
@@ -56,7 +56,7 @@ xnoremap <buffer> <expr> <LocalLeader>Q
let b:undo_ftplugin .= '|nunmap <buffer> <LocalLeader>Q'
\ . '|xunmap <buffer> <LocalLeader>Q'
-" Autoformat headings
+" Automatically format headings
command -buffer -nargs=1 MarkdownHeading
\ call markdown#Heading(<f-args>)
nnoremap <buffer> <LocalLeader>=
diff --git a/vim/ftplugin/textarea.vim b/vim/ftplugin/textarea.vim
deleted file mode 100644
index 4db97b58..00000000
--- a/vim/ftplugin/textarea.vim
+++ /dev/null
@@ -1,12 +0,0 @@
-" Set mail message as an alternative filetype
-if !exists('b:alternate_filetypes')
- let b:alternate_filetypes = [&filetype, 'mail']
-endif
-
-" Stop here if the user doesn't want ftplugin mappings
-if exists('no_plugin_maps') || exists('no_textarea_maps')
- finish
-endif
-
-" #s expands to the #signature tag used in Cerb
-inoreabbrev #s #signature
diff --git a/vim/plugin/2html.vim b/vim/plugin/2html.vim
deleted file mode 100644
index 95dcbb6c..00000000
--- a/vim/plugin/2html.vim
+++ /dev/null
@@ -1 +0,0 @@
-let g:html_font = ['DejaVu Sans Mono', 'Ubuntu Mono', 'Consolas']
diff --git a/vim/plugin/dist.vim b/vim/plugin/dist.vim
index 3a84abaa..94974f5f 100644
--- a/vim/plugin/dist.vim
+++ b/vim/plugin/dist.vim
@@ -14,3 +14,5 @@ let loaded_netrwPlugin = 1
let loaded_rrhelper = 1
" I don't need extra spelling files
let loaded_spellfile_plugin = 1
+" No thanks, just plain `less` is fine for manual pages
+let loaded_manpager_plugin = 1
diff --git a/vim/plugin/fortune.vim b/vim/plugin/fortune.vim
deleted file mode 100644
index efc03467..00000000
--- a/vim/plugin/fortune.vim
+++ /dev/null
@@ -1,4 +0,0 @@
-command! -bar Fortune
- \ call fortune#()
-nnoremap <silent> <Plug>(Fortune)
- \ :<C-U>Fortune<CR>
diff --git a/vim/plugin/matchit.vim b/vim/plugin/matchit.vim
index f842bd9c..392b2728 100644
--- a/vim/plugin/matchit.vim
+++ b/vim/plugin/matchit.vim
@@ -1,5 +1,5 @@
" Get matchit.vim, one way or another
-if has('packages') && !has('nvim')
+if has('packages')
packadd matchit
else
runtime macros/matchit.vim
diff --git a/vim/plugin/put_date.vim b/vim/plugin/put_date.vim
deleted file mode 100644
index 7848e95f..00000000
--- a/vim/plugin/put_date.vim
+++ /dev/null
@@ -1,6 +0,0 @@
-if exists('loaded_put_date') || &compatible || !exists('*strftime')
- finish
-endif
-let loaded_put_date = 1
-command! -bang -bar -nargs=* -range PutDate
- \ call put_date#(<q-line1>, <q-bang> ==# '!', <q-args>)
diff --git a/vim/scripts.vim b/vim/scripts.vim
index 3c3c53cd..e025a77a 100644
--- a/vim/scripts.vim
+++ b/vim/scripts.vim
@@ -13,14 +13,14 @@ if s:line !~# '^#!'
elseif s:line =~# '\<[gm]\=awk\d*\>'
setfiletype awk
-" Perl 5
+" Lua
+elseif s:line =~# '\<lua\d*\>'
+ setfiletype lua
+
+" Perl
elseif s:line =~# '\<perl5\=\>'
setfiletype perl
-" Perl 6
-elseif s:line =~# '\<perl6\>'
- setfiletype perl6
-
" PHP
elseif s:line =~# '\<php\d*\>'
setfiletype php
diff --git a/vim/syntax/jinja2.vim b/vim/syntax/jinja2.vim
new file mode 100644
index 00000000..2b4aef1a
--- /dev/null
+++ b/vim/syntax/jinja2.vim
@@ -0,0 +1,2 @@
+" Django is similar enough to Jinja2 to be useful for highlighting
+runtime! syntax/django.vim
diff --git a/vim/vimrc b/vim/vimrc
index 2328bb11..66c1c68f 100644
--- a/vim/vimrc
+++ b/vim/vimrc
@@ -1,163 +1,222 @@
-" ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
-" Tom Ryder (tejr)’s Literate Vimrc
-" ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
-"
-" Last updated: Thu, 19 Dec 2019 17:07:46 +1300
-"
-" │ And I was lifted up in heart, and thought
-" │ Of all my late-shown prowess in the lists,
-" │ How my strong lance had beaten down the knights,
-" │ So many and famous names; and never yet
-" │ Had heaven appeared so blue, nor earth so green,
-" │ For all my blood danced in me, and I knew
-" │ That I should light upon the Holy Grail.
-" │
-" │ —Tennyson
-"
-" This file is an attempt at something like a “literate vimrc”, in the
-" tradition of Donald Knuth’s “literate programming”:
+" -----------------------------------
+" Tom Ryder (tejr)'s Literate Vimrc
+" -----------------------------------
+"
+" Last updated: Sun, 14 Jan 2024 03:06:40 +0000
+"
+" > And I was lifted up in heart, and thought
+" > Of all my late-shown prowess in the lists,
+" > How my strong lance had beaten down the knights,
+" > So many and famous names; and never yet
+" > Had heaven appeared so blue, nor earth so green,
+" > For all my blood danced in me, and I knew
+" > That I should light upon the Holy Grail.
+"
+" ---Tennyson
+"
+" > your vimrc is better than the bible
+"
+" ---@polanco@mastodon.sdf.org
+" <https://mastodon.sdf.org/@polanco/104069285780040986>
+"
+
+" This file is an attempt at something like a "literate vimrc", in the
+" tradition of Donald Knuth's "literate programming":
" <http://www.literateprogramming.com/>
"
-" The dotfiles project that comprises it is maintained here:
-" <https://sanctum.geek.nz/cgit/dotfiles.git>
+" The dotfiles project as part of which it is maintained is here:
+" <https://dev.sanctum.geek.nz/cgit/dotfiles.git>
"
-" This is a long file, and comments abound within. Should this be bothersome,
-" one could execute this command in Vim itself to strip out all lines either
-" blank or comprising solely comments:
+" This is a long file, and comments abound. Should this be bothersome, one
+" could execute this command in Vim itself, to strip out comment blocks and
+" blank lines:
"
" :g/\m^$\|^\s*"/d
"
-" This file should be saved as ‘vimrc’—no leading period—in the user runtime
-" directory. On Unix-like operating systems, hereinafter referred to as
-" “*nix”, that directory is ‘~/.vim’; on Windows, it’s ‘~/vimfiles’.
-" Fortunately, those are the only two kinds of operating systems that exist,
-" anywhere in the world.
-"
-" It requires Vim v7.0.0 or newer, with the +eval feature, and the
-" 'compatible' option turned off, chiefly to allow line continuations. The
-" vimrc stub at ~/.vimrc (Unix) or ~/_vimrc (Windows) should check that these
-" conditions are met before loading this file with ‘:runtime vimrc’.
-"
-" All of this should survive a pass of the Vim script linter Vint with no
-" errors, warnings, or style problems: <https://github.com/Kuniwak/vint>
-"
-
-" We’ll begin by making sure that we and Vim are speaking the same language.
-" Since it’s been the future for a few years now, this file has characters
-" outside the ASCII character set, which prompts Vint to suggest declaring the
-" file encoding with a :scriptencoding command. The :help for that command
-" specifies that this should be done after 'encoding' is set, so we’ll do that
-" here, too.
-"
-" On *nix, I define the primary locale environment variable $LANG, almost
-" always specifying a multibyte locale. This informs Vim’s choice of internal
-" character encoding, but the default for the 'encoding' option in the absence
-" of a valid $LANG is ‘latin1’. Since this is almost never what I want, we’ll
-" manually choose the UTF-8 encoding for Unicode in the absence of any other
-" explicit specification.
-"
-if &encoding ==# 'latin1' && !exists('$LANG')
- set encoding=utf-8
+" This file should be saved as `vimrc`---note no leading period---in the user
+" runtime directory. On GNU/Linux, Mac OS X, and BSD, that directory is
+" `~/.vim`. On Windows, it's `~/vimfiles`. It requires Vim v7.0.0 or newer,
+" including the +eval feature, and with the 'compatible' option turned off.
+" That's to allow line continuations. The vimrc stub at ~/.vimrc (Unix) or
+" ~/_vimrc (Windows) checks that these conditions are met before loading this
+" file.
+"
+" The Vim script linter Vint should raise no errors, warnings, or style
+" problems with this file. <https://github.com/Kuniwak/vint>
+"
+
+" We'll begin by making sure that this file and Vim are speaking the same
+" language. Since it's been the future for a few years now, this file
+" indulges in characters outside the ASCII character set. The presence of
+" such characters prompts Vint to suggest declaring the file encoding with
+" a :scriptencoding command:
+"
+" > vim/vimrc:1:1: Use scriptencoding when multibyte char exists (see :help
+" > :scriptencoding)
+"
+" Furthermore, the :help for :scriptencoding specifies that :scriptencoding
+" should be set *after* 'encoding'.
+"
+" Which encoding to use? The answer is the UTF-8 encoding for Unicode,
+" wherever possible. On POSIX-fearing operating systems, I define the primary
+" locale environment variable $LANG to `en_NZ.UTF-8`. This informs Vim's
+" choice of internal character encoding. In the absence of such a setting,
+" 'encoding' defaults to `latin1` (ISO-8859-1) in most circumstances. Since
+" this is almost never what I want, even if I haven't said so explicitly by
+" exporting $LANG, we'll fall back to UTF-8 instead.
+"
+" However, we need to test that the +multi_byte feature is available before
+" doing any of this, because it was a compile-time feature that wasn't even
+" enabled by default in Vim v7.0. Its status as an optional feature wasn't
+" removed until v8.1.0733.
+"
+" <https://github.com/vim/vim/releases/tag/v8.1.0733>
+"
+if has('multi_byte')
+ if &encoding ==# 'latin1' && !exists('$LANG')
+ set encoding=utf-8
+ endif
+ scriptencoding utf-8
endif
-scriptencoding utf-8
-" With encoding handled, we’ll turn our attention to the value of the
+" With encoding handled, we'll turn our attention to the value of the
" 'runtimepath' option, since any scripts loaded from the paths specified
-" therein control so much of the behavior of Vim. I’d like to do this as
-" accurately as possible, even with Vim’s unusual behavior around escaping of
-" these variables. One of the first things we’ll need to be able to do is
-" split the value of 'runtimepath' into its constituent path parts.
-"
-" Splitting the values of comma-separated options correctly is surprisingly
-" complicated. The list separator for such options is more accurately defined
-" as follows:
-"
-" │ A comma not preceded by a backslash, and possibly followed by an arbitrary
-" │ number of spaces and commas.
-"
-" The pattern required for the split breaks down like this:
-"
-" \\ ← Literal backslash
-" \@<! ← Negative lookbehind assertion; means that whatever occurred
-" before this pattern, here a backslash, cannot precede what
-" follows, but anything that does precede it is not removed from
-" the data as part of the split delimiter
-" , ← Literal comma
-" [, ]* ← Any number of commas and spaces
-"
-" We don’t, however, have to deal with backslashes before other backslashes,
-" nor before any other character. You can read the source code for the ad-hoc
-" tokenizer in copy_option_part() in src/misc2.c in Vim’s source code, and
-" test it with some values of your own, if you want to understand why. Vim,
-" I love you, but you are really weird sometimes.
-"
-" We do all this with an autoloaded function option#Split().
-"
-" If an environment variable MYVIM exists, and it isn’t blank, apply its value
-" as the first value of 'runtimepath', after escaping it appropriately.
-" Otherwise, do it the other way around: the first path in the 'runtimepath'
-" list becomes MYVIM.
-"
-if exists('$MYVIM') && $MYVIM !=# ''
- execute 'set runtimepath^='.argument#Escape(option#item#Escape($MYVIM, 1))
-elseif &runtimepath !=# ''
- let $MYVIM = option#Split(&runtimepath)[0]
+" therein control so much of the behavior of Vim. We build this path up as
+" accurately as possible, accounting for Vim's unusual escaping behavior for
+" these list options.
+"
+" One of the first things we'll need to be able to do is split the value of
+" 'runtimepath' into its constituent paths. Correctly splitting the values of
+" comma-separated Vim options is surprisingly complicated. It's not as simple
+" as just splitting on commas, or even unescaped commas; a more accurate
+" definition of the delimiter is:
+"
+" > Any comma not preceded by a backslash, followed by any number of spaces
+" > and commas.
+"
+" The pattern we use for the call to split() therefore breaks down like this:
+"
+" \\ <- A literal backslash
+" \@<! <- A negative lookbehind assertion; this means that whatever
+" occurred before this pattern---in this case, a backslash---
+" cannot precede what follows, but anything that *does* precede it
+" is considered part of the datum, and not the delimiter.
+" , <- A literal comma
+" [, ]* <- Any number of commas and spaces
+"
+" We don't, however, have to deal with backslashes before other backslashes,
+" nor before any other character. If this seems wrong to you, I encourage you
+" to read the source code for the ad-hoc tokenizer in copy_option_part() in
+" src/misc2.c in Vim's source code.
+"
+" Vim, I do love you, but sometimes you're really weird.
+"
+" We fold all that mess away into an autoloaded function option#Split(); see
+" vim/autoload/option.vim. Provided a 'runtimepath' is actually set, using
+" the list returned from that function, we define an environment variable
+" MYVIM---to complement MYVIMRC---for ~/.vim or ~/vimfiles, by retrieving the
+" first value from the 'runtimepath'. We'll use this later on in the file to
+" comprehensively match expected paths for vimrc files.
+"
+if &runtimepath ==# ''
+ throw 'Empty ''runtimepath'''
+endif
+let $MYVIM = option#Split(&runtimepath)[0]
+
+" The next components of the runtime directory that we'll set up here will
+" make use of the user's configured XDG base directories:
+"
+" <https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html#variables>
+"
+" Note that this isn't an attempt to shoehorn all of Vim into the XDG mold;
+" all of this distribution's files are still expected to be installed into
+" $MYVIM, per the above. We're just leaning on XDG's conventions to provide
+" separate locations for cache files and other configuration.
+"
+" We'll start by retrieving the list of valid paths for configuration from
+" both the XDG_CONFIG_HOME and XDG_CONFIG_DIRS variables, or from their
+" defaults, using autoloaded xdg# functions.
+"
+let s:xdgconfigdirs
+ \ = xdg#ConfigDirs()
+let s:xdgconfighome
+ \ = xdg#ConfigHome()
+let s:xdgdatadirs
+ \ = xdg#DataDirs()
+let s:xdgdatahome
+ \ = xdg#DataHome()
+let s:xdgstatehome
+ \ = xdg#StateHome()
+
+" We put XDG_CONFIG_HOME at the front of the 'runtimepath' list with insert(),
+" provided it isn't empty, which is what the function returns when the
+" configured path isn't absolute. This is per the standard's dictum:
+"
+" > All paths set in these environment variables must be absolute. If an
+" > implementation encounters a relative path in any of these variables it
+" > should consider the path invalid and ignore it.
+"
+" ---XDG Base Directory Specification v0.7 (24th November 2010), "Basics",
+" <https://specifications.freedesktop.org/basedir-spec/0.7/ar01s02.html>
+"
+" Ours not to reason why...
+"
+if s:xdgconfighome !=# '' || !empty(s:xdgconfigdirs)
+ execute 'set runtimepath^='.option#Escape(join(map(
+ \ extend(
+ \ s:xdgconfighome !=# '' ? [s:xdgconfighome] : [],
+ \ s:xdgconfigdirs
+ \),
+ \ 'option#item#Escape(v:val)'
+ \), ','))
+ execute 'set runtimepath+='.option#Escape(join(map(
+ \ reverse(extend(
+ \ s:xdgconfighome !=# '' ? [s:xdgconfighome] : [],
+ \ s:xdgconfigdirs
+ \)),
+ \ 'option#item#Escape(v:val.''/after'')'
+ \), ','))
endif
-" We need a command to reliably establish a full path, whether or not the
-" directories already exist. We create a wrapper for the autoloaded function
-" path#Create() with similar calling conventions to mkdir(), but with the ‘p’
-" value for the second parameter {prot} forced on. Calling it with a bang
-" like :CreatePath! creates a private directory (permissions 0700).
-"
-command! -bang -bar -complete=dir -nargs=1 CreatePath
- \ call path#Create(expand(<q-args>), <q-bang> ==# '!')
-
-" Now that we have a way to create directories if they don’t already exist,
-" let’s apply it for the first time to the user runtime directory. Note that
-" we aren’t checking whether this actually succeeded. We do want errors
-" raised if there were problems with the creation, but we’ll barrel on ahead
-" regardless after warning the user about our failure.
-"
" Using a logical but non-default location for viminfo has the nice benefit of
" preventing command and search history from getting clobbered when something
" runs Vim without using this vimrc, because such an instance will safely
-" write its own history to the default viminfo path instead. It also
-" contributes to our aim of having everything related to the Vim runtime
-" process in one dedicated directory tree.
+" write its own history to the default viminfo path instead.
"
-" The normal method of specifying the path to the viminfo file, as applied
-" here, is an addendum of the path to the 'viminfo' option with an ‘n’ prefix.
-" Vim v8.1.716 introduced a nicer way to set this with an option named
-" 'viminfofile', but that’s still too new for us to use just yet.
+" This is the portable way to specify the path to the viminfo file, as an
+" addendum of the path to the 'viminfo' option with an `n` prefix. Vim
+" v8.1.716 introduced a way to set this with an option named 'viminfofile',
+" but I don't see a reason to use that.
"
-" <https://github.com/vim/vim/releases/tag/v8.1.0716>
-"
-execute 'set viminfo+='.argument#Escape('n'.$MYVIM.'/viminfo')
-CreatePath $MYVIM
+if s:xdgstatehome !=# ''
+ if !isdirectory(s:xdgstatehome)
+ call mkdir(s:xdgstatehome, 'p', 0700)
+ endif
+ execute 'set viminfo+='.option#Escape(
+ \ 'n'.s:xdgstatehome.'/viminfo'
+ \)
+endif
" Speaking of recorded data in viminfo files, the default Vim limit of a mere
-" 50 entries for command and search history is pretty stingy. Because I don’t
-" think I’m ever likely to be in a situation where remembering several
-" thousand Vim commands and search patterns is going to severely tax memory,
-" let alone disk space, I’d rather this limit were much higher. It’s
-" sometimes really handy to dig up commands from many days ago.
-"
-" The maximum value for the 'history' option is documented in ‘:help
-" 'history'’ as 10000, so let’s just use that, and see if anything breaks.
+" 50 entries for command and search history is pretty stingy. The documented
+" maximum value for this option is 10000. I used that for a while, but
+" eventually found that on lower-powered machines, keeping this much command
+" history slowed Vim startup down a bit much for my liking, so I've scaled
+" this back to a more conservative 300. If I end up missing useful commands,
+" I might try switching this on available memory instead.
"
-set history=10000
+set history=300
-" We’ll now enable automatic backups of most file buffers, since that’s off by
-" default. In practice, I don’t need these backups very much, at least if I’m
+" We'll now enable automatic backups of most file buffers, since that's off by
+" default. In practice, I don't need these backups very much, at least if I'm
" using version control sensibly, but they have still saved my bacon a few
" times.
"
-" We’ll try to keep the backup files in a dedicated cache directory, to stop
+" We'll try to keep the backup files in a dedicated cache directory, to stop
" them popping up next to the file to which they correspond, and getting
" accidentally committed to version control.
"
-" If Vim is new enough, we’ll add two trailing slashes to the path we’re
+" If Vim is new enough, we'll add two trailing slashes to the path we're
" inserting, which prompts Vim to incorporate the full escaped path of the
" relevant buffer in the backup filename, avoiding collisions.
"
@@ -165,81 +224,124 @@ set history=10000
" this trailing slashes hint for a long time before 'backupdir' caught up to
" them. The 'directory' option for swap files has supported it at least as
" far back as v5.8.0 (2001), and 'undodir' appears to have supported it since
-" its creation in v7.2.438. Even though ‘:help 'backupdir'’ didn’t say so,
+" its creation in v7.2.438. Even though `:help 'backupdir'` didn't say so,
" people assumed it would work the same way, when in fact Vim simply ignored
" it until v8.1.0251.
"
-" I don’t want to add the slashes to the option value in older versions of Vim
-" where they don’t do anything, so we’ll check the version ourselves to see if
-" there’s any point in including them.
+" I don't want to add the slashes to the option value in older versions of Vim
+" where they don't do anything, so we'll check the version ourselves to see if
+" there's any point in including them.
"
" <https://github.com/vim/vim/releases/tag/v8.1.0251>
"
-" It’s all so awkward. Surely separate options named something like
+" It's all so awkward. Surely separate options named something like
" 'backupfullname', 'swapfilefullname' would have been clearer.
"
set backup
-execute 'set backupdir^='.argument#Escape(option#item#Escape(
- \ $MYVIM.'/backup'.(has#('patch-8.1.251') ? '//' : ''),
- \))
-CreatePath! $MYVIM/backup
+if s:xdgstatehome !=# ''
+ if !isdirectory(s:xdgstatehome.'/backup')
+ call mkdir(s:xdgstatehome.'/backup', 'p', 0700)
+ endif
+ execute 'set backupdir^='.option#Escape(option#item#Escape(
+ \ s:xdgstatehome.'/backup'.(patch#('8.1.251') ? '//' : '')
+ \))
+endif
" Files in certain directories on Unix-compatible filesystems should not be
" backed up, for security reasons. This is particularly important if editing
-" temporary files created by sudoedit(8). On Unix-like systems, we here add
-" a few paths to the default value of 'backupskip' in order to prevent the
-" creation of such undesired backup files.
-"
-" * /dev/shm: RAM disk, default path for password-store’s temporary files
-" * /usr/tmp: Hard-coded path for sudoedit(8) [1/2]
-" * /var/tmp: Hard-coded path for sudoedit(8) [2/2]
-"
-" Prior to v8.1.1519, Vim didn’t check patterns added to 'backupskip' for
-" uniqueness, so adding the same path repeatedly resulted in duplicate strings
-" in the value. This was due to the absence of the P_NODUP flag for the
-" option’s definition in src/option.c in the Vim source code. If we’re using
-" a version older than v8.1.1519, we’ll need to explicitly reset 'backupskip'
-" to its default value before adding patterns to it, so that reloading this
-" file doesn’t stack up multiple copies of any added paths.
-"
-" <https://github.com/vim/vim/releases/tag/v8.1.1519>
-"
-if has#('unix')
- if !has#('patch-8.1.1519')
+" temporary files created by sudoedit(8). We add a few path patterns to the
+" default value of 'backupskip' here, in order to prevent the creation of such
+" undesired backup files.
+"
+if has('unix')
+
+ " Prior to v8.1.1519, Vim didn't check patterns added to 'backupskip' for
+ " uniqueness, so adding the same path repeatedly resulted in duplicate
+ " strings in the value. This was due to the absence of the P_NODUP flag for
+ " the option's definition in src/option.c in the Vim source code. If we're
+ " using a version older than v8.1.1519, we'll need to explicitly reset
+ " 'backupskip' to its default value before adding patterns to it, so that
+ " reloading this file doesn't stack up multiple copies of any added paths.
+ "
+ " <https://github.com/vim/vim/releases/tag/v8.1.1519>
+ "
+ if !patch#('8.1.1519')
set backupskip&
endif
- set backupskip^=/dev/shm/*,/usr/tmp/*,/var/tmp/*
+
+ " Typical temporary file locations
+ "" RAM disk, default path for password-store's temporary files
+ set backupskip+=/dev/shm/*
+ "" Hard-coded paths for sudoedit
+ set backupskip+=/usr/tmp/*,/var/tmp/*
+
+ " Per-repository temporary files for Git
+ "" Commit and tag messages
+ set backupskip+=*/*.git/?*_EDITMSG
+ "" Edited patches
+ set backupskip+=*/*.git/ADD_EDIT.patch
+ "" Email messages
+ set backupskip+=*/*.git/.gitsendemail.msg.*
+ "" Interactive rebase manifests
+ set backupskip+=*/*.git/rebase-merge/git-rebase-todo
+
+ " systemd user manager unit files
+ "" Full unit files
+ set backupskip+=*/systemd/user/.#?*.?*????????????????
+ "" Per-unit overrides
+ set backupskip+=*/systemd/user/?*.?*.d/.#override.conf????????????????
+
endif
" Keep swap files for file buffers in a dedicated directory, rather than the
" default of writing them to the same directory as the buffer file. Add two
" trailing slashes to the path to prompt Vim to use the full escaped path in
" its name, in order to avoid filename collisions, since the 'directory'
-" option has supported that hint for much longer than 'backupdir' has. We
-" apply path#Create() to attempt to create the path, if needed.
+" option has supported that hint for much longer than 'backupdir' has.
"
-execute 'set directory^='
- \.argument#Escape(option#item#Escape($MYVIM.'/swap//'))
-CreatePath! $MYVIM/swap
+if s:xdgstatehome !=# ''
+ if !isdirectory(s:xdgstatehome.'/swap')
+ call mkdir(s:xdgstatehome.'/swap', 'p', 0700)
+ endif
+ execute 'set directory^='.option#Escape(option#item#Escape(
+ \ s:xdgstatehome.'/swap//'
+ \))
+endif
" Keep tracked undo history for files permanently, in a dedicated cache
" directory, so that the u/:undo and CTRL-R/:redo commands will work between
" Vim invocations.
"
" The 'undodir' option has the same structure as 'backupdir' and 'directory';
-" if we have a user runtime directory, create a sub-subdirectory within it
-" dedicated to the undo files cache. Note also the trailing double-slash as
-" a signal to Vim to use the full path of the original file in its undo file
-" cache’s name.
+" if we have a user cache directory, create a subdirectory within it dedicated
+" to the undo files cache. Note also the trailing double-slash as a signal to
+" Vim to use the full path of the original file in its undo file cache's name.
"
" Support for these persistent undo file caches was not released until v7.3.0,
-" so we need to check for the feature’s presence before we enable it.
+" so we need to check for the feature's presence before we enable it.
"
-if has#('persistent_undo')
+if s:xdgstatehome !=# '' && has('persistent_undo')
set undofile
- execute 'set undodir^='
- \.argument#Escape(option#item#Escape($MYVIM.'/undo//'))
- CreatePath! $MYVIM/undo
+ if !isdirectory(s:xdgstatehome.'/undo')
+ call mkdir(s:xdgstatehome.'/undo', 'p', 0700)
+ endif
+ execute 'set undodir^='.option#Escape(option#item#Escape(
+ \ s:xdgstatehome.'/undo//'
+ \))
+endif
+
+" Set up a directory for files generated by :mkview. To date, I think I have
+" used this twice in my life, but may as well be consistent with the other
+" directories of this type. This isn't a comma-separated list like the others
+" ('backupdir', 'directory', 'spell', 'undodir')
+"
+if s:xdgstatehome !=# '' && has('mksession')
+ if !isdirectory(s:xdgstatehome.'/view')
+ call mkdir(s:xdgstatehome.'/view', 'p', 0700)
+ endif
+ execute 'set viewdir='.option#Escape(option#item#Escape(
+ \ s:xdgstatehome.'/view'
+ \))
endif
" Now that we have a bit more confidence in our runtime environment, set up
@@ -250,7 +352,7 @@ filetype plugin indent on
" There are a couple of contexts in which it's useful to reload filetypes for
" the current buffer, quietly doing nothing if filetypes aren't enabled.
" We'll set up a user command named :ReloadFileType to do this, with
-" a script-local function backing it.
+" an autoloaded function backing it.
"
command! -bar ReloadFileType
\ call reload#FileType()
@@ -265,10 +367,6 @@ command! -bar ReloadFileType
" define the new command wrapper around an autoloaded function that itself
" issues a :ReloadFileType command after the vimrc file is sourced.
"
-" We can't put the actual :source command into the script-local function we
-" define here, because Vim would get upset that we're trying to redefine
-" a function as it executes!
-"
command! -bar ReloadVimrc
\ call reload#Vimrc()
@@ -300,7 +398,7 @@ if exists('##SourceCmd')
\ ReloadVimrc
endif
-" For spelling, use New Zealand English by default, but later on we’ll
+" For spelling, use New Zealand English by default, but later on we'll
" configure a leader mapping to switch to United States English, since I so
" often have to write for Yankees.
"
@@ -309,65 +407,75 @@ set spelllang=en_nz
" Spell checking includes optional support for catching lower case letters at
" the start of sentences, and defines a pattern in 'spellcapcheck' for the end
" of a sentence. The default is pretty good, but with two-spacing with
-" 'cpoptions' including ‘J’ and 'formatoptions' including ‘p’ as set later in
+" 'cpoptions' including `J` and 'formatoptions' including `p` as set later in
" this file, we can be less ambiguous in this pattern. We require two
" consecutive spaces, a newline, a carriage return, or a tab to mark the end
-" of a sentence. This means that we could make abbreviations like “i.e.
-" something” without flagging “something” as a spelling error.
+" of a sentence. This means that we could make abbreviations like "i.e.
+" something" without flagging "something" as a spelling error.
"
set spellcapcheck=[.?!]\\%(\ \ \\\|[\\n\\r\\t]\\)
+" When spell-checking snakeCased or CamelCased words, treat every upper-case
+" character in a word text object as the beginning of a new word for separate
+" spell-checking. At the time of writing, this is still a very new option
+" (v8.2.0953, June 2020).
+"
+" <https://github.com/vim/vim/releases/tag/v8.2.0953>
+"
+if exists('+spelloptions')
+ set spelloptions+=camel
+endif
+
" For word completion in insert mode with CTRL-X CTRL-K, or if 'complete'
-" includes the ‘k’ flag, the 'dictionary' option specifies the path to the
+" includes the `k` flag, the 'dictionary' option specifies the path to the
" system word list. This makes the dictionary completion work consistently,
-" even if 'spell' isn’t set at the time to coax it into using 'spellfile'.
+" even if 'spell' isn't set at the time to coax it into using 'spellfile'.
"
-" It’s not an error if the system directory file added first doesn’t exist;
-" it’s just a common location that often yields a workable word list, and does
+" It's not an error if the system directory file added first doesn't exist;
+" it's just a common location that often yields a workable word list, and does
" so on all of my main machines.
"
" At some point, I may end up having to set this option along with 'spellfile'
" a bit more intelligently to ensure that spell checking and dictionary
" function consistently, and with reference to the same resources. For the
-" moment, I’ve just added another entry referring to a directory in the user
-" runtime directory, but I don’t have anything distinct to put there yet.
-"
-" In much the same way, we add an expected path to a thesaurus, for completion
-" with CTRL-X CTRL-T in insert mode, or with ‘t’ added to 'completeopt'. The
-" thesaurus data isn’t installed as part of the default ‘install-vim’ target
-" in tejr’s dotfiles, but it can be retrieved and installed with
-" ‘install-vim-thesaurus’.
-"
-" I got the thesaurus itself from the link in the :help for 'thesaurus' in
-" v8.1. It’s from WordNet and MyThes-1. I maintain a mirror on my own
-" website that the Makefile recipe attempts to retrieve. I had to remove the
-" first two metadata lines from thesaurus.txt, as Vim appeared to interpret
-" them as part of the body data.
-"
-" Extra checks for appending the 'dictionary' and 'thesaurus' paths in MYVIM
-" need to be made, because the P_NDNAME property is assigned to them, which
-" enforces a character blacklist in the option value. We check for the
-" expected Vim error code here, and if the MYVIM path offends, we just skip
-" the setting entirely, rather than throwing cryptic errors at the user. None
-" of the blacklisted characters are particularly wise characters to have in
-" paths, anyway, legal though they may be on Unix filesystems. We can’t work
-" around this one with 'isfname'; the blacklist is hard-coded.
+" moment, I've just added additional entries referring to the user's data
+" directory.
"
set dictionary^=/usr/share/dict/words
-let s:ref = $MYVIM.'/ref'
-try
- execute 'set dictionary^='
- \.argument#Escape(option#item#Escape(s:ref.'/dictionary.txt'))
- execute 'set thesaurus^='
- \.argument#Escape(option#item#Escape(s:ref.'/thesaurus.txt'))
-catch /^Vim\%((\a\+)\)\=:E474:/
-endtry
-
-" Next, we’ll modernize a little in adjusting some options with old
+if s:xdgdatahome !=# '' || !empty(s:xdgdatadirs)
+ execute 'set dictionary^='.option#Escape(join(map(
+ \ extend(
+ \ s:xdgdatahome !=# '' ? [s:xdgdatahome] : [],
+ \ s:xdgdatadirs
+ \),
+ \ 'option#item#Escape(v:val.''/dictionary.txt'')'
+ \), ','))
+endif
+
+" In much the same way as 'dictionary', we add an expected path to
+" a thesaurus, for completion with CTRL-X CTRL-T in insert mode, or with `t`
+" added to 'completeopt'. The thesaurus data isn't installed as part of the
+" default `install-vim` target in tejr's dotfiles, but a decent one can be
+" retrieved from my website at <https://sanctum.geek.nz/ref/thesaurus.txt>.
+" I got this from the link in the :help for 'thesaurus' in v8.1. It's from
+" WordNet and MyThes-1. I had to remove the first two metadata lines from
+" thesaurus.txt, as Vim appeared to interpret them as part of the body data.
+"
+if s:xdgdatahome !=# '' || !empty(s:xdgdatadirs)
+ execute 'set thesaurus^='.option#Escape(join(map(
+ \ extend(
+ \ s:xdgdatahome !=# '' ? [s:xdgdatahome] : [],
+ \ s:xdgdatadirs
+ \),
+ \ 'option#item#Escape(v:val.''/thesaurus.txt'')'
+ \), ','))
+endif
+
+" Next, we'll modernize a little in adjusting some options with old
" language-specific defaults.
"
" Traditional vi was often used for development in the C programming language.
-" The default values for a lot of Vim’s options still reflect this common use
+" The default values for a lot of Vim's options still reflect this common use
" pattern. In this case, the 'comments' and 'commentstring' options reflect
" the C syntax for comments:
"
@@ -382,20 +490,20 @@ endtry
"
" #include "baz.h"
"
-" Times change, however, and I don’t get to work with C nearly as much as I’d
+" Times change, however, and I don't get to work with C nearly as much as I'd
" like. The defaults for these options no longer make sense, and so we blank
" them, compelling filetype plugins to set them as they need instead.
"
" The default value for the 'path' option is similar, in that it has an aged
" default; this option specifies directories in which project files and
-" includes can be unearthed by navigation commands like 'gf'. Specifically,
-" its default value comprises /usr/include, which is another C default. Let’s
+" includes can be unearthed by navigation commands like `gf`. Specifically,
+" its default value comprises /usr/include, which is another C default. Let's
" get rid of that, too.
"
set comments= commentstring= define= include=
set path-=/usr/include
-" Relax traditional vi’s harsh standards over what regions of the buffer can
+" Relax traditional vi's harsh standards over what regions of the buffer can
" be removed with backspace in insert mode. While this admittedly allows bad
" habits to continue, since insert mode by definition is not really intended
" for deleting text, I feel the convenience outweighs that in this case.
@@ -405,7 +513,7 @@ set backspace+=indent " Leading whitespace characters created by 'autoindent'
set backspace+=start " Text before the start of the current insertion
" When soft-wrapping text with the 'wrap' option on, which is off by default,
-" break the lines between words, rather than within them; it’s much easier to
+" break the lines between words, rather than within them; it's much easier to
" read.
"
set linebreak
@@ -418,11 +526,11 @@ set linebreak
" … U+2026 HORIZONTAL ELLIPSIS
"
" Note that we test for the presence of a multi-byte encoding with a special
-" feature from ‘:help feature-list’, as recommended by ‘:help encoding’.
-" Checking that ‘&encoding ==# 'utf-8'’ is not quite the same thing, though
-" it’s unlikely I’ll ever use a different Unicode encoding by choice.
+" feature from `:help feature-list`, as recommended by `:help encoding`.
+" Checking that `&encoding ==# 'utf-8'` is not quite the same thing, though
+" it's unlikely I'll ever use a different Unicode encoding by choice.
"
-if has#('multi_byte_encoding')
+if has('multi_byte_encoding')
set showbreak=…
else
set showbreak=...
@@ -430,16 +538,16 @@ endif
" The visual structure of code provided by indents breaks down if a lot of the
" lines wrap. Ideally, most if not all lines would be kept below 80
-" characters, but in cases where this isn’t possible, soft-wrapping longer
+" characters, but in cases where this isn't possible, soft-wrapping longer
" lines when 'wrap' is on so that the indent is preserved in the following
" line mitigates this breakdown somewhat.
"
-" With this 'breakindent' option set, it’s particularly important to have
+" With this 'breakindent' option set, it's particularly important to have
" 'showbreak' set to something besides an empty string, as done above,
-" otherwise without line numbers it’s hard to tell what’s a logical line and
-" what’s not.
+" otherwise without line numbers it's hard to tell what's a logical line and
+" what's not.
"
-" The 'breakindent' option wasn’t added until v7.4.338, so we need to check it
+" The 'breakindent' option wasn't added until v7.4.338, so we need to check it
" exists before we set it.
"
" <https://github.com/vim/vim/releases/tag/v7.4.338>
@@ -448,20 +556,28 @@ if exists('+breakindent')
set breakindent
endif
+" I use `cd` with no argument to go $HOME in the shell all the time.
+" Analogous behavior for Vim with :cd makes sense to me. I can use :pwd (or
+" my <Leader>g mapping) if I want to see where I am.
+"
+if exists('+cdhome')
+ set cdhome
+endif
+
" Rather than rejecting operations like :write or :saveas when 'readonly' is
" set or in other situations in which data might be lost, Vim should give me
-" a prompt to allow me to confirm that I know what I’m doing.
+" a prompt to allow me to confirm that I know what I'm doing.
"
set confirm
-" If Vim receives an Escape key code in insert mode, it shouldn’t wait to see
-" if it’s going to be followed by another key code, despite this being how the
+" If Vim receives an Escape key code in insert mode, it shouldn't wait to see
+" if it's going to be followed by another key code, despite this being how the
" function keys and Meta/Alt modifier are implemented for many terminal types.
-" Otherwise, if I press Escape, there’s an annoying delay before 'showmode'
-" stops showing '--INSERT--'.
+" Otherwise, if I press Escape, there's an annoying delay before 'showmode'
+" stops showing `--INSERT--`.
"
" This breaks the function keys and the Meta/Alt modifier in insert mode in
-" most or maybe all of the terminals I use, but I don’t want those keys in
+" most or maybe all of the terminals I use, but I don't want those keys in
" insert mode, anyway. All of this works fine in the GUI, of course.
"
set noesckeys
@@ -472,109 +588,109 @@ set noesckeys
set foldlevel=256
" Automatic text wrapping options using flags in the 'formatoptions' option
-" begin here. I rely on the filetype plugins to set the ‘t’ and ‘c’ flags for
+" begin here. I rely on the filetype plugins to set the `t` and `c` flags for
" this option to configure whether text or comments should be wrapped, as
-" appropriate for the document type or language, and so I don’t mess with
+" appropriate for the document type or language, and so I don't mess with
" either of those flags here.
" If a line is already longer than 'textwidth' would otherwise limit when
-" editing of that line begins in insert mode, don’t suddenly automatically
-" wrap it; I’ll break it apart myself with a command like 'gq'. This doesn’t
-" seem to stop paragraph reformatting with ‘a’, if that’s set.
+" editing of that line begins in insert mode, don't suddenly automatically
+" wrap it; I'll break it apart myself with a command like `gq`. This doesn't
+" seem to stop paragraph reformatting with `a`, if that's set.
"
set formatoptions+=l
-" Don’t wrap a line in such a way that a single-letter word like “I” or “a” is
+" Don't wrap a line in such a way that a single-letter word like "I" or "a" is
" at the end of it. Typographically, as far as I can tell, this seems to be
-" a stylistic preference rather than a rule, rather like avoiding “widow” and
-" “orphan” lines in typesetting. I think it generally looks better to have
-" the short word start the line, so we’ll switch it on.
+" a stylistic preference rather than a rule, rather like avoiding "widow" and
+" "orphan" lines in typesetting. I think it generally looks better to have
+" the short word start the line, so we'll switch it on.
"
set formatoptions+=1
" If the filetype plugins have correctly described what the comment syntax for
-" the buffer’s language looks like, it makes sense to use that to figure out
+" the buffer's language looks like, it makes sense to use that to figure out
" how to join lines within comments without redundant comment syntax cropping
-" up. For example, with this set, joining lines in this very comment with ‘J’
-" would remove the leading ‘"’ characters.
+" up. For example, with this set, joining lines in this very comment with `J`
+" would remove the leading `"` characters.
"
-" This 'formatoptions' flag wasn’t added until v7.3.541. Because we can’t
+" This 'formatoptions' flag wasn't added until v7.3.541. Because we can't
" test for the availability of option flags directly, we resort to a version
-" number check before attempting to set it. I don’t like using :silent! to
+" number check before attempting to set it. I don't like using :silent! to
" suppress errors for this sort of thing when I can reasonably avoid it, even
" if the tests are somewhat more verbose.
"
" <https://github.com/vim/vim/releases/tag/v7.3.541>
"
-if has#('patch-7.3.541')
+if patch#('7.3.541')
set formatoptions+=j
endif
-" A momentary digression here into the doldrums of 'cpoptions'—after staunchly
-" opposing it for years, I have converted to two-spacing. You can blame Steve
-" Losh:
+" A momentary digression here into the doldrums of 'cpoptions'---after
+" staunchly opposing it for years, I have converted to two-spacing. You can
+" blame Steve Losh:
"
" <http://stevelosh.com/blog/2012/10/why-i-two-space/>
"
-" Consequently, we specify that sentence objects for the purposes of the ‘s’
-" text object, the ‘(’ and ‘)’ sentence motions, and formatting with the 'gq'
+" Consequently, we specify that sentence objects for the purposes of the `s`
+" text object, the `(` and `)` sentence motions, and formatting with the 'gq'
" command must be separated by *two* spaces. One space does not suffice.
"
" My defection to the two-spacers is also the reason I now leave 'joinspaces'
" set, per its default, so that two spaces are inserted when consecutive
-" sentences separated by a line break are joined onto one line by the ‘J’
+" sentences separated by a line break are joined onto one line by the `J`
" command.
"
set cpoptions+=J
" Separating sentences with two spaces has an advantage in making a clear
" distinction between two different types of periods: periods that abbreviate
-" longer words, as in “Mr. Moolenaar”, and periods that terminate sentences,
+" longer words, as in "Mr. Moolenaar", and periods that terminate sentences,
" like this one.
"
-" If we’re using two-period spacing for sentences, Vim can interpret the
+" If we're using two-period spacing for sentences, Vim can interpret the
" different spacing to distinguish between the two types, and can thereby
" avoid breaking a line just after an abbreviating period. For example, the
-" two words in “Mr. Moolenaar” should never be split apart, lest the
-" abbreviation “Mr.” look too much like the end of a sentence. This also
+" two words in "Mr. Moolenaar" should never be split apart, lest the
+" abbreviation "Mr." look too much like the end of a sentence. This also
" preserves the semantics of that same period for subsequent reformatting; its
-" single-space won’t get lost.
+" single-space won't get lost.
"
-" So, getting back to our 'formatoptions' settings, that is what the ‘p’ flag
+" So, getting back to our 'formatoptions' settings, that is what the `p` flag
" does. I wrote the patch that added it, after becoming envious of an
" analogous feature during an ill-fated foray into GNU Emacs usage.
"
" <https://github.com/vim/vim/releases/tag/v8.1.1523>
"
-if has#('patch-8.1.728')
+if patch#('8.1.728')
set formatoptions+=p
endif
" In an effort to avoid loading unnecessary files, we add a flag to the
" 'guioptions' option to prevent the menu.vim runtime file from being loaded.
-" It doesn’t do any harm, but I never use it, and it’s easy to turn it off.
+" It doesn't do any harm, but I never use it, and it's easy to turn it off.
"
-" The documentation for this flag in ‘:help 'go-M'’ includes a note saying the
+" The documentation for this flag in `:help 'go-M'` includes a note saying the
" flag should be set here, rather that in the GUI-specific gvimrc file, as one
" might otherwise think.
"
-if has#('gui_running')
+if has('gui_running')
set guioptions+=M
endif
-" By default, Vim doesn’t allow a file buffer to have unwritten changes if
-" it’s not displayed in a window. Setting this option removes that
+" By default, Vim doesn't allow a file buffer to have unwritten changes if
+" it's not displayed in a window. Setting this option removes that
" restriction so that buffers can remain in a modified state while not
" actually displayed anywhere.
"
-" This option is set in almost every vimrc I read; it’s so pervasive that
-" I sometimes see comments expressing astonishment or annoyance that it isn’t
-" set by default. However, I didn’t actually need this option for several
+" This option is set in almost every vimrc I read; it's so pervasive that
+" I sometimes see comments expressing astonishment or annoyance that it isn't
+" set by default. However, I didn't actually need this option for several
" years of Vim usage, because I instinctively close windows onto buffers only
" after the buffers within them have been written anyway.
"
" However, the option really is required for batch operations performed with
-" commands like :argdo or :bufdo, because Vim won’t otherwise tolerate
+" commands like :argdo or :bufdo, because Vim won't otherwise tolerate
" unwritten changes to a litany of buffers that are not displayed in any
" window. After I started using such command maps a bit more often,
" I realized I finally had a reason to turn this on permanently.
@@ -589,16 +705,16 @@ set hidden
set hlsearch
nohlsearch
-" Highlight search matches in my text while I’m still typing my pattern,
+" Highlight search matches in my text while I'm still typing my pattern,
" including scrolling the screen to show the first such match if necessary.
" This can be somewhat jarring, particularly when the cursor ends up scrolling
" a long way from home in a large file, but I think the benefits of being able
-" to see instances of what I’m trying to match as I type the pattern do
+" to see instances of what I'm trying to match as I type the pattern do
" outweigh that discomfort.
"
set incsearch
-" Don’t waste cycles and bandwidth redrawing the screen during execution of
+" Don't waste cycles and bandwidth redrawing the screen during execution of
" macro recordings and scripts.
"
set lazyredraw
@@ -615,39 +731,39 @@ set listchars+=trail:- " Trailing spaces
set listchars+=nbsp:+ " Non-breaking spaces
" The next pair of 'list' characters are arguably somewhat misplaced, in that
-" they don’t really represent invisible characters in the same way as the
+" they don't really represent invisible characters in the same way as the
" others, but are hints for the presence of other characters on unwrapped
-" lines that are wider than the screen. They’re very useful, though.
+" lines that are wider than the screen. They're very useful, though.
"
" If the current encoding supports it, use these non-ASCII characters for the
-" markers, as they’re visually distinctive:
+" markers, as they're visually distinctive:
"
" extends: Signals presence of unwrapped text to screen right
" » U+00BB RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
" precedes: Signals presence of unwrapped text to screen left
" « U+00BB LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
"
-" Failing that, ‘<’ and ‘>’ will do the trick.
+" Failing that, `<` and `>` will do the trick.
"
-if has#('multi_byte_encoding')
+if has('multi_byte_encoding')
set listchars+=extends:»,precedes:«
else
set listchars+=extends:>,precedes:<
endif
-" Don’t let your editor’s options be configured by content in arbitrary files!
-" Down with modelines! Purge them from your files! Écrasez l’infâme!
+" Don't let your editor's options be configured by content in arbitrary files!
+" Down with modelines! Purge them from your files! Écrasez l'infâme!
"
-" I think that modelines are Vim’s worst misfeature, and that 'nomodeline'
-" should be the default. It’s enabled pretty bad security vulnerabilities
-" over the years, and it’s a lot more effective to use filetype detection,
+" I think that modelines are Vim's worst misfeature, and that 'nomodeline'
+" should be the default. It's enabled pretty bad security vulnerabilities
+" over the years, and it's a lot more effective to use filetype detection,
" other automatic command hooks, or methods like .editorconfig to set
" variables specifically for a buffer or project.
"
set nomodeline
" The only octal numbers I can think of that I ever even encounter are Unix
-" permissions masks, and I’d never use CTRL-A or CTRL-X to increment them.
+" permissions masks, and I'd never use CTRL-A or CTRL-X to increment them.
" Numbers with leading zeroes are far more likely to be decimals.
"
set nrformats-=octal
@@ -663,7 +779,7 @@ set nrformats-=octal
set noruler
" Sessions preserve window, tab, and buffer layout, and are thereby great for
-" more complex and longer-term projects like books, but they don’t play
+" more complex and longer-term projects like books, but they don't play
" together well with plugins and filetype plugins. Restoring the same
" settings from both reloaded plugins and from the session causes screeds of
" errors. Adjusting session behavior to stop it trying to restore the sorts
@@ -672,74 +788,69 @@ set noruler
set sessionoptions-=localoptions " No buffer options or mappings
set sessionoptions-=options " No global options or mappings
-" Turn 'showcmd' off if a system vimrc has been rude enough to set it; I don’t
+" Turn 'showcmd' off if a system vimrc has been rude enough to set it; I don't
" like how it can interfere with the display of longer lines.
"
set noshowcmd
-" The ‘I’ flag for the 'shortmess' option prevents the display of the Vim
+" The `I` flag for the 'shortmess' option prevents the display of the Vim
" startup screen with version information, :help hints, and donation
-" suggestion. After I registered Vim and donated to Uganda per the screen’s
-" plea, I didn’t feel bad about turning this off anymore. Even with this
-" setting in place, I wouldn’t normally see it too often anyway, as I seldom
+" suggestion. After I registered Vim and donated to Uganda per the screen's
+" plea, I didn't feel bad about turning this off anymore. Even with this
+" setting in place, I wouldn't normally see it too often anyway, as I seldom
" start Vim with no file arguments.
"
-" I haven’t felt the need to mess with the other flags in this option.
-" I don’t have any problems with spurious Enter prompts, which seems to be the
+" I haven't felt the need to mess with the other flags in this option.
+" I don't have any problems with spurious Enter prompts, which seems to be the
" main reason people pile it full of letters.
"
set shortmess+=I
-" We’ll only use the old 'showmatch' method of a brief jump to the matching
-" bracket under the cursor if the much-preferred matchparen.vim standard
-" plugin doesn’t look like it’s going to load, whether because plugins have
-" been disabled, or it’s not in any of the plugin directories.
+" Scrolling by screen line rather than file line makes sense to me. Turn the
+" option to do so on, if it's there. This only works with mouse scrolling,
+" which I don't use, and with CTRL-E, CTRL-Y, which I should be using more
+" anyway.
"
-if !plugin#Ready('matchparen')
- set showmatch matchtime=3
+if exists('+smoothscroll')
+ set smoothscroll
endif
" I find the defaults of new windows opening above or to the left of the
-" previous window too jarring, because I’m used to both the i3 window manager
+" previous window too jarring, because I'm used to both the i3 window manager
" and the tmux terminal multiplexer doing it the other way around, in reading
" order. I prefer the visual effect of the previous text staying where it is,
" and the new window occupying previously blank space.
"
set splitbelow splitright
-" Vim has an internal list of terminal types that support using smoother
-" terminal redrawing, and for which 'ttyfast' is normally set, described in
-" ‘:help 'ttyfast'’. That list includes most of the terminals I use, but
-" there are a couple more for which the 'ttyfast' option should apply: the
-" windows terminal emulator PuTTY, and the terminal multiplexer tmux, both of
-" which I use heavily.
+" I don't like the titles of my terminal windows being changed, especially
+" when changing them back doesn't actually work. Just leave them alone, Vim,
+" even if you think you can handle it.
"
-if &term =~# '^putty\|^tmux'
- set ttyfast
-endif
+set notitle
-" We really don’t want a mouse; while I use it a lot for cut and paste in X,
+" We really don't want a mouse; while I use it a lot for cut and paste in X,
" it just gets in the way if the tool running in the terminal tries to use it
" too. Mouse events should be exclusively handled by the terminal emulator
-" application, so Vim shouldn’t try to give me terminal mouse support, even if
+" application, so Vim shouldn't try to give me terminal mouse support, even if
" it would work.
"
" The manual suggests that disabling this should be done by clearing 't_RV',
-" but that didn’t actually seem to work when I tried it.
+" but that didn't actually seem to work when I tried it.
"
set ttymouse=
" While using virtual block mode, allow me to navigate to any column of the
-" buffer window; don’t confine the boundaries of the block to the coordinates
+" buffer window; don't confine the boundaries of the block to the coordinates
" of characters that actually exist in the buffer text. While working with
-" formatted columnar data with this off is generally OK, it’s a hassle for
+" formatted columnar data with this off is generally OK, it's a hassle for
" more subtle applications of visual block mode.
"
set virtualedit+=block
-" I can’t recall a time that Vim’s error beeping or flashing was actually
+" I can't recall a time that Vim's error beeping or flashing was actually
" useful to me, and so we turn it off in the manner that the manual instructs
-" in ‘:help 'visualbell'’. This enables visual rather than audio error bells,
+" in `:help 'visualbell'`. This enables visual rather than audio error bells,
" but in the same breath, blanks the terminal attribute that would be used to
" trigger such screen blinking, indirectly disabling the bell altogether.
"
@@ -758,7 +869,7 @@ set visualbell t_vb=
"
" The default value of 'full' for the 'wildmode' option puts the full
" completion onto the line immediately, which I tolerate for insert mode
-" completion but don’t really like on the Ex command line. Instead, I arrange
+" completion but don't really like on the Ex command line. Instead, I arrange
" for that to happen only with a second key press.
"
set wildmenu
@@ -766,7 +877,7 @@ set wildmode=list:longest,full
" Define a list of patterns to ignore for file and directory command line
" completion. Files and directories with names matching any of these patterns
-" won’t be presented as candidates for tab completion on the command line.
+" won't be presented as candidates for tab completion on the command line.
"
" To make this list, I went right through my home directory with
" a `find`-toothed comb; counted the occurrences of every extension, forced
@@ -775,7 +886,7 @@ set wildmode=list:longest,full
"
" The following incantation does the trick with POSIX-compatible shell tools,
" giving patterns for the top 100 alphanumeric extensions for files from the
-" running user’s home directory:
+" running user's home directory:
"
" $ (LC_ALL=C ; find "$HOME" ! -type d -name '*.?*' -exec \
" sh -c 'for fn ; do
@@ -790,9 +901,9 @@ set wildmode=list:longest,full
"
" I turned out to have rather a lot of .html and .vim files.
"
-" If you’re scoffing at that and thinking “I could write a much simpler one,”
+" If you're scoffing at that and thinking "I could write a much simpler one,"
" please do so, and send it to me at <tom@sanctum.geek.nz> to have yours put
-" in here instead, with appropriate credit. Don’t forget to handle more than
+" in here instead, with appropriate credit. Don't forget to handle more than
" ARG_MAX files, include filenames with newlines, and that the -z or -0 null
" separator extensions are not standardized in POSIX.
"
@@ -808,12 +919,12 @@ set wildignore=*~,#*#,*.7z,.DS_Store,.git,.hg,.svn,*.a,*.adf,*.asc,*.au,*.aup
" Allow me to type a path to complete on the Ex command line in all-lowercase,
" and transform the consequent completion to match the appropriate case, like
-" the Readline setting ‘completion-ignore-case’ can be used for GNU Bash.
+" the Readline setting `completion-ignore-case` can be used for GNU Bash.
"
" When completing filenames on the command line, choose completions without
" regard to case, allowing me the ease of typing a partial path in
" all-lowercase. This is very similar to the Readline setting
-" ‘completion-ignore-case’ used for Bash.
+" `completion-ignore-case` used for Bash.
"
" The 'wildignorecase' option is not related to the similarly-named
" 'wildignore' option, nor to the +wildmenu feature.
@@ -827,7 +938,7 @@ if exists('+wildignorecase')
set wildignorecase
endif
-" Enable syntax highlighting, but only if it’s not already on, to save
+" Enable syntax highlighting, but only if it's not already on, to save
" reloading the syntax files unnecessarily.
"
" <https://sanctum.geek.nz/blinkenlights/syntax-on.jpg>
@@ -835,33 +946,33 @@ endif
" For several months in 2018, as an experiment, I tried using terminals with
" no color at all, imitating a phenomenally productive BSD purist co-worker
" who abhorred color in any form on his terminals. He only drank black
-" coffee, too. If you’re reading this: Hello, bdh!
+" coffee, too. If you're reading this: Hello, bdh!
"
" That experiment was instructive and interesting, and I found I had been
" leaning on color information in some surprising ways. However, some months
" later, I found I still missed my colors, and so I went back to my
-" Kodachrome roots, and didn’t pine at all for that monochrome world.
+" Kodachrome roots, and didn't pine at all for that monochrome world.
"
" The thing I most like about syntax highlighting is detecting runaway
" strings, which generally works in even the most threadbare language syntax
-" highlighting definitions. I kept missing such errors when I didn’t have the
-" colors. I don’t have high standards for it otherwise, except maybe for
+" highlighting definitions. I kept missing such errors when I didn't have the
+" colors. I don't have high standards for it otherwise, except maybe for
" shell script.
"
if !exists('syntax_on')
syntax enable
endif
-" Before we attempt to pick a syntax highlighting color scheme, we’ll set up
+" Before we attempt to pick a syntax highlighting color scheme, we'll set up
" a couple of hooks for color scheme loading. In this case, we turn
-" 'cursorline' on if my 'sahara' color scheme is loaded, since I’ve configured
-" it to be a very dark gray that doesn’t stand out too much against a black
+" 'cursorline' on if my 'sahara' color scheme is loaded, since I've configured
+" it to be a very dark gray that doesn't stand out too much against a black
" background. For any other color scheme, turn the option off, because it
" almost always stands out too much for my liking.
"
-" You’d think the pattern here could be used to match the color scheme name,
-" and it can be...after patch v7.4.108, when Christian Brabandt fixed it.
-" Until that version, it matched against the current buffer name, so we’re
+" You'd think the pattern here could be used to match the color scheme name,
+" and it can be---after patch v7.4.108, when Christian Brabandt fixed it.
+" Until that version, it matched against the current buffer name, so we're
" forced to have an explicit test in the command instead.
"
" <https://github.com/vim/vim/releases/tag/v7.4.108>
@@ -869,11 +980,11 @@ endif
autocmd vimrc ColorScheme *
\ call colorscheme#UpdateCursorline(g:colors_name, ['sahara'])
-" Use 'dark' as my default value for 'background', in the absence of an
+" Use `dark` as my default value for 'background', in the absence of an
" environment variable COLORFGBG or a response in v:termrbgresp that would set
" it specifically.
"
-if !exists('$COLORFGBG') && get(v:, 'termrbgresp', '') ==# ''
+if !exists('$COLORFGBG') && !get(v:, 'termrbgresp')
set background=dark
endif
@@ -882,7 +993,7 @@ endif
" it.
"
if &background ==# 'dark'
- \ && (has#('gui_running') || &t_Co >= 256)
+ \ && (has('gui_running') || str2nr(&t_Co) >= 256)
\ && globpath(&runtimepath, 'colors/sahara.vim') !=# ''
colorscheme sahara
endif
@@ -903,32 +1014,33 @@ endif
" use selection mode directly.
"
" * Avoid mapping in insert mode; let characters be literal to the greatest
-" extent possible, and avoid “doing more” in insert mode besides merely
-" inserting text as it’s typed.
+" extent possible, and avoid "doing more" in insert mode besides merely
+" inserting text as it's typed.
"
-" * Avoid key chords with Ctrl in favor of leader keys.
+" * Avoid key chords with CTRL in favor of leader keys.
"
" * Never use Alt/Meta key chords; the terminal support for them is just too
" confusing and flaky.
"
-" * Don’t suppress display of mapped commands for no reason; it’s OK to show
-" the user the command that’s being run under the hood. Do avoid HIT-ENTER
+" * Don't suppress display of mapped commands for no reason; it's OK to show
+" the user the command that's being run under the hood. Do avoid HIT-ENTER
" prompts, though.
"
-" * Avoid shadowing any of Vim’s existing functionality. If possible, extend
+" * Avoid shadowing any of Vim's existing functionality. If possible, extend
" or supplement what Vim does, rather than replacing it.
"
-" We’ll start with the non-leader mappings. Ideally, there shouldn’t be too
+" We'll start with the non-leader mappings. Ideally, there shouldn't be too
" many of these.
"
-" Use backspace as an even quicker way to switch to the current buffer’s
-" alternate buffer. User nickspoons of #vim was incredulous that I had never
-" used CTRL-^ and indeed did not know about it. I have since repented.
+" I use Mosh (the mobile shell) a lot, which uses CTRL-^ as its escape key.
+" That shadows Vim's shortcut to switch to the alternate buffer. Map
+" <Backspace> to do that instead.
"
-nnoremap <Backspace> <C-^>
+nnoremap <Backspace>
+ \ <C-^>
-" I find the space bar’s default behavior in normal mode of moving right one
+" I find the space bar's default behavior in normal mode of moving right one
" character to be useless. Instead, I remap it to be a lazy way of paging
" through the argument list buffers, scrolling a page until the last line of
" the buffer is visible, and then moving to the :next buffer.
@@ -937,53 +1049,13 @@ nnoremap <Backspace> <C-^>
"
nnoremap <expr> <Space>
\ line('w$') < line('$')
- \ ? "\<PageDown>"
- \ : ":\<C-U>next\<CR>"
-
-" I hate CTRL-C’s default insert mode behavior. It ends the insert session
-" without firing the InsertLeave event for automatic command hooks. Why would
-" anyone want that? It breaks plugins that hinge on mirrored functionality
-" between the InsertEnter and InsertLeave events, and doesn’t otherwise differ
-" from Escape or :stopinsert. Even worse, people think it’s a *synonym* for
-" Escape, and use it because it’s easier to reach than the Escape key or
-" CTRL-[. Terrible!
-"
-" Instead, I apply a custom plugin named insert_cancel.vim to make it cancel
-" the current insert operation; that is, if the buffer has changed at all
-" since the start of the insert operation, pressing CTRL-C will reverse it,
-" while ending insert mode and firing InsertLeave as normal. This makes way
-" more sense to me, and I use it all the time now.
-"
-" <https://sanctum.geek.nz/cgit/vim-insert-cancel.git/about/>
-"
-" You might think on a first look, as I did, that a plugin is overkill, and
-" that a mapping like this would be all that’s required:
-"
-" :inoremap <C-C> <Esc>u
-"
-" Indeed, it *mostly* works, but there are some subtle problems with it. The
-" primary issue is that if you didn’t make any changes during the insert mode
-" session that you’re terminating, it *still* reverses the previous change,
-" which will be something else entirely that you probably *didn’t* mean to be
-" undone. The plugin’s way of working around this and the other shortcomings
-" of the simple mapping above is not too much more complicated, but it was not
-" easy to figure out.
-"
-" At any rate, we only want to establish the mapping if we can expect the
-" plugin to load, so test that 'loadplugins' is set and that the plugin file
-" exists with the expected filename.
-"
-" If the plugin isn’t available, I just abandon CTRL-C to continue its
-" uselessness.
-"
-if plugin#Ready('insert_cancel')
- imap <C-C> <Plug>(InsertCancel)
-endif
+ \ ? "\<PageDown>"
+ \ : ":\<C-U>next\<CR>"
-" I often can’t remember (or guess) digraph codes, and want to look up how to
+" I often can't remember (or guess) digraph codes, and want to look up how to
" compose a specific character that I can name, at least in part. The table
-" in ‘:help digraph-table’ is what to use for that situation, and it solves
-" the problem, but I didn’t like the overhead of repeated lookups therein.
+" in `:help digraph-table` is what to use for that situation, and it solves
+" the problem, but I didn't like the overhead of repeated lookups therein.
"
" Steve Losh has a solution I liked where a double-tap of CTRL-K in insert
" mode brought up the applicable :help window:
@@ -1002,68 +1074,72 @@ endif
" > Í I' LATIN CAPITAL LETTER I WITH ACUTE
" > ...etc...
"
-" <https://sanctum.geek.nz/cgit/vim-digraph-search.git/about/>
+" <https://dev.sanctum.geek.nz/cgit/vim-digraph-search.git/about/>
"
" This leaves you in insert mode, ready to hit CTRL-K one more time and then
-" type the digraph that you’ve hopefully found.
+" type the digraph that you've hopefully found.
"
-" Since a double-tap of CTRL-K does nothing in default Vim, we don’t bother
-" checking that the plugin’s available before we map to it; it’ll just quietly
+" Since a double-tap of CTRL-K does nothing in default Vim, we don't bother
+" checking that the plugin's available before we map to it; it'll just quietly
" do nothing.
"
-imap <C-K><C-K> <Plug>(DigraphSearch)
+imap <C-K><C-K>
+ \ <Plug>(DigraphSearch)
" I end up hitting CTRL-L to clear or redraw the screen in interactive shells
" and tools like Mutt and Vim pretty often. It feels natural to me to stack
" issuing a :nohlsearch command to stop highlighting searches on top of this.
"
-" This gets by far the most use in normal mode, but I’d like it to work in
-" insert and visual modes, too, where it’s occasionally useful, especially on
+" This gets by far the most use in normal mode, but I'd like it to work in
+" insert and visual modes, too, where it's occasionally useful, especially on
" things like mobile phone terminal emulators that can be choppy and require
" a lot of redrawing.
"
" For each of these, we end the mapping with a CTRL-L in normal mode, thereby
-" extending rather than replacing Vim’s normal behavior.
+" extending rather than replacing Vim's normal behavior.
"
nnoremap <C-L>
\ :<C-U>nohlsearch<CR><C-L>
" The insert mode wrapper for normal CTRL-L uses i_CTRL-O to issue a single
-" normal mode command. We intentionally use ‘:normal’ rather than ‘:normal!’
+" normal mode command. We intentionally use `:normal` rather than `:normal!`
" so that the mapping works recursively. I tried using <C-O><C-L> with :imap
-" for this, but it didn’t work. Maybe i_CTRL-O doesn’t respect mappings.
-" I couldn’t find any documentation about it.
+" for this, but it didn't work. Maybe i_CTRL-O doesn't respect mappings.
+" I couldn't find any documentation about it.
"
-inoremap <C-L> <C-O>:execute "normal \<C-L>"<CR>
+inoremap <C-L>
+ \ <C-O>:execute "normal \<C-L>"<CR>
-" We use :vnoremap here rather than :xnoremap and thereby make the mapping
-" apply to select mode as well, because CTRL-L doesn’t reflect a printable
-" character, and so we may as well make it work, even though I don’t actually
-" use select mode directly.
+" We use :vmap here rather than :xmap to have the mapping applied for select
+" mode as well as visual mode. This is because CTRL-L doesn't reflect
+" a printable character, and so we don't shadow anything by making it work,
+" even though I don't actually use select mode directly very much.
"
-vmap <C-L> <Esc><C-L>gv
+vmap <C-L>
+ \ <Esc><C-L>gv
-" By default, the very-useful normal mode command ‘&’ that repeats the
-" previous :substitute command doesn’t preserve the flags from that
-" substitution. I’d prefer it to do so, like the :&& command does, and it’s
-" easily remapped for both normal and visual mode, so let’s just do it.
+" By default, the very-useful normal mode command `&` that repeats the
+" previous :substitute command doesn't preserve the flags from that
+" substitution. I'd prefer it to do so, like the :&& command does, and it's
+" easily remapped for both normal and visual mode, so let's just do it.
"
noremap &
\ :&&<CR>
ounmap &
sunmap &
-" I really like using the ‘!’ command in normal mode as an operator to filter
+" I really like using the `!` command in normal mode as an operator to filter
" text through a shell command. It always bugged me a little that there
-" didn’t seem to be an analogue for a motion to filter text through an
+" didn't seem to be an analogue for a motion to filter text through an
" internal command like :sort, so I wrote one.
"
-" <https://sanctum.geek.nz/cgit/vim-colon-operator.git/about/>
+" <https://dev.sanctum.geek.nz/cgit/vim-colon-operator.git/about/>
"
-nmap g: <Plug>(ColonOperator)
+nmap g:
+ \ <Plug>(ColonOperator)
-" I used Tim Pope’s unimpaired.vim plugin for ages, and I liked some of these
-" bracket pair mappings, so I’ve carried a few of the simpler ones over. All
+" I used Tim Pope's unimpaired.vim plugin for ages, and I liked some of these
+" bracket pair mappings, so I've carried a few of the simpler ones over. All
" of these can be prefixed with a count if needed, too. I use all of them
" pretty regularly, even though cycling through lists to look for something
" can be a bit wasteful.
@@ -1089,24 +1165,26 @@ nnoremap [l
nnoremap ]l
\ :lnext<CR>
-" Here’s another mapping I particularly liked from unimpaired.vim; insert
+" Here's another mapping I particularly liked from unimpaired.vim; insert
" blank lines from normal mode, using a custom plugin of mine called
-" put_blank_lines.vim. These use operator functions so that they’re
+" put_blank_lines.vim. These use operator functions so that they're
" repeatable without repeat.vim. They accept count prefixes, too.
"
-" <https://sanctum.geek.nz/cgit/vim-put-blank-lines.git/about/>
+" <https://dev.sanctum.geek.nz/cgit/vim-put-blank-lines.git/about/>
"
-nmap [<Space> <Plug>(PutBlankLinesAbove)
-nmap ]<Space> <Plug>(PutBlankLinesBelow)
+nmap [<Space>
+ \ <Plug>(PutBlankLinesAbove)
+nmap ]<Space>
+ \ <Plug>(PutBlankLinesBelow)
-" We’re on to the leader maps, now. It’s difficult to know in what order to
+" We're on to the leader maps, now. It's difficult to know in what order to
" describe and specify these. I used to have them in alphabetical order, but
" it seems much more useful to group them by the type of action they take.
"
-" First of all, let’s set the leader keys; backslash happens to be the
-" default, but I like to make my choice explicit here. As of 2019, I’m still
+" First of all, let's set the leader keys; backslash happens to be the
+" default, but I like to make my choice explicit here. As of 2019, I'm still
" not certain that comma is the best choice for my local leader. I use it all
-" the time for this purpose, and it works well, but I don’t much like that it
+" the time for this purpose, and it works well, but I don't much like that it
" shadows a useful function in the fFtT;, group, and I sometimes wonder if
" I would use the key for its original function more, had I not shadowed it.
"
@@ -1118,24 +1196,25 @@ let maplocalleader = ','
" relying on mapping 'timeout'.
"
if maplocalleader ==# ','
- noremap ,, ,
+ noremap ,,
+ \ ,
sunmap ,,
endif
-" Let’s start with some simple ones; these ones all just toggle a boolean
-" option, and print its new value. They’re dirt simple to specify, and don’t
+" Let's start with some simple ones; these ones all just toggle a boolean
+" option, and print its new value. They're dirt simple to specify, and don't
" require any plugins.
"
-" These are sometimes applicable in visual mode, and sometimes not. We’ll
+" These are sometimes applicable in visual mode, and sometimes not. We'll
" start with the ones that only make sense as normal mode maps. Annoyingly,
-" a visual mode mapping for 'cursorline' toggling doesn’t work at all;
+" a visual mode mapping for 'cursorline' toggling doesn't work at all;
" 'cursorline' is always off when in any visual mode, including block mode,
" where it actually might have been really handy.
"" Leader,TAB toggles automatic indentation based on the previous line
nnoremap <Leader><Tab>
\ :<C-U>set autoindent! autoindent?<CR>
-"" Leader,c toggles highlighted cursor row; doesn’t work in visual mode
+"" Leader,c toggles highlighted cursor row; doesn't work in visual mode
nnoremap <Leader>c
\ :<C-U>set cursorline! cursorline?<CR>
"" Leader,h toggles highlighting search results
@@ -1178,17 +1257,10 @@ noremap <Leader>w
ounmap <Leader>w
sunmap <Leader>w
-" This next one just shows option state of the 'formatoptions' affecting how
-" text is automatically formatted; it doesn’t change its value.
-
-"" Leader,f shows the current 'formatoptions' at a glance
-nnoremap <Leader>f
- \ :<C-U>set formatoptions?<CR>
-
" I often have to switch between US English and NZ English. The latter is
" almost exactly the same as UK English in most locales, although we use
" dollars rather than pounds. This is mostly so I remember things like
-" excluding or including the ‘u’ in words like 'favourite', depending on the
+" excluding or including the `u` in words like `favourite`, depending on the
" target audience. I generally use US English for international audiences.
"
nnoremap <Leader>z
@@ -1196,33 +1268,45 @@ nnoremap <Leader>z
nnoremap <Leader>u
\ :<C-U>set spelllang=en_us<CR>
-" The next mapping is also for toggling an option, but it’s more complicated;
+" I've also been trying to learn French lately (2023-04-03), and having
+" a spelling check there is handy for doing my homework.
+"
+" This mapping used to show the state of 'formatoptions', but I haven't been
+" using that nearly as often lately.
+"
+" <https://sanctum.geek.nz/images/ze-cultured-frenchman.png>
+"
+nnoremap <Leader>f
+ \ :<C-U>set spelllang=fr<CR>
+
+" The next mapping is also for toggling an option, but it's more complicated;
" it uses a simple plugin of mine called copy_linebreak.vim to manage several
" options at once, related to the 'wrap' option that soft-wraps text.
"
-" It’s designed for usage in terminal emulators and multiplexers to
+" It's designed for usage in terminal emulators and multiplexers to
" temporarily make the buffer text suitable for copying in such a way that the
-" wrapping and any associated soft formatting won’t pervert the text,
+" wrapping and any associated soft formatting won't pervert the text,
" including 'breakindent', 'linebreak', and 'showbreak' artifacts.
"
" This is really handy for quick selections of small regions of text. For
" larger blocks of text or for manipulating the text as it leaves the buffer,
" it makes more sense to use :! commands.
"
-" <https://sanctum.geek.nz/cgit/vim-copy-linebreak.git/about/>
+" <https://dev.sanctum.geek.nz/cgit/vim-copy-linebreak.git/about/>
"
"" Leader,b toggles settings friendly to copying and pasting
-nmap <Leader>b <Plug>(CopyLinebreakToggle)
+nmap <Leader>b
+ \ <Plug>(CopyLinebreakToggle)
" The above mappings show that mappings for toggling boolean options are
-" simple, but there isn’t a way to toggle single flags within option strings
+" simple, but there isn't a way to toggle single flags within option strings
" with just the :set command, so I wrote a plugin called toggle_flags.vim to
" provide :ToggleFlag and :ToggleFlagLocal commands. The first argument is
" the name of an option, and the second is the flag within it that should be
" toggled on or off.
-"" Leader,a toggles 'formatoptions' ‘a’ auto-flowing flag
+"" Leader,a toggles 'formatoptions' `a` auto-flowing flag
nnoremap <Leader>a
\ :<C-U>ToggleFlagLocal formatoptions a<CR>
"" Leader,L toggles 'colorcolumn' showing the first column beyond 'textwidth'
@@ -1232,12 +1316,13 @@ ounmap <Leader>L
sunmap <Leader>L
" This mapping uses my paste_insert.vim plugin to queue up automatic commands
-" for the next insert operation. It’s still pretty new. It replaces my old
+" for the next insert operation. It's still pretty new. It replaces my old
" paste_open.vim plugin which did this only for opening new lines, and which
-" kept confusing me. I’m hoping this will be better.
+" kept confusing me. I'm hoping this will be better.
"" Leader,p prepares the next insert for paste mode
-nmap <Leader>p <Plug>PasteInsert
+nmap <Leader>p
+ \ <Plug>PasteInsert
" These mappings are for managing filetypes. The first one uses the
" :ReloadFileType command that was defined much earlier in this file for
@@ -1264,20 +1349,19 @@ nnoremap <Leader>D
\ :PutDate!<CR>
" This group contains mappings that are to do with file and path management
-" relative to the current buffer. The Leader,P mapping that creates
-" directory hierarchies uses the :CreatePath command created earlier.
+" relative to the current buffer.
-"" Leader,g shows the current file’s fully expanded path
+"" Leader,g shows the current file's fully expanded path
nnoremap <Leader>g
\ :<C-U>echo expand('%:p')<CR>
-"" Leader,G changes directory to the current file’s location
+"" Leader,G changes directory to the current file's location
nnoremap <Leader>G
- \ :<C-U>cd %:h<Bar>pwd<CR>
-"" Leader,P creates the path to the current file if it doesn’t exist
+ \ :<C-U>cd %:h <Bar> pwd<CR>
+"" Leader,P creates the path to the current file if it doesn't exist
nnoremap <Leader>P
- \ :<C-U>CreatePath %:h<CR>
+ \ :<C-U>call mkdir(expand('%:h'), 'p')<CR>
-" This group contains mappings that show information about Vim’s internals:
+" This group contains mappings that show information about Vim's internals:
" marks, registers, variables, and the like.
"" Leader,H shows command history
@@ -1312,8 +1396,8 @@ nnoremap <Leader>y
\ :<C-U>registers<CR>
" This group contains mappings concerned with buffer navigation and
-" management. I use the “jetpack” buffer jumper one a lot. I got it from one
-" of bairui’s “Vim and Vigor” comics:
+" management. I use the "jetpack" buffer jumper one a lot. I got it from one
+" of bairui's "Vim and Vigor" comics:
"
" <http://of-vim-and-vigor.blogspot.com/p/vim-vigor-comic.html>
@@ -1329,27 +1413,28 @@ nnoremap <Leader>e
"" Leader,E locks a buffer, reversible with <Leader>e
nnoremap <Leader>E
\ :<C-U>set nomodifiable readonly<CR>
-"" Leader,j jumps to buffers—the “jetpack”
+"" Leader,j jumps to buffers---the "jetpack"
nnoremap <Leader>j
\ :<C-U>buffers<CR>:buffer<Space>
" Leader,o hacks up the list of old files from viminfo just long enough to
-" ensure that :browse :oldfiles fits in a screen, avoiding an Enter or ‘q’
+" ensure that :browse :oldfiles fits in a screen, avoiding an Enter or `q`
" keystroke before entering the number. This one is handy followed by
" <Leader>,\ to jump back to the last remembered position in that file, since
" by definition viminfo remembers that mark, too.
"
-nmap <Leader>o <Plug>(SelectOldFiles)
+nmap <Leader>o
+ \ <Plug>(SelectOldFiles)
" This group defines mappings for filtering and batch operations to clean up
" buffer text. All of these mappings use commands from my custom plugins:
"
" :KeepPosition
-" <https://sanctum.geek.nz/cgit/vim-keep-position.git/about/>
+" <https://dev.sanctum.geek.nz/cgit/vim-keep-position.git/about/>
" :SqueezeRepeatBlanks
-" <https://sanctum.geek.nz/cgit/vim-squeeze-repeat-blanks.git/about/>
+" <https://dev.sanctum.geek.nz/cgit/vim-squeeze-repeat-blanks.git/about/>
" :StripTrailingWhitespace
-" <https://sanctum.geek.nz/cgit/vim-strip-trailing-whitespace.git/about/>
+" <https://dev.sanctum.geek.nz/cgit/vim-strip-trailing-whitespace.git/about/>
"
"" Leader,x strips trailing whitespace
@@ -1371,7 +1456,7 @@ nnoremap <Leader>+
\ :<C-U>KeepPosition execute 'normal! 1GgqG'<CR>
" This group defines a few :onoremap commands to make my own text objects.
-" I should probably make some more of these, as they’ve proven to be
+" I should probably make some more of these, as they've proven to be
" terrifically handy.
"" Leader,_ uses last changed or yanked text as an object
@@ -1380,21 +1465,25 @@ onoremap <Leader>_
"" Leader,% or Leader,5 uses entire buffer as an object
onoremap <Leader>%
\ :<C-U>execute 'normal! 1GVG'<CR>
-omap <Leader>5 <Leader>%
+omap <Leader>5
+ \ <Leader>%
" This group defines some useful motions, including navigating by indent
" block using a custom plugin:
"
-" <https://sanctum.geek.nz/cgit/vim-vertical-region.git/about/>
+" <https://dev.sanctum.geek.nz/cgit/vim-vertical-region.git/about/>
"
"" Leader,{ and Leader,} move to top and bottom of indent region
-map <Leader>{ <Plug>(VerticalRegionUp)
+map <Leader>{
+ \ <Plug>(VerticalRegionUp)
sunmap <Leader>{
-map <Leader>} <Plug>(VerticalRegionDown)
+map <Leader>}
+ \ <Plug>(VerticalRegionDown)
sunmap <Leader>}
-"" Leader,\ jumps to the last edit position mark; think “Now, where was I?”
-noremap <Leader>\ `"
+"" Leader,\ jumps to the last edit position mark; think "Now, where was I?"
+noremap <Leader>\
+ \ `"
sunmap <Leader>\
" This group does both: useful motions on defined text objects.
@@ -1414,88 +1503,109 @@ nnoremap <Leader>/
nnoremap <Leader>?
\ :<C-U>lhelpgrep \c<S-Left>
-" This group contains miscellaneous mappings for which I couldn’t find any
+" This group contains miscellaneous mappings for which I couldn't find any
" other place. The plugin mappings probably require their own documentation
" comment block, but my hands are getting tired from all this typing.
"
-" * <https://sanctum.geek.nz/cgit/vim-alternate-filetype.git/about/>
-" * <https://sanctum.geek.nz/cgit/vim-regex-escape.git/about/>
-" * <https://sanctum.geek.nz/cgit/vim-replace-operator.git/about/>
-" * <https://sanctum.geek.nz/cgit/vim-scratch-buffer.git/about/>
+" * <https://dev.sanctum.geek.nz/cgit/vim-alternate-filetype.git/about/>
+" * <https://dev.sanctum.geek.nz/cgit/vim-regex-escape.git/about/>
+" * <https://dev.sanctum.geek.nz/cgit/vim-replace-operator.git/about/>
+" * <https://dev.sanctum.geek.nz/cgit/vim-scratch-buffer.git/about/>
"
"" Leader,. runs the configured make program into the location list
nnoremap <Leader>.
\ :<C-U>lmake!<CR>
"" Leader,q formats the current paragraph
-nnoremap <Leader>q gqap
+nnoremap <Leader>q
+ \ gqap
"" Leader,r acts as a replacement operator
-map <Leader>r <Plug>(ReplaceOperator)
+map <Leader>r
+ \ <Plug>(ReplaceOperator)
ounmap <Leader>r
sunmap <Leader>r
"" Leader,!/1 repeats the last command, adding a bang
nnoremap <Leader>!
\ :<Up><Home><S-Right>!<CR>
-nmap <Leader>1 <Leader>!
-"" Leader,#/3 switches the current buffer to the next altenate filetype
-nmap <Leader># <Plug>(AlternateFileType)
-nmap <Leader>3 <Leader>#
-"" Leader,$/4 gives me my fortune
-nmap <Leader>$ <Plug>(Fortune)
-nmap <Leader>4 <Leader>$
+nmap <Leader>1
+ \ <Leader>!
+"" Leader,#/3 switches the current buffer to the next alternate filetype
+nmap <Leader>#
+ \ <Plug>(AlternateFileType)
+nmap <Leader>3
+ \ <Leader>#
"" Leader,&/7 escapes regex metacharacters
-map <Leader>& <Plug>(RegexEscape)
+map <Leader>&
+ \ <Plug>(RegexEscape)
ounmap <Leader>&
sunmap <Leader>&
-map <Leader>7 <Leader>&
+map <Leader>7
+ \ <Leader>&
ounmap <Leader>7
sunmap <Leader>7
"" Leader,*/8 is "sticky star":
"" - Set search string to word under cursor
"" - Show search highlighting if it's enabled
"" - Don't move the cursor
-nnoremap <silent> <Leader>*
- \ :<C-U>let @/ = expand('<cword>')<CR>:let &hlsearch = &hlsearch<CR>
-nmap <Leader>8 <Leader>*
+nnoremap <Leader>*
+ \ :<C-U>let @/ = expand('<cword>') <Bar> let &hlsearch = &hlsearch<CR>
+nmap <Leader>8
+ \ <Leader>*
"" Leader,` opens a scratch buffer, horizontally split
-nnoremap <silent> <Leader>`
+nnoremap <Leader>`
\ :<C-U>ScratchBuffer<CR>
"" Leader,~ opens a scratch buffer, vertically split
-nnoremap <silent> <Leader>~
+nnoremap <Leader>~
\ :<C-U>vertical ScratchBuffer<CR>
-" And last, but definitely not least, I’m required by Vim fanatic law to
+" There's no digraph for ZERO WIDTH SPACE (U+200B), which I often need to work
+" around word boundary problems in tagging people on the Fediverse.
+"
+digraphs zs 8203
+
+" And last, but definitely not least, I'm required by Vim fanatic law to
" include a mapping that reloads my whole configuration. This uses the
" command wrapper defined much earlier in the file, so that filetypes also get
-" reloaded afterwards, meaning I don’t need to follow <Leader>R with
+" reloaded afterwards, meaning I don't need to follow <Leader>R with
" a <Leader>F to fix up broken global settings.
"
nnoremap <Leader>R
\ :<C-U>ReloadVimrc<CR>
-" I’ll close this file with a few abbreviations. Perhaps of everything in
-" here, I’m least confident that these should be in here, but they’ve proven
+" I'll close this file with a few abbreviations. Perhaps of everything in
+" here, I'm least confident that these should be in here, but they've proven
" pretty useful. First, some 'deliberate' abbreviations for stuff I type
" a lot:
"
-inoreabbrev tr@ tom@sanctum.geek.nz
-inoreabbrev tr/ <https://sanctum.geek.nz/>
+inoreabbrev tr@
+ \ tom@sanctum.geek.nz
+inoreabbrev tr/
+ \ <https://sanctum.geek.nz/>
" And then, just automatically fix some things I almsot always spell or type
" wrnog.
"
-inoreabbrev almsot almost
-inoreabbrev wrnog wrong
-inoreabbrev Fielding Feilding
-inoreabbrev THe The
-inoreabbrev THere There
+inoreabbrev almsot
+ \ almost
+inoreabbrev wrnog
+ \ wrong
+inoreabbrev Fielding
+ \ Feilding
+inoreabbrev Newsbeuter
+ \ Newsboat
+inoreabbrev newsbeuter
+ \ newsboat
+inoreabbrev THe
+ \ The
+inoreabbrev THere
+ \ There
" Here endeth the literate vimrc. Let us praise God.
"
-" │ Consequently, it is soon recognized that they write for the sake of
-" │ filling up the paper, and this is the case sometimes with the best
-" │ authors…as soon as this is perceived the book should be thrown away,
-" │ for time is precious.
-" │
-" │ —Schopenhauer
+" > Consequently, it is soon recognized that they write for the sake of
+" > filling up the paper, and this is the case sometimes with the best
+" > authors...as soon as this is perceived the book should be thrown away,
+" > for time is precious.
+" >
+" > ---Schopenhauer
"
diff --git a/vim/vimrc.stub b/vim/vimrc.stub
index d50cee55..2acd2d10 100644
--- a/vim/vimrc.stub
+++ b/vim/vimrc.stub
@@ -1,23 +1,25 @@
" We have a big, important decision to make here.
"
-" Check that we’re not running in 'compatible' mode, nor that the environment
-" calls for the same, and that we’re running Vim v7.0.0 or newer. If it’s all
+" Check that we're not running in 'compatible' mode, nor that the environment
+" calls for the same, and that we're running Vim v7.0.0 or newer. If it's all
" clear, we can load the main vimrc file from ~/.vim/vimrc to use Vim in all
" of its incompatible glory, and then stop sourcing the rest of this file.
"
-if !&compatible && !exists('$POSIXLY_CORRECT') && v:version >= 700
- runtime vimrc
- finish
+if !&compatible && !exists('$POSIXLY_CORRECT')
+ if v:version >= 700
+ runtime vimrc
+ finish
+ endif
endif
-" If we got this far, it means we’re running a tiny, 'compatible', and/or
-" ancient version of Vim.
-"
-" So, strip out the user runtime directories from 'runtimepath', force
-" 'compatible' on, source your trusty ‘~/.exrc’, put on your dubbed cassette
-" copy of Kraftwerk’s ‘Computerwelt’, and start using vi v3.7 on your
-" engineering department’s Sun OS 4.x server via your VT220 terminal. It’s
-" July 1985, you write K&R C, and it’s good for you, like raisin bran.
+" If we got this far, it means we're running a tiny, 'compatible', and/or
+" ancient version of Vim. So: strip out the user runtime dirs from
+" 'runtimepath', force 'compatible' on, :source your trusty ~/.exrc, put on
+" your dubbed cassette copy of Kraftwerk's 'Computerwelt', and start using vi
+" v3.7 on your engineering department's SunOS 2.0 server via your shiny new
+" VT220 terminal. It's December 1985, and you're going home soon for the
+" holidays. You're writing K&R C tonight. It's good for you, like raisin
+" bran.
"
set runtimepath-=~/.vim
set runtimepath-=~/.vim/after
diff --git a/vint/vintrc.yaml b/vint/vintrc.yaml
index 1a9900df..a5ba9380 100644
--- a/vint/vintrc.yaml
+++ b/vint/vintrc.yaml
@@ -1,3 +1,3 @@
# Show me all my problems, including matters of style
cmdargs:
- severity: style_problem
+ severity: style_problem
diff --git a/wget/profile.d/wget.sh b/wget/profile.d/wget.sh
new file mode 100644
index 00000000..884f19ed
--- /dev/null
+++ b/wget/profile.d/wget.sh
@@ -0,0 +1,5 @@
+# Set path to wgetrc file in XDG dirs. There's no mention of this environment
+# variable in the man page! I had to check the source.
+#
+WGETRC=${XDG_CONFIG_HOME:-$HOME/.config}/wget/wgetrc
+export WGETRC
diff --git a/x/Xresources b/x/Xresources
new file mode 100644
index 00000000..829b208e
--- /dev/null
+++ b/x/Xresources
@@ -0,0 +1,106 @@
+/* Declare our xterms have 256 colors */
+XTerm.termName: xterm-256color
+
+/**
+ * Just use "xterm" as the title, no need to complicate it with the name of the
+ * actual binary called.
+ */
+XTerm.title: xterm
+
+/**
+ * Don't pass mouse events to applications, even if they ask for it; mouse
+ * interaction with command-line tools isn't normally very well-written anyway.
+ * Better just to treat it as text.
+ */
+XTerm.vt100.allowMouseOps: false
+
+/**
+ * Don't let applications set the window title; it's usually more confusing
+ * than helpful, with things like command wrappers getting in the way.
+ */
+XTerm.vt100.allowTitleOps: false
+
+/* Don't munge characters' 8th bit with Alt, send Escape prefix instead */
+XTerm.vt100.altIsNotMeta: true
+XTerm.vt100.altSendsEscape: true
+
+/* Flash my window manager if a BEL is sounded in an xterm */
+XTerm.vt100.bellIsUrgent: true
+
+/**
+ * Stick all of the non-control ASCII characters into the same xterm selection
+ * group as the alphanumeric ones added by default, except for space and the
+ * left and right angle brackets (less-than and greater-than), because being
+ * able to click URLs quickly outweighs anything else.
+ */
+XTerm.vt100.charClass: \
+ 33-59:48, \
+ 60:60, \
+ 61:48, \
+ 62:60, \
+ 63-126:48
+
+/**
+ * Set some less harsh colors than the xterm defaults; I think I got these from
+ * somewhere else and tweaked them, but I can't remember where it was now.
+ */
+XTerm.vt100.background: rgb:03/03/03
+XTerm.vt100.foreground: rgb:e0/e0/e0
+XTerm.vt100.color0: rgb:03/03/03
+XTerm.vt100.color1: rgb:cc/00/00
+XTerm.vt100.color2: rgb:3e/aa/06
+XTerm.vt100.color3: rgb:c4/a0/00
+XTerm.vt100.color4: rgb:34/65/a4
+XTerm.vt100.color5: rgb:75/50/7b
+XTerm.vt100.color6: rgb:06/98/9a
+XTerm.vt100.color7: rgb:d3/d7/cf
+XTerm.vt100.color8: rgb:30/30/30
+XTerm.vt100.color9: rgb:ef/29/29
+XTerm.vt100.color10: rgb:7a/f2/34
+XTerm.vt100.color11: rgb:fc/e9/4f
+XTerm.vt100.color12: rgb:72/9f/cf
+XTerm.vt100.color13: rgb:ad/7f/a8
+XTerm.vt100.color14: rgb:34/e2/e2
+XTerm.vt100.color15: rgb:ee/ee/ec
+
+/**
+ * Use Ubuntu Mono as a TrueType font if I decide to switch to it, but default
+ * to using the default bitmap font.
+ */
+XTerm.vt100.faceName: xft:Ubuntu Mono
+XTerm.vt100.faceSize: 9
+XTerm.vt100.renderFont: defaultOff
+
+/**
+ * Draw our own box characters, even if the font seems to support them. Using
+ * Ubuntu Mono at least, this removes gaps between vertical lines.
+ */
+XTerm.vt100.forceBoxChars: true
+
+/**
+ * Put the terminal text contents flush against the edges of the window,
+ * otherwise things like tmux look awkward.
+ */
+XTerm.vt100.internalBorder: 0
+
+/**
+ * Jump to the end of the buffer if I write to it, but don't if there's just
+ * something new to read. Funny how the defaults are the other way around...
+ */
+XTerm.vt100.scrollKey: true
+XTerm.vt100.scrollTtyOutput: false
+
+/**
+ * Bind extra keys to copy/paste to/from CLIPBOARD rather than PRIMARY, as
+ * a simple selection does.
+ */
+XTerm.vt100.translations: #override \n\
+ Ctrl Shift <Key>C: copy-selection(CLIPBOARD) \n\
+ Ctrl Shift <Key>V: insert-selection(CLIPBOARD)
+
+/**
+ * Trim trailing spaces from selections; if I'm copying text from a terminal
+ * emulator window, I probably don't want it byte-perfect for hashing purposes
+ * or anything like that.
+ */
+XTerm.vt100.trimSelection: true
diff --git a/x/logrotate/config.d/xsession b/x/logrotate/config.d/xsession
new file mode 100644
index 00000000..1541375d
--- /dev/null
+++ b/x/logrotate/config.d/xsession
@@ -0,0 +1,7 @@
+~/.xsession-errors {
+ copytruncate
+ daily
+ missingok
+ olddir .local/state/xsession/log
+ rotate 30
+}
diff --git a/sh/shrc.d/x.sh b/x/shrc.d/x.sh
index ed921c68..ed921c68 100644
--- a/sh/shrc.d/x.sh
+++ b/x/shrc.d/x.sh
diff --git a/x/xsession.sh b/x/xsession.sh
new file mode 100644
index 00000000..9cf4a99a
--- /dev/null
+++ b/x/xsession.sh
@@ -0,0 +1,64 @@
+#
+# Custom i3wm X session to fit into Debian's way of doing things, for use with
+# startx(1) or xinit(1). From Debian's `man 1 startx` (xinit dpkg 1.4.0-1):
+#
+# > Note that in the Debian system, what many people traditionally put in the
+# > .xinitrc file should go in .xsession instead; this permits the same X
+# > environment to be presented whether startx, xdm, or xinit is used to start
+# > the X session. All discussion of the .xinitrc file in the xinit(1) manual
+# > page applies equally well to .xsession.
+#
+# This turns out to be important for having the X session wrappers in /etc/X11
+# on Debian-derived systems do things like dbus daemon and accessibility setup.
+#
+# At the time of writing, none of my machines running X are using anything
+# other than the Debian-derived X startup script layout, so we'll just conform
+# to that unless and until I actually need to abstract this.
+#
+
+# Monitor and wallpaper setup is very machine-specific, and isn't versioned in
+# here. Neither xrandr(1) nor xwallpaper(1) have config files, so we fake it
+# with xargs and looking for a file with argument tokens to read in
+# XDG_CONFIG_HOME, which will almost always be:
+#
+# - ~/.config/xrandr/config
+# - ~/.config/xwallpaper/config
+#
+xargs xrandr \
+ < "${XDG_CONFIG_HOME:-"$HOME"/.config}"/xrandr/config
+xargs xwallpaper \
+ < "${XDG_CONFIG_HOME:-"$HOME"/.config}"/xwallpaper/config
+
+# Set a few X user preferences:
+#
+# - No bell
+# - Power management on, but start with no timeouts
+# - Quick curved mouse acceleration
+# - No screen saver
+#
+xset \
+ b off \
+ dpms 0 0 0 \
+ mouse 5/2 0 \
+ s off
+
+# Start a few daemons if we can; it's OK if any of these don't exist, but we'll
+# log the failed attempt to start them to the errors file, as a hint that
+# I might want to install them.
+#
+## Message display (libnotify)
+dunst &
+## PulseAudio system tray tool
+pasystray &
+## Hide mouse after inactivity
+unclutter &
+
+# Load all supplementary scripts in ~/.xsession.d
+for sh in "$HOME"/.xsession.d/*.sh ; do
+ [ -e "$sh" ] || continue
+ . "$sh"
+done
+unset -v sh
+
+# Become an i3 window manager process, having set everything else up
+exec i3
diff --git a/x/xsessionrc b/x/xsessionrc
new file mode 100644
index 00000000..8d46ed0b
--- /dev/null
+++ b/x/xsessionrc
@@ -0,0 +1,17 @@
+# X startup commands go in here if they should run on every X session, whether
+# classic `startx` or a modern DE like LightDM. xsessionrc is a dpkg-specific
+# file.
+#
+
+# If $ENV isn't set, then this X startup process wasn't started from somewhere
+# beneath a login shell that sources ~/.profile to set up environment variables
+# yet, most likely because it's being opened by a display manager, so we'll do
+# it here.
+#
+if [ -z "$ENV" ] ; then
+ . "$HOME"/.profile
+fi
+
+# Update BROWSER, since .profile has already set this to a curses browser
+# shellcheck disable=SC2034
+BROWSER=x-www-browser
diff --git a/zsh/zshrc b/zsh/zshrc
index 0aac527e..30e7173b 100644
--- a/zsh/zshrc
+++ b/zsh/zshrc
@@ -15,10 +15,10 @@ bindkey -e
# History settings
setopt histignorealldups sharehistory
HISTFILE=$HOME/.zsh_history
-SAVEHIST=$((1 << 12))
+SAVEHIST=4096
# Load Zsh-specific startup files
-for zsh in "$HOME"/.zshrc.d/*.zsh ; do
+for zsh in "$HOME"/.zshrc.d/*.zsh(N) ; do
[[ -e $zsh ]] || continue
source "$zsh"
done
diff --git a/zsh/zshrc.d/keep.zsh b/zsh/zshrc.d/keep.zsh
index 869d2039..36d2f57d 100644
--- a/zsh/zshrc.d/keep.zsh
+++ b/zsh/zshrc.d/keep.zsh
@@ -29,7 +29,7 @@ keep() {
# Figure out the directory to which we're reading and writing these scripts
local zshkeep
- zshkeep=${ZSHKEEP:-"$HOME"/.zshkeep.d}
+ zshkeep=${XDG_DATA_HOME:-"$HOME"/.local/share}/zshkeep
mkdir -p -- "$zshkeep" || return
# Parse options
@@ -89,8 +89,8 @@ EOF
case $name in
# NAME must start with letters or an underscore, and contain no
- # characters besides letters, numbers, or underscores
- *[!a-zA-Z0-9_]*|[!a-zA-Z_]*)
+ # characters besides letters, numbers, underscores, or dashes
+ [!a-zA-Z_]*|*[!a-zA-Z0-9_-]*)
printf 'zsh: %s: %s not a valid NAME\n' \
"${FUNCNAME[0]}" "$name" >&2
((errors++))
@@ -141,7 +141,7 @@ EOF
}
# Load any existing scripts in zshkeep
-for zshkeep in "${ZSHKEEP:-"$HOME"/.zshkeep.d}"/*.zsh(N) ; do
+for zshkeep in "${XDG_DATA_HOME:-"$HOME"/.local/share}"/zshkeep/*.zsh(N) ; do
[[ -e $zshkeep ]] || continue
source "$zshkeep"
done
diff --git a/zsh/zshrc.d/prompt.zsh b/zsh/zshrc.d/prompt.zsh
index 980d8669..245f2973 100644
--- a/zsh/zshrc.d/prompt.zsh
+++ b/zsh/zshrc.d/prompt.zsh
@@ -8,22 +8,23 @@ prompt() {
on)
setopt promptsubst promptpercent
- # Basic prompt shape depends on whether we're in SSH or not
+ # Prompt has hostname via SSH outside of screen/tmux
PS1=
- if [[ -n $SSH_CLIENT || -n $SSH_CONNECTION ]] ; then
+ if [[ -n $SSH_CLIENT && -z $STY && -z $TMUX ]] ; then
PS1=$PS1'%m:'
fi
PS1=$PS1'%~'
- # Add sub-commands; VCS, job, and return status checks
- PS1=$PS1'$(ret=$?;prompt vcs;prompt job;prompt ret)'
-
# Add a helpful prefix if this shell appears to be exotic
case ${SHELL##*/} in
(zsh) ;;
(*) PS1=zsh:$PS1 ;;
esac
+ # Add sub-commands:
+ ## VCS, job, and return status checks as suffixes
+ PS1=$PS1'$(ret=$?;prompt vcs;prompt job;prompt ret)'
+
# Add prefix and suffix
PS1='${PROMPT_PREFIX}'$PS1'${PROMPT_SUFFIX}'
@@ -53,7 +54,6 @@ prompt() {
fi
;;
- # Git prompt function
git)
# Wrap as compound command; we don't want to see output from any of