diff options
281 files changed, 4282 insertions, 4117 deletions
@@ -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 @@ -171,12 +172,20 @@ /games/rot13 /games/squ /games/strik +/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 e78d89ea..e0ef1bf5 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,104 +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://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 @@ -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 @@ -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. @@ -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 \ @@ -265,16 +262,23 @@ GAMES = games/aaf \ games/pks \ games/rndn \ games/rot13 \ + games/uuu \ games/squ \ games/strik \ games/xyzzy \ 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 -- \ @@ -283,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 < $< > $@ @@ -334,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 @@ -349,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 @@ -362,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 @@ -411,251 +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: - mkdir -p $(VIMDIR)/after/ftplugin - cp -p -- vim/after/ftplugin/*.vim $(VIMDIR)/after/ftplugin - -install-vim-after-indent: - 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 - cp -p -- vim/autoload/*.vim $(VIMDIR)/autoload - -install-vim-bundle: install-vim-config - find vim/bundle/*/* \ - -type d -exec sh -c \ - 'mkdir -p -- $(VIMDIR)/"$${1#vim/bundle/*/}"' _ {} \; - find vim/bundle/*/*/* \ - -type f -exec sh -c \ - 'cp -p -- "$$1" $(VIMDIR)/"$${1#vim/bundle/*/}"' _ {} \; - $(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-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 \ @@ -663,7 +677,7 @@ check: check-bin \ check-man \ check-sh -check-bash: +check-bash: bin/han sh check/bash.sh check-bin: $(BINS) @@ -687,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 @@ -702,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 @@ -724,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 @@ -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,61 @@ 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; + - `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 +- `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 +268,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 +300,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 +312,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 +333,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,292 +357,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. -* `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 ------------------ @@ -660,7 +660,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'` @@ -1,2 +1,2 @@ -tejr dotfiles v8.3.0 -Wed, 11 Dec 2019 00:01:31 +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 @@ -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 @@ -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" + } +} @@ -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 @@ -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 } @@ -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 f1c4c402..f9569c8f 100644 --- a/finger/pgpkey +++ b/finger/pgpkey @@ -1,4 +1,4 @@ -pub rsa4096 2013-03-12 [C] [expires: 2020-01-18] +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-01-18] - 9DF1 A89F F8D9 70AF 3265 C882 96C2 CD91 E67A C61D -sub rsa4096 2013-03-12 [S] [expires: 2020-01-18] - 3179 90A1 4597 A1FC F82D 953A B5AF 5F89 2592 6609 -sub rsa4096 2019-08-06 [A] [expires: 2020-01-18] - 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/uuu.sed b/games/uuu.sed new file mode 100644 index 00000000..ab8927be --- /dev/null +++ b/games/uuu.sed @@ -0,0 +1,2 @@ +# uuuuuu uu +s/[[:alpha:]]/u/g 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" @@ -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 + } } @@ -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 @@ -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/uuu.6df b/man/man6/uuu.6df new file mode 100644 index 00000000..dd3fcc5a --- /dev/null +++ b/man/man6/uuu.6df @@ -0,0 +1,18 @@ +.TH UUU 6df "December 2019" "Manual page for uuu" +.SH NAME +.B uuu +\- uuuuu u uuuuuu uuuuu uuu uuuuu uuuuu +.SH USAGE +.B uuu +\< uuuu +.br +.B uuuuuuu +| uuu +.SH DESCRIPTION +.B uuu +uuuuuuuuu u uuuuuu uuuuu uuu uuuuu[1] uuuuu uuuuu, uuuuuuuuuu uu uuuu uuu uuuu +uuuu, uuu uuuuuu uu uu uuuuuu. +.SH SEE ALSO +[1]: <https://github.com/uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu/uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu> +.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 7d5a65db..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. -.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. +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 -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, 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. +Whether in a Git repository if applicable, .IP \[bu] 2 -The number of running background jobs, 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 \f[V]git:\f[R] +or \f[V]svn:\f[R] prefix is added appropriately for disambiguation. .IP \[bu] 2 -The exit status of the last command, 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. .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[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[C]x()\f[] is a one\-key shortcut for \f[C]exec\ startx\f[]. +\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,380 +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. -.IP \[bu] 2 -\f[C]dub(1df)\f[] lists the biggest entries in a directory. +\f[V]dub(1df)\f[R] lists the biggest entries in a directory. .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]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]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]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]exm(1df)\f[] works around a screen\-clearing quirk of Vim's -\f[C]ex\f[] mode. +\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]finc(1df)\f[] counts the number of results returned from a set of -given \f[C]find(1)\f[] conditions. +\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]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[C]mw(1df)\f[] prints alphabetic space\-delimited words from the input +\f[V]msc(1df)\f[R] crudely counts messages in an mbox. +.IP \[bu] 2 +\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[V]rot13(6df)\f[R] rotates the Latin letters in its input. .IP \[bu] 2 -\f[C]rot13(6df)\f[] rotates the Latin letters in its input. +\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 @@ -1028,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" @@ -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 -) @@ -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/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/c.vim b/vim/after/ftplugin/c.vim index f082ca18..d67e3654 100644 --- a/vim/after/ftplugin/c.vim +++ b/vim/after/ftplugin/c.vim @@ -1,4 +1,5 @@ -" Set 'commentstring', 'define', and 'include' back to their default C-friendly values +" Set 'commentstring', 'define', and 'include' back to their default +" C-friendly values setlocal commentstring&vim define&vim include&vim let b:undo_ftplugin .= '|setlocal commentstring< define< include<' @@ -6,10 +7,9 @@ let b:undo_ftplugin .= '|setlocal commentstring< define< include<' setlocal complete+=d let b:undo_ftplugin .= '|setlocal complete<' -" Fold based on indent level, but start with all folds open +" Fold based on indent level setlocal foldmethod=indent -setlocal foldlevel=99 -let b:undo_ftplugin .= '|setlocal foldmethod< foldlevel<' +let b:undo_ftplugin .= '|setlocal foldmethod<' " Include system headers on UNIX if has('unix') 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 7866f31b..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<' @@ -19,14 +19,14 @@ let b:undo_ftplugin .= '|unlet b:current_compiler' " it; we map \= to do the former, but don't actually set 'equalprg' for the " latter, instead falling back on the good-enough built-in Vim indentation " behavior -nnoremap <buffer> <Leader>= :<C-U>call html#TidyBuffer()<CR> +nnoremap <buffer> <Leader>= :<C-U>call html#Tidy()<CR> let b:undo_ftplugin .= '|nunmap <buffer> <Leader>=' " Set up hooks for timestamp updating augroup html_timestamp autocmd BufWritePre <buffer> \ if exists('b:html_timestamp_check') - \| call html#TimestampUpdate() + \| call html#timestamp#Update() \|endif augroup END let b:undo_ftplugin .= '|execute ''autocmd! html_timestamp''' @@ -39,5 +39,5 @@ endif " Transform URLs to HTML anchors nnoremap <buffer> <LocalLeader>r - \ :<C-U>call html#UrlLink()<CR> + \ :<C-U>call html#url#Anchor()<CR> let b:undo_ftplugin .= '|nunmap <buffer> <LocalLeader>r' diff --git a/vim/after/ftplugin/mail.vim b/vim/after/ftplugin/mail.vim index 9f8fc608..4c07bac3 100644 --- a/vim/after/ftplugin/mail.vim +++ b/vim/after/ftplugin/mail.vim @@ -1,61 +1,32 @@ +" 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 let b:undo_ftplugin .= '|unlet b:quote_space' -" Attempt to move to a good spot to start writing -function! s:SuggestStart() abort - - " Move to top of buffer - call setpos('.', [0, 1, 1, 0]) - - " Move to body text - call search('\m^$', 'c') | + - - " Start by trying to move to the first quoted line; this may fail if there's - " no quote, which is fine - call search('\m^>', 'c') - - " Delete quoted blank lines or quoted greetings until we get to something - " with substance. Yes, I like Perl, how could you tell? - while getline('.') =~? '^> *' - \ . '\%(' - \ . '\%(' - \ . 'g[''\u2019]\=day' - \ . '\|\%(good \)\=\%(morning\|afternoon\|evening\)' - \ . '\|h[eu]\%(ll\|rr\)o\+' - \ . '\|hey\+' - \ . '\|hi\+' - \ . '\|sup' - \ . '\|what[''\u2019]\=s up' - \ . '\|yo' - \ . '\)' - \ . '[[:punct:] ]*' - \ . '\%(' - \ . '\a\+' - \ . '[[:punct:] ]*' - \ . '\)\=' - \ . '\)\=$' - delete - endwhile - - " Now move to the first quoted or unquoted blank line - call search('\m^>\= *$', 'c') -endfunction -command! -bar -buffer SuggestStart - \ call s:SuggestStart() +command -bar -buffer SuggestStart + \ call mail#SuggestStart() let b:undo_ftplugin .= '|delcommand SuggestStart' SuggestStart -" Normalise quoting -command -buffer -bar -range=% StrictQuote +" Normalize quoting +command -bar -buffer -range=% StrictQuote \ call mail#StrictQuote(<q-line1>, <q-line2>) -nnoremap <LocalLeader>s - \ :StrictQuote<CR> -xnoremap <LocalLeader>s - \ :StrictQuote<CR> let b:undo_ftplugin .= '|delcommand StrictQuote' +command -bar -buffer -nargs=1 SetImportance + \ call mail#importance#Set(<f-args>) +let b:undo_ftplugin .= '|delcommand SetImportance' + " Add a space to the end of wrapped lines for format-flowed mail setlocal formatoptions+=w let b:undo_ftplugin .= '|setlocal formatoptions<' @@ -78,12 +49,15 @@ if exists('no_plugin_maps') || exists('no_mail_maps') endif " Flag messages as important/unimportant -nnoremap <buffer> <LocalLeader>h - \ :<C-U>call mail#FlagImportant()<CR> -let b:undo_ftplugin .= '|nunmap <buffer> <LocalLeader>h' -nnoremap <buffer> <LocalLeader>l - \ :<C-U>call mail#FlagUnimportant()<CR> -let b:undo_ftplugin .= '|nunmap <buffer> <LocalLeader>l' +nnoremap <buffer> <LocalLeader>ih + \ :<C-U>SetImportance high<CR> +let b:undo_ftplugin .= '|nunmap <buffer> <LocalLeader>ih' +nnoremap <buffer> <LocalLeader>il + \ :<C-U>SetImportance low<CR> +let b:undo_ftplugin .= '|nunmap <buffer> <LocalLeader>il' +nnoremap <buffer> <LocalLeader>in + \ :<C-U>SetImportance normal<CR> +let b:undo_ftplugin .= '|nunmap <buffer> <LocalLeader>in' " Quote operator nnoremap <buffer> <expr> <LocalLeader>q @@ -101,6 +75,14 @@ xnoremap <buffer> <expr> <LocalLeader>Q let b:undo_ftplugin .= '|nunmap <buffer> <LocalLeader>Q' \ . '|xunmap <buffer> <LocalLeader>Q' +" Mappings for enforcing strict quoting +nnoremap <buffer> <LocalLeader>s + \ :StrictQuote<CR> +xnoremap <buffer> <LocalLeader>s + \ :StrictQuote<CR> +let b:undo_ftplugin .= '|nunmap <buffer> <LocalLeader>s' + \ . '|xunmap <buffer> <LocalLeader>s' + " Maps using autoloaded function for quoted paragraph movement nnoremap <buffer> <silent> <LocalLeader>[ \ :<C-U>call mail#NewBlank(v:count1, 1, 0)<CR> diff --git a/vim/after/ftplugin/perl.vim b/vim/after/ftplugin/perl.vim index 5c9cf8a0..9333e234 100644 --- a/vim/after/ftplugin/perl.vim +++ b/vim/after/ftplugin/perl.vim @@ -1,13 +1,15 @@ " Use Perl itself for checking and Perl::Tidy for tidying compiler perl -setlocal equalprg=perltidy let b:undo_ftplugin .= '|unlet b:current_compiler' - \ . '|setlocal equalprg< errorformat< makeprg<' + \ . '|setlocal errorformat< makeprg<' +if executable('perltidy') + setlocal equalprg=perltidy + let b:undo_ftplugin .= '|setlocal equalprg<' +endif -" Fold based on indent level, but start with all folds open +" Fold based on indent level setlocal foldmethod=indent -setlocal foldlevel=99 -let b:undo_ftplugin .= '|setlocal foldmethod< foldlevel<' +let b:undo_ftplugin .= '|setlocal foldmethod<' " Add angle brackets to pairs of matched characters for q<...> setlocal matchpairs+=<:> @@ -38,6 +40,14 @@ nnoremap <buffer> <LocalLeader>l let b:undo_ftplugin .= '|nunmap <buffer> <LocalLeader>c' \ . '|nunmap <buffer> <LocalLeader>l' +" Mappings to choose 'equalprg' +nnoremap <buffer> <LocalLeader>t + \ :<C-U>setlocal equalprg=perltidy<CR> +nnoremap <buffer> <LocalLeader>i + \ :<C-U>setlocal equalprg<<CR> +let b:undo_ftplugin .= '|nunmap <buffer> <LocalLeader>t' + \ . '|nunmap <buffer> <LocalLeader>i' + " Bump version numbers nmap <buffer> <LocalLeader>v \ <Plug>(PerlVersionBumpMinor) diff --git a/vim/after/ftplugin/php.vim b/vim/after/ftplugin/php.vim index 0ce099a0..b747a14e 100644 --- a/vim/after/ftplugin/php.vim +++ b/vim/after/ftplugin/php.vim @@ -1,18 +1,20 @@ " Use PHP itself for syntax checking compiler php -setlocal equalprg=phpcsff let b:undo_ftplugin .= '|unlet b:current_compiler' - \ . '|setlocal equalprg< errorformat< makeprg<' + \ . '|setlocal errorformat< makeprg<' +if executable('php-cs-fixer') + setlocal equalprg=phpcsff + let b:undo_ftplugin .= '|setlocal equalprg<' +endif " Set comment formats setlocal comments=s1:/*,m:*,ex:*/,://,:# setlocal formatoptions+=or let b:undo_ftplugin .= '|setlocal comments< formatoptions<' -" Fold based on indent level, but start with all folds open +" Fold based on indent level setlocal foldmethod=indent -setlocal foldlevel=99 -let b:undo_ftplugin .= '|setlocal foldmethod< foldlevel<' +let b:undo_ftplugin .= '|setlocal foldmethod<' " Use pman as 'keywordprg' setlocal keywordprg=pman @@ -26,3 +28,16 @@ let b:undo_ftplugin .= '|unlet b:regex_escape_flavor' if !exists('b:alternate_filetypes') let b:alternate_filetypes = [&filetype, 'html'] endif + +" Stop here if the user doesn't want ftplugin mappings +if exists('no_plugin_maps') || exists('no_php_maps') + finish +endif + +" Mappings to choose 'equalprg' +nnoremap <buffer> <LocalLeader>f + \ :<C-U>setlocal equalprg=phpcsff<CR> +nnoremap <buffer> <LocalLeader>i + \ :<C-U>setlocal equalprg<<CR> +let b:undo_ftplugin .= '|nunmap <buffer> <LocalLeader>f' + \ . '|nunmap <buffer> <LocalLeader>i' 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/sh.vim b/vim/after/ftplugin/sh.vim index 39b8d0d6..2c68d83a 100644 --- a/vim/after/ftplugin/sh.vim +++ b/vim/after/ftplugin/sh.vim @@ -3,10 +3,9 @@ setlocal comments=:# setlocal formatoptions+=or let b:undo_ftplugin .= '|setlocal comments< formatoptions<' -" Fold based on indent level, but start with all folds open +" Fold based on indent level setlocal foldmethod=indent -setlocal foldlevel=99 -let b:undo_ftplugin .= '|setlocal foldmethod< foldlevel<' +let b:undo_ftplugin .= '|setlocal foldmethod<' " If subtype is Bash, set 'keywordprg' to han(1df) if exists('b:is_bash') diff --git a/vim/after/ftplugin/vim.vim b/vim/after/ftplugin/vim.vim index 481af0ec..112523da 100644 --- a/vim/after/ftplugin/vim.vim +++ b/vim/after/ftplugin/vim.vim @@ -9,10 +9,9 @@ endif let b:regex_escape_flavor = 'vim' let b:undo_ftplugin .= '|unlet b:regex_escape_flavor' -" Fold based on indent level, but start with all folds open +" Fold based on indent level setlocal foldmethod=indent -setlocal foldlevel=99 -let b:undo_ftplugin .= '|setlocal foldmethod< foldlevel<' +let b:undo_ftplugin .= '|setlocal foldmethod<' " Use :help as 'keywordprg' if not already set; this is the default since Vim " v8.1.1290 @@ -27,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/ftplugin/zsh.vim b/vim/after/ftplugin/zsh.vim index 880c2c39..c361c859 100644 --- a/vim/after/ftplugin/zsh.vim +++ b/vim/after/ftplugin/zsh.vim @@ -5,5 +5,4 @@ let b:undo_ftplugin .= '|unlet b:current_compiler' " Fold based on indent level, but start with all folds open setlocal foldmethod=indent -setlocal foldlevel=99 -let b:undo_ftplugin .= '|setlocal foldmethod< foldlevel<' +let b:undo_ftplugin .= '|setlocal foldmethod<' diff --git a/vim/after/indent/awk.vim b/vim/after/indent/awk.vim index ba6dfdeb..bff1b904 100644 --- a/vim/after/indent/awk.vim +++ b/vim/after/indent/awk.vim @@ -1,8 +1,2 @@ " Use four spaces for indentation -setlocal expandtab -setlocal shiftwidth=4 -let b:undo_ftplugin .= '|setlocal expandtab< shiftwidth<' -if &l:softtabstop != -1 - let &l:softtabstop = &l:shiftwidth - let b:undo_ftplugin .= '|setlocal softtabstop<' -endif +call indent#Spaces(4) diff --git a/vim/after/indent/css.vim b/vim/after/indent/css.vim index ba6dfdeb..bff1b904 100644 --- a/vim/after/indent/css.vim +++ b/vim/after/indent/css.vim @@ -1,8 +1,2 @@ " Use four spaces for indentation -setlocal expandtab -setlocal shiftwidth=4 -let b:undo_ftplugin .= '|setlocal expandtab< shiftwidth<' -if &l:softtabstop != -1 - let &l:softtabstop = &l:shiftwidth - let b:undo_ftplugin .= '|setlocal softtabstop<' -endif +call indent#Spaces(4) diff --git a/vim/after/indent/html.vim b/vim/after/indent/html.vim index 72c92d21..4cb4a678 100644 --- a/vim/after/indent/html.vim +++ b/vim/after/indent/html.vim @@ -1,15 +1,9 @@ +" Use four spaces for indentation +call indent#Spaces(4) + " Clear away the flag we set to indent after paragraphs unlet html_indent_inctags " Don't re-indent lines on right-angle-bracket or enter setlocal indentkeys-=<>>,<Return> let b:undo_ftplugin .= '|setlocal indentkeys<' - -" Use four spaces for indentation -setlocal expandtab -setlocal shiftwidth=4 -let b:undo_ftplugin .= '|setlocal expandtab< shiftwidth<' -if &l:softtabstop != -1 - let &l:softtabstop = &l:shiftwidth - let b:undo_ftplugin .= '|setlocal softtabstop<' -endif diff --git a/vim/after/indent/javascript.vim b/vim/after/indent/javascript.vim index ba6dfdeb..bff1b904 100644 --- a/vim/after/indent/javascript.vim +++ b/vim/after/indent/javascript.vim @@ -1,8 +1,2 @@ " Use four spaces for indentation -setlocal expandtab -setlocal shiftwidth=4 -let b:undo_ftplugin .= '|setlocal expandtab< shiftwidth<' -if &l:softtabstop != -1 - let &l:softtabstop = &l:shiftwidth - let b:undo_ftplugin .= '|setlocal softtabstop<' -endif +call indent#Spaces(4) diff --git a/vim/after/indent/mail.vim b/vim/after/indent/mail.vim index ba6dfdeb..bff1b904 100644 --- a/vim/after/indent/mail.vim +++ b/vim/after/indent/mail.vim @@ -1,8 +1,2 @@ " Use four spaces for indentation -setlocal expandtab -setlocal shiftwidth=4 -let b:undo_ftplugin .= '|setlocal expandtab< shiftwidth<' -if &l:softtabstop != -1 - let &l:softtabstop = &l:shiftwidth - let b:undo_ftplugin .= '|setlocal softtabstop<' -endif +call indent#Spaces(4) diff --git a/vim/after/indent/markdown.vim b/vim/after/indent/markdown.vim new file mode 100644 index 00000000..bff1b904 --- /dev/null +++ b/vim/after/indent/markdown.vim @@ -0,0 +1,2 @@ +" Use four spaces for indentation +call indent#Spaces(4) diff --git a/vim/after/indent/perl.vim b/vim/after/indent/perl.vim index ba6dfdeb..bff1b904 100644 --- a/vim/after/indent/perl.vim +++ b/vim/after/indent/perl.vim @@ -1,8 +1,2 @@ " Use four spaces for indentation -setlocal expandtab -setlocal shiftwidth=4 -let b:undo_ftplugin .= '|setlocal expandtab< shiftwidth<' -if &l:softtabstop != -1 - let &l:softtabstop = &l:shiftwidth - let b:undo_ftplugin .= '|setlocal softtabstop<' -endif +call indent#Spaces(4) diff --git a/vim/after/indent/php.vim b/vim/after/indent/php.vim index ba6dfdeb..bff1b904 100644 --- a/vim/after/indent/php.vim +++ b/vim/after/indent/php.vim @@ -1,8 +1,2 @@ " Use four spaces for indentation -setlocal expandtab -setlocal shiftwidth=4 -let b:undo_ftplugin .= '|setlocal expandtab< shiftwidth<' -if &l:softtabstop != -1 - let &l:softtabstop = &l:shiftwidth - let b:undo_ftplugin .= '|setlocal softtabstop<' -endif +call indent#Spaces(4) diff --git a/vim/after/indent/sh.vim b/vim/after/indent/sh.vim index ba6dfdeb..bff1b904 100644 --- a/vim/after/indent/sh.vim +++ b/vim/after/indent/sh.vim @@ -1,8 +1,2 @@ " Use four spaces for indentation -setlocal expandtab -setlocal shiftwidth=4 -let b:undo_ftplugin .= '|setlocal expandtab< shiftwidth<' -if &l:softtabstop != -1 - let &l:softtabstop = &l:shiftwidth - let b:undo_ftplugin .= '|setlocal softtabstop<' -endif +call indent#Spaces(4) diff --git a/vim/after/indent/vim.vim b/vim/after/indent/vim.vim index 320e5d7d..4300e125 100644 --- a/vim/after/indent/vim.vim +++ b/vim/after/indent/vim.vim @@ -5,11 +5,5 @@ if !exists('b:undo_indent') let b:undo_indent = 'setlocal indentkeys<' endif -" Observe VimL conventions for two-space indents -setlocal expandtab -setlocal shiftwidth=2 -let b:undo_indent .= '|setlocal expandtab< shiftwidth<' -if &softtabstop != -1 - let &l:softtabstop = &l:shiftwidth - let b:undo_indent .= '|setlocal softtabstop<' -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/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/colorscheme.vim b/vim/autoload/colorscheme.vim index 9ee9f24d..349ee374 100644 --- a/vim/autoload/colorscheme.vim +++ b/vim/autoload/colorscheme.vim @@ -1,8 +1,22 @@ -" Reset colorscheme based on current colorscheme name +" Reset window-global value for 'cursorline' based on current colorscheme name function! colorscheme#UpdateCursorline(colors_name, list) abort - if index(a:list, a:colors_name) >= 0 - set cursorline - else - set nocursorline - endif + + " Record current tab and window number so we can jump back once we're done + let l:tab = tabpagenr() + let l:win = winnr() + + " Set the window-global value for 'cursorline' in each window of each tab; + " on if the current colorscheme is in the whitelist, and off otherwise; fire + " the WinEnter and WinLeave events so any other 'cursorline' related hooks + " can run too + " + let l:cursorline = index(a:list, a:colors_name) >= 0 + tabdo windo let &g:cursorline = l:cursorline + \| silent doautocmd WinEnter,WinLeave + + " Move back to the tab and window the user started in + execute l:tab . 'tabnext' + execute l:win . 'wincmd w' + \| silent doautocmd WinEnter + 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/escape.vim b/vim/autoload/escape.vim deleted file mode 100644 index 0fdfba99..00000000 --- a/vim/autoload/escape.vim +++ /dev/null @@ -1,13 +0,0 @@ -function! escape#Arg(arg) abort - return exists('*fnameescape') - \ ? fnameescape(a:arg) - \ : escape(a:arg, "\n\r\t".' *?[{`$\%#''"|!<') -endfunction - -function! escape#Item(item) abort - return escape(a:item, ',') -endfunction - -function! escape#Wild(string) abort - return escape(a:string, '\*?[{`''$~') -endfunction diff --git a/vim/autoload/filetype.vim b/vim/autoload/filetype/repeat.vim index 6a66d62e..899bbcc4 100644 --- a/vim/autoload/filetype.vim +++ b/vim/autoload/filetype/repeat.vim @@ -1,6 +1,6 @@ " Helper function to run the 'filetypedetect' group on a file with its " extension stripped off -function! filetype#StripRepeat() abort +function! filetype#repeat#Strip() abort " Check we have the fnameescape() function if !exists('*fnameescape') @@ -33,7 +33,7 @@ endfunction " Helper function to run the 'filetypedetect' group on a file in a temporary " sudoedit(8) directory, modifying it with an attempt to reverse the temporary " filename change -function! filetype#SudoRepeat() abort +function! filetype#repeat#Sudo() abort " Check we have the fnameescape() function if !exists('*fnameescape') @@ -53,7 +53,7 @@ function! filetype#SudoRepeat() 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 6bbe6b3b..00000000 --- a/vim/autoload/fortune.vim +++ /dev/null @@ -1,46 +0,0 @@ -let s:paths = [ - \ $HOME.'/.fortunes', - \ $HOME.'/.local/share/games/fortunes', - \] - -let s:executables = [ - \ 'fortune', - \ 'timeout', - \] - -function! fortune#() abort - - for executable in s:executables - if !executable(executable) - echoerr 'Missing executable "'.executable.'"' - endif - endfor - - let limit = &columns - 1 - - let command = [ - \ 'timeout', - \ '0.3s', - \ 'fortune', - \ '-s', - \ '-n', - \ limit, - \] - - for path in s:paths - if isdirectory(path) - call add(command, path) - break - endif - endfor - - let fortune = substitute( - \ system(join(command)), - \ '[[:cntrl:][:space:]]\+', - \ ' ', - \ 'g', - \) - - echomsg fortune - -endfunction diff --git a/vim/autoload/gitcommit.vim b/vim/autoload/gitcommit.vim index 7aba1c5b..72d2b9ff 100644 --- a/vim/autoload/gitcommit.vim +++ b/vim/autoload/gitcommit.vim @@ -3,6 +3,7 @@ function! gitcommit#CursorColumn() abort " If we can find a line after the first that isn't a comment, we're " composing the message + " for num in range(1, line('$')) if num == 1 continue diff --git a/vim/autoload/has.vim b/vim/autoload/has.vim deleted file mode 100644 index 0100e913..00000000 --- a/vim/autoload/has.vim +++ /dev/null @@ -1,16 +0,0 @@ -function! has#(feature) abort - if has('patch-7.4.237') - return has(a:feature) - endif - 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] - let l:version = major * 100 + minor - return v:version != l:version - \ ? v:version > l:version - \ : has('patch-'.patch) -endfunction diff --git a/vim/autoload/html.vim b/vim/autoload/html.vim index 7ac4f9d3..2ce5288d 100644 --- a/vim/autoload/html.vim +++ b/vim/autoload/html.vim @@ -1,39 +1,6 @@ -" Make a bare URL into a link to itself -function! html#UrlLink() abort - - " Yank this whole whitespace-separated word - normal! yiW - " Open a link tag - normal! i<a href=""> - " Paste the URL into the quotes - normal! hP - " Move to the end of the link text URL - normal! E - " Close the link tag - normal! a</a> - -endfunction - " Tidy the whole buffer -function! html#TidyBuffer() abort +function! html#Tidy() abort let view = winsaveview() %!tidy -quiet call winrestview(view) endfunction - -" Update a timestamp -function! html#TimestampUpdate() abort - if !&modified - return - endif - let cv = winsaveview() - call cursor(1,1) - let li = search('\m\C^\s*<em>Last updated: .\+</em>$', 'n') - if li - let date = substitute(system('date -u'), '\n$', '', '') - let line = getline(li) - call setline(li, substitute(line, '\S.*', - \ '<em>Last updated: '.date.'</em>', '')) - endif - call winrestview(cv) -endfunction diff --git a/vim/autoload/html/timestamp.vim b/vim/autoload/html/timestamp.vim new file mode 100644 index 00000000..8f250710 --- /dev/null +++ b/vim/autoload/html/timestamp.vim @@ -0,0 +1,74 @@ +" Keys and date formats for return value of s:Timestamp() +let s:formats = { + \ 'human': '%a, %d %b %Y %T %Z', + \ 'machine': '%Y-%m-%dT%H:%M:%SZ', + \} + +" Get UTC timestamp string dictionary with layout in s:formats +function! s:Timestamp(time) abort + + " Force UTC, recording previous timezone, if any + if exists('$TZ') + let tz = $TZ + endif + let $TZ = 'UTC' + + " Get current time + let time = localtime() + + " Fill out timestamp dictionary + let timestamp = {} + for key in keys(s:formats) + let timestamp[key] = strftime(s:formats[key], time) + endfor + + " Clear UTC and restore previous timezone, if any + unlet $TZ + if exists('tz') + let $TZ = tz + endif + + " Return filled-out timestamp dictionary + return timestamp + +endfunction + +" Define timestamp prefix string +let s:prefix = 'Last updated: ' + +" Define pattern to match date timestamps; no ZALGO, please +let s:pattern = '\m\C' + \.s:prefix + \.'<time datetime="[^"]\+">' + \.'[^<]\+' + \.'</time>' + +" Update a timestamp +function! html#timestamp#Update() abort + + " Do nothing if the buffer hasn't been modified + if !&modified + return + endif + + " Find the first occurrence of the timestamp pattern, bail if none + let lnum = search(s:pattern, 'nw') + if !lnum + return + endif + + " Get timestamp dictionary + let timestamp = s:Timestamp(localtime()) + + " Fill out updated timestamp string with dictionary values + let update = s:prefix + \.'<time datetime="'.timestamp['machine'].'">' + \.timestamp['human'] + \.'</time>' + + " Apply the updated timestamp + let line = getline(lnum) + let line = substitute(line, s:pattern, update, '') + keepjumps call setline(lnum, line) + +endfunction diff --git a/vim/autoload/html/url.vim b/vim/autoload/html/url.vim new file mode 100644 index 00000000..99b4409e --- /dev/null +++ b/vim/autoload/html/url.vim @@ -0,0 +1,15 @@ +" Make a bare URL into a link to itself +function! html#url#Anchor() abort + + " Yank this whole whitespace-separated word + normal! yiW + " Open a link tag + normal! i<a href=""> + " Paste the URL into the quotes + normal! hP + " Move to the end of the link text URL + normal! E + " Close the link tag + normal! a</a> + +endfunction diff --git a/vim/autoload/indent.vim b/vim/autoload/indent.vim new file mode 100644 index 00000000..19a9f03d --- /dev/null +++ b/vim/autoload/indent.vim @@ -0,0 +1,35 @@ +" Set the current buffer to space indent +function! indent#Spaces(...) abort + setlocal expandtab + + " If an argument was provided, use that for the number of spaces; otherwise, + " set 'shiftwidth' to 0, which then copies 'tabstop' + let &l:shiftwidth = a:0 + \ ? a:1 + \ : 0 + + " 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 = patch#('7.3.693') + \ ? -1 + \ : &l:shiftwidth + + call indent#Undo() +endfunction + +" Set the current buffer to tab indent +function! indent#Tabs() abort + 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 + let undo = 'setlocal expandtab< shiftwidth< softtabstop<' + if exists('b:undo_indent') + let b:undo_indent .= '|'.undo + else + let b:undo_indent = undo + endif +endfunction diff --git a/vim/autoload/mail.vim b/vim/autoload/mail.vim index 3fbba860..6d4874ca 100644 --- a/vim/autoload/mail.vim +++ b/vim/autoload/mail.vim @@ -1,39 +1,7 @@ -" Add a header to a mail message -function! mail#AddHeaderField(name, body) abort - let num = 0 - while num < line('$') && getline(num + 1) !=# '' - let num += 1 - endwhile - call append(num, a:name.': '.a:body) -endfunction - -" Add a set of headers to a mail message -function! mail#AddHeaderFields(fields) abort - for name in sort(keys(a:fields)) - call mail#AddHeaderField(name, a:fields[name]) - endfor -endfunction - -" Flag a message as important -function! mail#FlagImportant() abort - call mail#AddHeaderFields({ - \ 'Importance': 'High', - \ 'X-Priority': 1 - \ }) -endfunction - -" Flag a message as unimportant -function! mail#FlagUnimportant() abort - call mail#AddHeaderFields({ - \ 'Importance': 'Low', - \ 'X-Priority': 5 - \ }) -endfunction - " 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 @@ -93,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 @@ -102,3 +70,43 @@ function! mail#StrictQuote(start, end) abort endfor endfunction + +" Attempt to move to a good spot to start writing +function! mail#SuggestStart() abort + + " Move to top of buffer + call setpos('.', [0, 1, 1, 0]) + + " Move to body text + call search('\m^$', 'c') | + + + " Start by trying to move to the first quoted line; this may fail if there's + " no quote, which is fine + call search('\m^>', 'c') + + " Delete quoted blank lines or quoted greetings until we get to something + " with substance. Yes, I like Perl, how could you tell? + while getline('.') =~? '^> *' + \ . '\%(' + \ . '\%(' + \ . 'g[''\u2019]\=day' + \ . '\|\%(good \)\=\%(morning\|afternoon\|evening\)' + \ . '\|h[eu]\%(ll\|rr\)o\+' + \ . '\|hey\+' + \ . '\|hi\+' + \ . '\|sup' + \ . '\|what[''\u2019]\=s up' + \ . '\|yo' + \ . '\)' + \ . '[[:punct:] ]*' + \ . '\%(' + \ . '\a\+' + \ . '[[:punct:] ]*' + \ . '\)\=' + \ . '\)\=$' + delete + endwhile + + " Now move to the first quoted or unquoted blank line + call search('\m^>\= *$', 'c') +endfunction diff --git a/vim/autoload/mail/header.vim b/vim/autoload/mail/header.vim new file mode 100644 index 00000000..5284b84d --- /dev/null +++ b/vim/autoload/mail/header.vim @@ -0,0 +1,59 @@ +" Parse a mail header into a list of dictionaries with 'name' and 'body' keys; +" preserve case of the name and whitespace in body, including leading space +" +function! mail#header#Read() abort + let fields = [] + for lnum in range(1, line('$')) + let line = getline(lnum) + let matchlist = matchlist( + \ line, + \ '^\([a-zA-Z0-9-]\+\):\s*\(\_.*\)', + \) + if !empty(matchlist) + let field = { + \ 'name': matchlist[1], + \ 'body': matchlist[2], + \} + call add(fields, field) + elseif line =~# '^\s' && exists('field') + let field['body'] .= "\n" . line + elseif line ==# '' + break + else + throw 'Parse error' + endif + endfor + let header = { + \'fields': fields, + \} + return header +endfunction + +" Flatten a header data structure into a string +function! mail#header#String(header) abort + let fields = copy(a:header['fields']) + return join( + \ map( + \ copy(a:header['fields']), + \ 'v:val[''name''] . '': '' . v:val[''body''] . "\n"'), + \ '', + \) +endfunction + +" Replace existing mail header with the provided one +function! mail#header#Write(header) abort + let start = 1 + for lnum in range(1, line('$')) + if getline(lnum) ==# '' + break + endif + let end = lnum + endfor + let curpos = getpos('.') + if exists('end') + let range = join([start, end], ',') + execute join(['silent', range, 'delete']) + endif + silent 0 put =mail#header#String(a:header) + call setpos('.', curpos) +endfunction diff --git a/vim/autoload/mail/header/field.vim b/vim/autoload/mail/header/field.vim new file mode 100644 index 00000000..db38c09f --- /dev/null +++ b/vim/autoload/mail/header/field.vim @@ -0,0 +1,45 @@ +" Add a field to a header, regardless of whether a field by the same name is +" already present +function! mail#header#field#Add(header, name, body) abort + let new = { + \ 'name': a:name, + \ 'body': a:body, + \} + call add(a:header['fields'], new) +endfunction + +" Set a field in a header, replacing the first one with the same name (if +" any), and removing any others +" +function! mail#header#field#Set(header, name, body) abort + let fields = [] + let new = { + \ 'name': a:name, + \ 'body': a:body, + \} + for field in a:header['fields'] + if field['name'] ==? a:name + if exists('new') + let field = new | unlet new + else + continue + endif + endif + call add(fields, field) + endfor + if exists('new') + call add(fields, new) | unlet new + endif + let a:header['fields'] = fields +endfunction + +" Remove a header field +function! mail#header#field#Clear(header, name) abort + let fields = [] + for field in a:header['fields'] + if field['name'] !=? a:name + call add(fields, field) + endif + endfor + let a:header['fields'] = fields +endfunction diff --git a/vim/autoload/mail/importance.vim b/vim/autoload/mail/importance.vim new file mode 100644 index 00000000..78fb53ac --- /dev/null +++ b/vim/autoload/mail/importance.vim @@ -0,0 +1,26 @@ +" Define header fields for high, low, and normal priorities +let s:fields = { + \ 'high': { + \ 'Importance': 'High', + \ 'X-Priority': '1', + \}, + \ 'low': { + \ 'Importance': 'Low', + \ 'X-Priority': '5', + \}, + \ 'normal': {}, + \} + +" Set the priority headers; pass in "high", "low", or "normal" +function! mail#importance#Set(level) abort + let header = mail#header#Read() + let fields = s:fields[a:level] + for name in ['Importance', 'X-Priority'] + if has_key(fields, name) + call mail#header#field#Set(header, name, fields[name]) + else + call mail#header#field#Clear(header, name) + endif + endfor + call mail#header#Write(header) +endfunction diff --git a/vim/autoload/map.vim b/vim/autoload/map.vim deleted file mode 100644 index d4bd90a2..00000000 --- a/vim/autoload/map.vim +++ /dev/null @@ -1,12 +0,0 @@ -" We declare a wrapper around map() to allow us always to call it with -" a Funcref as the second function parameter, which isn't directly supported -" by map() until Vim v7.4.1989. If the running version is older than that, -" apply string() to the Funcref to use the older calling convention. -" -" <https://github.com/vim/vim/releases/tag/v7.4.1989> -" -function! map#(list, Func) abort - return has('patch-7.4.1989') - \ ? map(a:list, a:Func) - \ : map(a:list, string(a:Func).'(0, v:val)') -endfunction diff --git a/vim/autoload/markdown.vim b/vim/autoload/markdown.vim index 8bac8045..0f03961c 100644 --- a/vim/autoload/markdown.vim +++ b/vim/autoload/markdown.vim @@ -1,3 +1,26 @@ +" Let's try this heading-based fold method out (Tim Pope) +function! markdown#Fold() abort + let line = getline(v:lnum) + + " Regular headers + let depth = match(line, '\(^#\+\)\@<=\( .*$\)\@=') + if depth > 0 + return '>' . depth + endif + + " Setext style headings + if line =~# '^.\+$' + let nextline = getline(v:lnum + 1) + if nextline =~# '^=\+$' + return '>1' + elseif nextline =~# '^-\+$' + return '>2' + endif + endif + + return '=' +endfunction + " Add an underline under a heading function! markdown#Heading(char) abort @@ -9,10 +32,12 @@ function! markdown#Heading(char) abort " Build underline string by repeating character by the string length of the " heading text + " let underline = repeat(a:char, strlen(heading)) " If the line after this one looks like it's already an underline, replace " it; otherwise, create a new underline + " if getline(pos[1] + 1) =~# '^[-=]\{2,}$' call setline(pos[1] + 1, underline) else diff --git a/vim/autoload/option.vim b/vim/autoload/option.vim new file mode 100644 index 00000000..49fbf1a4 --- /dev/null +++ b/vim/autoload/option.vim @@ -0,0 +1,17 @@ +" Split a comma-separated option value into parts, accounting for escaped +" commas and leading whitespace as Vim itself does internally +" +function! option#Split(expr, ...) abort + if a:0 > 1 + echoerr 'Too many arguments' + endif + let keepempty = a:0 ? a:1 : 0 + let parts = split(a:expr, '\\\@<!,[, ]*', keepempty) + 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/option/item.vim b/vim/autoload/option/item.vim new file mode 100644 index 00000000..ee92101f --- /dev/null +++ b/vim/autoload/option/item.vim @@ -0,0 +1,14 @@ +" Escape a single item for a comma-separated list, optionally escaping any +" filename wildcards +" +function! option#item#Escape(item, ...) abort + if a:0 > 1 + echoerr 'Too many arguments' + endif + let item = a:item + let wild = a:0 ? a:1 : 0 + if wild + let item = escape(item, '\*?[{`''$~') + endif + return escape(item, ',') +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 83102138..00000000 --- a/vim/autoload/path.vim +++ /dev/null @@ -1,12 +0,0 @@ -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 68e3d54b..00000000 --- a/vim/autoload/plugin.vim +++ /dev/null @@ -1,4 +0,0 @@ -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 c9f52c12..00000000 --- a/vim/autoload/put_date.vim +++ /dev/null @@ -1,19 +0,0 @@ -let s:rfc_2822 = '%a, %d %b %Y %T %z' - -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/reload.vim b/vim/autoload/reload.vim index 558f24d6..322c44d2 100644 --- a/vim/autoload/reload.vim +++ b/vim/autoload/reload.vim @@ -1,9 +1,13 @@ +" Re-run filetype detection, if it's run before function! reload#FileType() abort if exists('g:did_load_filetypes') doautocmd filetypedetect BufRead endif endfunction +" Re-read .vimrc file, reloading filetypes afterwards to avoid masking +" filetype plugin settings +" function! reload#Vimrc() abort noautocmd source $MYVIMRC call reload#FileType() diff --git a/vim/autoload/spellfile_local.vim b/vim/autoload/spellfile_local.vim deleted file mode 100644 index e119b718..00000000 --- a/vim/autoload/spellfile_local.vim +++ /dev/null @@ -1,72 +0,0 @@ -function! s:SplitOption(string) abort - return map( - \ split(a:string, '\\\@<!,[, ]*') - \,'substitute(v:val, ''\\,'', '''', ''g'')' - \) -endfunction - -function! s:JoinOption(list) abort - return join(map( - \ a:list - \,'substitute(v:val, ''\\\@<!,'', ''\\,'', ''g'')' - \), ',') -endfunction - -function! s:Establish(path) abort - return isdirectory(a:path) - \ || exists('*mkdir') && mkdir(a:path, 'p', 0700) -endfunction - -function! spellfile_local#() abort - - set spellfile< - - let spelllangs = s:SplitOption(&spelllang) - if !len(spelllangs) || spelllangs[0] ==# '' - echoerr 'Blank ''spelllang''' - endif - let spelllang = substitute(spelllangs[0], '_.*', '', '') - - if !len(&encoding) - echoerr 'Blank ''encoding''' - endif - - let spellfiles = s:SplitOption(&spellfile) - if len(spellfiles) != 1 || spellfiles[0] ==# '' - return - endif - - let spelldir = fnamemodify(spellfiles[0], ':h') - if spelldir ==# '' - echoerr 'Blank directory' - endif - - try - let path = tr(expand('%:p'), '/', '%') - if path ==# '' - echoerr 'Blank path' - endif - call s:Establish(spelldir.'/path') - call add(spellfiles, spelldir.'/path/'.join([ - \ path - \,spelllang - \,&encoding - \,'add' - \], '.')) - - if &filetype ==# '' - echoerr 'Blank filetype' - endif - call s:Establish(spelldir.'/filetype') - call add(spellfiles, spelldir.'/filetype/'.join([ - \ &filetype - \,spelllang - \,&encoding - \,'add' - \], '.')) - catch - endtry - - let &l:spellfile = s:JoinOption(spellfiles) - -endfunction diff --git a/vim/autoload/split.vim b/vim/autoload/split.vim deleted file mode 100644 index 44065094..00000000 --- a/vim/autoload/split.vim +++ /dev/null @@ -1,12 +0,0 @@ -if v:version < 702 || v:version == 702 && !has('patch-61') - runtime autoload/unescape.vim -endif - -function! split#Option(expr, ...) abort - if a:0 > 2 - echoerr 'Too many arguments' - endif - let keepempty = a:0 ? a:1 : 0 - let parts = split(a:expr, '\\\@<!,[, ]*', keepempty) - return map#(parts, function('unescape#Item')) -endfunction diff --git a/vim/autoload/unescape.vim b/vim/autoload/unescape.vim deleted file mode 100644 index a809827d..00000000 --- a/vim/autoload/unescape.vim +++ /dev/null @@ -1,3 +0,0 @@ -function! unescape#Item(key, val) abort - return substitute(a:val, '\\,', ',', 'g') -endfunction 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 a5ff8935fc2e81de46375d85378e59e333ee1ad +Subproject 403a44dc32533e631384dfcca40d520b9088b0d diff --git a/vim/bundle/spellfile_local b/vim/bundle/spellfile_local new file mode 160000 +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 12edb3d2..eea7f1f5 100644 --- a/vim/filetype.vim +++ b/vim/filetype.vim @@ -16,7 +16,7 @@ augroup filetypedetect \,?*~ \,?*.{bak,example,in,new,old,orig,sample,test} \,?*.dpkg-{bak,dist,new,old} - \ call filetype#StripRepeat() + \ call filetype#repeat#Strip() " Stuff Tom cares about enough and edits often enough to type based on " filename patterns follows. @@ -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,10 +573,10 @@ 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#SudoRepeat() + \| call filetype#repeat#Sudo() \|endif " Generic text, config, and log files, if no type assigned yet @@ -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/awk.vim b/vim/ftplugin/awk.vim index dbefa5cd..76637486 100644 --- a/vim/ftplugin/awk.vim +++ b/vim/ftplugin/awk.vim @@ -11,8 +11,7 @@ let b:undo_ftplugin = 'setlocal comments< formatoptions<' " Fold based on indent level, but start with all folds open setlocal foldmethod=indent -setlocal foldlevel=99 -let b:undo_ftplugin .= '|setlocal foldmethod< foldlevel<' +let b:undo_ftplugin .= '|setlocal foldmethod<' " Specify ERE flavor for regex_escape.vim let b:regex_escape_flavor = 'ere' 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 da2228b3..ddd88e2c 100644 --- a/vim/ftplugin/markdown.vim +++ b/vim/ftplugin/markdown.vim @@ -18,32 +18,9 @@ let &l:formatlistpat = '^\s*\d\+\.\s\+\|^[-*+]\s\+\|^\[^\ze[^\]]\+\]:' let b:undo_ftplugin .= '|setlocal formatoptions< formatlistpat<' " Let's try this heading-based fold method out (Tim Pope) -function! MarkdownFold() - let line = getline(v:lnum) - - " Regular headers - let depth = match(line, '\(^#\+\)\@<=\( .*$\)\@=') - if depth > 0 - return '>' . depth - endif - - " Setext style headings - if line =~# '^.\+$' - let nextline = getline(v:lnum + 1) - if nextline =~# '^=\+$' - return '>1' - elseif nextline =~# '^-\+$' - return '>2' - endif - endif - - return '=' -endfunction -let b:undo_ftplugin .= '|delfunction MarkdownFold' -setlocal foldexpr=MarkdownFold() +setlocal foldexpr=markdown#Fold() setlocal foldmethod=expr -setlocal foldlevel=99 -let b:undo_ftplugin .= '|setlocal foldexpr< foldmethod< foldlevel<' +let b:undo_ftplugin .= '|setlocal foldexpr< foldmethod<' " Spellcheck documents we're actually editing (not just viewing) if &modifiable && !&readonly @@ -79,8 +56,8 @@ xnoremap <buffer> <expr> <LocalLeader>Q let b:undo_ftplugin .= '|nunmap <buffer> <LocalLeader>Q' \ . '|xunmap <buffer> <LocalLeader>Q' -" Autoformat headings -command! -buffer -nargs=1 MarkdownHeading +" Automatically format headings +command -buffer -nargs=1 MarkdownHeading \ call markdown#Heading(<f-args>) nnoremap <buffer> <LocalLeader>= \ :<C-U>MarkdownHeading =<CR> diff --git a/vim/ftplugin/sed.vim b/vim/ftplugin/sed.vim index 35e705a4..04d86d7d 100644 --- a/vim/ftplugin/sed.vim +++ b/vim/ftplugin/sed.vim @@ -11,5 +11,4 @@ let b:undo_ftplugin = 'setlocal comments< formatoptions<' " Fold based on indent level, but start with all folds open setlocal foldmethod=indent -setlocal foldlevel=99 -let b:undo_ftplugin .= '|setlocal foldmethod< foldlevel<' +let b:undo_ftplugin .= '|setlocal foldmethod<' 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/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/plugin/spellfile_local.vim b/vim/plugin/spellfile_local.vim deleted file mode 100644 index f6918bfb..00000000 --- a/vim/plugin/spellfile_local.vim +++ /dev/null @@ -1,12 +0,0 @@ -if exists('loaded_spellfile_local') || &compatible - finish -endif -let loaded_spellfile_local = 1 - -command! -bar SetLocalSpellFiles - \ call spellfile_local#() - -augroup spellfile_local - autocmd BufNew,BufRead * - \ SetLocalSpellFiles -augroup END 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 @@ -1,163 +1,222 @@ -" ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -" Tom Ryder (tejr)’s Literate Vimrc -" ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -" -" Last updated: Tue, 09 Jul 2019 13:11:16 +1200 -" -" │ 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: Fri, 06 May 2022 12:23:48 +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 split#Option(). -" -" 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^='.escape#Arg(escape#Item(escape#Wild($MYVIM))) -elseif &runtimepath !=# '' - let $MYVIM = split#Option(&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. -" -" 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. +" write its own history to the default viminfo path instead. " -" <https://github.com/vim/vim/releases/tag/v8.1.0716> +" 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. " -execute 'set viminfo+='.escape#Arg('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. +" 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. " -" 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. -" -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,79 +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^='.escape#Arg(escape#Item( - \ $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^='.escape#Arg(escape#Item($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^='.escape#Arg(escape#Item($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 @@ -248,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() @@ -263,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() @@ -298,95 +398,84 @@ 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. We’ll set the 'spellfile' option too, to -" place it in the cache directory into which we’ve been putting everything. -" We’ll follow Vim’s standard naming convention for the file itself, though. -" If available, my plugin spellfile_local.vim will extend this later to add -" more spelling word lists per filetype and per file. -" -" We briefly set 'isfname' to every character but NUL if we’re using Unix, -" since Vim uses it internally for 'spellfile' assignment to decide whether -" the path is valid. We put it back immediately afterwards. +" often have to write for Yankees. " set spelllang=en_nz -let s:spelllang = split#Option(&spelllang) -let s:spellfile = $MYVIM.'/spell/'.join([ - \ split(s:spelllang[0], '_')[0], &encoding, 'add', - \], '.') -if has#('unix') - let s:isfname = &isfname - set isfname=1-255 -endif -set spellfile& -execute 'set spellfile^='.escape#Arg(escape#Item(s:spellfile)) -if exists('s:isfname') - execute 'set isfname='.escape#Arg(s:isfname) - unlet s:isfname -endif -CreatePath $MYVIM/spell " 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^='.escape#Arg(escape#Item(s:ref.'/dictionary.txt')) - execute 'set thesaurus^='.escape#Arg(escape#Item(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: " @@ -401,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. @@ -424,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 @@ -437,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=... @@ -449,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> @@ -469,126 +558,131 @@ 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 +" Always start with 'foldlevel' set high enough to have all folds of any +" practical depth open by default. +" +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. @@ -603,16 +697,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 @@ -629,39 +723,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 @@ -677,7 +771,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 @@ -686,80 +780,60 @@ 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. -" -if !plugin#Ready('matchparen') - set showmatch matchtime=3 -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 -" Limit the number of characters per line that syntax highlighting will -" attempt to match. This is as much an effort to encourage me to break long -" lines and do hard wrapping correctly as it is for efficiency. -" -set synmaxcol=500 - -" 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. " @@ -778,7 +852,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 @@ -786,7 +860,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 @@ -795,7 +869,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 @@ -810,9 +884,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. " @@ -828,12 +902,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. @@ -847,7 +921,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> @@ -855,33 +929,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> @@ -889,11 +963,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 @@ -902,7 +976,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 @@ -923,32 +997,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 +" 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. " -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. @@ -957,53 +1032,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: @@ -1022,68 +1057,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. @@ -1109,24 +1148,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. " @@ -1138,24 +1179,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 @@ -1198,17 +1240,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 @@ -1216,33 +1251,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' @@ -1252,12 +1299,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 @@ -1284,20 +1332,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 @@ -1332,8 +1379,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> @@ -1349,27 +1396,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 @@ -1391,7 +1439,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 @@ -1400,21 +1448,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. @@ -1434,88 +1486,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 gives me my fortune -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..92c53dfb 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 +" 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. +" '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. " 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 @@ -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 |