--- a/.hgignore Fri Apr 14 15:01:35 2023 -0400
+++ b/.hgignore Fri Jul 07 16:11:02 2023 -0400
@@ -48,3 +48,4 @@
lisp/man
mutt/accounts
weechat/plugins.conf
+fish/fish_variables
--- a/.hgsub Fri Apr 14 15:01:35 2023 -0400
+++ b/.hgsub Fri Jul 07 16:11:02 2023 -0400
@@ -10,16 +10,13 @@
vim/bundle/delimitmate = [git]https://github.com/Raimondi/delimitMate
vim/bundle/fugitive = [git]https://github.com/tpope/vim-fugitive
vim/bundle/gdl = [hg]ssh://hg.stevelosh.com/repos/gdl.vim/
-vim/bundle/glsl = [git]https://github.com/tikhomirov/vim-glsl
vim/bundle/gnupg = [git]https://github.com/jamessan/vim-gnupg
vim/bundle/gnuplot = [git]https://github.com/vim-scripts/gnuplot.vim
vim/bundle/gundo = [hg]ssh://hg.stevelosh.com/repos/gundo.vim/
vim/bundle/html5 = [git]https://github.com/othree/html5.vim
-vim/bundle/indent-object = [git]https://github.com/michaeljsmith/vim-indent-object
vim/bundle/javascript = [git]https://github.com/pangloss/vim-javascript
-vim/bundle/jsx = [git]https://github.com/mxw/vim-jsx
vim/bundle/markdown = [git]https://github.com/sjl/vim-markdown
-vim/bundle/miniyank = [git]https://github.com/bfredl/nvim-miniyank
+vim/bundle/neoformat = [git]https://github.com/sbdchd/neoformat
vim/bundle/nerdtree = [git]https://github.com/scrooloose/nerdtree
vim/bundle/paredit = [git]https://github.com/kovisoft/paredit
vim/bundle/pgsql = [git]https://github.com/exu/pgsql.vim
@@ -29,9 +26,8 @@
vim/bundle/rhubarb = [git]https://github.com/tpope/vim-rhubarb
vim/bundle/securemodelines = [git]https://github.com/ciaranm/securemodelines
vim/bundle/sexp = [git]https://github.com/guns/vim-sexp
-vim/bundle/shaderhighlight = [git]https://github.com/vim-scripts/ShaderHighLight
vim/bundle/shellcheck = [git]https://github.com/itspriddle/vim-shellcheck
-vim/bundle/sparkup = [git]https://github.com/rstacruz/sparkup
+vim/bundle/simpylfold = [git]https://github.com/tmhedberg/SimpylFold
vim/bundle/splice = [hg]ssh://hg.stevelosh.com/repos/splice.vim
vim/bundle/strftimedammit = [hg]ssh://hg.stevelosh.com/repos/strftimedammit.vim/
vim/bundle/surround = [git]https://github.com/tpope/vim-surround
--- a/.hgsubstate Fri Apr 14 15:01:35 2023 -0400
+++ b/.hgsubstate Fri Jul 07 16:11:02 2023 -0400
@@ -1,8 +1,8 @@
-0d3229120aff331970cba4591c1304f7fc59b394 mercurial/hg-prompt
+16aa2def1d5b91f2f38c0bf50a955d28559c7ebe mercurial/hg-prompt
1fc4a9fbead7e0acc4c828b346f3be2658ec3df9 mercurial/templates
b6a8b49e2173ba5a1b34d00e68e0ed8addac3ebd vim/bundle/abolish
a16a9b63eb85cc0960a7f25c54647ac1f99f3360 vim/bundle/ack
-e7f8786668bb9b7ac3b68198437e11f9c5c465b6 vim/bundle/badwolf
+599e1bb1aee98e563132553cf8b7bc32cb402b75 vim/bundle/badwolf
24f6d94dd03ba0fdc703265fe281f70cf2b45ba6 vim/bundle/boxdraw
b542a7bc4d9bc5da8fb12e110fe7975131fb57a4 vim/bundle/clam
8295187ea1210138c0b171d8e3ec3569936f4c1a vim/bundle/commentary
@@ -10,17 +10,14 @@
38487bbec8ba50834e257940b357de03991fa8f9 vim/bundle/delimitmate
755554bb3c44944f70f4b2048acf0c69261782ac vim/bundle/fugitive
127d706f2def96876605e6bd5d366c973cb8e406 vim/bundle/gdl
-6ea4e1983b18cf440c8f800a3e94b57338a3e99f vim/bundle/glsl
7fcea1a08423da3012aac87f5224738c85d212a1 vim/bundle/gnupg
0d57b080f9fae8573c688b6679b31eb1666edc4c vim/bundle/gnuplot
1d84591fff04caebab75cba2294fc3843f0a4a29 vim/bundle/gundo
fccd580f5f11d576169ee347907c9fbd77af410a vim/bundle/html5
-78fffa609b3e6b84ef01ee4c9aba6d7435d7b18e vim/bundle/indent-object
dd84369d731bcb8feee0901cbb9b63a2b219bf28 vim/bundle/javascript
-ffc0bfd9da15d0fce02d117b843f718160f7ad27 vim/bundle/jsx
e2d7fcd682a461a3951e8b5067cc8a0083e75e35 vim/bundle/markdown
-1362fdc7c32855794659cafe6e65d3239843d9df vim/bundle/miniyank
-d6032c876c6d6932ab7f07e262a16c9a85a31d5b vim/bundle/nerdtree
+964c66fa22500ae7375114342d212d7fe15da341 vim/bundle/neoformat
+9310f91476a94ee9c2f3a587171893743a343e26 vim/bundle/nerdtree
c76e0987ec45c84103b408691ec0506e7b99cb30 vim/bundle/paredit
1a436f7d875b4ec630da081b041c73264235c7e7 vim/bundle/pgsql
d241974f40e8d206f9970e51fb0069951862ba35 vim/bundle/python-mode
@@ -29,15 +26,14 @@
e57ed3b6be2c4a49656f1a816919f0af22fae324 vim/bundle/rhubarb
10d6c6b52fcdd12f3ba457126f66fee4ccceec04 vim/bundle/securemodelines
b4398689f7483b01684044ab6b55bf369744c9b3 vim/bundle/sexp
-e02c3e218c51c1e2ea1821a3fe412d4e09ca1502 vim/bundle/shaderhighlight
4346419ac57ef341a15aa39c827c0848f17c6faf vim/bundle/shellcheck
-d400a570bf64b0c216aa7c8e1795820b911a7404 vim/bundle/sparkup
+0459df8a0bbfc8ef1bfd88db889e881626f65914 vim/bundle/simpylfold
062b18eebd153c13e6f36577707acb17893cd959 vim/bundle/splice
26fbdd7d1f1aa5600d2ebf39bbdd292c38aac16e vim/bundle/strftimedammit
aa1f120ad3a29c27cc41d581cda3751c59343cce vim/bundle/surround
19c3d966440b6cfe8d74251881a48e961ddb8648 vim/bundle/swig
f6f2d6618a321f5b0065586a7bc934325fec81ab vim/bundle/targets
-2c6bffb492f4f9b101e45610b0d7b9c328916894 vim/bundle/vim-go
+e9d7ff3eb4a369f0cb2069c8f77ae68796bca308 vim/bundle/vim-go
5d5c71044880443035e07009497962feacb56b20 vim/bundle/vimtex
54feb567738398ab65d783e096bc84938e7620a0 vim/bundle/vlime
6876fe38b33732cb124d415ffc4156f16da5e118 vim/bundle/windowswap
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/.mbsyncrc Fri Jul 07 16:11:02 2023 -0400
@@ -0,0 +1,81 @@
+# tweaked https://raw.githubusercontent.com/bm4cs/dots/Far/.mbsyncrc
+
+IMAPAccount fastmail
+Host imap.fastmail.com
+Port 993
+User steve@stevelosh.com
+PassCmd "pass show mutt/ouroboros/steve@stevelosh.com | head -n 1"
+SSLType IMAPS
+SSLVersion TLSv1.2
+CertificateFile /etc/ssl/certs/ca-certificates.crt
+
+# Remote
+IMAPStore mail-remote
+Account fastmail
+
+# Local
+MaildirStore mail-local
+Subfolders Verbatim
+Path ~/.mail2/sjl/
+Inbox ~/.mail2/sjl/INBOX
+
+# CONNECTIONS SPECIFY LINKS BETWEEN REMOTE AND LOCAL FOLDERS
+# CONNECTIONS ARE SPECIFIED USING PATTERNS, WHICH MATCH REMOTE MAIl
+# FOLDERS. SOME COMMONLY USED PATTERS INCLUDE:
+#
+# 1 "*" TO MATCH EVERYTHING
+# 2 "!DIR" TO EXCLUDE "DIR"
+# 3 "DIR" TO MATCH DIR
+
+Channel mail-inbox
+Far :mail-remote:
+Near :mail-local:
+Patterns INBOX
+Create Near
+Sync All
+Expunge Both
+SyncState *
+
+Channel mail-sent
+Far :mail-remote:
+Near :mail-local:
+Patterns "Sent"
+Create Both
+Sync All
+Expunge Both
+SyncState *
+
+Channel mail-spam
+Far :mail-remote:
+Near :mail-local:
+Patterns "Uncaught Spam"
+Create Near
+Sync All
+Expunge Both
+SyncState *
+
+Channel mail-drafts
+Far :mail-remote:
+Near :mail-local:
+Patterns "Drafts"
+Create Near
+Sync All
+Expunge Both
+SyncState *
+
+Channel mail-archive
+Far :mail-remote:
+Near :mail-local:
+Patterns "Arc*"
+Create Near
+Sync All
+Expunge Both
+SyncState *
+
+Group mail
+Channel mail-inbox
+Channel mail-spam
+Channel mail-drafts
+Channel mail-sent
+Channel mail-archive
+
--- a/Xmodmap Fri Apr 14 15:01:35 2023 -0400
+++ b/Xmodmap Fri Jul 07 16:11:02 2023 -0400
@@ -13,28 +13,41 @@
keycode 47 = minus colon
keycode 20 = semicolon underscore
keycode 108 = Mode_switch
+! F14 to compose
+keycode 192 = Multi_key
+keycode 193 = F15
+keycode 194 = F16
+keycode 195 = F17
+keycode 196 = F18
+keycode 197 = F19
+keycode 198 = F20
+keycode 199 = F21
+keycode 200 = F22
+keycode 201 = F23
+keycode 202 = F24
+keycode 203 = F25
-keycode 900 = F16
+! keycode 900 = F16
! for some reason this fucks up keycode 133. I have no idea why this happens.
! keycode 901 = F17
-keycode 902 = F18
-keycode 903 = F19
-keycode 904 = F20
-keycode 905 = F21
-keycode 906 = F22
-keycode 907 = F23
-keycode 908 = F24
-keycode 909 = F25
+! keycode 902 = F18
+! keycode 903 = F19
+! keycode 904 = F20
+! keycode 905 = F21
+! keycode 906 = F22
+! keycode 907 = F23
+! keycode 908 = F24
+! keycode 909 = F25
keycode 910 = F26
-keycode 911 = F27
-keycode 912 = F28
-keycode 913 = F29
-keycode 914 = F30
-keycode 915 = F31
-keycode 916 = F32
-keycode 917 = F33
-keycode 918 = F34
-keycode 919 = F35
+! keycode 911 = F27
+! keycode 912 = F28
+! keycode 913 = F29
+! keycode 914 = F30
+! keycode 915 = F31
+! keycode 916 = F32
+! keycode 917 = F33
+! keycode 918 = F34
+! keycode 919 = F35
add control = Control_L
add mod1 = Alt_L
--- a/bash_profile Fri Apr 14 15:01:35 2023 -0400
+++ b/bash_profile Fri Jul 07 16:11:02 2023 -0400
@@ -1,5 +1,9 @@
#!/usr/bin/env bash
+if test -e /etc/profile; then
+ source /etc/profile
+fi
+
shopt -s expand_aliases
shopt -s histappend
@@ -107,3 +111,6 @@
export GPG_TTY
export EDITOR=nvim
+
+export NVM_DIR="$HOME/.nvm"
+[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/bin/addcontact Fri Jul 07 16:11:02 2023 -0400
@@ -0,0 +1,12 @@
+#!/usr/bin/env bash
+
+set -euo pipefail
+
+# USAGE: addcontact 'Kevin Wu <kevinwuhoo@gmail.com>'
+
+RAW="$1"
+
+EMAIL="$(echo "$1" | grep -Po '<.+>' | tr -d '<>')"
+NAME="$(echo "$1" | sed -e 's/ [^ ]*$//')"
+
+printf "$EMAIL"'\t'"$NAME"'\t\n' >> ~/.contacts
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/bin/backpackfor Fri Jul 07 16:11:02 2023 -0400
@@ -0,0 +1,6 @@
+#!/usr/bin/env bash
+
+set -euo pipefail
+
+cp ~/Dropbox/tasks/backpack-archive ~/Dropbox/tasks/backpack.txt
+nvim ~/Dropbox/tasks/backpack.txt
--- a/bin/bootstrap.sh Fri Apr 14 15:01:35 2023 -0400
+++ b/bin/bootstrap.sh Fri Jul 07 16:11:02 2023 -0400
@@ -54,7 +54,6 @@
ensure_link "src/dotfiles/sqliterc" ".sqliterc"
ensure_link "src/dotfiles/stumpwmrc" ".stumpwmrc"
ensure_link "src/dotfiles/stumpwm/local-share-stumpwm" ".local/share/stumpwm"
-ensure_link "src/dotfiles/tmux/tmux.conf" ".tmux.conf"
ensure_link "src/dotfiles/vim" ".vim"
ensure_link "src/dotfiles/vim/vimrc" ".vimrc"
ensure_link "src/dotfiles/w3m-keymap" ".w3m/keymap"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/bin/c Fri Jul 07 16:11:02 2023 -0400
@@ -0,0 +1,5 @@
+#!/usr/bin/env bash
+
+set -euo pipefail
+
+cacl --no-inform --batch "$@"
--- a/bin/cacl Fri Apr 14 15:01:35 2023 -0400
+++ b/bin/cacl Fri Jul 07 16:11:02 2023 -0400
@@ -2,8 +2,7 @@
set -e
-LISPS=("sbcl" "ccl" "abcl" "ecl")
+# LISPS=("sbcl" "ccl" "abcl")
LISPS=("sbcl" "ccl")
-LISPS=("sbcl")
rlwrap ~/src/cacl/build/cacl-$(shuf -n1 -e "${LISPS[@]}") "$@"
--- a/bin/clean_mail Fri Apr 14 15:01:35 2023 -0400
+++ b/bin/clean_mail Fri Jul 07 16:11:02 2023 -0400
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
import sys
--- a/bin/disks Fri Apr 14 15:01:35 2023 -0400
+++ b/bin/disks Fri Jul 07 16:11:02 2023 -0400
@@ -8,9 +8,14 @@
'
echo
echo
-echo
OUT=$(df -h)
echo "$OUT" | head -1
echo "$OUT" | head -1 | sed 's/./-/g'
echo "$OUT" | tail +2 | grep -Pv '^/dev/loop' | grep -Pv tmpfs | sort -k6
+
+echo
+OUT=$(df -i)
+echo "$OUT" | head -1
+echo "$OUT" | head -1 | sed 's/./-/g'
+echo "$OUT" | tail +2 | grep -Pv '^/dev/loop' | grep -Pv tmpfs | sort -k6
--- a/bin/e Fri Apr 14 15:01:35 2023 -0400
+++ b/bin/e Fri Jul 07 16:11:02 2023 -0400
@@ -2,4 +2,8 @@
set -euo pipefail
-"$EDITOR" "$@"
+if test "$#" -eq 0; then
+ "$EDITOR" .
+else
+ "$EDITOR" "$@"
+fi
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/bin/ecl-raw Fri Jul 07 16:11:02 2023 -0400
@@ -0,0 +1,4 @@
+#!/usr/bin/env bash
+
+set -e
+/usr/local/bin/ecl "$@"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/bin/ecl-vlime Fri Jul 07 16:11:02 2023 -0400
@@ -0,0 +1,4 @@
+#!/usr/bin/env bash
+
+set -e
+ecl --eval "(load \"~/src/dotfiles/vim/bundle/vlime/lisp/start-vlime.lisp\")" "$@"
--- a/bin/ee Fri Apr 14 15:01:35 2023 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,5 +0,0 @@
-#!/usr/bin/env bash
-
-set -euo pipefail
-
-e .
--- a/bin/external-ip Fri Apr 14 15:01:35 2023 -0400
+++ b/bin/external-ip Fri Jul 07 16:11:02 2023 -0400
@@ -2,5 +2,7 @@
set -euo pipefail
-dig @resolver1.opendns.com ANY myip.opendns.com +short
+#dig @resolver1.opendns.com ANY myip.opendns.com +short
+curl https://whatismyip.stevelosh.com
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/bin/git-du Fri Jul 07 16:11:02 2023 -0400
@@ -0,0 +1,23 @@
+#!/usr/bin/env bash
+
+set -euo pipefail
+
+ROOT="$1"
+shift
+
+git-object-sizes \
+ | head -200 \
+ | grep -P "^\d+,\d+,[0-9a-f]+,$ROOT.*" \
+ | awk --field-separator , '
+ {
+ sums[$4] += $1
+ }
+ END {
+ for (x in sums) {
+ print sums[x], x
+ }
+ }
+ '
+
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/bin/git-object-sizes Fri Jul 07 16:11:02 2023 -0400
@@ -0,0 +1,38 @@
+#!/usr/bin/env bash
+
+# Shows you the largest objects in your repo's pack file.
+# Written for osx.
+#
+# @see http://stubbisms.wordpress.com/2009/07/10/git-script-to-show-largest-pack-objects-and-trim-your-waist-line/
+# @author Antony Stubbs
+#
+# Edited by sjl
+
+# set the internal field spereator to line break, so that we can iterate easily over the verify-pack output
+IFS=$'\n';
+
+# list all objects including their size, sort by size
+objects=`git verify-pack -v .git/objects/pack/pack-*.idx | grep -P '(tree|blob|commit)'`
+
+# echo "All sizes are in bytes. The pack column is the size of the object, compressed, inside the pack file." >&2
+
+# echo "size,pack,SHA,location"
+for y in $objects
+do
+ # echo "$y"
+
+ # extract the size in bytes
+ size=`echo $y | f 3`
+
+ # extract the compressed size in bytes
+ compressedSize=`echo $y | f 4`
+
+ # extract the SHA
+ sha=`echo $y | f 1`
+
+ # find the objects location in the repository tree
+ loc=`git rev-list --all --objects | grep $sha | f 2`
+
+ #lineBreak=`echo -e "\n"`
+ echo "${size},${compressedSize},${sha},${loc}"
+done
--- a/bin/hist Fri Apr 14 15:01:35 2023 -0400
+++ b/bin/hist Fri Jul 07 16:11:02 2023 -0400
@@ -7,9 +7,14 @@
USAGE: $0 [OPTIONS]
+Note that the output lines will be unsorted. For sorted output you can pipe the
+output to sort:
+
+ cat foo.dat | hist | sort -n -k3
+
Options:
- -h, --help display this help text and exit
- -w N, --width N how wide the histograms should be
+ -h, --help display this help text and exit
+ -w COLS, --width COLS how wide the histogram bars should be
"
}
@@ -49,7 +54,7 @@
bars = int(val * x * width)
pads = width - bars
- printf "%s ", val
+ printf "%s |", val
for(i=0; i<bars; i++) printf "█"
for(i=0; i<pads; i++) printf " "
print key
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/bin/hl Fri Jul 07 16:11:02 2023 -0400
@@ -0,0 +1,3 @@
+#!/usr/bin/env bash
+
+less -R
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/bin/isbinary Fri Jul 07 16:11:02 2023 -0400
@@ -0,0 +1,5 @@
+#!/usr/bin/env bash
+
+set -euo pipefail
+
+grep -om1 '' "$1" | grep '^Binary' >/dev/null
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/bin/join-regex-or Fri Jul 07 16:11:02 2023 -0400
@@ -0,0 +1,4 @@
+#!/usr/bin/env python3
+
+import sys
+print("|".join(sys.stdin.readlines()).replace('\n', ''))
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/bin/join-strings Fri Jul 07 16:11:02 2023 -0400
@@ -0,0 +1,4 @@
+#!/usr/bin/env python3
+
+import sys
+print(sys.argv[1].join(sys.stdin.readlines()))
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/bin/kpa Fri Jul 07 16:11:02 2023 -0400
@@ -0,0 +1,5 @@
+#!/usr/bin/env bash
+
+set -euo pipefail
+
+killall pulseaudio
--- a/bin/myctags Fri Apr 14 15:01:35 2023 -0400
+++ b/bin/myctags Fri Jul 07 16:11:02 2023 -0400
@@ -2,14 +2,16 @@
set -e
-/usr/local/bin/ctags -R . && sed -i .bak -E -e '/^[^ ]+ [^ ]+.py .+v$/d' tags
+CTAGS=$(command -v ctags)
+# $CTAGS -R . && sed -i.bak -E -e '/^[^ ]+ [^ ]+.py .+v$/d' tags
-mv tags tags1
-touch tags2
+$CTAGS -R --sort=yes --exclude='bazel-*' .
+# mv tags tags1
+# touch tags2
-echo '!_TAG_FILE_FORMAT 2 /extended format; --format=1 will not append ;" to lines/' > tags
-echo '!_TAG_FILE_SORTED 1 /0=unsorted, 1=sorted, 2=foldcase/' >> tags
+# echo '!_TAG_FILE_FORMAT 2 /extended format; --format=1 will not append ;" to lines/' >> tags2
+# echo '!_TAG_FILE_SORTED 1 /0=unsorted, 1=sorted, 2=foldcase/' >> tags2
-cat tags1 tags2 | grep -Ev '^!' | grep -v 'anonymous_function' | sort >> tags
+# cat tags1 tags2 | grep -Ev '^!' | grep -v 'anonymous_function' | sort >> tags
-rm tags1 tags2
+# rm tags1 tags2
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/bin/o Fri Jul 07 16:11:02 2023 -0400
@@ -0,0 +1,9 @@
+#!/usr/bin/env bash
+
+set -euo pipefail
+
+if test "$#" -eq 0; then
+ open .
+else
+ open "$@"
+fi
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/bin/packfor Fri Jul 07 16:11:02 2023 -0400
@@ -0,0 +1,6 @@
+#!/usr/bin/env bash
+
+set -euo pipefail
+
+cp ~/Dropbox/tasks/pack-archive ~/Dropbox/tasks/pack.txt
+nvim ~/Dropbox/tasks/pack.txt
--- a/bin/pastebin Fri Apr 14 15:01:35 2023 -0400
+++ b/bin/pastebin Fri Jul 07 16:11:02 2023 -0400
@@ -2,7 +2,7 @@
set -euo pipefail
-PASTE_SHA=$(ssh paste.stevelosh.com -- 'cat > tmppaste && sha1sum tmppaste | cut -d" " -f1 && mv tmppaste /var/www/paste/`sha1sum tmppaste | cut -d" " -f1`')
+PASTE_SHA=$(ssh paste.stevelosh.com -- 'cat > tmppaste && sha1sum tmppaste | cut -d" " -f1 && mv tmppaste /var/www/paste.stevelosh.com/`sha1sum tmppaste | cut -d" " -f1`')
URL="https://paste.stevelosh.com/$PASTE_SHA"
echo -n "$URL" | pbcopy
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/bin/pf Fri Jul 07 16:11:02 2023 -0400
@@ -0,0 +1,12 @@
+#!/usr/bin/env bash
+
+set -euo pipefail
+
+P="$1"
+F=$(basename "$P")
+
+scp "$P" paste.stevelosh.com:"/var/www/paste/$F"
+URL="https://paste.stevelosh.com/$F"
+
+echo -n "$URL" | pbcopy
+echo "Copied $URL to the clipboard."
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/bin/posix Fri Jul 07 16:11:02 2023 -0400
@@ -0,0 +1,12 @@
+#!/usr/bin/env bash
+
+if [ -z "$1" ]; then
+ w3m "$HOME/Dropbox/docs/posix/idx/utilities.html"
+else
+ HTMLFILE="$HOME/Dropbox/docs/posix/utilities/$1.html"
+ if [ -s "$HTMLFILE" ]; then
+ w3m "$HTMLFILE"
+ else
+ echo "No matching file for '$1'"
+ fi
+fi
--- a/bin/sbcl-raw Fri Apr 14 15:01:35 2023 -0400
+++ b/bin/sbcl-raw Fri Jul 07 16:11:02 2023 -0400
@@ -2,7 +2,4 @@
set -e
-rlwrap --quote-characters '' \
- --histsize 1000 \
- --history-filename "$HOME/.rlwrap-lisp-history" \
- /usr/local/bin/sbcl --noinform "$@"
+/usr/local/bin/sbcl --noinform "$@"
--- a/bin/t Fri Apr 14 15:01:35 2023 -0400
+++ b/bin/t Fri Jul 07 16:11:02 2023 -0400
@@ -2,4 +2,4 @@
set -euo pipefail
-python ~/src/t/t.py --task-dir ~/plan --list TODO "$@"
+python3 ~/src/t/t.py --task-dir ~/Dropbox/tasks/ --list tasks.txt "$@"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/bin/unheic Fri Jul 07 16:11:02 2023 -0400
@@ -0,0 +1,5 @@
+#!/usr/bin/env bash
+
+set -euo pipefail
+
+for f in *.HEIC; do heif-convert -q 100 "$f" "$f.jpg"; done
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/bin/unix-timestamp-seconds Fri Jul 07 16:11:02 2023 -0400
@@ -0,0 +1,3 @@
+#!/usr/bin/env bash
+
+date '+%s'
--- a/ffignore Fri Apr 14 15:01:35 2023 -0400
+++ b/ffignore Fri Jul 07 16:11:02 2023 -0400
@@ -1,9 +1,13 @@
syntax:literal
+venv
+.venv
+.vagrant
.DS_Store
cookbook
banner.txt
UnityTempFile
.m2
+.mail
node_modules
fake-gopath
slug
@@ -17,3 +21,4 @@
\.dx64fsl$
\.lx64fsl$
\.pyc$
+bazel-.*
--- a/fish/config.fish Fri Apr 14 15:01:35 2023 -0400
+++ b/fish/config.fish Fri Jul 07 16:11:02 2023 -0400
@@ -6,6 +6,7 @@
function eg; nvim ~/.gitconfig; end
function eh; nvim ~/.hgrc; end
function ei; hg -R ~/src/inventory/ pull -u; and nvim ~/src/inventory/inventory.markdown; and hg -R ~/src/inventory/ ci -m 'Update inventory'; and hg -R ~/src/inventory/ push; end
+function el; cd ~/Dropbox/life; nvim .; end
function em; nvim ~/.mutt/muttrc; end
function es; cd ~/src/stumpwm; nvim ~/.stumpwmrc; end
function ev; nvim ~/.vimrc; end
@@ -67,6 +68,7 @@
function please_fish_just_bind_the_keys
bind \cn accept-autosuggestion
bind \cw backward-kill-word
+ fzf_key_bindings
end
function fish_user_keybindings
please_fish_just_bind_the_keys
@@ -125,6 +127,21 @@
set -g -x LESS_TERMCAP_ue (printf '\e[0m') # end underline
set -g -x LESS_TERMCAP_us (printf '\e[04;38;5;146m') # begin underline
+set -g -x FZF_DEFAULT_COMMAND 'ffind | head -10000'
+set -g -x FZF_DEFAULT_OPTS '--height 15'
+
+set -g -x ANSIBLE_NOCOWS 1
+
+# }}}
+# Disable Spyware {{{
+
+set -g -x DO_NOT_TRACK 1
+set -g -x STRIPE_CLI_TELEMETRY_OPTOUT 1
+set -g -x GOTELEMETRY off
+set -g -x GOPROXY direct
+set -g -x VAGRANT_CHECKPOINT_DISABLE 1
+set -g -x CHECKPOINT_DISABLE 1
+
# }}}
# Python {{{
@@ -189,7 +206,7 @@
set_color normal
printf ' on '
set_color magenta
- printf '%s' (git current-branch ^/dev/null)
+ printf '%s' (git current-branch 2>/dev/null)
set_color green
git_prompt_status
set_color normal
@@ -201,6 +218,22 @@
echo $PWD | sed -e "s|^$HOME|~|"
end
+set elapsed_start 0
+set elapsed 0
+
+function prompt_time_elapsed --description 'Print the time taken by the previous command, if significant.'
+ if test $elapsed -gt 2
+ echo -n ' ('$elapsed's)'
+ end
+end
+
+function elapsed_timer_pre -e fish_preexec
+ set elapsed_start (date '+%s')
+end
+
+function elapsed_timer_post -e fish_postexec
+ set elapsed (math (date '+%s') - $elapsed_start)
+end
function fish_prompt
set last_status $status
@@ -225,6 +258,9 @@
git_prompt
end
+ set_color brblack
+ prompt_time_elapsed
+
echo
if test $last_status -eq 0
--- a/fish/functions/hl.fish Fri Apr 14 15:01:35 2023 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-function hl -d "Highlighted Less"
- less -R
-end
--- a/fish/functions/o.fish Fri Apr 14 15:01:35 2023 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-function o -d "open" --wraps "open"
- open $argv
-end
--- a/fish/functions/oo.fish Fri Apr 14 15:01:35 2023 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-function oo -d "open ."
- open .
-end
--- a/fish/functions/packfor.fish Fri Apr 14 15:01:35 2023 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-function packfor
- cp ~/Dropbox/tasks/pack-archive ~/Dropbox/tasks/pack.txt
-end
--- a/fish/functions/serve-this.fish Fri Apr 14 15:01:35 2023 -0400
+++ b/fish/functions/serve-this.fish Fri Jul 07 16:11:02 2023 -0400
@@ -1,3 +1,3 @@
function serve-this -d "Launch a webserver on 8000 serving the cwd"
- python -m SimpleHTTPServer
+ python3 -m http.server
end
--- a/gitconfig Fri Apr 14 15:01:35 2023 -0400
+++ b/gitconfig Fri Jul 07 16:11:02 2023 -0400
@@ -8,11 +8,18 @@
excludesfile = ~/.gitignore
[alias]
+ mainbranch = "!f() { git branch | grep -P ' (master|main)$' | sed -Ee 's/.* //'; }; f"
tags = tag -l
branches = branch -a
remotes = remote -v
make-the-fucking-branch-point-at-the-fucking-commit = "!sh -c 'git checkout $1 && git reset --hard $2' -"
+ mtfbpatfc = "!sh -c 'git checkout $1 && git reset --hard $2' -"
+
+ reset-main-to-origin = "!sh -c 'git mtfbpatfc $(git mainbranch) origin/$(git mainbranch)' -"
+
+ repoint = "!sh -c 'git update-ref HEAD $1 && git reset' -"
+
root = rev-parse --show-toplevel
l = log -18 --color=always --all --topo-order --pretty='format:%Cgreen%h%Creset %s%Cred%d%Creset %C(black bold)(by %an)%Creset'
@@ -30,12 +37,12 @@
ack = log --color=always --all --topo-order --pretty='format:%Cgreen%h%Creset %s%Cred%d%Creset %C(black bold)(by %an)%Creset' --full-history -S
+ # not much what's up with you
+ upsub = submodule update --init --recursive
+
ci = commit
cm = commit -m
- rom = rebase origin/master
- rec = rebase --continue
-
d = diff
di = diff --cached
dl = "!f() { git diff \"$@\" | nvim -R -c 'set ft=diff' -; }; f"
@@ -61,10 +68,13 @@
delete-remote-branch = "!sh -c 'git push $1 --delete $2' -"
delete-branch = "!sh -c 'git delete-local-branch $1; git remotes | cut -f1 | sort | uniq | xargs -n1 -I % git delete-local-reference-to-remote-branch % $1' -"
delete-current-branch = "!bash -c 'git checkout master && git delete-branch $1' - $(git current-branch)"
+ purge-branch = "!sh -c 'set -x; git delete-local-branch $1; git delete-local-reference-to-remote-branch origin $1 && git delete-remote-branch origin $1' -"
clean-local-branches = "!sh -c 'git branch --merged master | grep -v master$ | xargs git branch -d' -"
clean-remote-tracking-branches = "!sh -c 'git branch -r --merged master | grep -v /master$ | xargs git branch -rd' -"
clean-branches = "!sh -c 'git checkout master && git fetch origin && git merge --ff-only origin/master && git clean-local-branches && git clean-remote-tracking-branches' -"
+ branch-activity = "!sh -c 'git log -n1 --pretty=format:\"%aI%d\n\" $1 --' -"
+
current-branch = rev-parse --abbrev-ref HEAD
fo = fetch origin
@@ -81,7 +91,10 @@
fuu = "!sh -c 'git fu && git uu' -"
fuo = "!sh -c 'git fo && git uo' -"
- fuom = "!sh -c 'git co master && git fo && git uo' -"
+ fuom = "!sh -c 'git co $(git mainbranch) && git fo && git uo' -"
+ fuum = "!sh -c 'git co $(git mainbranch) && git fu && git uu' -"
+ rom = "!sh -c 'git fo && git rebase origin/$(git mainbranch)' -"
+ recon = rebase --continue
addremove = !git add . && git add -u
addrem = !git addremove
@@ -96,6 +109,8 @@
purge = "!sh -c 'git untracked && confirm && git actually-purge'"
actually-purge = "!sh -c 'git untracked | xargs rm'"
+ bazel-log = log --pretty=bazel --date=raw --all --graph --topo-order
+
[push]
default = current
@@ -123,7 +138,20 @@
path = ~/.gitconfig_local
[credential]
- helper = store
+ helper = store
+ useHttpPath = true
[sendemail]
smtpserver = "/home/sjl/src/dotfiles/bin/msmtp-stevelosh"
+
+[pretty]
+ bazel = %C(auto)%H %Cgreen%cd %C(auto)%s %Cred%al %C(auto)%d
+[pull]
+ ff = only
+[filter "lfs"]
+ clean = git-lfs clean -- %f
+ smudge = git-lfs smudge -- %f
+ process = git-lfs filter-process
+ required = true
+[diff "lfs"]
+ textconv = cat
--- a/gitignore Fri Apr 14 15:01:35 2023 -0400
+++ b/gitignore Fri Jul 07 16:11:02 2023 -0400
@@ -16,5 +16,6 @@
*.lx64fsl
*.dx64fsl
.sjl-rsync-exclude
+sjl-jupyter
*.waiting
--- a/gnuplot Fri Apr 14 15:01:35 2023 -0400
+++ b/gnuplot Fri Jul 07 16:11:02 2023 -0400
@@ -23,8 +23,8 @@
tau = 2 * pi
e = 2.71828182845905
r2 = sqrt(2.0)
-rfc3339 = "%Y-%m-%d %H:%M:%S."
-iso8601 = "%Y-%m-%dT%H:%M:%S."
+rfc3339 = "%Y-%m-%dT%H:%M:%S"
+iso8601 = "%Y-%m-%dT%H:%M:%S"
# }}}
# Utility Functions ------------------------------------------------------- {{{
@@ -52,6 +52,24 @@
lrt4(mp, bp) = baselrt(m4, b4, mp, bp)
# }}}
+# Convenience Wrappers ---------------------------------------------------- {{{
+# usage: @xrfc3339
+
+csvinput = 'set datafile separator ","'
+xrfc3339 = "set xdata time; set timefmt rfc3339"
+yrfc3339 = "set ydata time; set timefmt rfc3339"
+
+y_def = sprintf("set ytics format '%h'") # eval y_def()
+y_eng(n) = sprintf("set ytics format '%." . n . "sx10^%S'") # eval y_eng(1) → 100.1 x 10⁶
+
+# }}}
+# Quick Plots ------------------------------------------------------------- {{{
+# usage: @qpng
+
+qpng = 'set terminal pngcairo size 1600,1200; set termoption font "Routed Gothic,18"; set output "plot.png"'
+qpdf = 'set terminal pdfcairo size 16in,12in; set termoption font "Routed Gothic,20"; set output "plot.pdf"'
+
+# }}}
# Exporting --------------------------------------------------------------- {{{
export(file, terminal) = sprintf( \
@@ -71,6 +89,16 @@
png = "eval export_png('graph')"
# }}}
+# Histograms -------------------------------------------------------------- {{{
+
+histogram_bin_width=1024*256
+histogram_bin(x,width)=width*floor(x/width) + width/2.0
+set boxwidth histogram_bin_width*0.9
+set style fill solid 0.5
+
+# plot 'sizes' using (histogram_bin($1,histogram_bin_width)):(1.0) smooth freq with boxes
+
+# }}}
# Other ------------------------------------------------------------------- {{{
kdens(file, column, bandwidth) = sprintf( \
--- a/gnuplot-scripts/black-and-white-lines-points.gp Fri Apr 14 15:01:35 2023 -0400
+++ b/gnuplot-scripts/black-and-white-lines-points.gp Fri Jul 07 16:11:02 2023 -0400
@@ -1,15 +1,15 @@
set palette defined (0 '#111111', 1 '#eeeeee')
-set linetype 1 linewidth 1.25 pointtype 7 ps 1.0 linecolor rgb 'black' pointinterval -1 dt solid
-set linetype 2 linewidth 1.25 pointtype 1 ps 1.1 linecolor rgb 'black' pointinterval -1 dt '-'
-set linetype 3 linewidth 1.25 pointtype 9 ps 1.3 linecolor rgb 'black' pointinterval -1 dt '.'
-set linetype 4 linewidth 1.25 pointtype 6 ps 1.0 linecolor rgb 'black' pointinterval -1 dt (10, 5, 2, 5)
-set linetype 5 linewidth 1.25 pointtype 10 ps 1.3 linecolor rgb 'black' pointinterval -1 dt (8, 7, 2, 7, 2, 7)
-set linetype 6 linewidth 1.25 pointtype 7 ps 1.0 linecolor rgb 'black' pointinterval -1 dt solid
-set linetype 7 linewidth 1.25 pointtype 1 ps 1.1 linecolor rgb 'black' pointinterval -1 dt '-'
-set linetype 8 linewidth 1.25 pointtype 9 ps 1.3 linecolor rgb 'black' pointinterval -1 dt '.'
-set linetype 9 linewidth 1.25 pointtype 6 ps 1.0 linecolor rgb 'black' pointinterval -1 dt (10, 5, 2, 5)
-set linetype 10 linewidth 1.25 pointtype 10 ps 1.3 linecolor rgb 'black' pointinterval -1 dt (8, 7, 2, 7, 2, 7)
+set linetype 1 linewidth 2 pointtype 7 ps 1.0 linecolor rgb 'black' pointinterval -1 dt solid
+set linetype 2 linewidth 2 pointtype 1 ps 1.3 linecolor rgb 'black' pointinterval -1 dt '-'
+set linetype 3 linewidth 2 pointtype 9 ps 1.3 linecolor rgb 'black' pointinterval -1 dt '.'
+set linetype 4 linewidth 2 pointtype 6 ps 1.0 linecolor rgb 'black' pointinterval -1 dt (10, 5, 2, 5)
+set linetype 5 linewidth 2 pointtype 10 ps 1.3 linecolor rgb 'black' pointinterval -1 dt (8, 7, 2, 7, 2, 7)
+set linetype 6 linewidth 2 pointtype 7 ps 1.0 linecolor rgb 'black' pointinterval -1 dt solid
+set linetype 7 linewidth 2 pointtype 1 ps 1.1 linecolor rgb 'black' pointinterval -1 dt '-'
+set linetype 8 linewidth 2 pointtype 9 ps 1.3 linecolor rgb 'black' pointinterval -1 dt '.'
+set linetype 9 linewidth 2 pointtype 6 ps 1.0 linecolor rgb 'black' pointinterval -1 dt (10, 5, 2, 5)
+set linetype 10 linewidth 2 pointtype 10 ps 1.3 linecolor rgb 'black' pointinterval -1 dt (8, 7, 2, 7, 2, 7)
unset linetype 11
unset linetype 12
--- a/gnuplot-scripts/black-and-white-lines.gp Fri Apr 14 15:01:35 2023 -0400
+++ b/gnuplot-scripts/black-and-white-lines.gp Fri Jul 07 16:11:02 2023 -0400
@@ -1,15 +1,15 @@
set palette defined (0 '#111111', 1 '#eeeeee')
-set linetype 1 linewidth 1.25 pointtype 7 ps 1.0 linecolor rgb 'black' pointinterval -1 dt solid
-set linetype 2 linewidth 1.25 pointtype 7 ps 1.0 linecolor rgb 'black' pointinterval -1 dt '-'
-set linetype 3 linewidth 1.25 pointtype 7 ps 1.0 linecolor rgb 'black' pointinterval -1 dt '.'
-set linetype 4 linewidth 1.25 pointtype 7 ps 1.0 linecolor rgb 'black' pointinterval -1 dt (10, 5, 2, 5)
-set linetype 5 linewidth 1.25 pointtype 7 ps 1.0 linecolor rgb 'black' pointinterval -1 dt (8, 7, 2, 7, 2, 7)
-set linetype 6 linewidth 1.25 pointtype 7 ps 1.0 linecolor rgb 'black' pointinterval -1 dt solid
-set linetype 7 linewidth 1.25 pointtype 7 ps 1.0 linecolor rgb 'black' pointinterval -1 dt '-'
-set linetype 8 linewidth 1.25 pointtype 7 ps 1.0 linecolor rgb 'black' pointinterval -1 dt '.'
-set linetype 9 linewidth 1.25 pointtype 7 ps 1.0 linecolor rgb 'black' pointinterval -1 dt (10, 5, 2, 5)
-set linetype 10 linewidth 1.25 pointtype 7 ps 1.0 linecolor rgb 'black' pointinterval -1 dt (8, 7, 2, 7, 2, 7)
+set linetype 1 linewidth 3 pointtype 7 ps 1.0 linecolor rgb 'black' pointinterval -1 dt solid
+set linetype 2 linewidth 3 pointtype 7 ps 1.0 linecolor rgb 'black' pointinterval -1 dt '-'
+set linetype 3 linewidth 3 pointtype 7 ps 1.0 linecolor rgb 'black' pointinterval -1 dt '.'
+set linetype 4 linewidth 3 pointtype 7 ps 1.0 linecolor rgb 'black' pointinterval -1 dt (10, 5, 2, 5)
+set linetype 5 linewidth 3 pointtype 7 ps 1.0 linecolor rgb 'black' pointinterval -1 dt (8, 7, 2, 7, 2, 7)
+set linetype 6 linewidth 3 pointtype 7 ps 1.0 linecolor rgb 'black' pointinterval -1 dt solid
+set linetype 7 linewidth 3 pointtype 7 ps 1.0 linecolor rgb 'black' pointinterval -1 dt '-'
+set linetype 8 linewidth 3 pointtype 7 ps 1.0 linecolor rgb 'black' pointinterval -1 dt '.'
+set linetype 9 linewidth 3 pointtype 7 ps 1.0 linecolor rgb 'black' pointinterval -1 dt (10, 5, 2, 5)
+set linetype 10 linewidth 3 pointtype 7 ps 1.0 linecolor rgb 'black' pointinterval -1 dt (8, 7, 2, 7, 2, 7)
unset linetype 11
unset linetype 12
--- a/gnuplot-scripts/color.gp Fri Apr 14 15:01:35 2023 -0400
+++ b/gnuplot-scripts/color.gp Fri Jul 07 16:11:02 2023 -0400
@@ -1,16 +1,16 @@
set palette defined (0 '#fef0d9', 1 '#d7301f', 2 '#fc8d59', 3 '#d7301f')
-set linetype 1 linewidth 1.25 pointtype 7 ps 1.0 linecolor rgb '#1f78b4' pointinterval -1 dashtype solid
-set linetype 2 linewidth 1.25 pointtype 1 ps 1.1 linecolor rgb '#33a02c' pointinterval -1 dashtype solid
-set linetype 3 linewidth 1.25 pointtype 9 ps 1.2 linecolor rgb '#e31a1c' pointinterval -1 dashtype solid
-set linetype 4 linewidth 1.25 pointtype 6 ps 1.0 linecolor rgb '#ff7f00' pointinterval -1 dashtype solid
-set linetype 5 linewidth 1.25 pointtype 10 ps 1.2 linecolor rgb '#6a3d9a' pointinterval -1 dashtype solid
+set linetype 1 linewidth 2 pointtype 7 ps 1.0 linecolor rgb '#1f78b4' pointinterval -1 dashtype solid
+set linetype 2 linewidth 2 pointtype 1 ps 1.1 linecolor rgb '#33a02c' pointinterval -1 dashtype solid
+set linetype 3 linewidth 2 pointtype 9 ps 1.2 linecolor rgb '#e31a1c' pointinterval -1 dashtype solid
+set linetype 4 linewidth 2 pointtype 6 ps 1.0 linecolor rgb '#ff7f00' pointinterval -1 dashtype solid
+set linetype 5 linewidth 2 pointtype 10 ps 1.2 linecolor rgb '#6a3d9a' pointinterval -1 dashtype solid
-set linetype 6 linewidth 1.5 pointtype 7 ps 1.0 linecolor rgb '#1f78b4' pointinterval -1 dt (10, 6)
-set linetype 7 linewidth 1.5 pointtype 1 ps 1.1 linecolor rgb '#33a02c' pointinterval -1 dt (2, 4)
-set linetype 8 linewidth 1.5 pointtype 9 ps 1.2 linecolor rgb '#e31a1c' pointinterval -1 dt (10, 5, 2, 5)
-set linetype 9 linewidth 1.5 pointtype 6 ps 1.0 linecolor rgb '#ff7f00' pointinterval -1 dt (8, 7, 2, 7, 2, 7)
-set linetype 10 linewidth 1.5 pointtype 10 ps 1.2 linecolor rgb '#6a3d9a' pointinterval -1 dt (8, 4, 2, 4, 2, 4, 2, 4)
+set linetype 6 linewidth 3.5 pointtype 7 ps 1.0 linecolor rgb '#1f78b4' pointinterval -1 dt (10, 6)
+set linetype 7 linewidth 3.5 pointtype 1 ps 1.1 linecolor rgb '#33a02c' pointinterval -1 dt (2, 4)
+set linetype 8 linewidth 3.5 pointtype 9 ps 1.2 linecolor rgb '#e31a1c' pointinterval -1 dt (10, 5, 2, 5)
+set linetype 9 linewidth 3.5 pointtype 6 ps 1.0 linecolor rgb '#ff7f00' pointinterval -1 dt (8, 7, 2, 7, 2, 7)
+set linetype 10 linewidth 3.5 pointtype 10 ps 1.2 linecolor rgb '#6a3d9a' pointinterval -1 dt (8, 4, 2, 4, 2, 4, 2, 4)
unset linetype 11
unset linetype 12
--- a/grcat/conf.curl Fri Apr 14 15:01:35 2023 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,22 +0,0 @@
-# request
-regexp=(^\* .*)
-colours=bright_black
-=======
-# request
-regexp=(^> .*)
-colours=bright_black
-=======
-# response
-regexp=(^< .*)
-colours=blue
-=======
-# ok response code
-regexp=^< HTTP.+ ([23]...*)
-colours=blue, bold green
-=======
-# error response code
-regexp=^< HTTP.+ ([45]...*)
-colours=blue, bold red
-=======
-regexp=.*\[.* bytes data\]
-colours=bright_black
--- a/grcat/conf.go-test Fri Apr 14 15:01:35 2023 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,13 +0,0 @@
-regexp=(^=== RUN).*
-colours=cyan,bold cyan
-=======
-regexp=(^--- PASS).*
-colours=green,bold green
-=======
-regexp=(^--- FAIL).*
-colours=red,bold red
-=======
-regexp=(^(ok|FAIL|\?)\s.*$)
-colours=bright_black,bright_black
-
-
--- a/grcat/conf.tail-vm Fri Apr 14 15:01:35 2023 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,15 +0,0 @@
-# err
-regexp=(ERR )
-colours=default,red
-=======
-# warn
-regexp=(WARNING )
-colours=default,yellow
-=======
-# info
-regexp=(INFO )
-colours=default,cyan
-=======
-# time
-regexp=(^\d\d:\d\d:\d\d)
-colours=bright_black
--- a/hgrc Fri Apr 14 15:01:35 2023 -0400
+++ b/hgrc Fri Jul 07 16:11:02 2023 -0400
@@ -22,9 +22,23 @@
fetch =
shelve =
histedit =
+absorb =
prompt = ~/src/dotfiles/mercurial/hg-prompt/prompt.py
hggit = ~/.hg-git/hggit
+[absorb]
+# only check 50 recent non-public changesets at most
+max-stack-size = 50
+# whether to add noise to new commits to avoid obsolescence cycle
+add-noise = 1
+# make `amend --correlated` a shortcut to the main command
+amend-flag = correlated
+
+[color]
+absorb.description = yellow
+absorb.node = blue bold
+absorb.path = bold
+
[progress]
delay = 1.0
--- a/lisp/Makefile Fri Apr 14 15:01:35 2023 -0400
+++ b/lisp/Makefile Fri Jul 07 16:11:02 2023 -0400
@@ -1,4 +1,4 @@
-files := $(shell ls *.lisp)
+files := $(wildcard *.lisp)
names := $(files:.lisp=)
.PHONY: all clean $(names)
@@ -7,14 +7,14 @@
$(names): %: bin/% man/man1/%.1
-bin/%: %.lisp build-binary
+bin/%: %.lisp build-binary.sh Makefile
mkdir -p bin
- ./build-binary $<
+ ./build-binary.sh $<
mv $(@F) bin/
-man/man1/%.1: %.lisp build-manual
+man/man1/%.1: %.lisp build-manual.sh Makefile
mkdir -p man/man1
- ./build-manual $<
+ ./build-manual.sh $<
mv $(@F) man/man1/
clean:
--- a/lisp/batchcolor.lisp Fri Apr 14 15:01:35 2023 -0400
+++ b/lisp/batchcolor.lisp Fri Jul 07 16:11:02 2023 -0400
@@ -8,34 +8,8 @@
(in-package :batchcolor)
;;;; Configuration ------------------------------------------------------------
-(defparameter *version* "1.0.0")
(defparameter *start* 0)
(defparameter *dark* t)
-(defparameter *only-matching* nil)
-
-
-;;;; Colors -------------------------------------------------------------------
-(defun rgb-code (r g b)
- ;; The 256 color mode color values are essentially r/g/b in base 6, but
- ;; shifted 16 higher to account for the intiial 8+8 colors.
- (+ (* r 36)
- (* g 6)
- (* b 1)
- 16))
-
-(defun make-colors (excludep)
- (let ((result (make-array 256 :fill-pointer 0)))
- (dotimes (r 6)
- (dotimes (g 6)
- (dotimes (b 6)
- (unless (funcall excludep (+ r g b))
- (vector-push-extend (rgb-code r g b) result)))))
- result))
-
-(defparameter *dark-colors* (make-colors (lambda (v) (< v 3))))
-(defparameter *light-colors* (make-colors (lambda (v) (> v 11))))
-
-(defparameter *explicits* (make-hash-table :test #'equal))
;;;; Errors -------------------------------------------------------------------
@@ -60,6 +34,29 @@
;;;; Functionality ------------------------------------------------------------
+(defun rgb-code (r g b)
+ ;; The 256 color mode color values are essentially r/g/b in base 6, but
+ ;; shifted 16 higher to account for the intiial 8+8 colors.
+ (+ (* r 36)
+ (* g 6)
+ (* b 1)
+ 16))
+
+(defun make-colors (excludep)
+ (let ((result (make-array 256 :fill-pointer 0)))
+ (dotimes (r 6)
+ (dotimes (g 6)
+ (dotimes (b 6)
+ (unless (funcall excludep (+ r g b))
+ (vector-push-extend (rgb-code r g b) result)))))
+ result))
+
+(defparameter *dark-colors* (make-colors (lambda (v) (< v 3))))
+(defparameter *light-colors* (make-colors (lambda (v) (> v 11))))
+
+(defparameter *explicits* (make-hash-table :test #'equal))
+
+
(defun djb2 (string)
;; http://www.cse.yorku.ca/~oz/hash.html
(reduce (lambda (hash c)
@@ -101,8 +98,7 @@
(print-colorized (subseq line word-start word-end))
(setf start word-end))
starts ends)))
- (unless (and (zerop start) *only-matching*)
- (write-line line *standard-output* :start start))
+ (write-line line *standard-output* :start start)
(values))
@@ -156,13 +152,6 @@
:help-no "Optimize for light terminals."
:initial-value t))
-(adopt:defparameters (*option-only-matching* *option-no-only-matching*)
- (adopt:make-boolean-options 'only-matching
- :long "only-matching"
- :long-no "all-lines"
- :short #\o
- :help "Only print lines with at least one match."
- :help-no "Print all lines, even if they don't have any matches (the default)."))
(defparameter *option-explicit*
(adopt:make-option 'explicit
@@ -185,12 +174,6 @@
:short #\h
:reduce (constantly t)))
-(defparameter *option-version*
- (adopt:make-option 'version
- :help "Display version information and exit."
- :long "version"
- :reduce (constantly t)))
-
(adopt:define-string *help-text*
"batchcolor takes a regular expression and matches it against standard ~
@@ -219,8 +202,8 @@
. "tail -f /var/log/foo | batchcolor '[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}'")
("Colorize some keywords explicitly and IPv4 addresses randomly (note that the keywords have to be in the main regex too, not just in the -e options):"
. "batchcolor 'WARN|INFO|ERR|(?:[0-9]{1,3}\\\\.){3}[0-9]{1,3}' -e '5,0,0:ERR' -e '5,4,0:WARN' -e '2,2,5:INFO' foo.log")
- ("Colorize earmuffed symbols in a Lisp file, only printing lines with at least one such symbol:"
- . "batchcolor --only-matching '(?:^|[^*])([*][-a-zA-Z0-9]+[*])(?:$|[^*])' tests/test.lisp")))
+ ("Colorize earmuffed symbols in a Lisp file:"
+ . "batchcolor '(?:^|[^*])([*][-a-zA-Z0-9]+[*])(?:$|[^*])' tests/test.lisp")))
(defparameter *ui*
@@ -229,11 +212,10 @@
:usage "[OPTIONS] REGEX [FILE...]"
:summary "colorize regex matches in batches"
:help *help-text*
- :manual (concatenate 'string *help-text* (format nil "~2%") *extra-manual-text*)
+ :manual (format nil "~A~2%~A" *help-text* *extra-manual-text*)
:examples *examples*
:contents (list
*option-help*
- *option-version*
*option-debug*
*option-no-debug*
(adopt:make-group 'color-options
@@ -242,11 +224,7 @@
*option-no-randomize*
*option-dark*
*option-light*
- *option-explicit*))
- (adopt:make-group 'output-options
- :title "Output Options"
- :options (list *option-only-matching*
- *option-no-only-matching*)))))
+ *option-explicit*)))))
(defmacro exit-on-ctrl-c (&body body)
@@ -259,8 +237,7 @@
(setf *start* (if (gethash 'randomize options)
(random 256 (make-random-state t))
0)
- *dark* (gethash 'dark options)
- *only-matching* (gethash 'only-matching options)))
+ *dark* (gethash 'dark options)))
(defun toplevel ()
(sb-ext:disable-debugger)
@@ -271,7 +248,6 @@
(handler-case
(cond
((gethash 'help options) (adopt:print-help-and-exit *ui*))
- ((gethash 'version options) (write-line *version*) (adopt:exit))
((null arguments) (error 'missing-regex))
(t (destructuring-bind (pattern . files) arguments
(configure options)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/lisp/bucket.lisp Fri Jul 07 16:11:02 2023 -0400
@@ -0,0 +1,247 @@
+(eval-when (:compile-toplevel :load-toplevel :execute)
+ (ql:quickload '(:adopt :alexandria :cl-ppcre :with-user-abort :local-time)
+ :silent t))
+
+(defpackage :bucket
+ (:use :cl)
+ (:export :toplevel :*ui*))
+
+(in-package :bucket)
+
+;;;; Configuration ------------------------------------------------------------
+(setf local-time:*default-timezone* local-time:+utc-zone+)
+
+
+;;;; Functionality ------------------------------------------------------------
+(defun collect-values (time-mode path)
+ (flet ((collect (stream)
+ (loop :for line = (read-line stream nil nil)
+ :while line
+ :for value = (if time-mode
+ (local-time:parse-rfc3339-timestring line)
+ (parse-integer line :junk-allowed t))
+ :when value :collect value)))
+ (if (string= path "-")
+ (collect *standard-input*)
+ (with-open-file (s path)
+ (collect s)))))
+
+
+(defun floor-to-nearest (n divisor)
+ (* divisor (floor n divisor)))
+
+(declaim (inline in-range-p in-time-p))
+(defun in-range-p (val start end)
+ (and (<= start val)
+ (< val end)))
+
+(defun in-time-p (val start end)
+ (and (local-time:timestamp<= start val)
+ (local-time:timestamp< val end)))
+
+(defun bucket-numeric (data width skip-empty output)
+ (loop :with data = (sort (coerce data 'vector) #'<)
+ :with len = (length data)
+ :with i = 0
+ :for bs :from (floor-to-nearest (aref data 0) width) :by width
+ :for be = (+ bs width)
+ :while (< i len)
+ :for count = (loop :while (< i len)
+ :while (in-range-p (aref data i) bs be)
+ :sum 1
+ :do (incf i))
+ :do (unless (and skip-empty (zerop count))
+ (format t "~12F ~10D~%"
+ (ecase output
+ (:lower bs)
+ (:upper be)
+ (:mid (/ (+ bs bs width) 2.0d0)))
+ count))))
+
+(defun bucket-temporal (data width skip-empty output)
+ (loop :with data = (sort (coerce data 'vector) #'local-time:timestamp<)
+ :with len = (length data)
+ :with i = 0
+ :with bs = (local-time:timestamp-minimize-part (aref data 0) :sec)
+ :for be = (local-time:timestamp+ bs width :sec)
+ :while (< i len)
+ :for count = (loop :while (< i len)
+ :while (in-time-p (aref data i) bs be)
+ :sum 1
+ :do (incf i))
+ :do (unless (and skip-empty (zerop count))
+ (format t "~A ~10D~%"
+ (local-time:format-rfc3339-timestring
+ nil
+ (ecase output
+ (:lower bs)
+ (:upper be)
+ (:mid (local-time:timestamp+ bs (truncate (* width 1000000000) 2) :nsec)))) ; hack
+ count))
+ :do (setf bs (local-time:timestamp+ bs width :sec))))
+
+(defun run (paths &key time-mode width skip-empty (output :mid))
+ (when (null width)
+ (error "Bucket width must be specified."))
+ (let ((data (mapcan (alexandria:curry #'collect-values time-mode)
+ (or paths '("-")))))
+ (when (null data)
+ (error "No data found."))
+ (if time-mode
+ (bucket-temporal data width skip-empty output)
+ (bucket-numeric data width skip-empty output))))
+
+
+;;;; User Interface -----------------------------------------------------------
+(defparameter *option/help*
+ (adopt:make-option 'help
+ :help "Display help and exit."
+ :long "help"
+ :short #\h
+ :reduce (constantly t)))
+
+(adopt:defparameters (*option/time* *option/no-time*)
+ (adopt:make-boolean-options 'time
+ :help "Bucket in timestamp (RFC3339) mode."
+ :help-no "Bucket in numeric mode (the default)."
+ :long "time"
+ :short #\t))
+
+(adopt:defparameters (*option/skip-empty* *option/no-skip-empty*)
+ (adopt:make-boolean-options 'skip-empty
+ :help "Skip outputting empty buckets."
+ :help-no "Include empty buckets (the default)."
+ :long "skip-empty"
+ :short #\e))
+
+
+(defparameter *option/output/lower*
+ (adopt:make-option 'output/lower
+ :result-key 'output
+ :help "Output the lower bound of the bucket."
+ :long "lower"
+ :short #\l
+ :reduce (constantly :lower)))
+
+(defparameter *option/output/mid*
+ (adopt:make-option 'output/mid
+ :result-key 'output
+ :help "Output the midpoint of the bucket (the default)."
+ :long "mid"
+ :short #\m
+ :initial-value :mid
+ :reduce (constantly :mid)))
+
+(defparameter *option/output/upper*
+ (adopt:make-option 'output/upper
+ :result-key 'output
+ :help "Output the upper bound of the bucket."
+ :long "upper"
+ :short #\u
+ :reduce (constantly :upper)))
+
+
+(defparameter *option/width*
+ (adopt:make-option 'width
+ :result-key 'width
+ :help "Set bucket width to N."
+ :parameter "N"
+ :long "width"
+ :short #\W
+ :initial-value nil
+ :key #'parse-integer
+ :reduce #'adopt:last))
+
+(defparameter *option/width/seconds*
+ (adopt:make-option 'width/seconds
+ :result-key 'width
+ :help "Set bucket width to N seconds."
+ :parameter "N"
+ :long "seconds"
+ :short #\S
+ :key (lambda (n)
+ (parse-integer n))
+ :reduce #'adopt:last))
+
+(defparameter *option/width/minutes*
+ (adopt:make-option 'width/minutes
+ :result-key 'width
+ :help "Set bucket width to N minutes."
+ :parameter "N"
+ :long "minutes"
+ :short #\M
+ :key (lambda (n)
+ (* 60 (parse-integer n)))
+ :reduce #'adopt:last))
+
+(defparameter *option/width/hours*
+ (adopt:make-option 'width/hours
+ :result-key 'width
+ :help "Set bucket width to N hours."
+ :parameter "N"
+ :long "hours"
+ :short #\H
+ :key (lambda (n)
+ (* 60 60 (parse-integer n)))
+ :reduce #'adopt:last))
+
+
+(adopt:define-string *help-text*
+ "bucket groups lines into histogrammy buckets.~@
+ ~@
+ This is handy if you have some non-bucketed data that you want to graph as ~
+ a histogram with gnuplot, because gnuplot unbelievably does not have built-in ~
+ histogramming.")
+
+(defparameter *examples*
+ '())
+
+
+(defparameter *ui*
+ (adopt:make-interface
+ :name "bucket"
+ :usage "[OPTIONS] [FILE...]"
+ :summary "bucket things for easier histogramming"
+ :help *help-text*
+ :examples *examples*
+ :contents (list *option/help*
+ *option/time*
+ *option/no-time*
+ *option/skip-empty*
+ *option/no-skip-empty*
+ (adopt:make-group 'bucket-width
+ :title "Bucket Widths"
+ :options (list
+ *option/width*
+ *option/width/seconds*
+ *option/width/minutes*
+ *option/width/hours*))
+ (adopt:make-group 'bucket-labels
+ :title "Bucket Labels"
+ :options (list
+ *option/output/lower*
+ *option/output/mid*
+ *option/output/upper*)))))
+
+
+(defun toplevel ()
+ ;; #+sbcl (sb-ext:disable-debugger)
+ (handler-case
+ (adopt::quit-on-ctrl-c ()
+ (multiple-value-bind (arguments options) (adopt:parse-options-or-exit *ui*)
+ (cond
+ ((gethash 'help options) (adopt:print-help-and-exit *ui*))
+ (t (progn (local-time:reread-timezone-repository)
+ (run arguments
+ :time-mode (gethash 'time options)
+ :width (gethash 'width options)
+ :skip-empty (gethash 'skip-empty options)
+ :output (gethash 'output options)))))))
+ (error (c) (adopt:print-error-and-exit c))))
+
+
+#; Scratch --------------------------------------------------------------------
+
+
+(ppcre:scan "(\\d{4})-(\\d{2})-(\\d{2})[ T](\\d{2}):(\\d{2}):(\\d{2})(?:\\.\\d+)?([+-]\\d{2}:\\d{2}|Z)?"
+ "2022-04-25T17:00:41.289049Z")
--- a/lisp/build-binary Fri Apr 14 15:01:35 2023 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,9 +0,0 @@
-#!/usr/bin/env bash
-
-set -euo pipefail
-
-LISP=$1
-BINARY=$(basename "$1" .lisp)
-shift
-
-sbcl --load "$LISP" --eval "(sb-ext:save-lisp-and-die \"$BINARY\" :executable t :save-runtime-options t :toplevel '$BINARY:toplevel)" "$@"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/lisp/build-binary.sh Fri Jul 07 16:11:02 2023 -0400
@@ -0,0 +1,14 @@
+#!/usr/bin/env bash
+
+set -euo pipefail
+
+LISP=$1
+NAME=$(basename "$1" .lisp)
+shift
+
+sbcl --load "$LISP" \
+ --eval "(sb-ext:save-lisp-and-die \"$NAME\"
+ :executable t
+ :compression t
+ :save-runtime-options t
+ :toplevel '$NAME:toplevel)"
--- a/lisp/build-manual Fri Apr 14 15:01:35 2023 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,10 +0,0 @@
-#!/usr/bin/env bash
-
-set -euo pipefail
-
-LISP=$1
-NAME=$(basename "$LISP" .lisp)
-OUT="$NAME.1"
-shift
-
-sbcl --disable-debugger --load "$LISP" --eval "(with-open-file (f \"$OUT\" :direction :output :if-exists :supersede) (adopt:print-manual $NAME:*ui* :stream f))" --quit "$@"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/lisp/build-manual.sh Fri Jul 07 16:11:02 2023 -0400
@@ -0,0 +1,13 @@
+#!/usr/bin/env bash
+
+set -euo pipefail
+
+LISP=$1
+NAME=$(basename "$LISP" .lisp)
+OUT="$NAME.1"
+shift
+
+sbcl --load "$LISP" \
+ --eval "(with-open-file (f \"$OUT\" :direction :output :if-exists :supersede)
+ (adopt:print-manual $NAME:*ui* :stream f))" \
+ --quit
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/lisp/drivethru.lisp Fri Jul 07 16:11:02 2023 -0400
@@ -0,0 +1,115 @@
+(eval-when (:compile-toplevel :load-toplevel :execute)
+ (ql:quickload
+ '(:adopt :with-user-abort :iterate :losh :hunchentoot :lparallel)
+ :silent t))
+
+(defpackage :drivethru
+ (:use :cl :iterate :losh)
+ (:export :toplevel :*ui*))
+
+(in-package :drivethru)
+
+;;;; State --------------------------------------------------------------------
+(defvar *acceptor* nil)
+
+;; in: (req . promise)
+;; ↑
+;; out: (status . body)
+(defvar *q* (lparallel.queue:make-queue))
+
+
+;;;; Server -------------------------------------------------------------------
+(defun prompt (message)
+ (write-string message)
+ (finish-output))
+
+(defun handle ()
+ (let ((p (lparallel:promise)))
+ (lparallel.queue:push-queue (cons hunchentoot:*request* p) *q*)
+ (destructuring-bind (status . body) (lparallel:force p)
+ (setf (hunchentoot:return-code*) status)
+ body)))
+
+(defun serve (r)
+ (destructuring-bind (request . promise) r
+ (let ((auth (multiple-value-list (hunchentoot:authorization request))))
+ (format t "~%~C[1;96m;;;; ~A ~A --------------~%~C[0m"
+ #\esc
+ (hunchentoot:request-method request)
+ (hunchentoot:request-uri request)
+ #\esc)
+ (when auth
+ (format t ";; User: ~S~%;; Pass: ~S~%" (first auth) (second auth))))
+ (let ((status (progn (prompt "Reponse code: ")
+ (parse-integer (read-line))))
+ (body (progn (prompt "Reponse body: ")
+ (read-line))))
+ (lparallel:fulfill promise (cons status body)))))
+
+(defun dispatch (request)
+ (declare (ignore request))
+ #'handle)
+
+
+;;;; Run ----------------------------------------------------------------------
+(defun run (port)
+ (setf hunchentoot:*dispatch-table* '(dispatch)
+ *acceptor* (hunchentoot:start (make-instance 'hunchentoot:easy-acceptor
+ :port port)))
+ (unwind-protect (loop (serve (lparallel.queue:pop-queue *q*)))
+ (hunchentoot:stop *acceptor*)))
+
+
+;;;; User Interface -----------------------------------------------------------
+(defparameter *option-help*
+ (adopt:make-option 'help
+ :help "Display help and exit."
+ :long "help"
+ :short #\h
+ :reduce (constantly t)))
+
+(defparameter *option-port*
+ (adopt:make-option 'port
+ :help "Listen on port N (default 33455)."
+ :parameter "N"
+ :long "port"
+ :short #\p
+ :reduce #'adopt:last
+ :key #'parse-integer
+ :initial-value 33455))
+
+(adopt:define-string *help-text*
+ "drivethru listens for HTTP requests and lets you give responses by hand on ~
+ the fly, as a low-tech mock when testing an API.")
+
+(defparameter *examples*
+ '(("Run on port 80:" . "drivethru -p 80")))
+
+(defparameter *ui*
+ (adopt:make-interface
+ :name "drivethru"
+ :usage "[OPTIONS]"
+ :summary "serve HTTP requests by hand"
+ :help *help-text*
+ :examples *examples*
+ :contents (list *option-port*
+ *option-help*)))
+
+
+(defmacro exit-on-ctrl-c (&body body)
+ `(handler-case
+ (with-user-abort:with-user-abort (progn ,@body))
+ (with-user-abort:user-abort () (adopt:exit 130))))
+
+
+(defun toplevel ()
+ (exit-on-ctrl-c
+ (multiple-value-bind (arguments options) (adopt:parse-options-or-exit *ui*)
+ (handler-case
+ (if (gethash 'help options)
+ (adopt:print-help-and-exit *ui*)
+ (progn
+ (assert (null arguments))
+ (run (gethash 'port options))))
+ (error (e) (adopt:print-error-and-exit e))))))
+
--- a/lisp/genpass.lisp Fri Apr 14 15:01:35 2023 -0400
+++ b/lisp/genpass.lisp Fri Jul 07 16:11:02 2023 -0400
@@ -12,7 +12,8 @@
(defparameter *words* nil)
(defparameter *version* "0.0.1")
(defparameter *random-path* "/dev/urandom")
-(defparameter *wordlist-path* "/usr/share/dict/words")
+(defparameter *wordlist-path* "/usr/share/dict/scowl/english-words.20")
+(defparameter *wordlist-encoding* :ISO-8859-1)
;;;; Functionality ------------------------------------------------------------
@@ -30,10 +31,11 @@
(defun word-list ()
(unless *words*
(setf *words*
- (iterate
- (for line :in-file *wordlist-path* :using #'read-line)
- (when (every #'safep line)
- (collect line :result-type vector)))))
+ (with-open-file (s *wordlist-path* :external-format *wordlist-encoding*)
+ (iterate
+ (for line :in-stream s :using #'read-line)
+ (when (every #'safep line)
+ (collect line :result-type vector))))))
*words*)
(defun random-unsigned-byte-32 ()
--- a/lisp/gtp.lisp Fri Apr 14 15:01:35 2023 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,351 +0,0 @@
-(eval-when (:compile-toplevel :load-toplevel :execute)
- (ql:quickload '(:adopt :alexandria :cl-ppcre :with-user-abort :local-time)
- :silent t))
-
-(defpackage :gtp
- (:use :cl)
- (:export :toplevel :*ui*))
-
-(in-package :gtp)
-
-;;;; Configuration ------------------------------------------------------------
-(defparameter *version* "1.0.0")
-(setf local-time:*default-timezone* local-time:+utc-zone+)
-
-(defparameter *time-formats*
- `((:rfc-3339 . ("(\\d{4})-(\\d{2})-(\\d{2})[ T](\\d{2}):(\\d{2}):(\\d{2})(?:[.]\\d{4-})?([+-]\\d{2}:\\d{2}|Z)?"
- ,local-time:+rfc3339-format+))
- (:iso-8601 . ("(\\d{4})-(\\d{2})-(\\d{2})T(\\d{2}):(\\d{2}):(\\d{2})(?:,\\d{4-})?([+-]\\d{2}:\\d{2}|Z)?"
- ,local-time:+iso-8601-format+))
- (:simple . ("(\\d{4})/(\\d{2})/(\\d{2}) (\\d{2}):(\\d{2}):(\\d{2})()"
- ((:year 4) #\/ (:month 2) #\/ (:day 2) #\space (:hour 2) #\: (:min 2) #\: (:sec 2))))
- (:gnuplot . ("(\\d{2})/(\\d{2})/(\\d{2}),(\\d{2}):(\\d{2})"
- ((:day 2) #\/ (:month 2) #\/ #\Y #\, (:hour 2) #\: (:min 2))))
- (:unix-milliseconds . ("(\\d{13,14})" nil))
- (:unix-seconds . ("(\\d{10,11})" nil))))
-
-
-;;;; Utilities ----------------------------------------------------------------
-(defmacro match ((register-vars (start end) (regex target)) &body body)
- (alexandria:with-gensyms (rs re)
- (alexandria:once-only (regex target)
- `(multiple-value-bind (,start ,end ,rs ,re) (ppcre:scan ,regex ,target)
- (when ,start
- (let (,@(loop :for r :from 0
- :for var :in register-vars
- :collect `(,var (when (aref ,rs ,r)
- (subseq ,target (aref ,rs ,r) (aref ,re ,r))))))
- ,@body))))))
-
-(defun i (s)
- (parse-integer s))
-
-(defun keywordize (s)
- (alexandria:make-keyword (string-upcase s)))
-
-
-;;;; Time Formats -------------------------------------------------------------
-
-(defun get-format (format)
- (or (alexandria:assoc-value *time-formats* format)
- (error "Unknown time format ~S" format)))
-
-(defun get-regex (format)
- (first (get-format format)))
-
-(defun get-local-time-format (format)
- (second (get-format format)))
-
-(defun parse-timezone (string)
- (if (member string '(nil "" "Z" "UTC" "+00:00" "-00:00") :test #'equal)
- local-time:+utc-zone+
- (or (local-time:find-timezone-by-location-name string)
- (error "TODO: handle timezone ~S" string))))
-
-
-(defgeneric make-parser (format))
-
-(defmethod make-parser (format)
- (let ((scanner (ppcre:create-scanner (get-regex format))))
- (lambda (s)
- (match ((year month day hour minute second timezone)
- (start end)
- (scanner s))
- (values
- (local-time:encode-timestamp
- 0 (i second) (i minute) (i hour) (i day) (i month) (i year)
- :timezone (parse-timezone timezone))
- start end)))))
-
-(defmethod make-parser ((format (eql :gnuplot)))
- (let ((scanner (ppcre:create-scanner (get-regex format))))
- (lambda (s)
- (match ((day month year hour minute)
- (start end)
- (scanner s))
- (values (local-time:encode-timestamp
- 0 0 (i minute) (i hour) (i day) (i month) (+ 2000 (i year)))
- start end)))))
-
-(defmethod make-parser ((format (eql :unix-seconds)))
- (let ((scanner (ppcre:create-scanner (get-regex format))))
- (lambda (s)
- (match ((unix)
- (start end)
- (scanner s))
- (when unix ; shut up sbcl
- (values (local-time:unix-to-timestamp (parse-integer unix)) start end))))))
-
-(defmethod make-parser ((format (eql :unix-milliseconds)))
- (let ((scanner (ppcre:create-scanner (get-regex format))))
- (lambda (s)
- (match ((unix)
- (start end)
- (scanner s))
- (when unix ; shut up sbcl
- (multiple-value-bind (sec ms) (truncate (parse-integer unix) 1000)
- (values (local-time:unix-to-timestamp sec :nsec (* ms 1000 1000))
- start end)))))))
-
-
-(defun make-predicate (format start end)
- (let ((parser (make-parser format)))
- (lambda (line)
- (multiple-value-bind (line-time s e) (funcall parser line)
- (when (and line-time
- (or (null start) (local-time:timestamp<= start line-time))
- (or (null end) (local-time:timestamp<= line-time end)))
- (values line-time s e))))))
-
-
-(defgeneric make-formatter (format))
-
-(defmethod make-formatter (format)
- (let ((local-time-format (get-local-time-format format)))
- (lambda (time stream)
- (local-time:format-timestring stream time :format local-time-format))))
-
-(defmethod make-formatter ((format (eql :gnuplot)))
- (let ((local-time-format (get-local-time-format :gnuplot)))
- (lambda (time stream)
- (let ((s (local-time:format-timestring nil time :format local-time-format)))
- ;; "16/07/Y,15:05"
- (write-string s stream :start 0 :end 6)
- (format stream "~2,'0D" (mod (local-time:timestamp-year time) 100))
- (write-string s stream :start 7)))))
-
-(defmethod make-formatter ((format (eql :unix-seconds)))
- (lambda (time stream)
- (format stream "~D" (local-time:timestamp-to-unix time))))
-
-(defmethod make-formatter ((format (eql :unix-milliseconds)))
- (lambda (time stream)
- (format stream "~D" (+ (* 1000 (local-time:timestamp-to-unix time))
- (local-time:timestamp-millisecond time)))))
-
-
-(defun parse-time-flexibly (string)
- ;; todo optimize this
- (loop :for format :in *time-formats*
- :for parser = (make-parser (car format))
- :for result = (funcall parser string)
- :when result :do (return-from parse-time-flexibly result))
- (error "Don't know how to parse ~S as a time." string))
-
-
-;;;; Run ----------------------------------------------------------------------
-(defun run% (predicate in out path prefix reformat)
- (loop
- :for line = (read-line in nil)
- :while line
- :do (multiple-value-bind (time start end) (funcall predicate line)
- (when time
- (when prefix
- (write-string path out)
- (write-char #\: out))
- (if reformat
- (progn (write-string line out :start 0 :end start)
- (funcall reformat time out)
- (write-line line out :start end))
- (write-line line out))))))
-
-(defun run (paths &key format start end prefix reformat)
- (when (null paths)
- (setf paths '("-")))
- (when (and start end (local-time:timestamp< end start))
- (error "Start ~S is after end ~S." start end))
- (when reformat
- (setf reformat (make-formatter reformat)))
- (let ((pred (make-predicate format start end)))
- (dolist (path paths)
- (if (string= "-" path)
- (run% pred *standard-input* *standard-output* path prefix reformat)
- (with-open-file (stream path :direction :input)
- (run% pred stream *standard-output* path prefix reformat))))))
-
-
-;;;; User Interface -----------------------------------------------------------
-(defparameter *option-help*
- (adopt:make-option 'help
- :help "Display help and exit."
- :long "help"
- :short #\h
- :reduce (constantly t)))
-
-(defparameter *option-version*
- (adopt:make-option 'version
- :help "Display version information and exit."
- :long "version"
- :reduce (constantly t)))
-
-
-(defparameter *option-prefix*
- (adopt:make-option 'prefix
- :help "Prefix output lines with their path."
- :short #\p
- :long "prefix"
- :reduce (constantly t)))
-
-(defparameter *option-no-prefix*
- (adopt:make-option 'no-prefix
- :result-key 'prefix
- :help "Do not prefix output lines with their path (default)."
- :short #\P
- :long "no-prefix"
- :reduce (constantly nil)))
-
-
-(defparameter *option-format*
- (adopt:make-option 'format
- :help "The time format used to parse times from lines."
- :parameter "FORMAT"
- :long "format"
- :short #\f
- :initial-value :simple
- :key #'keywordize
- :reduce #'adopt:last))
-
-(defparameter *option-reformat*
- (adopt:make-option 'reformat
- :help "Reformat parsed timestamps into FORMAT before outputting them."
- :parameter "FORMAT"
- :long "reformat"
- :short #\r
- :initial-value nil
- :key #'keywordize
- :reduce #'adopt:last))
-
-(defparameter *option-no-reformat*
- (adopt:make-option 'reformat
- :help "Do not reformat parsed timestamps (default)."
- :long "no-reformat"
- :short #\R
- :reduce (constantly nil)))
-
-
-(defparameter *option-start*
- (adopt:make-option 'start
- :help "Only show lines at or after START."
- :parameter "START"
- :long "start"
- :short #\s
- :initial-value nil
- :key #'parse-time-flexibly
- :reduce #'adopt:last))
-
-(defparameter *option-end*
- (adopt:make-option 'end
- :help "Only show lines at or before END."
- :parameter "END"
- :long "end"
- :short #\e
- :initial-value nil
- :key #'parse-time-flexibly
- :reduce #'adopt:last))
-
-
-(adopt:define-string *help-text*
- "gtp filters lines by time. Instead of g/re/p it's g/time/p.~@
- ~@
- gtp will only print lines that have a timestamp somewhere in them. Use ~
- --format to select the timestamp format. Supported formats:~@
- ~@
- ~:
- * simple: 2020/11/23 18:55:30 (default)
- * rfc-3339: 2020-11-23 18:55:30Z
- * iso-8601: 2020-11-23T18:55:30Z
- * gnuplot: 11/23/20,18:55~@
- ~@
- You can additionally filter based on a time range using --start and/or --end. ~
- For convenience, these parameters can be given in any supported timestamp ~
- format, they don't have to match --format.")
-
-(defparameter *examples*
- '(("Filter standard input and only print lines with an RFC-3339 time:"
- . "gtp --format rfc-3339")
- ("Print log lines after a particular time, and prefix each output line with its source filename:"
- . "gtp **.log --prefix --after '2020/06/14 12:22:01'")
- ("Print RFC-3339 log lines starting now, with now given in a different format:"
- . "tail -f foo | gtp --format rfc-3339 --after \"$(date --utc --iso-8601=sec)\"")))
-
-
-(defparameter *ui*
- (adopt:make-interface
- :name "gtp"
- :usage "[OPTIONS] [FILE...]"
- :summary "filter lines by timestamp"
- :help *help-text*
- :examples *examples*
- :contents (list *option-help*
- *option-version*
- *option-format*
- *option-reformat*
- *option-no-reformat*
- *option-start*
- *option-end*
- *option-prefix*
- *option-no-prefix*)))
-
-
-(defmacro exit-on-error (&body body)
- `(handler-case (progn ,@body)
- (error (c) (adopt:print-error-and-exit c))))
-
-(defmacro exit-on-ctrl-c (&body body)
- `(handler-case
- (with-user-abort:with-user-abort (progn ,@body))
- (with-user-abort:user-abort () (adopt:exit 130))))
-
-
-(defun toplevel ()
- #+sbcl (sb-ext:disable-debugger)
- (exit-on-error
- (exit-on-ctrl-c
- (multiple-value-bind (arguments options) (adopt:parse-options-or-exit *ui*)
- (cond
- ((gethash 'help options) (adopt:print-help-and-exit *ui*))
- ((gethash 'version options) (write-line *version*) (adopt:exit))
- (t (progn (local-time:reread-timezone-repository)
- (run arguments
- :format (gethash 'format options)
- :start (gethash 'start options)
- :end (gethash 'end options)
- :prefix (gethash 'prefix options)
- :reformat (gethash 'reformat options)))))))))
-
-
-#; Scratch --------------------------------------------------------------------
-
-(run
- '("/home/sjl/scratch/logs/test/passport/passport.172.24.20.49.log")
- :format :simple
- :start (parse-time-flexibly "2020-07-15T17:31:00.000000")
- :end (parse-time-flexibly "2020-07-15T17:31:55")
- :prefix nil
- :reformat :iso-8601)
-
-(parse-time-flexibly "2020-07-15 16:08:15.0000Z")
-
-(local-time:find-timezone-by-location-name "EDT")
-
-(local-time:reread-timezone-repository)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/lisp/parsre.lisp Fri Jul 07 16:11:02 2023 -0400
@@ -0,0 +1,227 @@
+(eval-when (:compile-toplevel :load-toplevel :execute)
+ (ql:quickload '(:adopt :cl-ppcre :iterate :with-user-abort
+ :jarl :conserve :losh)
+ :silent t))
+
+(defpackage :parsre
+ (:use :cl :iterate)
+ (:export :toplevel :*ui*))
+
+(in-package :parsre)
+
+;;;; Configuration ------------------------------------------------------------
+(defparameter *output-format* :text)
+(defparameter *case-sensitive* t)
+
+
+;;;; Errors -------------------------------------------------------------------
+(define-condition user-error (error) ())
+
+(define-condition missing-regex (user-error) ()
+ (:report "A regular expression is required."))
+
+(define-condition missing-registers (user-error) ()
+ (:report "Invalid regex, at least one named register is required."))
+
+(define-condition anonymous-register (user-error) ()
+ (:report "Invalid regex, anonymous registers are not supported. Use non-capturing groups (?:…) if you need grouping but not capturing."))
+
+(define-condition malformed-regex (user-error)
+ ((underlying-error :initarg :underlying-error))
+ (:report (lambda (c s)
+ (format s "Invalid regex: ~A" (slot-value c 'underlying-error)))))
+
+
+;;;; Functionality ------------------------------------------------------------
+(defgeneric header (format names))
+(defmethod header (format names) nil)
+(defmethod header ((format (eql :csv)) names) (conserve:write-row names))
+
+
+(defmethod output (format names values))
+
+(defmethod output ((format (eql :text)) names values)
+ (iterate (for name :in names)
+ (for value :in values)
+ (format t "~A: ~A~%" name value))
+ (terpri))
+
+(defmethod output ((format (eql :json)) names values)
+ (jarl:print (alexandria:alist-hash-table (mapcar #'cons names values) :test #'equal))
+ (terpri))
+
+(defmethod output ((format (eql :csv)) names values)
+ (declare (ignore names))
+ (conserve:write-row values))
+
+
+(defun register-values (string register-starts register-ends)
+ (iterate
+ (for start :in-vector register-starts)
+ (for end :in-vector register-ends)
+ (collect (subseq string start end))))
+
+(defun run%% (scanner register-names string)
+ (iterate (with start = 0)
+ (for (values ms me rs re) = (ppcre:scan scanner string :start start))
+ (while ms)
+ (output *output-format* register-names (register-values string rs re))
+ (setf start (max (1+ start) me))))
+
+(defun run% (scanner register-names stream)
+ (iterate (for line :in-stream stream :using #'read-line)
+ (run%% scanner register-names line)
+ (force-output)))
+
+
+(defun make-scanner (pattern)
+ (handler-case
+ (ppcre:create-scanner pattern
+ :case-insensitive-mode (not *case-sensitive*)
+ :single-line-mode t)
+ (ppcre:ppcre-syntax-error (c) (error 'malformed-regex :underlying-error c))))
+
+(defun run (pattern paths)
+ (let ((ppcre:*allow-named-registers* t)
+ (ppcre:*use-bmh-matchers* t)
+ (paths (or paths '("-"))))
+ (multiple-value-bind (scanner register-names) (make-scanner pattern)
+ (cond ((null register-names) (error 'missing-registers))
+ ((member nil register-names) (error 'anonymous-register)))
+ (header *output-format* register-names)
+ (dolist (path paths)
+ (if (string= "-" path)
+ (run% scanner register-names *standard-input*)
+ (with-open-file (stream path :direction :input)
+ (run% scanner register-names stream)))))))
+
+
+;;;; User Interface -----------------------------------------------------------
+(defparameter *examples*
+ '(("Parse some web service logs:" .
+ "parsre '^(?<timestamp>\\\\S+) (?<level>INFO|WARN|ERROR|DEBUG) (?<message>.*)$'")
+ ("Parse wordcount report into JSON:" .
+ "wc **.lisp | parsre --json '^ *(?<lines>\\\\d+) +(?<words>\\\\d+) +(?<bytes>\\\\d+) +(?<path>.+)$'")))
+
+
+(defparameter *option/help*
+ (adopt:make-option 'help
+ :help "Display help and exit."
+ :long "help"
+ :short #\h
+ :reduce (constantly t)))
+
+(defparameter *option/version*
+ (adopt:make-option 'version
+ :help "Display version information and exit."
+ :long "version"
+ :reduce (constantly t)))
+
+(adopt:defparameters (*option/debug* *option/no-debug*)
+ (adopt:make-boolean-options 'debug
+ :long "debug"
+ :short #\d
+ :help "Enable the Lisp debugger."
+ :help-no "Disable the Lisp debugger (default)."))
+
+(adopt:defparameters (*option/profile* *option/no-profile*)
+ (adopt:make-boolean-options 'profile
+ :long "profile"
+ :help "Profile the run and write results to lisp.prof."
+ :help-no "Do not profile (default)."))
+
+(adopt:defparameters (*option/matching/ignore-case* *option/matching/no-ignore-case*)
+ (adopt:make-boolean-options 'ignore-case
+ :long "ignore-case"
+ :short #\i
+ :help "Ignore case (i.e. case-insensitive)."
+ :help-no "Do not ignore case (i.e. case-sensitive) (default)."
+ :initial-value nil))
+
+(defparameter *option/output-format/text*
+ (adopt:make-option 'output-format/text
+ :result-key 'output-format
+ :help "Output results as text (default)."
+ :long "text"
+ :short #\t
+ :initial-value :text
+ :reduce (constantly :text)))
+
+(defparameter *option/output-format/json*
+ (adopt:make-option 'output-format/json
+ :result-key 'output-format
+ :help "Output results as JSON."
+ :long "json"
+ :short #\j
+ :reduce (constantly :json)))
+
+(defparameter *option/output-format/csv*
+ (adopt:make-option 'output-format/csv
+ :result-key 'output-format
+ :help "Output results as CSV."
+ :long "csv"
+ :short #\c
+ :reduce (constantly :csv)))
+
+
+(adopt:define-string *help-text*
+ "Parsre takes a Perl-compatible regular expression, matches it against input, ~
+ and outputs the expression's registers in a variety of formats.~@
+ ~@
+ The regular expression will be matched against the input line-by-line. ~
+ Multiple matches per line are supported.~@
+ ~@
+ Registers can be named or anonymous. Anonymous registers will be named ~
+ arbitrarily (the scheme may change in the future).")
+
+
+(defparameter *ui*
+ (adopt:make-interface
+ :name "parsre"
+ :usage "[OPTIONS] REGEX [FILE...]"
+ :summary "almost a parser"
+ :help *help-text*
+ :examples *examples*
+ :contents (list *option/help*
+ *option/version*
+ (adopt:make-group
+ 'matching-options
+ :title "Matching Options"
+ :options (list *option/matching/ignore-case*
+ *option/matching/no-ignore-case*))
+ (adopt:make-group
+ 'output-options
+ :title "Output Options"
+ :options (list *option/output-format/text*
+ *option/output-format/json*
+ *option/output-format/csv*))
+ (adopt:make-group
+ 'debugging-options
+ :title "Debugging Options"
+ :options (list *option/debug*
+ *option/no-debug*
+ *option/profile*
+ *option/no-profile*)))))
+
+(defun configure (options)
+ (setf *output-format* (gethash 'output-format options)
+ *case-sensitive* (not (gethash 'ignore-case options)))
+ (values))
+
+(defun toplevel ()
+ (sb-ext:disable-debugger)
+ (multiple-value-bind (arguments options) (adopt:parse-options-or-exit *ui*)
+ (when (gethash 'debug options)
+ (sb-ext:enable-debugger))
+ (handler-case
+ (with-user-abort:with-user-abort
+ (cond
+ ((gethash 'help options) (adopt:print-help-and-exit *ui*))
+ ((null arguments) (error 'missing-regex))
+ (t (destructuring-bind (pattern . files) arguments
+ (configure options)
+ (if (gethash 'profile options)
+ (losh:profile (run pattern files))
+ (run pattern files))))))
+ (with-user-abort:user-abort () (adopt:exit 130))
+ (user-error (e) (adopt:print-error-and-exit e)))))
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/lisp/twizzle.lisp Fri Jul 07 16:11:02 2023 -0400
@@ -0,0 +1,394 @@
+(eval-when (:compile-toplevel :load-toplevel :execute)
+ (ql:quickload '(:adopt :alexandria :cl-ppcre :with-user-abort :local-time)
+ :silent t))
+
+(defpackage :twizzle
+ (:use :cl)
+ (:export :toplevel :*ui*))
+
+(in-package :twizzle)
+
+;;;; Configuration ------------------------------------------------------------
+(setf local-time:*default-timezone* local-time:+utc-zone+)
+
+(defparameter *time-formats*
+ ;; An alist of (name . (parse-regex local-time-format-spec)), or (name . nil)
+ ;; for more complicated formats.
+ `((:rfc-3339 . ("(\\d{4})-(\\d{2})-(\\d{2})[ T](\\d{2}):(\\d{2}):(\\d{2})(?:[.]\\d+)?([+-]\\d{2}:\\d{2}|Z)?"
+ ,local-time:+rfc3339-format+))
+ (:iso-8601 . ("(\\d{4})-(\\d{2})-(\\d{2})T(\\d{2}):(\\d{2}):(\\d{2})(?:,\\d+)?([+-]\\d{2}:\\d{2}|Z)?"
+ ,local-time:+iso-8601-format+))
+ (:simple . ("(\\d{4})/(\\d{2})/(\\d{2}) (\\d{2}):(\\d{2}):(\\d{2})()"
+ ((:year 4) #\/ (:month 2) #\/ (:day 2) #\space (:hour 2) #\: (:min 2) #\: (:sec 2))))
+ (:gnuplot . nil)
+ (:golang . nil)
+ (:unix-seconds . nil)
+ (:unix-milliseconds . nil)))
+
+
+;;;; Utilities ----------------------------------------------------------------
+(defmacro match ((register-vars (start end) (regex target)) &body body)
+ (alexandria:with-gensyms (rs re)
+ (alexandria:once-only (regex target)
+ `(multiple-value-bind (,start ,end ,rs ,re) (ppcre:scan ,regex ,target)
+ (when ,start
+ (let (,@(loop :for r :from 0
+ :for var :in register-vars
+ :collect `(,var (when (aref ,rs ,r)
+ (subseq ,target (aref ,rs ,r) (aref ,re ,r))))))
+ ,@body))))))
+
+(defun i (s)
+ (parse-integer s))
+
+(defun keywordize (s)
+ (alexandria:make-keyword (string-upcase s)))
+
+
+;;;; Time Formats -------------------------------------------------------------
+(defun microseconds->nanoseconds (msec)
+ (* msec 1000))
+
+(defun milliseconds->nanoseconds (msec)
+ (* msec 1000 1000))
+
+
+(defun get-format (format)
+ (or (alexandria:assoc-value *time-formats* format)
+ (error "Unknown time format ~S" format)))
+
+(defun get-regex (format)
+ (first (get-format format)))
+
+(defun get-local-time-format (format)
+ (second (get-format format)))
+
+
+(defun parse-timezone (string)
+ (if (member string '(nil "" "Z" "UTC" "+00:00" "-00:00") :test #'equal)
+ local-time:+utc-zone+
+ (or (local-time:find-timezone-by-location-name string)
+ (error "TODO: handle timezone ~S" string))))
+
+
+(defgeneric make-parser (format)
+ (:documentation "Return a parsing function for the given format."))
+
+(defmethod make-parser (format)
+ (let ((scanner (ppcre:create-scanner (get-regex format))))
+ (lambda (s)
+ (match ((year month day hour minute second timezone)
+ (start end)
+ (scanner s))
+ (values
+ (local-time:encode-timestamp
+ 0 (i second) (i minute) (i hour) (i day) (i month) (i year)
+ :timezone (parse-timezone timezone))
+ start end)))))
+
+(defmethod make-parser ((format (eql :golang)))
+ (let ((scanner (ppcre:create-scanner "(\\d{4})/(\\d{2})/(\\d{2}) (\\d{2}):(\\d{2}):(\\d{2})(?:\\.(\\d{6}))?")))
+ (lambda (s)
+ (match ((year month day hour minute seconds microseconds)
+ (start end)
+ (scanner s))
+ (values (local-time:encode-timestamp
+ (microseconds->nanoseconds (i microseconds))
+ (i seconds) (i minute) (i hour) (i day) (i month) (i year))
+ start end)))))
+
+(defmethod make-parser ((format (eql :gnuplot)))
+ (let ((scanner (ppcre:create-scanner "(\\d{2})/(\\d{2})/(\\d{2}),(\\d{2}):(\\d{2})")))
+ (lambda (s)
+ (match ((day month year hour minute)
+ (start end)
+ (scanner s))
+ (values (local-time:encode-timestamp
+ 0 0 (i minute) (i hour) (i day) (i month) (+ 2000 (i year)))
+ start end)))))
+
+(defmethod make-parser ((format (eql :unix-seconds)))
+ (let ((scanner (ppcre:create-scanner "(\\d{13,14})")))
+ (lambda (s)
+ (match ((unix)
+ (start end)
+ (scanner s))
+ (when unix ; shut up sbcl
+ (values (local-time:unix-to-timestamp (i unix)) start end))))))
+
+(defmethod make-parser ((format (eql :unix-milliseconds)))
+ (let ((scanner (ppcre:create-scanner "(\\d{10,11})")))
+ (lambda (s)
+ (match ((unix)
+ (start end)
+ (scanner s))
+ (when unix ; shut up sbcl
+ (multiple-value-bind (sec ms) (truncate (i unix) 1000)
+ (values (local-time:unix-to-timestamp sec :nsec (milliseconds->nanoseconds ms))
+ start end)))))))
+
+
+(defun make-predicate (format start end)
+ "Return a matching predicate for the user's query.
+
+ This predicate will taka a line and return four values:
+
+ * The timestamp found, if any.
+ * Whether the timestamp is inside the filtering bounds, if any.
+ * The start of the timestamp in the string, if any.
+ * The end of the timestamp in the string, if any.
+
+ "
+ (let ((parser (make-parser format)))
+ (lambda (line)
+ (multiple-value-bind (line-time s e) (funcall parser line)
+ (values line-time
+ (and line-time
+ (or (null start) (local-time:timestamp<= start line-time))
+ (or (null end) (local-time:timestamp<= line-time end)))
+ s
+ e)))))
+
+
+(defgeneric make-formatter (format))
+
+(defmethod make-formatter (format)
+ (let ((local-time-format (get-local-time-format format)))
+ (lambda (time stream)
+ (local-time:format-timestring stream time :format local-time-format))))
+
+(defmethod make-formatter ((format (eql :golang)))
+ (lambda (time stream)
+ (local-time:format-timestring
+ stream time
+ :format '((:year 4) #\/ (:month 2) #\/ (:day 2) #\space (:hour 2) #\: (:min 2) #\: (:sec 2)))))
+
+(defmethod make-formatter ((format (eql :gnuplot)))
+ (lambda (time stream)
+ (let* ((f '((:day 2) #\/ (:month 2) #\/ #\Y #\, (:hour 2) #\: (:min 2)))
+ (s (local-time:format-timestring nil time :format f)))
+ ;; "16/07/Y,15:05"
+ (write-string s stream :start 0 :end 6)
+ (format stream "~2,'0D" (mod (local-time:timestamp-year time) 100))
+ (write-string s stream :start 7))))
+
+(defmethod make-formatter ((format (eql :unix-seconds)))
+ (lambda (time stream)
+ (format stream "~D" (local-time:timestamp-to-unix time))))
+
+(defmethod make-formatter ((format (eql :unix-milliseconds)))
+ (lambda (time stream)
+ (format stream "~D" (+ (* 1000 (local-time:timestamp-to-unix time))
+ (local-time:timestamp-millisecond time)))))
+
+
+(defun parse-time-flexibly (string)
+ ;; todo optimize this
+ (loop :for format :in *time-formats*
+ :for parser = (make-parser (car format))
+ :for result = (funcall parser string)
+ :when result :do (return-from parse-time-flexibly result))
+ (error "Don't know how to parse ~S as a time." string))
+
+
+;;;; Run ----------------------------------------------------------------------
+(defun run% (predicate in out path prefix reformat only)
+ (loop
+ :for line = (read-line in nil)
+ :while line
+ ; todo support multiple timestamps per line
+ :do (multiple-value-bind (time in-bounds start end) (funcall predicate line)
+ (if (null time)
+ (unless only
+ (write-line line out))
+ (when in-bounds
+ (when prefix
+ (write-string path out)
+ (write-char #\: out))
+ (if reformat
+ (progn (write-string line out :start 0 :end start)
+ (funcall reformat time out)
+ (write-line line out :start end))
+ (write-line line out)))))))
+
+(defun run (paths &key format start end prefix reformat only)
+ (when (null paths)
+ (setf paths '("-")))
+ (when (and start end (local-time:timestamp< end start))
+ (error "Start ~S is after end ~S." start end))
+ (when reformat
+ (setf reformat (make-formatter reformat)))
+ (let ((pred (make-predicate format start end)))
+ (dolist (path paths)
+ (if (string= "-" path)
+ (run% pred *standard-input* *standard-output* path prefix reformat only)
+ (with-open-file (stream path :direction :input)
+ (run% pred stream *standard-output* path prefix reformat only))))))
+
+
+;;;; User Interface -----------------------------------------------------------
+(defparameter *option-help*
+ (adopt:make-option 'help
+ :help "Display help and exit."
+ :long "help"
+ :short #\h
+ :reduce (constantly t)))
+
+
+(adopt:defparameters (*option-prefix* *option-no-prefix*)
+ (adopt:make-boolean-options 'prefix
+ :help "Prefix output lines with their path."
+ :help-no "Do not prefix output lines with their path (default)."
+ :short #\p
+ :long "prefix"))
+
+
+(adopt:defparameters (*option-only* *option-all*)
+ (adopt:make-boolean-options 'only
+ :help "Only output lines containing a timestamp."
+ :help-no "Output all lines, even those without a timestamp (default)."
+ :short #\o
+ :short-no #\a
+ :long "only"
+ :long-no "all"))
+
+
+(defparameter *option-format*
+ (adopt:make-option 'format
+ :help "The time format used to parse times from lines."
+ :parameter "FORMAT"
+ :long "format"
+ :short #\f
+ :initial-value :simple
+ :key #'keywordize
+ :reduce #'adopt:last))
+
+(defparameter *option-reformat*
+ (adopt:make-option 'reformat
+ :help "Reformat parsed timestamps into FORMAT before outputting them."
+ :parameter "FORMAT"
+ :long "reformat"
+ :short #\r
+ :initial-value nil
+ :key #'keywordize
+ :reduce #'adopt:last))
+
+(defparameter *option-no-reformat*
+ (adopt:make-option 'reformat
+ :help "Do not reformat parsed timestamps (default)."
+ :long "no-reformat"
+ :short #\R
+ :reduce (constantly nil)))
+
+
+(defparameter *option-start*
+ (adopt:make-option 'start
+ :help "Only show lines at or after START."
+ :parameter "START"
+ :long "start"
+ :short #\s
+ :initial-value nil
+ :key #'parse-time-flexibly
+ :reduce #'adopt:last))
+
+(defparameter *option-end*
+ (adopt:make-option 'end
+ :help "Only show lines at or before END."
+ :parameter "END"
+ :long "end"
+ :short #\e
+ :initial-value nil
+ :key #'parse-time-flexibly
+ :reduce #'adopt:last))
+
+
+(adopt:define-string *help-text*
+ "twizzle lets you swizzle timestamps.~@
+ ~@
+ Use --format to select the incoming timestamp format, and --reformat to ~
+ swizzle them into a different format if desired. Supported formats:~@
+ ~@
+ ~:
+ * simple: 2020/11/23 18:55:30 (default)
+ * rfc-3339: 2020-11-23 18:55:30Z
+ * iso-8601: 2020-11-23T18:55:30Z
+ * gnuplot: 11/23/20,18:55~@
+ ~@
+ You can additionally filter based on a time range using --start and/or --end. ~
+ For convenience, these parameters can be given in any supported timestamp ~
+ format, they don't have to match --format.~@
+ ~@
+ Currently only the first timestamp per line is considered.")
+
+(defparameter *examples*
+ '(("Filter standard input and only print lines with an RFC-3339 time:"
+ . "twizzle --format rfc-3339")
+ ("Print log lines after a particular time, and prefix each output line with its source filename:"
+ . "twizzle **.log --prefix --after '2020/06/14 12:22:01'")
+ ("Print RFC-3339 log lines starting now, with now given in a different format:"
+ . "tail -f foo | twizzle --format rfc-3339 --after \"$(date --utc --iso-8601=sec)\"")))
+
+
+(defparameter *ui*
+ (adopt:make-interface
+ :name "twizzle"
+ :usage "[OPTIONS] [FILE...]"
+ :summary "swizzle timestamps"
+ :help *help-text*
+ :examples *examples*
+ :contents (list *option-help*
+ (adopt:make-group 'timestamp-formats
+ :title "Timestamp Formats"
+ :options (list *option-format*
+ *option-reformat*
+ *option-no-reformat*))
+ (adopt:make-group 'output-filtering
+ :title "Output Control"
+ :options (list *option-only*
+ *option-all*
+ *option-start*
+ *option-end*
+ *option-prefix*
+ *option-no-prefix*)))))
+
+
+(defmacro exit-on-error (&body body)
+ `(handler-case (progn ,@body)
+ (error (c) (adopt:print-error-and-exit c))))
+
+(defmacro exit-on-ctrl-c (&body body)
+ `(handler-case
+ (with-user-abort:with-user-abort (progn ,@body))
+ (with-user-abort:user-abort () (adopt:exit 130))))
+
+
+(defun toplevel ()
+ #+sbcl (sb-ext:disable-debugger)
+ (exit-on-error
+ (exit-on-ctrl-c
+ (multiple-value-bind (arguments options) (adopt:parse-options-or-exit *ui*)
+ (cond
+ ((gethash 'help options) (adopt:print-help-and-exit *ui*))
+ (t (progn (local-time:reread-timezone-repository)
+ (run arguments
+ :format (gethash 'format options)
+ :start (gethash 'start options)
+ :end (gethash 'end options)
+ :prefix (gethash 'prefix options)
+ :only (gethash 'only options)
+ :reformat (gethash 'reformat options)))))))))
+
+
+#; Scratch --------------------------------------------------------------------
+
+(run
+ '("/home/sjl/scratch/logs/logs/prod/saas-warehouse-i-06b0ea6fe4e6dd3fd.log")
+ :format :golang
+ :prefix nil
+ :reformat :rfc-3339)
+
+(parse-time-flexibly "2020-07-15 16:08:15.0000Z")
+
+(local-time:find-timezone-by-location-name "EDT")
+
+(local-time:reread-timezone-repository)
--- a/lisp/weather.lisp Fri Apr 14 15:01:35 2023 -0400
+++ b/lisp/weather.lisp Fri Jul 07 16:11:02 2023 -0400
@@ -45,6 +45,10 @@
;;;; OpenWeatherMap -----------------------------------------------------------
+;;; TODO Switch to weather.gov some day to get my taxes' worth, e.g.
+;;; https://forecast.weather.gov/MapClick.php?lat=43.1577&lon=-77.6066&FcstType=digitalDWML
+;;; Sadly this is XML.
+
(defclass* response ()
((hourly :json (vector hour)))
(:metaclass jarl:json-class))
@@ -175,7 +179,7 @@
(adopt:print-help-and-exit *ui*)
(progn
(load-config)
- (run (or (first arguments) "14604")
+ (run (or (first arguments) "14607")
:hours (gethash 'hours options))))
(error (e) (adopt:print-error-and-exit e))))))
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/lisp/when.lisp Fri Jul 07 16:11:02 2023 -0400
@@ -0,0 +1,211 @@
+(eval-when (:compile-toplevel :load-toplevel :execute)
+ (ql:quickload '(:adopt :iterate :chronicity :local-time :losh)
+ :silent t))
+
+(defpackage :when
+ (:use :cl :iterate :losh)
+ (:export :toplevel :*ui*))
+
+(in-package :when)
+
+;;;; Configuration ------------------------------------------------------------
+(defparameter +iso-8601-seconds-format+
+ '((:year 4) #\- (:month 2) #\- (:day 2)
+ #\T
+ (:hour 2) #\: (:min 2) #\: (:sec 2)
+ :gmt-offset-or-z))
+
+
+(defparameter *time-formats*
+ `((:rfc-3339 . ,local-time:+rfc3339-format+)
+ (:iso-8601 . ,local-time:+iso-8601-format+)
+ (:iso-8601-seconds . ,+iso-8601-seconds-format+)
+ (:gnuplot . ((:day 2) #\/ (:month 2) #\/ (:year 4) #\, (:hour 2) #\: (:min 2)))))
+
+
+;;;; Errors -------------------------------------------------------------------
+(define-condition user-error (error) ())
+
+(define-condition need-one-time-string (user-error) ()
+ (:report "Exactly one time string is required."))
+
+
+
+;;;; Functionality ------------------------------------------------------------
+(defun jitter-ns (seconds)
+ (if (zerop seconds)
+ 0
+ (_ (coerce seconds 'double-float)
+ random
+ (* 1000000000 _)
+ floor)))
+
+(defun run (time-string &key (output-format :iso-8601) (jitter 0) timezone)
+ (local-time:format-timestring
+ *standard-output*
+ (local-time:timestamp+ (chronicity:parse time-string :endian-preference :middle)
+ (jitter-ns jitter)
+ :nsec)
+ :format (or (assocdr output-format *time-formats*)
+ (error "Unknown time format ~S." output-format))
+ :timezone (or timezone local-time:*default-timezone*)))
+
+
+;;;; User Interface -----------------------------------------------------------
+(defparameter *examples*
+ '(("Print the current time in RFC 3339 format:" . "when now --rfc-3339")
+ ("Print a randomish time from a while ago:" . "when '12 hours ago' --jitter-hours 4")
+ ("Print a randomish time next year in UTC:" . "when '1 year from now' --jitter-days 30 --utc")))
+
+
+(defparameter *option/help*
+ (adopt:make-option 'help
+ :help "Display help and exit."
+ :long "help"
+ :short #\h
+ :reduce (constantly t)))
+
+
+(defparameter *option/output-format/iso-8601*
+ (adopt:make-option 'output-format/iso-8601
+ :result-key 'output-format
+ :help "Output results as ISO-8601 (default)."
+ :long "iso-8601"
+ :short #\i
+ :initial-value :iso-8601
+ :reduce (constantly :iso-8601)))
+
+(defparameter *option/output-format/iso-8601-seconds*
+ (adopt:make-option 'output-format/iso-8601-seconds
+ :result-key 'output-format
+ :help "Output results as ISO-8601 with a precision of seconds (no nanoseconds)."
+ :long "iso-8601-seconds"
+ :short #\I
+ :reduce (constantly :iso-8601-seconds)))
+
+(defparameter *option/output-format/rfc-3339*
+ (adopt:make-option 'output-format/rfc-3339
+ :result-key 'output-format
+ :help "Output results as RFC 3339."
+ :long "rfc-3339"
+ :short #\r
+ :reduce (constantly :rfc-3339)))
+
+(defparameter *option/output-format/gnuplot*
+ (adopt:make-option 'output-format/gnuplot
+ :result-key 'output-format
+ :help "Output results as Gnuplot timestamps."
+ :long "gnuplot"
+ :short #\g
+ :reduce (constantly :gnuplot)))
+
+
+(defparameter *option/jitter/seconds*
+ (adopt:make-option 'jitter/seconds
+ :result-key 'jitter
+ :parameter "N"
+ :help "Jitter result by up to N seconds."
+ :long "jitter-seconds"
+ :short #\S
+ :initial-value 0
+ :key #'parse-integer
+ :reduce (lambda (old n) (declare (ignore old)) n)))
+
+(defparameter *option/jitter/minutes*
+ (adopt:make-option 'jitter/minutes
+ :result-key 'jitter
+ :parameter "N"
+ :help "Jitter result by up to N minutes."
+ :long "jitter-minutes"
+ :short #\M
+ :key #'parse-integer
+ :reduce (lambda (old n) (declare (ignore old)) (* 60 n))))
+
+(defparameter *option/jitter/hours*
+ (adopt:make-option 'jitter/hours
+ :result-key 'jitter
+ :parameter "N"
+ :help "Jitter result by up to N hours."
+ :long "jitter-hours"
+ :short #\H
+ :key #'parse-integer
+ :reduce (lambda (old n) (declare (ignore old)) (* 60 60 n))))
+
+(defparameter *option/jitter/days*
+ (adopt:make-option 'jitter/days
+ :result-key 'jitter
+ :parameter "N"
+ :help "Jitter result by up to N days."
+ :long "jitter-days"
+ :short #\D
+ :key #'parse-integer
+ :reduce (lambda (old n) (declare (ignore old)) (* 24 60 60 n))))
+
+
+(defparameter *option/timezone/local*
+ (adopt:make-option 'jitter/timezone/local
+ :result-key 'timezone
+ :help "Print result in current local computer timezone (default)."
+ :long "local-timezone"
+ :short #\l
+ :initial-value nil
+ :reduce (constantly nil)))
+
+(defparameter *option/timezone/utc*
+ (adopt:make-option 'jitter/timezone/utc*
+ :result-key 'timezone
+ :help "Print the result in UTC."
+ :long "utc"
+ :short #\u
+ :reduce (constantly local-time:+utc-zone+)))
+
+
+(adopt:define-string *help-text*
+ "when takes a human-readable time like '2 hours ago' and prints it as a ~
+ computer-readable time. It can also jitter the time by a random amount if ~
+ you want to produce randomish data.")
+
+
+(defparameter *ui*
+ (adopt:make-interface
+ :name "when"
+ :usage "[OPTIONS] TIME-STRING"
+ :summary "convert human time to computer time"
+ :help *help-text*
+ :examples *examples*
+ :contents (list *option/help*
+ (adopt:make-group
+ 'output-options
+ :title "Output Options"
+ :options (list *option/output-format/iso-8601*
+ *option/output-format/iso-8601-seconds*
+ *option/output-format/rfc-3339*
+ *option/output-format/gnuplot*))
+ (adopt:make-group
+ 'timezone-options
+ :title "Timezone Options"
+ :options (list *option/timezone/local*
+ *option/timezone/utc*))
+ (adopt:make-group
+ 'jitter-options
+ :title "Jitter Options"
+ :options (list *option/jitter/seconds*
+ *option/jitter/minutes*
+ *option/jitter/hours*
+ *option/jitter/days*)))))
+
+
+(defun toplevel ()
+ (sb-ext:disable-debugger)
+ (setf *random-state* (make-random-state t))
+ (multiple-value-bind (arguments options) (adopt:parse-options-or-exit *ui*)
+ (handler-case
+ (adopt::quit-on-ctrl-c ()
+ (cond
+ ((gethash 'help options) (adopt:print-help-and-exit *ui*))
+ ((/= (length arguments) 1) (error 'need-one-time-string))
+ (t (run (first arguments)
+ :output-format (gethash 'output-format options)
+ :jitter (gethash 'jitter options)
+ :timezone (gethash 'timezone options)))))
+ (user-error (e) (adopt:print-error-and-exit e)))))
--- a/lispwords Fri Apr 14 15:01:35 2023 -0400
+++ b/lispwords Fri Jul 07 16:11:02 2023 -0400
@@ -49,12 +49,15 @@
; arrows
(1 -> ->> -<> -<>> _)
+; drakma
+(1 http-request)
+
; sketch
(1 with-pen with-font)
(2 defsketch)
; sbcl
-(1 with-profiling)
+(1 with-profiling save-lisp-and-die)
; policy-cond
(1 policy-if)
@@ -87,8 +90,8 @@
(1 if-let* if-let)
(1 gathering-vector)
(1 multiple-value-bind*)
-(1 do-repeat)
-(1 do-range do-irange)
+(1 do-repeat do-range do-irange do-ring-buffer do-vector do-file do-hash-set)
+(1 timing profile-when)
; qtools
(1 qtenumcase)
@@ -122,10 +125,11 @@
; stumpwm
(3 defcommand)
+(1 when-let-window)
; adopt
(2 define-interface)
-(1 make-option make-boolean-options)
+(1 make-option make-boolean-options make-group)
(1 quit-on-ctrl-c)
@@ -139,3 +143,8 @@
(1 dovec)
(1 dolist)
+; boots
+(1 event-case)
+
+; parsnip
+(1 let!)
--- a/mutt/muttrc Fri Apr 14 15:01:35 2023 -0400
+++ b/mutt/muttrc Fri Jul 07 16:11:02 2023 -0400
@@ -25,7 +25,7 @@
source ~/.vim/bundle/badwolf/contrib/badwolf.muttrc
-set folder = ~/.mail # mail location
+set folder = ~/.mail2 # mail location
set wait_key = no # shut up, mutt
set mbox_type = Maildir # mailbox type
@@ -183,8 +183,8 @@
macro index \Cr "T~U<enter><tag-prefix><clear-flag>N<untag-pattern>.<enter>" "mark all messages as read"
# Sync email
-macro index O "<shell-escape>offlineimap<enter>" "run offlineimap to sync all mail"
-macro index o "<shell-escape>offlineimap -qf INBOX<enter>" "run offlineimap to sync inbox"
+macro index O "<sync-mailbox><shell-escape>mbsync --all<enter><sync-mailbox>" "run mbsync to sync all mail"
+macro index o "<sync-mailbox><shell-escape>mbsync mail-inbox<enter><sync-mailbox>" "run mbsync to sync inbox"
# Saner copy/move dialogs
macro index C "<copy-message>?<toggle-mailboxes>" "copy a message to a mailbox"
@@ -226,7 +226,7 @@
bind compose p postpone-message
bind compose P pgp-menu
-macro compose H "| htmlify-email<enter><attach-file>~/.mutt/temp/neomutt-alternative.html<enter><tag-entry><previous-entry><tag-entry><group-alternatives>"
+macro compose H "| htmlify-email<enter><attach-file>~/.mutt/temp/neomutt-alternative.html<enter><tag-entry><previous-entry><tag-entry><toggle-disposition><group-alternatives>"
# }}}
# Attachment {{{
--- a/mutt/view_attachment.sh Fri Apr 14 15:01:35 2023 -0400
+++ b/mutt/view_attachment.sh Fri Jul 07 16:11:02 2023 -0400
@@ -57,7 +57,7 @@
#
# the tmp directory to use.
-tmpdir="$HOME/.tmp/mutt_attach"
+tmpdir="$HOME/scratch/mutt_attach"
# the name of the debug file if debugging is turned on.
debug_file=$tmpdir/debug
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ncdu-excludes Fri Jul 07 16:11:02 2023 -0400
@@ -0,0 +1,2 @@
+/cryo
+/dump
--- a/psqlrc Fri Apr 14 15:01:35 2023 -0400
+++ b/psqlrc Fri Jul 07 16:11:02 2023 -0400
@@ -5,8 +5,11 @@
\pset pager on
\pset null '∅'
+
\set PROMPT1 '%[%033[1;34m%]%M:%> %n@%/%R%#%x%[%033[0m%] '
\timing
\setenv PAGER less
\setenv LESS -iS
+
+set time zone 'etc/UTC';
--- a/remote/bash_profile Fri Apr 14 15:01:35 2023 -0400
+++ b/remote/bash_profile Fri Jul 07 16:11:02 2023 -0400
@@ -1,1 +1,103 @@
-../bash_profile
\ No newline at end of file
+#!/usr/bin/env bash
+
+# Similar to my normal bash_profile, but stripped down for running on servers.
+
+if test -e /etc/profile; then
+ source /etc/profile
+fi
+
+shopt -s expand_aliases
+shopt -s histappend
+
+# Save multiline commands as a single history entry.
+shopt -s cmdhist
+
+HISTFILESIZE=100000
+HISTSIZE=100000
+HISTCONTROL=ignoreboth
+
+# Flush commands to history immediately instead of waiting for logout.
+PROMPT_COMMAND='history -a'
+
+if test -e ~/.dircolors; then
+ eval "$(dircolors -b ~/.dircolors)"
+fi
+
+D=$'\e[37m'
+RED=$'\e[31m'
+GREEN=$'\e[32m'
+ORANGE=$'\e[33m'
+BLUE=$'\e[34m'
+PINK=$'\e[35m'
+# CYAN=$'\e[36m'
+
+function last_return_value() {
+ x="$?"
+ if test "$x" -ne 0; then
+ echo -n "${RED}[$x] ${D}"
+ fi
+}
+
+function histgrep {
+ history | grep "$@" | tac | f 2-
+}
+
+if [ -n "$SSH_CLIENT" ] || [ -n "$SSH_TTY" ]; then
+ HOST_COLOR="$BLUE"
+else
+ HOST_COLOR="$ORANGE"
+fi
+
+export PS1='\n${PINK}\u ${D}at ${HOST_COLOR}\h ${D}in ${GREEN}\w${D} $(last_return_value)$ '
+
+alias ..="cd .."
+alias ...="cd ../.."
+alias ....="cd ../../.."
+alias .....="cd ../../../.."
+alias ......="cd ../../../../.."
+
+alias js='cd ~/scratch'
+
+alias :q=exit
+alias :qa=exit
+alias :wqa=exit
+
+if command -v ag >/dev/null; then
+ AG_BIN="$(command -v ag)"
+ function ag() {
+ if test -f '.agignore' && grep -q 'pragma: skipvcs' '.agignore'; then
+ $AG_BIN --search-files -U "$@"
+ else
+ $AG_BIN --search-files "$@"
+ fi
+ }
+fi
+
+function prepend_to_path {
+ if test -d "$1"; then
+ PATH="$1":"$PATH"
+ fi
+}
+
+prepend_to_path "$HOME/src/dotfiles/lisp/bin"
+prepend_to_path "$HOME/src/dotfiles/bin"
+prepend_to_path "$HOME/bin"
+export PATH
+
+export LESS_TERMCAP_mb=$(printf '\e[01;31m') # begin blinking
+export LESS_TERMCAP_md=$(printf '\e[01;38;5;74m') # begin bold
+export LESS_TERMCAP_me=$(printf '\e[0m') # end mode
+export LESS_TERMCAP_se=$(printf '\e[0m') # end standout-mode
+export LESS_TERMCAP_so=$(printf '\e[38;5;246m') # begin standout-mode - info box
+export LESS_TERMCAP_ue=$(printf '\e[0m') # end underline
+export LESS_TERMCAP_us=$(printf '\e[04;38;5;146m') # begin underline
+export PAGER='less -iX'
+
+function psg() {
+ ps auxww | grep --color=always "$@" | grep -v grep | collapse | cuts -f 2,11-
+}
+
+GPG_TTY=$(tty)
+export GPG_TTY
+
+export EDITOR=vim
--- a/remote/bootstrap.sh Fri Apr 14 15:01:35 2023 -0400
+++ b/remote/bootstrap.sh Fri Jul 07 16:11:02 2023 -0400
@@ -9,8 +9,7 @@
# Already linked.
true
elif test -e "$dst"; then
- echo File "$dst" already exists and is not a symbolic link.
- exit 1
+ echo File "$dst" already exists, skipping.
elif test ! -e "$src"; then
echo File "$src" does not exist.
exit 1
@@ -30,5 +29,4 @@
ensure_link "src/dotfiles/dircolors" ".dircolors"
ensure_link "src/dotfiles/ffignore" ".ffignore"
ensure_link "src/dotfiles/config.fish" ".config/fish/config.fish"
-ensure_link "src/dotfiles/tmux.conf" ".tmux.conf"
ensure_link "src/dotfiles/hushlogin" ".hushlogin"
--- a/remote/tmux.conf Fri Apr 14 15:01:35 2023 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-../tmux/tmux.conf
\ No newline at end of file
--- a/restic/excludes.txt Fri Apr 14 15:01:35 2023 -0400
+++ b/restic/excludes.txt Fri Jul 07 16:11:02 2023 -0400
@@ -23,6 +23,7 @@
/home/sjl/.slime
/home/sjl/.steam
/home/sjl/.virtualenvs
+/home/sjl/.xsession-errors
/home/sjl/Dropbox/.dropbox.cache
/home/sjl/Pictures
/home/sjl/Videos
@@ -33,4 +34,6 @@
/home/sjl/src/dotfiles/vim/tmp
/home/sjl/Pictures/Webcam
/home/sjl/Pictures/darktable_export
+/home/sjl/bin/tetrio-desktop
+/home/sjl/.config/tetrio-desktop
cache2
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/stumpwm/local-share-stumpwm/thirds.dump Fri Jul 07 16:11:02 2023 -0400
@@ -0,0 +1,7 @@
+#S(GDUMP
+ :NUMBER 1
+ :NAME "Default"
+ :TREE ((#S(FDUMP :NUMBER 0 :X 0 :Y 0 :WIDTH 1200 :HEIGHT 1440 :WINDOWS NIL :CURRENT NIL)
+ (#S(FDUMP :NUMBER 1 :X 1200 :Y 0 :WIDTH 2720 :HEIGHT 1440 :WINDOWS NIL :CURRENT NIL)
+ #S(FDUMP :NUMBER 2 :X 3920 :Y 0 :WIDTH 1200 :HEIGHT 1440 :WINDOWS NIL :CURRENT NIL))))
+ :CURRENT 1)
--- a/stumpwm/local-share-stumpwm/work.dump Fri Apr 14 15:01:35 2023 -0400
+++ b/stumpwm/local-share-stumpwm/work.dump Fri Jul 07 16:11:02 2023 -0400
@@ -1,44 +1,9 @@
#S(GDUMP
- :NUMBER 1
- :NAME "Default"
- :TREE ((#S(FDUMP
- :NUMBER 0
- :X 0
- :Y 0
- :WIDTH 1920
- :HEIGHT 2160
- :WINDOWS (41943045 39845893 54525957 16777221)
- :CURRENT 41943045)
- #S(FDUMP
- :NUMBER 4
- :X 1920
- :Y 0
- :WIDTH 1920
- :HEIGHT 2160
- :WINDOWS (44040195 77594629)
- :CURRENT 44040195))
- (#S(FDUMP
- :NUMBER 1
- :X 3840
- :Y 0
- :WIDTH 960
- :HEIGHT 1080
- :WINDOWS (23068677)
- :CURRENT 23068677)
- (#S(FDUMP
- :NUMBER 2
- :X 4800
- :Y 0
- :WIDTH 960
- :HEIGHT 465
- :WINDOWS (35651589)
- :CURRENT 35651589)
- #S(FDUMP
- :NUMBER 3
- :X 4800
- :Y 465
- :WIDTH 960
- :HEIGHT 615
- :WINDOWS (27262977)
- :CURRENT 27262977))))
- :CURRENT 4)
+ :NUMBER 1
+ :NAME "Default"
+ :TREE ((#S(FDUMP :NUMBER 0 :X 0 :Y 0 :WIDTH 1920 :HEIGHT 2160 :WINDOWS (41943045 39845893 54525957 16777221) :CURRENT 41943045)
+ #S(FDUMP :NUMBER 4 :X 1920 :Y 0 :WIDTH 1920 :HEIGHT 2160 :WINDOWS (44040195 77594629) :CURRENT 44040195))
+ (#S(FDUMP :NUMBER 1 :X 3840 :Y 0 :WIDTH 960 :HEIGHT 1080 :WINDOWS (23068677) :CURRENT 23068677)
+ (#S(FDUMP :NUMBER 2 :X 4800 :Y 0 :WIDTH 960 :HEIGHT 465 :WINDOWS (35651589) :CURRENT 35651589)
+ #S(FDUMP :NUMBER 3 :X 4800 :Y 465 :WIDTH 960 :HEIGHT 615 :WINDOWS (27262977) :CURRENT 27262977))))
+ :CURRENT 4)
--- a/stumpwmrc Fri Apr 14 15:01:35 2023 -0400
+++ b/stumpwmrc Fri Jul 07 16:11:02 2023 -0400
@@ -1,13 +1,16 @@
(in-package :stumpwm-user)
+(shadow :window)
-(ql:quickload '(:losh :split-sequence :alexandria :parse-number :str :cl-ppcre :bordeaux-threads) :silent t)
+(ql:quickload '(:losh :split-sequence :alexandria :parse-number :str :cl-ppcre :bordeaux-threads :jarl :local-time)
+ :silent t)
+
(use-package :losh)
-
;;;; Config -------------------------------------------------------------------
(set-prefix-key (kbd "C-space"))
+(local-time:reread-timezone-repository)
-(redirect-all-output (data-dir-file "debug" "log"))
+(defvar *redirected* (redirect-all-output (data-dir-file "debug" "log")))
(setf *mouse-focus-policy* :click
*message-window-gravity* :center
@@ -28,47 +31,47 @@
(and (search needle string :test #'char=) t))
(defun string-grep (needle text &key first-only)
- (-<> text
- (split-sequence:split-sequence #\newline <>)
+ (_ text
+ (split-sequence:split-sequence #\newline _)
(if first-only
- (find needle <> :test #'string-contains)
- (remove-if-not (alexandria:curry #'string-contains needle) <>))))
+ (find needle _ :test #'string-contains)
+ (remove-if-not (alexandria:curry #'string-contains needle) _))))
(defun string-split (delimiters string)
(split-sequence:split-sequence delimiters string
:test (lambda (bag ch)
(find ch bag :test #'char=))))
+(defun run-and-echo-shell-command (command &rest args)
+ (message command)
+ (apply #'run-shell-command command args))
+
(defun mod+ (n increment modulo)
(mod (+ n increment) modulo))
(defun volume ()
- (-<> (run-shell-command "amixer sget Master" t)
- (string-grep "Front Left:" <> :first-only t)
- (string-split "[]" <>)
+ (_ (run-shell-command "amixer sget Master" t)
+ (string-grep "Front Left:" _ :first-only t)
+ (string-split "[]" _)
second
- (string-trim "%" <>)
+ (string-trim "%" _)
parse-integer))
-(defun battery ()
- (run-shell-command
- "acpi -b | tail -n1 | awk -F '[ ,]' '{printf \"%s%s\", $3, $5}' | sed s/Discharging// | sed s/Unknown// | sed s/Full// | sed s/Charging/+/"
- t))
-
(defun current-frame ()
(stumpwm::tile-group-current-frame (current-group)))
(defun keywordize (string)
- (-<> string
- (string-trim (string #\newline) <>)
+ (_ string
+ (string-trim (string #\newline) _)
string-upcase
- (intern <> (find-package :keyword))))
+ (intern _ (find-package :keyword))))
-(defparameter *host* (keywordize (run-shell-command "hostname" t)))
+(defparameter *host* (keywordize (machine-instance)))
+
(defmacro ehostcase (&body clauses)
`(ecase *host* ,@clauses))
@@ -144,6 +147,10 @@
"Find and return a fresh list of all windows that match `query` under `window-match-p`."
(remove-if-not (lambda (w) (window-match-p query w)) (all-windows)))
+(defmacro when-let-window ((symbol title-query) &body body)
+ `(when-let ((,symbol (find-window `(:title ,(ppcre:create-scanner ,title-query)))))
+ ,@body))
+
;;;; Posture ------------------------------------------------------------------
(defparameter *posture-thread* nil)
@@ -229,6 +236,57 @@
:name "Posture thread"))))
+;;;; Budget ------------------------------------------------------------------
+(defparameter *tz/eastern*
+ (local-time:find-timezone-by-location-name "US/Eastern"))
+
+(defparameter *budget/start*
+ (local-time:encode-timestamp 0 0 0 0 21 5 2023 :timezone *tz/eastern*))
+
+(defun budget/per-day ()
+ (first (losh:read-all-from-file "/home/sjl/Dropbox/budget/per-day")))
+
+(defun budget/elapsed ()
+ (local-time:timestamp-difference (local-time:now) *budget/start*))
+
+(defun budget/days-elapsed ()
+ (floor (/ (budget/elapsed) (* 60 60 24))))
+
+(defun budget/in ()
+ (* (budget/days-elapsed) (budget/per-day)))
+
+(defun budget/out ()
+ (loop :for path :in (directory "/home/sjl/Dropbox/budget/hosts/*/total")
+ :summing (print (first (read-all-from-file (print path))))))
+
+(defun budget/current ()
+ (- (budget/in) (budget/out)))
+
+(defcommand budget-dump () ()
+ (message
+ (sh '("sh" "-c" "tail -n 5 /home/sjl/Dropbox/budget/hosts/*/records")
+ :result-type 'string)))
+
+(defcommand budget () ()
+ (message "$~D" (budget/current)))
+
+(defmacro with-budget-file ((f file &rest open-args) &body body)
+ `(with-open-file
+ (,f (format nil "/home/sjl/Dropbox/budget/hosts/~(~A~)/~A" *host* ,file)
+ ,@open-args)
+ ,@body))
+
+(defcommand spend (amount what) ((:integer "Amount: $") (:string "For: "))
+ (let ((current (with-budget-file (total "total")
+ (first (read-all-from-file total))))
+ (timestamp (local-time:to-rfc3339-timestring (local-time:now))))
+ (with-budget-file (total "total" :direction :output :if-exists :supersede)
+ (print (+ current amount) total))
+ (with-budget-file (records "records" :direction :output :if-exists :append :if-does-not-exist :create)
+ (print (list timestamp amount what) records))
+ (message "Spent $~D for ~A at ~A" amount what timestamp)))
+
+
;;;; Load ---------------------------------------------------------------------
(load-module "pass")
@@ -251,10 +309,13 @@
(aref *brightness-values* *brightness-index*))
(defun set-brightness (value)
- (run-shell-command
+ (run-and-echo-shell-command
(hostcase
- ((:mobius :alephnull) (format nil "xbacklight -set ~D" value))
- ((:papyrifera) (format nil "xrandr --output eDP --brightness ~D" (/ value 100.0)))
+ ((:mobius) (format nil "xbacklight -set ~D" value))
+ ((:papyrifera :alephnull) (format nil "xrandr --output ~A --brightness ~D"
+ (hostcase (:papyrifera "eDP")
+ (:alephnull "eDP-1"))
+ (/ value 100.0)))
(t (message "Not sure how to set brightness on this machine.")))))
(defun rotate-brightness (delta)
@@ -262,6 +323,7 @@
(mod+ *brightness-index* delta (length *brightness-values*)))
(set-brightness (brightness)))
+
(defcommand rotate-brightness-up () ()
(rotate-brightness 1))
@@ -311,8 +373,8 @@
(defcommand screen-laptop () ()
(only)
- (loop :with laptop = "eDP1"
- :with extern = "DP1"
+ (loop :with laptop = "eDP-1"
+ :with extern = "DP-1"
:for (output commands) :in `((,laptop ("--auto"))
(,laptop ("--primary"))
(,extern ("--off")))
@@ -320,14 +382,14 @@
(defcommand screen-external () ()
(only)
- (loop :with laptop = "eDP1"
- :with extern = "DP1"
+ (loop :with laptop = "eDP-1"
+ :with extern = "DP-1"
:for (output commands) :in `(
- (,laptop ("--off"))
+ ;; (,laptop ("--off"))
(,extern ("--auto"))
(,extern ("--primary"))
- ;; (,laptop ("--auto"))
- ;; (,laptop ("--right-of" ,extern))
+ (,laptop ("--auto"))
+ (,laptop ("--left-of" ,extern))
)
:do (uiop:run-program `("xrandr" "--output" ,output ,@commands))))
@@ -369,7 +431,7 @@
((:alephnull :mobius :papyrifera)
(run-shell-command "exec lock-screen")
(run-shell-command "systemctl suspend"))
- (t (message "Not sleeping this machine for safety.."))))
+ (t (message "Not sleeping this machine for safety."))))
(defcommand copy-clhs-url (s)
((:string "Symbol: "))
@@ -378,25 +440,30 @@
(defcommand describe-window () ()
(show-window-properties))
-(defcommand unfuck-zoom-link () ()
- (let ((url (pbpaste)))
- (ppcre:register-groups-bind
- (meeting-id meeting-pass)
- ("^https://[a-zA-Z0-9]+[.]zoom[.]us/j/(\\d+)[?]pwd=([A-Za-z0-9]+)$" url)
- (pbcopy meeting-id)
- (message "Zoom meeting ID copied.")
- (bt:make-thread (lambda ()
- (sleep 3)
- (pbcopy meeting-pass)
- (message "Zoom meeting password copied.")
- (sleep 5)
- (pbcopy ""))
- :name "Zoom Link Defuckulator")
- (return-from unfuck-zoom-link))
- (message "Clipboard doesn't seem to be a Zoom link.")))
+(defcommand rain () ()
+ (_ '("/home/sjl/src/dotfiles/lisp/bin/weather" "-H" "36")
+ (losh:sh _ :result-type 'list)
+ (mapcar (lambda (line) (ppcre:regex-replace " 1[0-9]:00 " line "^6\\&^*")) _)
+ (message "~{~A~^~%~}" _)))
+
+(defcommand mark (thing) ((:string "Mark: "))
+ (run-shell-command (format nil "mark ~A" thing)))
-(defcommand rain () ()
- (message (run-shell-command "weather -H 36" t)))
+(defcommand toggle-zoom-mute () ()
+ (when-let-window (win "^Zoom Meeting.*")
+ ;; Zoom stupidly won't accept the shortcut unless it's in focus
+ (unless (eql (window-group win) (current-group))
+ ;; jesus christ stump just export switch-to-group come on
+ (gselect (princ-to-string (group-number (window-group win)))))
+ (focus-window win t)
+ (meta (kbd "M-a"))))
+
+(defcommand end-zoom () ()
+ (when-let-window (win "^Zoom Meeting.*")
+ (kill-window win))
+ (sleep 2)
+ (when-let-window (win "^Zoom -.*")
+ (kill-window win)))
;;;; Terminal Fonts -----------------------------------------------------------
@@ -408,8 +475,8 @@
(read f))
11)))
-(defparameter *terminal-font-size* (if (probe-file "~/.terminal-font")
- (with-open-file (f "~/.terminal-font")
+(defparameter *terminal-font-size* (if (probe-file "/home/sjl/.terminal-font")
+ (with-open-file (f "/home/sjl/.terminal-font")
(read f))
11))
@@ -427,6 +494,9 @@
;;;; Clipboard/Data Generation ------------------------------------------------
+(load-module "clipboard-history")
+(clipboard-history:start-clipboard-manager)
+
(defcommand generate-random-uuid () ()
(run-shell-command "uuidgen | tr -d '\\n' | ~/src/dotfiles/bin/pbcopy")
(message "Copied random UUID to clipboard."))
@@ -453,7 +523,7 @@
(run-shell-command "open $HOME"))
(defcommand browser () ()
- (run-or-raise "firefox" '(:class "Firefox")))
+ (run-or-raise "firefox" '(:class "firefox")))
(defcommand vlc () ()
(run-or-raise "vlc" '(:class "vlc")))
@@ -465,8 +535,8 @@
(run-or-raise "gcontrol" '(:class "Gnome-control-center")))
(defcommand zoom () ()
- (when-let ((window (find-window `(:title ,(ppcre:create-scanner "^Zoom Meeting.*")))))
- (focus-window window t)))
+ (when-let-window (w "^Zoom Meeting.*")
+ (focus-window w t)))
;;;; Timers -------------------------------------------------------------------
@@ -507,6 +577,65 @@
(run-shell-command (format nil "tea ~D" seconds)))
+;;;; Isk ----------------------------------------------------------------------
+(defcommand send-key (key &optional (win (current-window))) (:key)
+ "Send key press and key release events for KEY to window WIN."
+ ;; from https://github.com/alezost/stumpwm-config/blob/master/utils.lisp
+ (let ((xwin (window-xwin win)))
+ (multiple-value-bind (code state) (stumpwm::key-to-keycode+state key)
+ (flet ((send (event)
+ (xlib:send-event xwin event (xlib:make-event-mask event)
+ :display *display*
+ :root (screen-root (window-screen win))
+ :x 0 :y 0 :root-x 0 :root-y 0
+ :window xwin :event-window xwin
+ :code code
+ :state state)))
+ (send :key-press)
+ (send :key-release)
+ (xlib:display-finish-output *display*)))))
+
+(defun send-keys (keys &key (win (current-window)) (sleep 0))
+ (dolist (k keys)
+ (send-key (kbd k) win)
+ (sleep sleep)))
+
+(defmacro defmultikey (name key compose-keys)
+ ;; Unfortunately we can't reliably autogen the name with something like
+ ;; (symb 'mk- compose-key) here because things like đ (th) and Đ (TH) would
+ ;; case fold to the same name.
+ `(progn
+ (defcommand ,name () ()
+ (send-keys '("Multi_key" ,@(map 'list #'string compose-keys))))
+ (define-key *top-map*
+ (kbd ,key) ,(string name))))
+
+(defmacro defmultikeys (&rest bindings)
+ `(progn ,@(loop for binding :in bindings :collect `(defmultikey ,@binding))))
+
+(defmultikeys
+ (isk-l-á "M-a" "'a")
+ (isk-u-Á "M-A" "'A")
+ (isk-l-é "M-e" "'e")
+ (isk-u-É "M-E" "'E")
+ (isk-l-í "M-i" "'i")
+ (isk-u-Í "M-I" "'I")
+ (isk-l-ó "M-o" "'o")
+ (isk-u-Ó "M-O" "'O")
+ (isk-l-ö "M-m" "\"o")
+ (isk-u-Ö "M-M" "\"O")
+ (isk-l-ú "M-u" "'u")
+ (isk-u-Ú "M-U" "'U")
+ (isk-l-ý "M-y" "'y")
+ (isk-u-Ý "M-Y" "'Y")
+ (isk-l-þ "M-t" "th")
+ (isk-u-Þ "M-T" "TH")
+ (isk-l-đ "M-d" "dh")
+ (isk-u-Đ "M-D" "DH")
+ (isk-l-æ "M-h" "ae")
+ (isk-u-Æ "M-H" "AE"))
+
+
;;;; Key Mapping --------------------------------------------------------------
;;; Conventions:
;;;
@@ -527,16 +656,20 @@
(define-top-keys ;; miscellaneous
("H-m" "terminal")
+ ("H-M" "mark")
("H-SunPageUp" "st-font-up")
("H-SunPageDown" "st-font-down")
("H-Home" "st-font-reset")
("H-\\" "pass-personal")
("H-|" "generate-password")
("H-b" "browser")
- ("H-B" "exec firefox")
("H-O" "spotify")
("H-o" "files")
("H-z" "zoom")
+ ("H-Z" "toggle-zoom-mute")
+ ("C-H-Z" "end-zoom")
+ ("F26" "prev")
+ ("S-F26" "next")
("H-q" "exec lock-screen")
("H-y" "screenshot")
("H-g" "gcontrol")
@@ -544,13 +677,17 @@
("H-F" "delete-fucked-screenshot")
("H-R" "loadrc")
("H-r" "rain")
- ("H-V" "vlc"))
+ ("H-V" "vlc")
+ ("H-4" "budget")
+ ("H-$" "spend")
+ )
(define-top-keys ;; clipboard
+ ("H-c" "show-clipboard-history")
+ ("H-C" "clear-clipboard-history")
("H-u" "generate-random-uuid")
- ("H-U" "bee-movie-script")
- ("M-H-u" "urlize-jira-issue")
- ("H-Z" "unfuck-zoom-link"))
+ ("H-B" "bee-movie-script")
+ ("M-H-u" "urlize-jira-issue"))
(define-top-keys ;; movement
("H-h" "move-focus* left")
@@ -563,12 +700,13 @@
("H-K" "move-window up")
("H-L" "move-window right")
- ("H-1" "gmove 1")
- ("H-2" "gmove 2")
- ("H-3" "gmove 3")
- ("H-4" "gmove 4")
- ("H-5" "gmove 5")
- ("H-6" "gmove 6")
+ ("H-1" "gselect 1")
+ ("H-2" "gselect 2")
+ ("H-3" "gselect 3")
+
+ ("H-!" "gmove 1")
+ ("H-@" "gmove 2")
+ ("H-#" "gmove 3")
("C-H-H" "exchange-direction left")
("C-H-J" "exchange-direction down")
@@ -608,6 +746,7 @@
("H-F8" "screen-external"))
(define-top-keys ;; layout
+ ("s-H-t" "restore-from-file thirds")
("s-H-m" "restore-from-file dev")
("s-H-s" "restore-from-file streaming")
("s-H-w" "restore-from-file work")
@@ -627,7 +766,7 @@
(define-top-keys ;; stump
("Pause" "terminal") ; jesus christ
- ("H-F9" "sleep-machine")
+ ("H-F9" "sleep-machine")
("H-F10" "toggle-stumptray")
("H-F11" "toggle-current-mode-line")
("H-F12" "refresh-heads"))
@@ -641,7 +780,7 @@
("C-=" . "S-C-SunPageUp")
("C--" . "S-C-SunPageDown")
("C-0" . "S-C-Home"))
- ("(Firefox|Google-chrome|Chromium-browser)"
+ ("(firefox|Google-chrome|Chromium-browser)"
("s-1" . "C-S-Tab")
("s-2" . "C-Tab")
("C-a" . "Home")
@@ -651,7 +790,6 @@
;; interest of not having a random collection of bookmarks grow over time,
;; I'll just add a mapping to compensate for my stupid brain.
("C-d" . "C-w")
- ("C-w" . "C-BackSpace")
;; todo debug why this breaks a really fast C-a-k roll
;; ("C-a" . "Home")
;; ("C-e" . "End")
@@ -673,36 +811,101 @@
("s-v" . "C-v"))))
+;;;; Sensors ------------------------------------------------------------------
+(defun ? (obj &rest keys)
+ (if (null keys)
+ obj
+ (apply #'? (etypecase obj
+ (hash-table (gethash (first keys) obj)))
+ (rest keys))))
+
+(defun parse-sensors ()
+ ;; sensors -j is stupid and will output errors before the actual output on
+ ;; standard out, instead of putting them on standard err like a reasonable
+ ;; program, e.g.:
+ ;;
+ ;; ERROR: Can't get value of subfeature temp1_input: Can't read
+ ;; {
+ ;; "iwlwifi_1-virtual-0":{ … },
+ ;; …
+ ;;
+ ;; So we'll have to drop the `ERROR` lines before we can get to the actual
+ ;; goddamn JSON. UNIX programs are so great.
+ (let ((s (losh:sh '("sensors" "-j") :result-type 'stream)))
+ (loop :while (char= #\E (peek-char nil s)) :do (read-line s))
+ (jarl:read t s)))
+
+(defparameter *sensors-refresh-delay* 5.0 "How long between sensor refreshes (in seconds).")
+(defparameter *sensors-next-refresh* nil)
+(defparameter *sensors-cache* nil)
+
+(defun sensors% (&aux (sensors (parse-sensors)))
+ (hostcase
+ (:ouroboros (format nil "[CPU ~D°C] [GPU ~D°C ~D°C ~D°C]"
+ (round (? sensors "nct6779-isa-0290" "CPUTIN" "temp2_input"))
+ (round (? sensors "amdgpu-pci-4500" "edge" "temp1_input"))
+ (round (? sensors "amdgpu-pci-4500" "junction" "temp2_input"))
+ (round (? sensors "amdgpu-pci-4500" "mem" "temp3_input"))))
+ (t "?")))
+
+(defun sensors (&aux (now (get-internal-real-time)))
+ (if (or (null *sensors-next-refresh*)
+ (>= now *sensors-next-refresh*))
+ (setf *sensors-next-refresh* (+ now (* internal-time-units-per-second *sensors-refresh-delay*))
+ *sensors-cache* (sensors%))
+ *sensors-cache*))
+
+(defun sensors-modeline (ml)
+ (declare (ignore ml))
+ (sensors))
+
+(add-screen-mode-line-formatter #\S #'sensors-modeline)
+
+
;;;; Modeline -----------------------------------------------------------------
+(load-module "battery-portable")
+(load-module "cpu")
+(load-module "hostname")
+(load-module "mem")
+
(defun ensure-mode-line ()
(when (not (stumpwm::head-mode-line (current-head)))
(toggle-mode-line (current-screen) (current-head))))
+
(defun configure-modeline ()
(setf
*time-modeline-string*
"%a %b %e %H:%M"
+ cpu::*cpu-usage-modeline-fmt*
+ "^[~A~3D%^]"
+
+ cpu::*cpu-modeline-fmt*
+ "[%c] [%f]"
+
+ mem::*mem-modeline-fmt*
+ "%b"
+
*screen-mode-line-format*
(append
- (list "[^B%n^b] %W^>")
+ (list "[^B%n^b@%h] %W^>")
#+todo-some-day (list ;; "(V "
;; ;; '(:eval (volume))
;; ")"
" ")
+ ;; battery and brightness for laptops
(hostcase
((:mobius :alephnull :papyrifera)
- '("(B "
- (:eval (princ-to-string (battery)))
- ")"
+ '("(B %B)"
" (BR "
(:eval (princ-to-string (brightness)))
"%)")))
- ;; time and tray
- (list " %d %T")))
+ ;; temp, cpu, mem, time, tray
+ (list "(TEMP %S) (CPU %C) (MEM %M) %d %T")))
(setf *mode-line-timeout* 10)
(setf *mode-line-background-color* "#111111")
@@ -724,15 +927,14 @@
;;;; Startup ------------------------------------------------------------------
-;; (defvar *network-manager*
- ;; (run-shell-command "nm-applet --sm-disable"))
-
;; (defvar *dropbox*
;; (run-shell-command "~/.dropbox-dist/dropboxd"))
(defvar *dunst*
(run-shell-command "/usr/bin/dunst -conf ~/.dunstrc"))
+(when (probe-file "/home/sjl/.stumpwmrc.local")
+ (load "/home/sjl/.stumpwmrc.local"))
+
+
#;;; Scratch ------------------------------------------------------------------
-(message (format nil "~S" (remove #\newline (run-shell-command "acpi" t))))
-
--- a/tmux/tmux.conf Fri Apr 14 15:01:35 2023 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,130 +0,0 @@
-# Use something easier to type as the prefix.
-set -g prefix C-f
-unbind C-b
-bind C-f send-prefix
-
-# Relax!
-set -sg escape-time 0
-set -sg repeat-time 600
-
-# Shut up.
-#set -g quiet on
-
-# Focus
-set -g focus-events
-
-# Mouse
-set -g mouse on
-
-# Less stretching to get to the first item.
-set -g base-index 1
-setw -g pane-base-index 1
-
-# Reload the config.
-bind R source-file ~/.tmux.conf \; display "Reloaded ~/.tmux.conf"
-
-# Rename session.
-bind r command-prompt -I "#S" "rename-session '%%'"
-
-# Saner splitting.
-bind v split-window -h -c '#{pane_current_path}'
-bind s split-window -v -c '#{pane_current_path}'
-bind S choose-session
-
-# Pane movement
-bind h select-pane -L
-bind j select-pane -D
-bind k select-pane -U
-bind l select-pane -R
-
-# DVTM style pane selection
-# bind 1 select-pane -t 1
-# bind 2 select-pane -t 2
-# bind 3 select-pane -t 3
-# bind 4 select-pane -t 4
-# bind 5 select-pane -t 5
-# bind 6 select-pane -t 6
-# bind 7 select-pane -t 7
-# bind 8 select-pane -t 8
-# bind 9 select-pane -t 9
-
-# Layouts
-# set -g main-pane-width 260
-# bind M select-layout main-vertical
-# bind E select-layout even-horizontal
-
-# Pane resizing
-bind -r C-h resize-pane -L 5
-bind -r C-j resize-pane -D 5
-bind -r C-k resize-pane -U 5
-bind -r C-l resize-pane -R 5
-
-# Window movement
-# Only really makes sense if you have your parens bound to shifts like me.
-bind -r ( select-window -t :-
-bind -r ) select-window -t :+
-bind-key -r H swap-window -t -1
-bind-key -r L swap-window -t +1
-bind m command-prompt "move-window -t %%"
-bind - choose-tree
-
-# 256 colors please
-set -g default-terminal "screen-256color"
-# set -g default-terminal "tmux-256color"
-
-# Bad Wolf
-set -g status-fg white
-set -g status-bg colour234
-set -g window-status-activity-attr bold
-set -g pane-border-fg colour245
-set -g pane-active-border-fg colour39
-set -g message-fg colour16
-set -g message-bg colour221
-set -g message-attr bold
-
-# Custom status bar
-# Powerline symbols: ⮂ ⮃ ⮀ ⮁ ⭤
-set -g status-left-length 32
-set -g status-right-length 150
-set -g status-interval 5
-
-set -g status-left '#[fg=colour16,bg=colour254,bold] #S #[fg=colour238,bg=colour234,nobold] '
-
-set -g status-right "#[fg=colour245]#(date -u +%%H:%%M) UTC %d %b #[fg=colour16,bg=colour254,bold] #h "
-
-set -g window-status-format "#[fg=white,bg=colour234] #I #W "
-set -g window-status-current-format "#[fg=colour16,bg=colour39,noreverse,bold] #I #W #[fg=colour39,bg=colour234,nobold] "
-
-# Activity
-setw -g monitor-activity on
-set -g visual-activity off
-
-# Autorename sanely.
-# setw -g automatic-rename on
-
-# Better name management
-bind c new-window -a
-bind , command-prompt "rename-window '%%'"
-bind > run-shell "tmux rename-window `basename #{pane_current_path}`"
-
-# Copy mode
-setw -g mode-keys vi
-bind ` copy-mode
-unbind [
-unbind p
-bind p paste-buffer
-
-bind -T copy-mode-vi 'v' send -X begin-selection
-bind -T copy-mode-vi 'y' send -X copy-pipe-and-cancel pbcopy
-bind -T copy-mode-vi Escape send -X cancel
-bind -T copy-mode-vi V send -X rectangle-toggle
-bind -T copy-mode-vi H send-keys -X start-of-line
-bind -T copy-mode-vi L send-keys -X end-of-line
-bind y run "tmux save-buffer - | xsel --clipboard --input"
-
-# Toggle synchronized panes for the current window
-bind S set synchronize-panes
-
-# Let neovim change the cursor shape
-set -g -a terminal-overrides ',*:Ss=\E[%p1%d q:Se=\E[2 q'
-
--- a/uhk.json Fri Apr 14 15:01:35 2023 -0400
+++ b/uhk.json Fri Jul 07 16:11:02 2023 -0400
@@ -373,7 +373,48 @@
},
{
"id": 2,
- "keyActions": []
+ "keyActions": [
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 76
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 42
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 40
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "leftClick"
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "middleClick"
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "rightClick"
+ }
+ ]
+ },
+ {
+ "id": 4,
+ "keyActions": [
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "leftClick"
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "rightClick"
+ }
+ ]
}
]
},
@@ -660,6 +701,51 @@
},
null
]
+ },
+ {
+ "id": 2,
+ "keyActions": [
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 76
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 42
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 40
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "leftClick"
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "middleClick"
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "rightClick"
+ }
+ ]
+ },
+ {
+ "id": 4,
+ "keyActions": [
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "leftClick"
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "rightClick"
+ }
+ ]
}
]
},
@@ -828,6 +914,51 @@
null,
null
]
+ },
+ {
+ "id": 2,
+ "keyActions": [
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 76
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 42
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 40
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "leftClick"
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "middleClick"
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "rightClick"
+ }
+ ]
+ },
+ {
+ "id": 4,
+ "keyActions": [
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "leftClick"
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "rightClick"
+ }
+ ]
}
]
},
@@ -999,6 +1130,51 @@
},
null
]
+ },
+ {
+ "id": 2,
+ "keyActions": [
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 76
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 42
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 40
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "leftClick"
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "middleClick"
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "rightClick"
+ }
+ ]
+ },
+ {
+ "id": 4,
+ "keyActions": [
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "leftClick"
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "rightClick"
+ }
+ ]
}
]
}
@@ -1358,7 +1534,48 @@
},
{
"id": 2,
- "keyActions": []
+ "keyActions": [
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 76
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 42
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 40
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "leftClick"
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "middleClick"
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "rightClick"
+ }
+ ]
+ },
+ {
+ "id": 4,
+ "keyActions": [
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "leftClick"
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "rightClick"
+ }
+ ]
}
]
},
@@ -1655,6 +1872,51 @@
},
null
]
+ },
+ {
+ "id": 2,
+ "keyActions": [
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 76
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 42
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 40
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "leftClick"
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "middleClick"
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "rightClick"
+ }
+ ]
+ },
+ {
+ "id": 4,
+ "keyActions": [
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "leftClick"
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "rightClick"
+ }
+ ]
}
]
},
@@ -1822,6 +2084,51 @@
null,
null
]
+ },
+ {
+ "id": 2,
+ "keyActions": [
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 76
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 42
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 40
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "leftClick"
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "middleClick"
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "rightClick"
+ }
+ ]
+ },
+ {
+ "id": 4,
+ "keyActions": [
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "leftClick"
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "rightClick"
+ }
+ ]
}
]
},
@@ -1993,6 +2300,51 @@
},
null
]
+ },
+ {
+ "id": 2,
+ "keyActions": [
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 76
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 42
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 40
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "leftClick"
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "middleClick"
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "rightClick"
+ }
+ ]
+ },
+ {
+ "id": 4,
+ "keyActions": [
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "leftClick"
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "rightClick"
+ }
+ ]
}
]
}
@@ -2352,7 +2704,48 @@
},
{
"id": 2,
- "keyActions": []
+ "keyActions": [
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 76
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 42
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 40
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "leftClick"
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "middleClick"
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "rightClick"
+ }
+ ]
+ },
+ {
+ "id": 4,
+ "keyActions": [
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "leftClick"
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "rightClick"
+ }
+ ]
}
]
},
@@ -2639,6 +3032,51 @@
},
null
]
+ },
+ {
+ "id": 2,
+ "keyActions": [
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 76
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 42
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 40
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "leftClick"
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "middleClick"
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "rightClick"
+ }
+ ]
+ },
+ {
+ "id": 4,
+ "keyActions": [
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "leftClick"
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "rightClick"
+ }
+ ]
}
]
},
@@ -2807,6 +3245,51 @@
null,
null
]
+ },
+ {
+ "id": 2,
+ "keyActions": [
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 76
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 42
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 40
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "leftClick"
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "middleClick"
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "rightClick"
+ }
+ ]
+ },
+ {
+ "id": 4,
+ "keyActions": [
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "leftClick"
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "rightClick"
+ }
+ ]
}
]
},
@@ -2978,6 +3461,51 @@
},
null
]
+ },
+ {
+ "id": 2,
+ "keyActions": [
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 76
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 42
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 40
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "leftClick"
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "middleClick"
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "rightClick"
+ }
+ ]
+ },
+ {
+ "id": 4,
+ "keyActions": [
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "leftClick"
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "rightClick"
+ }
+ ]
}
]
}
@@ -3337,7 +3865,48 @@
},
{
"id": 2,
- "keyActions": []
+ "keyActions": [
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 76
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 42
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 40
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "leftClick"
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "middleClick"
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "rightClick"
+ }
+ ]
+ },
+ {
+ "id": 4,
+ "keyActions": [
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "leftClick"
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "rightClick"
+ }
+ ]
}
]
},
@@ -3634,6 +4203,51 @@
},
null
]
+ },
+ {
+ "id": 2,
+ "keyActions": [
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 76
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 42
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 40
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "leftClick"
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "middleClick"
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "rightClick"
+ }
+ ]
+ },
+ {
+ "id": 4,
+ "keyActions": [
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "leftClick"
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "rightClick"
+ }
+ ]
}
]
},
@@ -3801,6 +4415,51 @@
null,
null
]
+ },
+ {
+ "id": 2,
+ "keyActions": [
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 76
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 42
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 40
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "leftClick"
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "middleClick"
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "rightClick"
+ }
+ ]
+ },
+ {
+ "id": 4,
+ "keyActions": [
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "leftClick"
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "rightClick"
+ }
+ ]
}
]
},
@@ -3972,6 +4631,51 @@
},
null
]
+ },
+ {
+ "id": 2,
+ "keyActions": [
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 76
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 42
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 40
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "leftClick"
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "middleClick"
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "rightClick"
+ }
+ ]
+ },
+ {
+ "id": 4,
+ "keyActions": [
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "leftClick"
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "rightClick"
+ }
+ ]
}
]
}
@@ -4331,7 +5035,48 @@
},
{
"id": 2,
- "keyActions": []
+ "keyActions": [
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 76
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 42
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 40
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "leftClick"
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "middleClick"
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "rightClick"
+ }
+ ]
+ },
+ {
+ "id": 4,
+ "keyActions": [
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "leftClick"
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "rightClick"
+ }
+ ]
}
]
},
@@ -4618,6 +5363,51 @@
},
null
]
+ },
+ {
+ "id": 2,
+ "keyActions": [
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 76
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 42
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 40
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "leftClick"
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "middleClick"
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "rightClick"
+ }
+ ]
+ },
+ {
+ "id": 4,
+ "keyActions": [
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "leftClick"
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "rightClick"
+ }
+ ]
}
]
},
@@ -4786,6 +5576,51 @@
null,
null
]
+ },
+ {
+ "id": 2,
+ "keyActions": [
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 76
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 42
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 40
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "leftClick"
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "middleClick"
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "rightClick"
+ }
+ ]
+ },
+ {
+ "id": 4,
+ "keyActions": [
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "leftClick"
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "rightClick"
+ }
+ ]
}
]
},
@@ -4951,6 +5786,51 @@
},
null
]
+ },
+ {
+ "id": 2,
+ "keyActions": [
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 76
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 42
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 40
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "leftClick"
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "middleClick"
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "rightClick"
+ }
+ ]
+ },
+ {
+ "id": 4,
+ "keyActions": [
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "leftClick"
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "rightClick"
+ }
+ ]
}
]
}
@@ -5310,7 +6190,48 @@
},
{
"id": 2,
- "keyActions": []
+ "keyActions": [
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 76
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 42
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 40
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "leftClick"
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "middleClick"
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "rightClick"
+ }
+ ]
+ },
+ {
+ "id": 4,
+ "keyActions": [
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "leftClick"
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "rightClick"
+ }
+ ]
}
]
},
@@ -5607,6 +6528,51 @@
},
null
]
+ },
+ {
+ "id": 2,
+ "keyActions": [
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 76
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 42
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 40
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "leftClick"
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "middleClick"
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "rightClick"
+ }
+ ]
+ },
+ {
+ "id": 4,
+ "keyActions": [
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "leftClick"
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "rightClick"
+ }
+ ]
}
]
},
@@ -5774,6 +6740,51 @@
null,
null
]
+ },
+ {
+ "id": 2,
+ "keyActions": [
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 76
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 42
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 40
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "leftClick"
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "middleClick"
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "rightClick"
+ }
+ ]
+ },
+ {
+ "id": 4,
+ "keyActions": [
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "leftClick"
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "rightClick"
+ }
+ ]
}
]
},
@@ -5939,6 +6950,51 @@
},
null
]
+ },
+ {
+ "id": 2,
+ "keyActions": [
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 76
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 42
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 40
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "leftClick"
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "middleClick"
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "rightClick"
+ }
+ ]
+ },
+ {
+ "id": 4,
+ "keyActions": [
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "leftClick"
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "rightClick"
+ }
+ ]
}
]
}
@@ -6286,7 +7342,7 @@
{
"keyActionType": "keystroke",
"type": "basic",
- "scancode": 101
+ "scancode": 70
},
{
"keyActionType": "switchLayer",
@@ -6298,7 +7354,50 @@
},
{
"id": 2,
- "keyActions": []
+ "keyActions": [
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "rightClick"
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "leftClick"
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 108
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 104
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "middleClick"
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 105
+ }
+ ]
+ },
+ {
+ "id": 4,
+ "keyActions": [
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 106
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 107
+ }
+ ]
}
]
},
@@ -6428,7 +7527,11 @@
"modifierMask": 32
},
null,
- null,
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 57
+ },
null,
{
"keyActionType": "switchLayer",
@@ -6492,7 +7595,7 @@
},
{
"keyActionType": "switchKeymap",
- "keymapAbbreviation": "COL"
+ "keymapAbbreviation": "WIN"
},
{
"keyActionType": "keystroke",
@@ -6612,6 +7715,52 @@
},
null
]
+ },
+ {
+ "id": 2,
+ "keyActions": [
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "rightClick"
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "leftClick"
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 40
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 104
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "middleClick"
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "rightClick"
+ }
+ ]
+ },
+ {
+ "id": 4,
+ "keyActions": [
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 106
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 107
+ }
+ ]
}
]
},
@@ -6812,6 +7961,52 @@
null,
null
]
+ },
+ {
+ "id": 2,
+ "keyActions": [
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "rightClick"
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "leftClick"
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 40
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 104
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "middleClick"
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "rightClick"
+ }
+ ]
+ },
+ {
+ "id": 4,
+ "keyActions": [
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 106
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 107
+ }
+ ]
}
]
},
@@ -6982,6 +8177,1279 @@
},
null
]
+ },
+ {
+ "id": 2,
+ "keyActions": [
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "rightClick"
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "leftClick"
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 40
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 104
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "middleClick"
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "rightClick"
+ }
+ ]
+ },
+ {
+ "id": 4,
+ "keyActions": [
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 106
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 107
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "isDefault": false,
+ "abbreviation": "WIN",
+ "name": "SJL Windows",
+ "description": "My personal mappings.",
+ "layers": [
+ {
+ "modules": [
+ {
+ "id": 0,
+ "keyActions": [
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 36
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 37
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 38
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 39
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 45
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 46
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 42
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 24
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 12
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 18
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 19
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 47
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 48
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 49
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 28
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 13
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 14
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 15
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 51
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 52
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 40
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 11
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 17
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 16
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 54
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 55
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 56
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "modifierMask": 32
+ },
+ null,
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 44
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 72
+ },
+ {
+ "keyActionType": "switchLayer",
+ "layer": "mod",
+ "switchLayerMode": "hold"
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "modifierMask": 64
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "modifierMask": 8
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "modifierMask": 1
+ }
+ ]
+ },
+ {
+ "id": 1,
+ "keyActions": [
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 53
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 30
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 31
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 32
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 33
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 34
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 35
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 43
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 20
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 26
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 8
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 21
+ },
+ null,
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 23
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 41,
+ "secondaryRoleAction": "leftCtrl"
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 4
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 22
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 7
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 9
+ },
+ null,
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 10
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "modifierMask": 2
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 100
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 29
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 27
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 6
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 25
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 5
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "modifierMask": 1
+ },
+ {
+ "keyActionType": "switchLayer",
+ "layer": "mouse",
+ "switchLayerMode": "toggle"
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "modifierMask": 8
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "modifierMask": 4
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 70
+ },
+ {
+ "keyActionType": "switchLayer",
+ "layer": "mod",
+ "switchLayerMode": "hold"
+ },
+ null
+ ]
+ },
+ {
+ "id": 2,
+ "keyActions": [
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 104
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 105
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 106
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "leftClick"
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "middleClick"
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "rightClick"
+ }
+ ]
+ },
+ {
+ "id": 4,
+ "keyActions": [
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "leftClick"
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "rightClick"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "modules": [
+ {
+ "id": 0,
+ "keyActions": [
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 64
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 65
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 66
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 67
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 68
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 69
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 76
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 78
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 75
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 77
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 76
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 70
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 71
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 108
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 74
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 81
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 82
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 79
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 73
+ },
+ null,
+ null,
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 80
+ },
+ {
+ "keyActionType": "playMacro",
+ "macroIndex": 2
+ },
+ {
+ "keyActionType": "playMacro",
+ "macroIndex": 3
+ },
+ {
+ "keyActionType": "playMacro",
+ "macroIndex": 4
+ },
+ {
+ "keyActionType": "playMacro",
+ "macroIndex": 5
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 101
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "modifierMask": 32
+ },
+ null,
+ null,
+ null,
+ {
+ "keyActionType": "switchLayer",
+ "layer": "mod",
+ "switchLayerMode": "hold"
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "modifierMask": 64
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "modifierMask": 8
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "modifierMask": 1
+ }
+ ]
+ },
+ {
+ "id": 1,
+ "keyActions": [
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 41
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 58
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 59
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 60
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 61
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 62
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 63
+ },
+ {
+ "keyActionType": "switchKeymap",
+ "keymapAbbreviation": "SJL"
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 41
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 75,
+ "modifierMask": 1
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 23,
+ "modifierMask": 1
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 78,
+ "modifierMask": 1
+ },
+ null,
+ null,
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 57
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 57
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 80,
+ "modifierMask": 5
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 43,
+ "modifierMask": 4
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 79,
+ "modifierMask": 5
+ },
+ null,
+ null,
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "modifierMask": 2
+ },
+ null,
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 29,
+ "modifierMask": 8
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 27,
+ "modifierMask": 8
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 6,
+ "modifierMask": 8
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 25,
+ "modifierMask": 8
+ },
+ null,
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "modifierMask": 1
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "modifierMask": 8
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "modifierMask": 8
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "modifierMask": 4
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "modifierMask": 1
+ },
+ {
+ "keyActionType": "switchLayer",
+ "layer": "mod",
+ "switchLayerMode": "hold"
+ },
+ null
+ ]
+ },
+ {
+ "id": 2,
+ "keyActions": [
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 76
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 42
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 40
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "leftClick"
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "middleClick"
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "rightClick"
+ }
+ ]
+ },
+ {
+ "id": 4,
+ "keyActions": [
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "leftClick"
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "rightClick"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "modules": [
+ {
+ "id": 0,
+ "keyActions": [
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 42
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 84
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 85
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 86
+ },
+ null,
+ null,
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 42
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 95
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 37
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 97
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 87
+ },
+ null,
+ null,
+ null,
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 83
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 92
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 93
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 94
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 51
+ },
+ null,
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 88
+ },
+ null,
+ null,
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 89
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 90
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 91
+ },
+ null,
+ null,
+ null,
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 44
+ },
+ null,
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 98
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 99
+ },
+ null,
+ null
+ ]
+ },
+ {
+ "id": 1,
+ "keyActions": [
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 43
+ },
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 57
+ },
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "modifierMask": 2
+ },
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "modifierMask": 1
+ },
+ null,
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "modifierMask": 8
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "modifierMask": 4
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "modifierMask": 1
+ },
+ null,
+ null
+ ]
+ },
+ {
+ "id": 2,
+ "keyActions": [
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 76
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 42
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 40
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "leftClick"
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "middleClick"
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "rightClick"
+ }
+ ]
+ },
+ {
+ "id": 4,
+ "keyActions": [
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "leftClick"
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "rightClick"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "modules": [
+ {
+ "id": 0,
+ "keyActions": [
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "scrollDown"
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "scrollUp"
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "scrollRight"
+ },
+ null,
+ null,
+ null,
+ null,
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "scrollLeft"
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 81
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 82
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 79
+ },
+ null,
+ null,
+ null,
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 80
+ },
+ null,
+ null,
+ null,
+ null,
+ null,
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "modifierMask": 32
+ },
+ null,
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "leftClick"
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "rightClick"
+ },
+ null,
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "modifierMask": 64
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "modifierMask": 8
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "modifierMask": 1
+ }
+ ]
+ },
+ {
+ "id": 1,
+ "keyActions": [
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 57
+ },
+ null,
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 27
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 24
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 19
+ },
+ null,
+ null,
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "modifierMask": 2
+ },
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ {
+ "keyActionType": "switchLayer",
+ "layer": "mouse",
+ "switchLayerMode": "toggle"
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "modifierMask": 8
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "modifierMask": 4
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "modifierMask": 1
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "accelerate"
+ },
+ null
+ ]
+ },
+ {
+ "id": 2,
+ "keyActions": [
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 76
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 42
+ },
+ {
+ "keyActionType": "keystroke",
+ "type": "basic",
+ "scancode": 40
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "leftClick"
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "middleClick"
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "rightClick"
+ }
+ ]
+ },
+ {
+ "id": 4,
+ "keyActions": [
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "leftClick"
+ },
+ {
+ "keyActionType": "mouse",
+ "mouseAction": "rightClick"
+ }
+ ]
}
]
}
@@ -7027,6 +9495,110 @@
{
"isLooped": false,
"isPrivate": true,
+ "name": "TE:C Emote 1",
+ "macroActions": [
+ {
+ "macroActionType": "key",
+ "action": "press",
+ "type": "basic",
+ "scancode": 41
+ },
+ {
+ "macroActionType": "key",
+ "action": "press",
+ "type": "basic",
+ "scancode": 80,
+ "modifierMask": 4
+ },
+ {
+ "macroActionType": "key",
+ "action": "release",
+ "type": "basic",
+ "scancode": 41
+ }
+ ]
+ },
+ {
+ "isLooped": false,
+ "isPrivate": true,
+ "name": "TE:C Emote 2",
+ "macroActions": [
+ {
+ "macroActionType": "key",
+ "action": "press",
+ "type": "basic",
+ "scancode": 41
+ },
+ {
+ "macroActionType": "key",
+ "action": "press",
+ "type": "basic",
+ "scancode": 79,
+ "modifierMask": 4
+ },
+ {
+ "macroActionType": "key",
+ "action": "release",
+ "type": "basic",
+ "scancode": 41
+ }
+ ]
+ },
+ {
+ "isLooped": false,
+ "isPrivate": true,
+ "name": "TE:C Emote 3",
+ "macroActions": [
+ {
+ "macroActionType": "key",
+ "action": "press",
+ "type": "basic",
+ "scancode": 41
+ },
+ {
+ "macroActionType": "key",
+ "action": "press",
+ "type": "basic",
+ "scancode": 82,
+ "modifierMask": 4
+ },
+ {
+ "macroActionType": "key",
+ "action": "release",
+ "type": "basic",
+ "scancode": 41
+ }
+ ]
+ },
+ {
+ "isLooped": false,
+ "isPrivate": true,
+ "name": "TE:C Emote 4",
+ "macroActions": [
+ {
+ "macroActionType": "key",
+ "action": "press",
+ "type": "basic",
+ "scancode": 41
+ },
+ {
+ "macroActionType": "key",
+ "action": "press",
+ "type": "basic",
+ "scancode": 81,
+ "modifierMask": 4
+ },
+ {
+ "macroActionType": "key",
+ "action": "release",
+ "type": "basic",
+ "scancode": 41
+ }
+ ]
+ },
+ {
+ "isLooped": false,
+ "isPrivate": true,
"name": "Type Silent Bob's address",
"macroActions": [
{
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/userContent.css Fri Jul 07 16:11:02 2023 -0400
@@ -0,0 +1,4 @@
+@-moz-document domain(sumologic.com) {
+ table#search_query_results_view_table td.message { padding: 0 !important; }
+ table#search_query_results_view_table td.offset { padding: 0 !important; }
+}
--- a/vim/autoload/Powerline/Colorschemes/badwolf.vim Fri Apr 14 15:01:35 2023 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,166 +0,0 @@
-call Pl#Hi#Allocate({
- \ 'black' : 16,
- \ 'white' : 231,
- \
- \ 'darkestgreen' : 22,
- \ 'darkgreen' : 28,
- \ 'mediumgreen' : 70,
- \ 'brightgreen' : 148,
- \
- \ 'darkestcyan' : 23,
- \ 'mediumcyan' : 117,
- \
- \ 'darkestblue' : 24,
- \ 'darkblue' : 31,
- \
- \ 'darkestred' : 52,
- \ 'darkred' : 88,
- \ 'mediumred' : 124,
- \ 'brightred' : 160,
- \ 'brightestred' : 196,
- \
- \ 'darkestpurple' : 55,
- \ 'mediumpurple' : 98,
- \ 'brightpurple' : 189,
- \
- \ 'brightorange' : 208,
- \ 'brightestorange': 214,
- \
- \ 'gray0' : 234,
- \ 'gray1' : 235,
- \ 'gray2' : 236,
- \ 'gray3' : 238,
- \ 'gray4' : 240,
- \ 'gray5' : 241,
- \ 'gray6' : 244,
- \ 'gray7' : 245,
- \ 'gray8' : 247,
- \ 'gray9' : 250,
- \ 'gray10' : 252,
- \ })
-
-let g:Powerline#Colorschemes#badwolf#colorscheme = Pl#Colorscheme#Init([
- \ Pl#Hi#Segments(['SPLIT'], {
- \ 'n': ['white', 'gray2'],
- \ 'N': ['white', 'gray1'],
- \ 'i': ['white', 'darkestblue'],
- \ }),
- \
- \ Pl#Hi#Segments(['mode_indicator'], {
- \ 'n': ['darkestgreen', 'brightgreen', ['bold']],
- \ 'i': ['darkestcyan', 'white', ['bold']],
- \ 'v': ['darkred', 'brightorange', ['bold']],
- \ 'r': ['white', 'brightred', ['bold']],
- \ 's': ['white', 'gray5', ['bold']],
- \ }),
- \
- \ Pl#Hi#Segments(['branch', 'scrollpercent', 'raw', 'filesize'], {
- \ 'n': ['gray9', 'gray4'],
- \ 'N': ['gray4', 'gray2'],
- \ 'i': ['mediumcyan', 'darkblue'],
- \ }),
- \
- \ Pl#Hi#Segments(['fileinfo', 'filename'], {
- \ 'n': ['white', 'gray4', ['bold']],
- \ 'N': ['gray7', 'gray2', ['bold']],
- \ 'i': ['white', 'darkblue', ['bold']],
- \ }),
- \
- \ Pl#Hi#Segments(['fileinfo.filepath'], {
- \ 'n': ['gray10'],
- \ 'N': ['gray6'],
- \ 'i': ['mediumcyan'],
- \ }),
- \
- \ Pl#Hi#Segments(['static_str'], {
- \ 'n': ['white', 'gray4'],
- \ 'N': ['gray7', 'gray1'],
- \ 'i': ['white', 'darkblue'],
- \ }),
- \
- \ Pl#Hi#Segments(['fileinfo.flags'], {
- \ 'n': ['brightestred', ['bold']],
- \ 'N': ['darkred'],
- \ 'i': ['brightestred', ['bold']],
- \ }),
- \
- \ Pl#Hi#Segments(['currenttag', 'fullcurrenttag', 'fileformat', 'fileencoding', 'pwd', 'filetype', 'rvm:string', 'rvm:statusline', 'virtualenv:statusline', 'charcode', 'currhigroup'], {
- \ 'n': ['gray8', 'gray2'],
- \ 'i': ['mediumcyan', 'darkestblue'],
- \ }),
- \
- \ Pl#Hi#Segments(['lineinfo'], {
- \ 'n': ['gray2', 'gray10', ['bold']],
- \ 'N': ['gray7', 'gray3', ['bold']],
- \ 'i': ['darkestcyan', 'mediumcyan', ['bold']],
- \ }),
- \
- \ Pl#Hi#Segments(['errors'], {
- \ 'n': ['brightestorange', 'gray2', ['bold']],
- \ 'i': ['brightestorange', 'darkestblue', ['bold']],
- \ }),
- \
- \ Pl#Hi#Segments(['lineinfo.line.tot'], {
- \ 'n': ['gray6'],
- \ 'N': ['gray5'],
- \ 'i': ['darkestcyan'],
- \ }),
- \
- \ Pl#Hi#Segments(['paste_indicator', 'ws_marker'], {
- \ 'n': ['white', 'brightred', ['bold']],
- \ }),
- \
- \ Pl#Hi#Segments(['gundo:static_str.name', 'command_t:static_str.name'], {
- \ 'n': ['white', 'mediumred', ['bold']],
- \ 'N': ['brightred', 'darkestred', ['bold']],
- \ }),
- \
- \ Pl#Hi#Segments(['gundo:static_str.buffer', 'command_t:raw.line'], {
- \ 'n': ['white', 'darkred'],
- \ 'N': ['brightred', 'darkestred'],
- \ }),
- \
- \ Pl#Hi#Segments(['gundo:SPLIT', 'command_t:SPLIT'], {
- \ 'n': ['white', 'darkred'],
- \ 'N': ['white', 'darkestred'],
- \ }),
- \
- \ Pl#Hi#Segments(['lustyexplorer:static_str.name', 'minibufexplorer:static_str.name', 'nerdtree:raw.name', 'tagbar:static_str.name'], {
- \ 'n': ['white', 'mediumgreen', ['bold']],
- \ 'N': ['mediumgreen', 'darkestgreen', ['bold']],
- \ }),
- \
- \ Pl#Hi#Segments(['lustyexplorer:static_str.buffer', 'tagbar:static_str.buffer'], {
- \ 'n': ['brightgreen', 'darkgreen'],
- \ 'N': ['mediumgreen', 'darkestgreen'],
- \ }),
- \
- \ Pl#Hi#Segments(['lustyexplorer:SPLIT', 'minibufexplorer:SPLIT', 'nerdtree:SPLIT', 'tagbar:SPLIT'], {
- \ 'n': ['white', 'darkgreen'],
- \ 'N': ['white', 'darkestgreen'],
- \ }),
- \
- \ Pl#Hi#Segments(['ctrlp:focus', 'ctrlp:byfname'], {
- \ 'n': ['brightpurple', 'darkestpurple'],
- \ }),
- \
- \ Pl#Hi#Segments(['ctrlp:prev', 'ctrlp:next', 'ctrlp:pwd'], {
- \ 'n': ['white', 'mediumpurple'],
- \ }),
- \
- \ Pl#Hi#Segments(['ctrlp:item'], {
- \ 'n': ['darkestpurple', 'white', ['bold']],
- \ }),
- \
- \ Pl#Hi#Segments(['ctrlp:marked'], {
- \ 'n': ['brightestred', 'darkestpurple', ['bold']],
- \ }),
- \
- \ Pl#Hi#Segments(['ctrlp:count'], {
- \ 'n': ['darkestpurple', 'white'],
- \ }),
- \
- \ Pl#Hi#Segments(['ctrlp:SPLIT'], {
- \ 'n': ['white', 'darkestpurple'],
- \ }),
- \ ])
--- a/vim/colors/molokai.vim Fri Apr 14 15:01:35 2023 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,246 +0,0 @@
-" Vim color file
-"
-" Author: Tomas Restrepo <tomas@winterdom.com>
-" Modified by: Steve Losh <steve@stevelosh.com>
-"
-" Note: Based on the monokai theme for textmate
-" by Wimer Hazenberg and its darker variant
-" by Hamish Stuart Macpherson
-"
-
-set background=dark
-let g:colors_name="molokai"
-
-" Basic Layout {{{
-
-hi Normal guifg=#F8F8F2 guibg=#1B1E1F
-hi Folded guifg=#666666 guibg=bg
-hi CursorLine guibg=#232728
-hi CursorColumn guibg=#232728
-hi ColorColumn guibg=#232728
-hi LineNr guifg=#AAAAAA guibg=bg
-hi FoldColumn guifg=#AAAAAA guibg=bg
-hi VertSplit guifg=#AAAAAA guibg=bg gui=none
-hi Search guifg=#000000 guibg=#E4E500
-hi IncSearch guibg=#000000 guifg=#FF8D00
-hi Operator guifg=#F92672
-hi MatchParen guifg=#ffec00 guibg=#232728 gui=bold
-
-" }}}
-" Syntax {{{
-
-hi Boolean guifg=#AE81FF
-hi Comment guifg=#5c7176
-hi Character guifg=#E6DB74
-hi Number guifg=#AE81FF
-hi String guifg=#E6DB74
-hi Conditional guifg=#F92672 gui=bold
-hi Constant guifg=#AE81FF gui=bold
-hi Debug guifg=#BCA3A3 gui=bold
-hi Define guifg=#66D9EF
-hi Delimiter guifg=#8F8F8F
-hi Float guifg=#AE81FF
-hi Function guifg=#A6E22E
-hi Identifier guifg=#FD971F
-hi Error guifg=#960050 guibg=#1E0010
-hi Keyword guifg=#F92672 gui=bold
-hi Label guifg=#E6DB74 gui=none
-hi Macro guifg=#C4BE89 gui=italic
-hi SpecialKey guifg=#66D9EF gui=italic
-
-" }}}
-" Diffs {{{
-
-hi DiffAdd guibg=#1e4313
-hi DiffChange guifg=#89807D guibg=#322F2D
-hi DiffDelete guifg=#ff0088 guibg=#1B1E1F
-hi DiffText guibg=#4A4340 gui=italic,bold
-
-" }}}
-" Cursor {{{
-
-hi Cursor guifg=#000000 guibg=#F35FBC
-hi iCursor guifg=#000000 guibg=#FDFF00
-hi vCursor guifg=#000000 guibg=#AAF412
-
-" }}}
-" Block Colors {{{
-
-hi BlockColor1 guibg=#2a2a2a
-hi BlockColor2 guibg=#333333
-hi BlockColor3 guibg=#3b3b3b
-hi BlockColor4 guibg=#424242
-
-" }}}
-" Makegreen {{{
-
-hi GreenBar term=reverse ctermfg=white ctermbg=green guifg=black guibg=#9edf1c
-hi RedBar term=reverse ctermfg=white ctermbg=red guifg=white guibg=#C50048
-
-" }}}
-" EasyMotion {{{
-
-hi EasyMotionTarget guifg=#E4E500 guibg=bg gui=bold
-hi EasyMotionShade guifg=#444444 guibg=bg
-
-" }}}
-
-hi Directory guifg=#A6E22E gui=bold
-hi ErrorMsg guifg=#F92672 guibg=#232526 gui=bold
-hi Exception guifg=#A6E22E gui=bold
-hi Ignore guifg=#808080 guibg=bg
-
-
-hi InterestingWord1 guifg=#000000 guibg=#FFA700
-hi InterestingWord2 guifg=#000000 guibg=#53FF00
-hi InterestingWord3 guifg=#000000 guibg=#FF74F8
-
-
-hi ModeMsg guifg=#E6DB74
-hi MoreMsg guifg=#E6DB74
-
-" Completion Menu {{{
-hi Pmenu guifg=#cccccc guibg=#232728
-hi PmenuSel guifg=#000000 guibg=#AAF412
-hi PmenuSbar guibg=#131414
-hi PmenuThumb guifg=#777777
-" }}}
-
-hi PreCondit guifg=#A6E22E gui=bold
-hi PreProc guifg=#A6E22E
-hi Question guifg=#66D9EF
-hi Repeat guifg=#F92672 gui=bold
-
-" marks column
-hi IndentGuides guibg=#373737
-hi SignColumn guifg=#A6E22E guibg=#151617
-hi SpecialChar guifg=#F92672 gui=bold
-hi SpecialComment guifg=#465457 gui=bold
-hi Special guifg=#66D9EF guibg=bg gui=italic
-hi SpecialKey guifg=#888A85 gui=italic
-hi Statement guifg=#F92672 gui=bold
-hi StatusLine guifg=#262626 guibg=fg
-hi StatusLineNC guifg=#262626 guibg=#080808
-hi StorageClass guifg=#FD971F gui=italic
-hi Structure guifg=#66D9EF
-hi Tag guifg=#F92672 gui=italic
-hi Title guifg=#ef5939
-hi Todo guifg=#FFFFFF guibg=bg gui=bold
-
-hi Typedef guifg=#66D9EF
-hi Type guifg=#66D9EF gui=none
-hi Underlined guifg=#808080 gui=underline
-
-hi WarningMsg guifg=#FFFFFF guibg=#333333 gui=bold
-hi WildMenu guifg=#66D9EF guibg=#000000
-
-hi MyTagListFileName guifg=#F92672 guibg=bg gui=bold
-
-" Spelling {{{
-if has("spell")
- hi SpellBad guisp=#FF0000 gui=undercurl
- hi SpellCap guisp=#7070F0 gui=undercurl
- hi SpellLocal guisp=#70F0F0 gui=undercurl
- hi SpellRare guisp=#FFFFFF gui=undercurl
-endif
-" }}}
-" Visual Mode {{{
-hi VisualNOS guibg=#403D3D
-hi Visual guibg=#403D3D
-" }}}
-" Invisible character colors {{{
-highlight NonText guifg=#444444 guibg=bg
-highlight SpecialKey guifg=#444444 guibg=bg
-" }}}
-
-" Support for 256-color terminals {{{
-if &t_Co > 255
- hi Boolean ctermfg=135
- hi Character ctermfg=144
- hi Number ctermfg=135
- hi String ctermfg=144
- hi Conditional ctermfg=161 cterm=bold
- hi Constant ctermfg=135 cterm=bold
- hi Cursor ctermfg=16 ctermbg=253
- hi Debug ctermfg=225 cterm=bold
- hi Define ctermfg=81
- hi Delimiter ctermfg=241
-
- hi EasyMotionTarget ctermfg=11
- hi EasyMotionShade ctermfg=8
-
- hi DiffAdd ctermbg=24
- hi DiffChange ctermfg=181 ctermbg=239
- hi DiffDelete ctermfg=162 ctermbg=53
- hi DiffText ctermbg=102 cterm=bold
-
- hi Directory ctermfg=118 cterm=bold
- hi Error ctermfg=219 ctermbg=89
- hi ErrorMsg ctermfg=199 ctermbg=16 cterm=bold
- hi Exception ctermfg=118 cterm=bold
- hi Float ctermfg=135
- hi FoldColumn ctermfg=67 ctermbg=233
- hi Folded ctermfg=67 ctermbg=233
- hi Function ctermfg=118
- hi Identifier ctermfg=208
- hi Ignore ctermfg=244 ctermbg=232
- hi IncSearch ctermfg=193 ctermbg=16
-
- hi Keyword ctermfg=161 cterm=bold
- hi Label ctermfg=229 cterm=none
- hi Macro ctermfg=193
- hi SpecialKey ctermfg=81
- hi MailHeaderEmail ctermfg=3 ctermbg=233
- hi MailEmail ctermfg=3 ctermbg=233
-
- hi MatchParen ctermfg=16 ctermbg=208 cterm=bold
- hi ModeMsg ctermfg=229
- hi MoreMsg ctermfg=229
- hi Operator ctermfg=161
-
- " complete menu
- hi Pmenu ctermfg=81 ctermbg=16
- hi PmenuSel ctermbg=244
- hi PmenuSbar ctermbg=232
- hi PmenuThumb ctermfg=81
-
- hi PreCondit ctermfg=118 cterm=bold
- hi PreProc ctermfg=118
- hi Question ctermfg=81
- hi Repeat ctermfg=161 cterm=bold
- hi Search ctermfg=253 ctermbg=66
-
- " marks column
- hi SignColumn ctermfg=118 ctermbg=235
- hi SpecialChar ctermfg=161 cterm=bold
- hi SpecialComment ctermfg=245 cterm=bold
- hi Special ctermfg=81 ctermbg=232
- hi SpecialKey ctermfg=245
-
- hi Statement ctermfg=161 cterm=bold
- hi StatusLine ctermfg=130 ctermbg=15
- hi StatusLineNC ctermfg=242 ctermbg=15
- hi StorageClass ctermfg=208
- hi Structure ctermfg=81
- hi Tag ctermfg=161
- hi Title ctermfg=166
- hi Todo ctermfg=231 ctermbg=232 cterm=bold
-
- hi Typedef ctermfg=81
- hi Type ctermfg=81 cterm=none
- hi Underlined ctermfg=244 cterm=underline
-
- hi VertSplit ctermfg=244 ctermbg=232 cterm=bold
- hi VisualNOS ctermbg=238
- hi Visual ctermbg=235
- hi WarningMsg ctermfg=231 ctermbg=238 cterm=bold
- hi WildMenu ctermfg=81 ctermbg=16
-
- hi Normal ctermfg=252 ctermbg=233
- hi Comment ctermfg=59
- hi CursorLine ctermbg=234 cterm=none
- hi CursorColumn ctermbg=234
- hi ColorColumn ctermbg=234
- hi LineNr ctermfg=250 ctermbg=233
- hi NonText ctermfg=240 ctermbg=233
-end " }}}
--- a/vim/colors/mustang.vim Fri Apr 14 15:01:35 2023 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,60 +0,0 @@
-" Maintainer: Henrique C. Alves (hcarvalhoalves@gmail.com)
-" Version: 1.0
-" Last Change: September 25 2008
-
-set background=dark
-
-hi clear
-
-if exists("syntax_on")
- syntax reset
-endif
-
-let colors_name = "mustang"
-
-" Vim >= 7.0 specific colors
-if version >= 700
- hi CursorLine guibg=#2d2d2d ctermbg=236
- hi ColorColumn guibg=#2d2d2d ctermbg=236
- hi CursorColumn guibg=#2D2D2D ctermbg=236
- hi MatchParen guifg=#d0ffc0 guibg=#2f2f2f gui=bold ctermfg=157 ctermbg=237 cterm=bold
- hi Pmenu guifg=#ffffff guibg=#444444 ctermfg=255 ctermbg=238
- hi PmenuSel guifg=#000000 guibg=#b1d631 ctermfg=0 ctermbg=148
-endif
-
-" General colors
-hi Cursor guifg=NONE guibg=#626262 gui=none ctermbg=241
-hi Normal guifg=#e2e2e5 guibg=#202020 gui=none ctermfg=253 ctermbg=234
-hi NonText guifg=#808080 guibg=#202020 gui=none ctermfg=244 ctermbg=235
-hi LineNr guifg=#808080 guibg=#000000 gui=none ctermfg=244 ctermbg=232
-hi StatusLine guifg=#d3d3d5 guibg=#444444 gui=italic ctermfg=253 ctermbg=238 cterm=italic
-hi StatusLineNC guifg=#939395 guibg=#444444 gui=none ctermfg=246 ctermbg=238
-hi VertSplit guifg=#444444 guibg=#444444 gui=none ctermfg=238 ctermbg=238
-hi Folded guibg=#202020 guifg=#808080 gui=none ctermbg=4 ctermfg=248
-hi Title guifg=#f6f3e8 guibg=NONE gui=bold ctermfg=254 cterm=bold
-hi Visual guifg=#faf4c6 guibg=#3c414c gui=none ctermfg=254 ctermbg=4
-hi SpecialKey guifg=#808080 guibg=#202020 gui=none ctermfg=244 ctermbg=236
-
-" Syntax highlighting
-hi Comment guifg=#606060 gui=italic ctermfg=244
-hi Todo guifg=#8f8f8f gui=italic ctermfg=245
-hi Boolean guifg=#b1d631 gui=none ctermfg=148
-hi String guifg=#b1d631 gui=italic ctermfg=148
-hi Identifier guifg=#b1d631 gui=none ctermfg=148
-hi Function guifg=#ffffff gui=bold ctermfg=255
-hi Type guifg=#7e8aa2 gui=none ctermfg=103
-hi Statement guifg=#7e8aa2 gui=none ctermfg=103
-hi Keyword guifg=#ff9800 gui=none ctermfg=208
-hi Constant guifg=#ff9800 gui=none ctermfg=208
-hi Number guifg=#ff9800 gui=none ctermfg=208
-hi Special guifg=#ff9800 gui=none ctermfg=208
-hi PreProc guifg=#faf4c6 gui=none ctermfg=230
-hi Todo guifg=#000000 guibg=#e6ea50 gui=italic
-
-" Code-specific colors
-hi pythonOperator guifg=#7e8aa2 gui=none ctermfg=103
-
-" Cursor Colors
-hi Cursor guifg=#000000 guibg=#F35FBC
-hi iCursor guifg=#000000 guibg=#FDFF00
-hi vCursor guifg=#000000 guibg=#AAF412
--- a/vim/colors/vitamins.vim Fri Apr 14 15:01:35 2023 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,55 +0,0 @@
-" Maintainer: Henrique C. Alves (hcarvalhoalves@gmail.com)
-" Version: 1.1
-" Last Change: September 23 2008
-
-set background=dark
-
-hi clear
-
-if exists("syntax_on")
- syntax reset
-endif
-
-let colors_name = "vitamins"
-
-" Vim >= 7.0 specific colors
-if version >= 700
- hi CursorLine guibg=#2d2d2d ctermbg=236
- hi ColorColumn guibg=#2d2d2d ctermbg=236
- hi CursorColumn guibg=#2d2d2d ctermbg=236
- hi MatchParen guifg=#f6f3e8 guibg=#857b6f gui=bold ctermbg=59
- hi Pmenu guifg=#f6f3e8 guibg=#444444 ctermbg=242
- hi PmenuSel guifg=#000000 guibg=#cdd129 ctermfg=0 ctermbg=184
-endif
-
-" General colors
-hi Cursor guifg=NONE guibg=#656565 gui=none ctermbg=0x241
-hi Normal guifg=#f6f3f0 guibg=#212121 gui=none ctermfg=254 ctermbg=235
-hi NonText guifg=#808080 guibg=#212121 gui=none ctermfg=242 ctermbg=237
-hi LineNr guifg=#5c5a4f guibg=#000000 gui=none ctermfg=239 ctermbg=232
-hi StatusLine guifg=#f6f3e8 guibg=#444444 gui=italic
-hi StatusLineNC guifg=#857b6f guibg=#444444 gui=none
-hi VertSplit guifg=#777777 guibg=#212121 gui=none
-hi Folded guibg=#212121 guifg=#777777 gui=none
-hi Title guifg=#f6f3e8 guibg=NONE gui=bold
-hi Visual guifg=#ffffd7 guibg=#444444 gui=none ctermfg=186 ctermbg=238
-hi SpecialKey guifg=#808080 guibg=#212121 gui=none
-
-" Syntax highlighting
-hi Comment guifg=#aaaaaa gui=italic ctermfg=244
-hi Todo guifg=#8f8f8f gui=italic ctermfg=245
-hi Constant guifg=#acf0f2 gui=none ctermfg=159
-hi String guifg=#ff5d28 gui=italic ctermfg=202
-hi Identifier guifg=#ff5d28 gui=none ctermfg=202
-hi Function guifg=#cdd129 gui=none ctermfg=184
-hi Type guifg=#cdd129 gui=none ctermfg=184
-hi Statement guifg=#af5f5f gui=none ctermfg=131
-hi Keyword guifg=#cdd129 gui=none ctermfg=184
-hi PreProc guifg=#ede39e gui=none ctermfg=187
-hi Number guifg=#ede39e gui=none ctermfg=187
-hi Special guifg=#acf0f2 gui=none ctermfg=159
-
-" Cursor Colors
-hi Cursor guifg=#000000 guibg=#AAF412
-hi iCursor guifg=#000000 guibg=#FDFF00
-hi vCursor guifg=#000000 guibg=#FDFF00
--- a/vim/compiler/cake-test-wrapper.py Fri Apr 14 15:01:35 2023 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +0,0 @@
-#!/usr/bin/env python
-
-import os, subprocess
-
-def parse_filename(l):
- ns = l.split(' ', 3)[-1].rsplit('/', 1)[0]
- return os.path.join('./test', *ns.split('.')) + '.clj'
-
-def process_error(fn, l, lines):
- lnum = int(l.rsplit(' ', 1)[-1].split(':')[-1])
-
- message = lines.pop(0)
-
- print '%s:%d:%s' % (fn, lnum, message)
-
- return message
-
-if __name__ == '__main__':
- out = subprocess.check_output(r"cake test | perl -pe 's/\e\[?.*?[\@-~]//g'", shell=True)
-
- prev = ""
- fn = None
- lines = out.splitlines()
- while lines:
- l = lines.pop(0)
- if l.startswith('cake test ') and '/' in l:
- fn = parse_filename(l)
-
- if l.startswith('FAIL!'):
- prev = process_error(fn, l, lines)
- else:
- prev = l
-
--- a/vim/compiler/clojure.vim Fri Apr 14 15:01:35 2023 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,20 +0,0 @@
-"============================================================================
-"Compiler: Clojure (cake test)
-"Maintainer: Steve Losh <steve@stevelosh.com>
-"License: MIT/X11
-"============================================================================
-
-" if exists("current_compiler")
-" finish
-" endif
-let current_compiler = "clojure"
-
-let s:cpo_save = &cpo
-set cpo-=C"endif
-
-let &l:makeprg=fnameescape(globpath(&runtimepath, 'compiler/cake-test-wrapper.py'))
-
-setlocal errorformat=%f:%l:%m
-
-let &cpo = s:cpo_save
-unlet s:cpo_save
--- a/vim/custom-dictionary.utf-8.add Fri Apr 14 15:01:35 2023 -0400
+++ b/vim/custom-dictionary.utf-8.add Fri Jul 07 16:11:02 2023 -0400
@@ -318,3 +318,20 @@
Astron
Rethe
Forelithe
+UUIDs
+metaclass
+async
+valkyrie
+Greatshield
+sudoers
+Virtualbox
+libvirt
+qemu
+superclasses
+metaclasses
+Metaobject
+memoize
+metaobjects
+memoized
+skald
+dwarven
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/ftdetect/hcl.vim Fri Jul 07 16:11:02 2023 -0400
@@ -0,0 +1,7 @@
+" vint: -ProhibitAutocmdWithNoGroup
+" By default, Vim associates .tf files with TinyFugue - tell it not to.
+silent! autocmd! filetypedetect BufRead,BufNewFile *.tf
+autocmd BufRead,BufNewFile *.hcl set filetype=hcl
+autocmd BufRead,BufNewFile .terraformrc,terraform.rc set filetype=hcl
+autocmd BufRead,BufNewFile *.tf,*.tfvars set filetype=terraform
+autocmd BufRead,BufNewFile *.tfstate,*.tfstate.backup set filetype=json
--- a/vim/ftdetect/io.vim Fri Apr 14 15:01:35 2023 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,5 +0,0 @@
-" Io
-au BufNewFile,BufRead *.io set filetype=io
-
-" Ikefile
-au BufNewFile,BufRead [iI]kefile,*.ike set filetype=io
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/ftdetect/martian.vim Fri Jul 07 16:11:02 2023 -0400
@@ -0,0 +1,1 @@
+autocmd BufRead,BufNewFile *.mro set filetype=martian
--- a/vim/haskellmode.config Fri Apr 14 15:01:35 2023 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,249 +0,0 @@
--- 7.4.1
-AlternativeLayoutRule
-AlternativeLayoutRuleTransitional
-Arrows
-BangPatterns
-CApiFFI
-CPP
-ConstrainedClassMethods
-ConstraintKinds
-DataKinds
-DatatypeContexts
-DefaultSignatures
-DeriveDataTypeable
-DeriveFoldable
-DeriveFunctor
-DeriveGeneric
-DeriveTraversable
-DisambiguateRecordFields
-DoAndIfThenElse
-DoRec
-EmptyDataDecls
-ExistentialQuantification
-ExplicitForAll
-ExtendedDefaultRules
-FlexibleContexts
-FlexibleInstances
-ForeignFunctionInterface
-FunctionalDependencies
-GADTSyntax
-GADTs
-GHCForeignImportPrim
-GeneralizedNewtypeDeriving
-Haskell2010
-Haskell98
-ImplicitParams
-ImplicitPrelude
-ImpredicativeTypes
-IncoherentInstances
-InterruptibleFFI
-KindSignatures
-LiberalTypeSynonyms
-MagicHash
-MonadComprehensions
-MonoLocalBinds
-MonoPatBinds
-MonomorphismRestriction
-MultiParamTypeClasses
-NPlusKPatterns
-NamedFieldPuns
-NoAlternativeLayoutRule
-NoAlternativeLayoutRuleTransitional
-NoArrows
-NoBangPatterns
-NoCApiFFI
-NoCPP
-NoConstrainedClassMethods
-NoConstraintKinds
-NoDataKinds
-NoDatatypeContexts
-NoDefaultSignatures
-NoDeriveDataTypeable
-NoDeriveFoldable
-NoDeriveFunctor
-NoDeriveGeneric
-NoDeriveTraversable
-NoDisambiguateRecordFields
-NoDoAndIfThenElse
-NoDoRec
-NoEmptyDataDecls
-NoExistentialQuantification
-NoExplicitForAll
-NoExtendedDefaultRules
-NoFlexibleContexts
-NoFlexibleInstances
-NoForeignFunctionInterface
-NoFunctionalDependencies
-NoGADTSyntax
-NoGADTs
-NoGHCForeignImportPrim
-NoGeneralizedNewtypeDeriving
-NoImplicitParams
-NoImplicitPrelude
-NoImpredicativeTypes
-NoIncoherentInstances
-NoInterruptibleFFI
-NoKindSignatures
-NoLiberalTypeSynonyms
-NoMagicHash
-NoMonadComprehensions
-NoMonoLocalBinds
-NoMonoPatBinds
-NoMonomorphismRestriction
-NoMultiParamTypeClasses
-NoNPlusKPatterns
-NoNamedFieldPuns
-NoNondecreasingIndentation
-NoOverlappingInstances
-NoOverloadedStrings
-NoPackageImports
-NoParallelArrays
-NoParallelListComp
-NoPatternGuards
-NoPatternSignatures
-NoPolyKinds
-NoPolymorphicComponents
-NoPostfixOperators
-NoQuasiQuotes
-NoRank2Types
-NoRankNTypes
-NoRebindableSyntax
-NoRecordPuns
-NoRecordWildCards
-NoRecursiveDo
-NoRelaxedLayout
-NoRelaxedPolyRec
-NoScopedTypeVariables
-NoStandaloneDeriving
-NoTemplateHaskell
-NoTraditionalRecordSyntax
-NoTransformListComp
-NoTupleSections
-NoTypeFamilies
-NoTypeOperators
-NoTypeSynonymInstances
-NoUnboxedTuples
-NoUndecidableInstances
-NoUnicodeSyntax
-NoUnliftedFFITypes
-NoViewPatterns
-NondecreasingIndentation
-OverlappingInstances
-OverloadedStrings
-PackageImports
-ParallelArrays
-ParallelListComp
-PatternGuards
-PatternSignatures
-PolyKinds
-PolymorphicComponents
-PostfixOperators
-QuasiQuotes
-Rank2Types
-RankNTypes
-RebindableSyntax
-RecordPuns
-RecordWildCards
-RecursiveDo
-RelaxedLayout
-RelaxedPolyRec
-Safe
-ScopedTypeVariables
-StandaloneDeriving
-TemplateHaskell
-TraditionalRecordSyntax
-TransformListComp
-Trustworthy
-TupleSections
-TypeFamilies
-TypeOperators
-TypeSynonymInstances
-UnboxedTuples
-UndecidableInstances
-UnicodeSyntax
-UnliftedFFITypes
-Unsafe
-ViewPatterns
---
--fdo-lambda-eta-expansion
--fembed-manifest
--fgen-manifest
--fghci-history
--fghci-sandbox
--fhelpful-errors
--fignore-interface-pragmas
--fimplicit-import-qualified
--fno-break-on-error
--fno-break-on-exception
--fno-building-cabal-package
--fno-case-merge
--fno-cse
--fno-dicts-cheap
--fno-do-eta-reduction
--fno-eager-blackholing
--fno-enable-rewrite-rules
--fno-excess-precision
--fno-expose-all-unfoldings
--fno-ext-core
--fno-float-in
--fno-force-recomp
--fno-full-laziness
--fno-hpc-no-auto
--fno-ignore-asserts
--fno-liberate-case
--fno-new-codegen
--fno-pedantic-bottoms
--fno-print-bind-result
--fno-print-evld-with-show
--fno-print-explicit-foralls
--fno-prof-cafs
--fno-regs-graph
--fno-regs-iterative
--fno-rewrite-rules
--fno-run-cps
--fno-run-cpsz
--fno-spec-constr
--fno-specialise
--fno-static-argument-transformation
--fno-strictness
--fno-unbox-strict-fields
--fno-vectorise
--fno-warn-auto-orphans
--fno-warn-dodgy-exports
--fno-warn-dodgy-imports
--fno-warn-hi-shadowing
--fno-warn-identities
--fno-warn-implicit-prelude
--fno-warn-incomplete-patterns
--fno-warn-incomplete-record-updates
--fno-warn-incomplete-uni-patterns
--fno-warn-missing-import-lists
--fno-warn-missing-local-sigs
--fno-warn-missing-signatures
--fno-warn-monomorphism-restriction
--fno-warn-name-shadowing
--fno-warn-orphans
--fno-warn-safe
--fno-warn-tabs
--fno-warn-type-defaults
--fno-warn-unsafe
--fno-warn-unused-binds
--fno-warn-unused-do-bind
--fno-warn-unused-imports
--fno-warn-unused-matches
--fomit-interface-pragmas
--fprint-bind-contents
--fprof-count-entries
--fshared-implib
--fwarn-alternative-layout-rule-transitional
--fwarn-deprecated-flags
--fwarn-deprecations
--fwarn-dodgy-foreign-imports
--fwarn-duplicate-exports
--fwarn-lazy-unlifted-bindings
--fwarn-missing-fields
--fwarn-missing-methods
--fwarn-overlapping-patterns
--fwarn-unrecognised-pragmas
--fwarn-warnings-deprecations
--fwarn-wrong-do-bind
--- a/vim/init.vim Fri Apr 14 15:01:35 2023 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-/Users/sjl/.vimrc
\ No newline at end of file
--- a/vim/jsl.conf Fri Apr 14 15:01:35 2023 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,115 +0,0 @@
-#
-# Configuration File for JavaScript Lint 0.3.0
-# Developed by Matthias Miller (http://www.JavaScriptLint.com)
-#
-# This configuration file can be used to lint a collection of scripts, or to enable
-# or disable warnings for scripts that are linted via the command line.
-#
-
-### Warnings
-# Enable or disable warnings based on requirements.
-# Use "+WarningName" to display or "-WarningName" to suppress.
-#
-+no_return_value # function {0} does not always return a value
-+duplicate_formal # duplicate formal argument {0}
-+equal_as_assign # test for equality (==) mistyped as assignment (=)?{0}
-+var_hides_arg # variable {0} hides argument
-+redeclared_var # redeclaration of {0} {1}
-+anon_no_return_value # anonymous function does not always return a value
-+missing_semicolon # missing semicolon
-+meaningless_block # meaningless block; curly braces have no impact
-+comma_separated_stmts # multiple statements separated by commas (use semicolons?)
-+unreachable_code # unreachable code
-+missing_break # missing break statement
-+missing_break_for_last_case # miss-+-------------+ent for last case in switch
-+comparison_type_conv # compa|isons against|null, 0, true, false, or an empty string allowing implicit type conversion (use === or !==)
-+inc_dec_within_stmt # incre|ent (++) and |ecrement (--) operators used as part of greater statement
-+useless_void # use o| the void typ| may be unnecessary (void is always undefined)
-+multiple_plus_minus # unkno|n order of op|rations for successive plus (e.g. x+++y) or minus (e.g. x---y) signs
-+use_of_label # use o| label |
-+block_without_braces # block|statement wit|out curly braces
-+leading_decimal_point # leadi|g decimal poi|t may indicate a number or an object member
-+trailing_decimal_point # trail|ng decimal po|nt may indicate a number or an object member
-+octal_number # leadi|g zeros make |n octal number
-+nested_comment # neste+-------------+
-+misplaced_regex # regular expressions should be preceded by a left parenthesis, assignment, colon, or comma
--ambiguous_newline # unexpected end of line; it is ambiguous whether these lines are part of the same statement
-+empty_statement # empty statement or extra semicolon
--missing_option_explicit # the "option explicit" control comment is missing
-+partial_option_explicit # the "option explicit" control comment, if used, must be in the first script tag
-+dup_option_explicit # duplicate "option explicit" control comment
-+useless_assign # useless assignment
-+ambiguous_nested_stmt # block statements containing block statements should use curly braces to resolve ambiguity
-+ambiguous_else_stmt # the else statement could be matched with one of multiple if statements (use curly braces to indicate intent)
-+missing_default_case # missing default case in switch statement
-+duplicate_case_in_switch # duplicate case in switch statements
-+default_not_at_end # the default case is not at the end of the switch statement
-+legacy_cc_not_understood # couldn't understand control comment using /*@keyword@*/ syntax
-+jsl_cc_not_understood # couldn't understand control comment using /*jsl:keyword*/ syntax
-+useless_comparison # useless comparison; comparing identical expressions
-+with_statement # with statement hides undeclared variables; use temporary variable instead
-+trailing_comma_in_array # extra comma is not recommended in array initializers
-+assign_to_function_call # assignment to a function call
-+parseint_missing_radix # parseInt missing radix parameter
-
-
-### Output format
-# Customize the format of the error message.
-# __FILE__ indicates current file path
-# __FILENAME__ indicates current file name
-# __LINE__ indicates current line
-# __ERROR__ indicates error message
-#
-# Visual Studio syntax (default):
-+output-format __FILE__(__LINE__): __ERROR__
-# Alternative syntax:
-#+output-format __FILE__:__LINE__: __ERROR__
-
-
-### Context
-# Show the in-line position of the error.
-# Use "+context" to display or "-context" to suppress.
-#
-+context
-
-
-### Semicolons
-# By default, assignments of an anonymous function to a variable or
-# property (such as a function prototype) must be followed by a semicolon.
-#
-+lambda_assign_requires_semicolon
-
-
-### Control Comments
-# Both JavaScript Lint and the JScript interpreter confuse each other with the syntax for
-# the /*@keyword@*/ control comments and JScript conditional comments. (The latter is
-# enabled in JScript with @cc_on@). The /*jsl:keyword*/ syntax is preferred for this reason,
-# although legacy control comments are enabled by default for backward compatibility.
-#
-+legacy_control_comments
-
-
-### JScript Function Extensions
-# JScript allows member functions to be defined like this:
-# function MyObj() { /*constructor*/ }
-# function MyObj.prototype.go() { /*member function*/ }
-#
-# It also allows events to be attached like this:
-# function window::onload() { /*init page*/ }
-#
-# This is a Microsoft-only JavaScript extension. Enable this setting to allow them.
-#
--jscript_function_extensions
-
-
-### Defining identifiers
-# By default, "option explicit" is enabled on a per-file basis.
-# To enable this for all files, use "+always_use_option_explicit"
--always_use_option_explicit
-
-# Define certain identifiers of which the lint is not aware.
-# (Use this in conjunction with the "undeclared identifier" warning.)
-#
-# Common uses for webpages might be:
-+define window
-+define document
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/plugin/redact_pass.vim Fri Jul 07 16:11:02 2023 -0400
@@ -0,0 +1,58 @@
+"
+" redact_pass.vim: Switch off the 'viminfo', 'backup', 'writebackup',
+" 'swapfile', and 'undofile' globally when editing a password in pass(1).
+"
+" This is to prevent anyone being able to extract passwords from your Vim
+" cache files in the event of a compromise.
+"
+" Author: Tom Ryder <tom@sanctum.geek.nz>
+" License: Same as Vim itself
+"
+if exists('g:loaded_redact_pass') || &compatible
+ finish
+endif
+if !has('autocmd') || v:version < 600
+ finish
+endif
+let g:loaded_redact_pass = 1
+
+" Check whether we should set redacting options or not
+function! s:CheckArgsRedact()
+
+ " Ensure there's one argument and it's the matched file
+ if argc() != 1 || fnamemodify(argv(0), ':p') !=# expand('<afile>:p')
+ return
+ endif
+
+ " Disable all the leaky options globally
+ set nobackup
+ set nowritebackup
+ set noswapfile
+ set viminfo=
+ if has('persistent_undo')
+ set noundofile
+ endif
+
+ " Tell the user what we're doing so they know this worked, via a message and
+ " a global variable they can check
+ redraw
+ echomsg 'Editing password file--disabled leaky options!'
+ let g:redact_pass_redacted = 1
+
+endfunction
+
+" Auto function loads only when Vim starts up
+augroup redact_pass
+ autocmd!
+ autocmd VimEnter
+ \ /dev/shm/pass.?*/?*.txt
+ \,$TMPDIR/pass.?*/?*.txt
+ \,/tmp/pass.?*/?*.txt
+ \ call s:CheckArgsRedact()
+ " Work around macOS' dynamic symlink structure for temporary directories
+ if has('mac')
+ autocmd VimEnter
+ \ /private/var/?*/pass.?*/?*.txt
+ \ call s:CheckArgsRedact()
+ endif
+augroup END
--- a/vim/snippets/_.snippets Fri Apr 14 15:01:35 2023 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,17 +0,0 @@
-# Global snippets
-
-# (c) holds no legal value ;)
-snippet c)
- `&enc[:2] == "utf" ? "©" : "(c)"` Copyright `strftime("%Y")` ${1:`g:snips_author`}. All Rights Reserved.${2}
-snippet date
- `strftime("%Y-%m-%d")`
-snippet sl
- http://stevelosh.com/
-snippet gh
- http://github.com/
-snippet ghs
- http://github.com/sjl/
-snippet bb
- http://bitbucket.org/
-snippet bbs
- http://bitbucket.org/sjl/
--- a/vim/snippets/autoit.snippets Fri Apr 14 15:01:35 2023 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,66 +0,0 @@
-snippet if
- If ${1:condition} Then
- ${2:; True code}
- EndIf
-snippet el
- Else
- ${1}
-snippet elif
- ElseIf ${1:condition} Then
- ${2:; True code}
-# If/Else block
-snippet ifel
- If ${1:condition} Then
- ${2:; True code}
- Else
- ${3:; Else code}
- EndIf
-# If/ElseIf/Else block
-snippet ifelif
- If ${1:condition 1} Then
- ${2:; True code}
- ElseIf ${3:condition 2} Then
- ${4:; True code}
- Else
- ${5:; Else code}
- EndIf
-# Switch block
-snippet switch
- Switch (${1:condition})
- Case {$2:case1}:
- {$3:; Case 1 code}
- Case Else:
- {$4:; Else code}
- EndSwitch
-# Select block
-snippet select
- Select (${1:condition})
- Case {$2:case1}:
- {$3:; Case 1 code}
- Case Else:
- {$4:; Else code}
- EndSelect
-# While loop
-snippet while
- While (${1:condition})
- ${2:; code...}
- WEnd
-# For loop
-snippet for
- For ${1:n} = ${3:1} to ${2:count}
- ${4:; code...}
- Next
-# New Function
-snippet func
- Func ${1:fname}(${2:`indent('.') ? 'self' : ''`}):
- ${4:Return}
- EndFunc
-# Message box
-snippet msg
- MsgBox(${3:MsgType}, ${1:"Title"}, ${2:"Message Text"})
-# Debug Message
-snippet debug
- MsgBox(0, "Debug", ${1:"Debug Message"})
-# Show Variable Debug Message
-snippet showvar
- MsgBox(0, "${1:VarName}", $1)
--- a/vim/snippets/c.snippets Fri Apr 14 15:01:35 2023 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,110 +0,0 @@
-# main()
-snippet main
- int main(int argc, const char *argv[])
- {
- ${1}
- return 0;
- }
-# #include <...>
-snippet inc
- #include <${1:stdio}.h>${2}
-# #include "..."
-snippet Inc
- #include "${1:`Filename("$1.h")`}"${2}
-# #ifndef ... #define ... #endif
-snippet Def
- #ifndef $1
- #define ${1:SYMBOL} ${2:value}
- #endif${3}
-snippet def
- #define
-snippet ifdef
- #ifdef ${1:FOO}
- ${2:#define }
- #endif
-snippet #if
- #if ${1:FOO}
- ${2}
- #endif
-# Header Include-Guard
-# (the randomizer code is taken directly from TextMate; it could probably be
-# cleaner, I don't know how to do it in vim script)
-snippet once
- #ifndef ${1:`toupper(Filename('', 'UNTITLED').'_'.system("/usr/bin/ruby -e 'print (rand * 2821109907455).round.to_s(36)'"))`}
-
- #define $1
-
- ${2}
-
- #endif /* end of include guard: $1 */
-# If Condition
-snippet if
- if (${1:/* condition */}) {
- ${2:/* code */}
- }
-snippet el
- else {
- ${1}
- }
-# Tertiary conditional
-snippet t
- ${1:/* condition */} ? ${2:a} : ${3:b}
-# Do While Loop
-snippet do
- do {
- ${2:/* code */}
- } while (${1:/* condition */});
-# While Loop
-snippet wh
- while (${1:/* condition */}) {
- ${2:/* code */}
- }
-# For Loop
-snippet for
- for (${2:i} = 0; $2 < ${1:count}; $2${3:++}) {
- ${4:/* code */}
- }
-# Custom For Loop
-snippet forr
- for (${1:i} = ${2:0}; ${3:$1 < 10}; $1${4:++}) {
- ${5:/* code */}
- }
-# Function
-snippet fun
- ${1:void} ${2:function_name}(${3})
- {
- ${4:/* code */}
- }
-# Function Declaration
-snippet fund
- ${1:void} ${2:function_name}(${3});${4}
-# Typedef
-snippet td
- typedef ${1:int} ${2:MyCustomType};${3}
-# Struct
-snippet st
- struct ${1:`Filename('$1_t', 'name')`} {
- ${2:/* data */}
- }${3: /* optional variable list */};${4}
-# Typedef struct
-snippet tds
- typedef struct ${2:_$1 }{
- ${3:/* data */}
- } ${1:`Filename('$1_t', 'name')`};
-# Typdef enum
-snippet tde
- typedef enum {
- ${1:/* data */}
- } ${2:foo};
-# printf
-# unfortunately version this isn't as nice as TextMates's, given the lack of a
-# dynamic `...`
-snippet pr
- printf("${1:%s}\n"${2});${3}
-# fprintf (again, this isn't as nice as TextMate's version, but it works)
-snippet fpr
- fprintf(${1:stderr}, "${2:%s}\n"${3});${4}
-snippet .
- [${1}]${2}
-snippet un
- unsigned
--- a/vim/snippets/clojure.snippets Fri Apr 14 15:01:35 2023 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,12 +0,0 @@
-# Fucking imports, how do they work?
-snippet nfis
- (:use ${1:foo.core})
-snippet nfi
- (:use [${1:foo.core} :only (${2:bar})])
-snippet ni
- (:require [${1:foo.core}])
-snippet nia
- (:require [${1:foo.core} :as ${2:bar}])
-snippet niar
- (:require [${1:foo.core}])
- (:import [$1 ${2:Bar}])
--- a/vim/snippets/cpp.snippets Fri Apr 14 15:01:35 2023 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,30 +0,0 @@
-# Read File Into Vector
-snippet readfile
- std::vector<char> v;
- if (FILE *${2:fp} = fopen(${1:"filename"}, "r")) {
- char buf[1024];
- while (size_t len = fread(buf, 1, sizeof(buf), $2))
- v.insert(v.end(), buf, buf + len);
- fclose($2);
- }${3}
-# std::map
-snippet map
- std::map<${1:key}, ${2:value}> map${3};
-# std::vector
-snippet vector
- std::vector<${1:char}> v${2};
-# Namespace
-snippet ns
- namespace ${1:`Filename('', 'my')`} {
- ${2}
- } /* $1 */
-# Class
-snippet cl
- class ${1:`Filename('$1_t', 'name')`} {
- public:
- $1 (${2:arguments});
- virtual ~$1 ();
-
- private:
- ${3:/* data */}
- };
--- a/vim/snippets/django.snippets Fri Apr 14 15:01:35 2023 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,128 +0,0 @@
-# Model Fields
-
-# Note: Optional arguments are using defaults that match what Django will use
-# as a default, e.g. with max_length fields. Doing this as a form of self
-# documentation and to make it easy to know whether you should override the
-# default or not.
-
-# Note: Optional arguments that are booleans will use the opposite since you
-# can either not specify them, or override them, e.g. auto_now_add=False.
-
-snippet auto
- ${1:FIELDNAME} = models.AutoField()
-snippet bool
- ${1:FIELDNAME} = models.BooleanField(${2:default=True})
-snippet char
- ${1:FIELDNAME} = models.CharField(max_length=${2}${3:, blank=True})
-snippet comma
- ${1:FIELDNAME} = models.CommaSeparatedIntegerField(max_length=${2}${3:, blank=True})
-snippet date
- ${1:FIELDNAME} = models.DateField()
-snippet datetime
- ${1:FIELDNAME} = models.DateTimeField()
-snippet decimal
- ${1:FIELDNAME} = models.DecimalField(max_digits=${2}, decimal_places=${3})
-snippet email
- ${1:FIELDNAME} = models.EmailField(max_length=${2:75}${3:, blank=True})
-snippet file
- ${1:FIELDNAME} = models.FileField(upload_to=${2:path/for/upload}${3:, max_length=100})
-snippet filepath
- ${1:FIELDNAME} = models.FilePathField(path=${2:"/abs/path/to/dir"}${3:, max_length=100}${4:, match="*.ext"}${5:, recursive=True}${6:, blank=True, })
-snippet float
- ${1:FIELDNAME} = models.FloatField()
-snippet image
- ${1:FIELDNAME} = FileBrowseField(format='Image', max_length=200)
-snippet djangoimage
- ${1:FIELDNAME} = models.ImageField(upload_to=${2:path/for/upload}${3:, height_field=height, width_field=width}${4:, max_length=100})
-snippet int
- ${1:FIELDNAME} = models.IntegerField()
-snippet ip
- ${1:FIELDNAME} = models.IPAddressField()
-snippet nullbool
- ${1:FIELDNAME} = models.NullBooleanField()
-snippet posint
- ${1:FIELDNAME} = models.PositiveIntegerField()
-snippet possmallint
- ${1:FIELDNAME} = models.PositiveSmallIntegerField()
-snippet slug
- ${1:FIELDNAME} = models.SlugField(max_length=${2:50}${3:, blank=True})
-snippet smallint
- ${1:FIELDNAME} = models.SmallIntegerField()
-snippet text
- ${1:FIELDNAME} = models.TextField(${2:blank=True})
-snippet time
- ${1:FIELDNAME} = models.TimeField()
-snippet url
- ${1:FIELDNAME} = models.URLField(${2:verify_exists=False}${3:, max_length=200}${4:, blank=True})
-snippet xml
- ${1:FIELDNAME} = models.XMLField(schema_path=${2:None}${3:, blank=True})
-# Relational Fields
-snippet fk
- ${1:FIELDNAME} = models.ForeignKey(${2:OtherModel})
-snippet m2m
- ${1:FIELDNAME} = models.ManyToManyField(${2:OtherModel})
-snippet bl
- blank=True
-snippet dc
- db_column='${1:colname}'
-snippet dt
- db_table='${1:tablename}'
-snippet o2o
- ${1:FIELDNAME} = models.OneToOneField(${2:OtherModel}${3:, parent_link=True}${4:, related_name=''}${5:, limit_choices_to=}${6:, to_field=''})
-
-# Code Skeletons
-
-snippet form
- class ${1:FormName}(forms.Form):
- """${2:docstring}"""
- ${3}
-
-snippet manager
- class ${1:ModelName}Manager(models.Manager):
- def get_query_set(self):
- return super($1Manager, self).get_query_set()
- ${3}
-
-snippet model
- class ${1:ModelName}(${2:models.Model}):
- ${4}
-
- class Meta:
- ordering = ('${3:-created}',)
-
- def __unicode__(self):
- return u'%s' % ''
-
-snippet modeladmin
- class ${1:ModelName}Admin(admin.ModelAdmin):
- ${2}
-
- admin.site.register($1, $1Admin)
-
-snippet r2r
- return render_to_response('${1:template.html}', {
- ${2}
- }${3:, context_instance=RequestContext(request)}
- )
-
-snippet tabularinline
- class ${1:ModelName}Inline(admin.TabularInline):
- model = $1
- extra = ${2:3}
-
-snippet stackedinline
- class ${1:ModelName}Inline(admin.StackedInline):
- model = $1
- extra = ${2:3}
-
-# Ugly crap.
-
-snippet reverse
- reverse('${1:view-name}'${2:, args=[]}${3:, kwargs=None})${4}
-snippet view
- @render_to('${1}')
- def ${2:view_name}(request${3:, ...}):${4}
- return {}
-snippet defu
- def __unicode__(self):
- return u'${1}' % (${2})
--- a/vim/snippets/html.snippets Fri Apr 14 15:01:35 2023 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,190 +0,0 @@
-# Some useful Unicode entities
-# Non-Breaking Space
-snippet nbs
-
-# ←
-snippet left
- ←
-# →
-snippet right
- →
-# ↑
-snippet up
- ↑
-# ↓
-snippet down
- ↓
-# ↩
-snippet return
- ↩
-# ⇤
-snippet backtab
- ⇤
-# ⇥
-snippet tab
- ⇥
-# ⇧
-snippet shift
- ⇧
-# ⌃
-snippet control
- ⌃
-# ⌅
-snippet enter
- ⌅
-# ⌘
-snippet command
- ⌘
-# ⌥
-snippet option
- ⌥
-# ⌦
-snippet delete
- ⌦
-# ⌫
-snippet backspace
- ⌫
-# ⎋
-snippet escape
- ⎋
-# Generic Doctype
-snippet doctype HTML 4.01 Strict
- <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN""
- "http://www.w3.org/TR/html4/strict.dtd">
-snippet doctype HTML 4.01 Transitional
- <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""
- "http://www.w3.org/TR/html4/loose.dtd">
-snippet doctype HTML 5
- <!DOCTYPE HTML>
-snippet doctype XHTML 1.0 Frameset
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-snippet doctype XHTML 1.0 Strict
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-snippet doctype XHTML 1.0 Transitional
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-snippet doctype XHTML 1.1
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
- "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
-# HTML Doctype 4.01 Strict
-snippet docts
- <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN""
- "http://www.w3.org/TR/html4/strict.dtd">
-# HTML Doctype 4.01 Transitional
-snippet doct
- <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""
- "http://www.w3.org/TR/html4/loose.dtd">
-# HTML Doctype 5
-snippet doct5
- <!DOCTYPE HTML>
-# XHTML Doctype 1.0 Frameset
-snippet docxf
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
-# XHTML Doctype 1.0 Strict
-snippet docxs
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-# XHTML Doctype 1.0 Transitional
-snippet docxt
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-# XHTML Doctype 1.1
-snippet docx
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
- "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
-snippet html
- <html>
- ${1}
- </html>
-snippet xhtml
- <html xmlns="http://www.w3.org/1999/xhtml">
- ${1}
- </html>
-snippet body
- <body>
- ${1}
- </body>
-snippet head
- <head>
- <meta http-equiv="content-type" content="text/html; charset=utf-8"`Close()`>
-
- <title>${1:`substitute(Filename('', 'Page Title'), '^.', '\u&', '')`}</title>
- ${2}
- </head>
-snippet title
- <title>${1:`substitute(Filename('', 'Page Title'), '^.', '\u&', '')`}</title>${2}
-snippet script
- <script type="text/javascript" charset="utf-8">
- ${1}
- </script>${2}
-snippet scriptsrc
- <script src="${1}.js" type="text/javascript" charset="utf-8"></script>${2}
-snippet style
- <style type="text/css" media="${1:screen}">
- ${2}
- </style>${3}
-snippet base
- <base href="${1}" target="${2}"`Close()`>
-snippet r
- <br`Close()[1:]`>
-snippet div
- <div id="${1:name}">
- ${2}
- </div>
-# Embed QT Movie
-snippet movie
- <object width="$2" height="$3" classid="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B"
- codebase="http://www.apple.com/qtactivex/qtplugin.cab">
- <param name="src" value="$1"`Close()`>
- <param name="controller" value="$4"`Close()`>
- <param name="autoplay" value="$5"`Close()`>
- <embed src="${1:movie.mov}"
- width="${2:320}" height="${3:240}"
- controller="${4:true}" autoplay="${5:true}"
- scale="tofit" cache="true"
- pluginspage="http://www.apple.com/quicktime/download/"
- `Close()[1:]`>
- </object>${6}
-snippet fieldset
- <fieldset id="$1">
- <legend>${1:name}</legend>
-
- ${3}
- </fieldset>
-snippet form
- <form action="${1:`Filename('$1_submit')`}" method="${2:get}" accept-charset="utf-8">
- ${3}
-
-
- <p><input type="submit" value="Continue →"`Close()`></p>
- </form>
-snippet h1
- <h1 id="${1:heading}">${2:$1}</h1>
-snippet input
- <input type="${1:text/submit/hidden/button}" name="${2:some_name}" value="${3}"`Close()`>${4}
-snippet label
- <label for="${2:$1}">${1:name}</label><input type="${3:text/submit/hidden/button}" name="${4:$2}" value="${5}" id="${6:$2}"`Close()`>${7}
-snippet link
- <link rel="${1:stylesheet}" href="${2:/css/master.css}" type="text/css" media="${3:screen}" charset="utf-8"`Close()`>${4}
-snippet mailto
- <a href="mailto:${1:joe@example.com}?subject=${2:feedback}">${3:email me}</a>
-snippet meta
- <meta name="${1:name}" content="${2:content}"`Close()`>${3}
-snippet opt
- <option value="${1:option}">${2:$1}</option>${3}
-snippet optt
- <option>${1:option}</option>${2}
-snippet select
- <select name="${1:some_name}" id="${2:$1}">
- <option value="${3:option}">${4:$3}</option>
- </select>${5}
-snippet table
- <table border="${1:0}">
- <tr><th>${2:Header}</th></tr>
- <tr><th>${3:Data}</th></tr>
- </table>${4}
-snippet textarea
- <textarea name="${1:Name}" rows="${2:8}" cols="${3:40}">${4}</textarea>${5}
--- a/vim/snippets/htmldjango.snippets Fri Apr 14 15:01:35 2023 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,135 +0,0 @@
-# Generic Tags
-snippet %
- {% ${1} %}${2}
-snippet %%
- {% ${1:tag_name} %}
- ${2}
- {% end$1 %}
-snippet {
- {{ ${1} }}${2}
-snippet gau
- get_absolute_url${1}
-snippet gfn
- get_full_name${1}
-# Template Tags
-
-snippet autoescape
- {% autoescape ${1:off} %}
- ${2}
- {% endautoescape %}
-snippet block
- {% block ${1} %}
- ${2}
- {% endblock %}
-snippet #
- {# ${1:comment} #}
-snippet comment
- {% comment %}
- ${1}
- {% endcomment %}
-snippet cycle
- {% cycle ${1:val1} ${2:val2} ${3:as ${4}} %}
-snippet debug
- {% debug %}
-snippet extends
- {% extends "${1:base.html}" %}
-snippet filter
- {% filter ${1} %}
- ${2}
- {% endfilter %}
-snippet firstof
- {% firstof ${1} %}
-snippet for
- {% for ${1} in ${2} %}
- ${3}
- {% endfor %}
-snippet empty
- {% empty %}
-snippet if
- {% if ${1} %}
- ${2}
- {% endif %}
-snippet else
- {% else %}
-snippet ifchanged
- {% ifchanged %}${1}{% endifchanged %}
-snippet ifequal
- {% ifequal ${1} ${2} %}
- ${3}
- {% endifequal %}
-snippet ifnotequal
- {% ifnotequal ${1} ${2} %}
- ${3}
- {% endifnotequal %}
-snippet include
- {% include "${1}" %}
-snippet load
- {% load ${1} %}
-snippet now
- {% now "${1:jS F Y H:i}" %}
-snippet regroup
- {% regroup ${1} by ${2} as ${3} %}
-snippet spaceless
- {% spaceless %}${1}{% endspaceless %}
-snippet ssi
- {% ssi ${1} %}
-snippet trans
- {% trans "${1:string}" %}
-snippet url
- {% url ${1} as ${2} %}
-snippet widthratio
- {% widthratio ${1:this_value} ${2:max_value} ${3:100} %}
-snippet with
- {% with ${1} as ${2} %}
-# Template Filters
-
-# Note: Since SnipMate can't determine which template filter you are
-# expanding without the "|" character, these do not add the "|"
-# character. These save a few keystrokes still.
-
-# Note: Template tags that take no arguments are not implemented.
-
-snippet add
- add:"${1}"
-snippet center
- center:"${1}"
-snippet cut
- cut:"${1}"
-snippet date
- date:"${1}"
-snippet default
- default:"${1}"
-snippet defaultifnone
- default_if_none:"${1}"
-snippet dictsort
- dictsort:"${1}"
-snippet dictsortrev
- dictsortreversed:"${1}"
-snippet divisibleby
- divisibleby:"${1}"
-snippet floatformat
- floatformat:"${1}"
-snippet getdigit
- get_digit:"${1}"
-snippet join
- join:"${1}"
-snippet lengthis
- length_is:"${1}"
-snippet pluralize
- pluralize:"${1}"
-snippet removetags
- removetags:"${1}"
-snippet slice
- slice:"${1}"
-snippet stringformat
- stringformat:"${1}"
-snippet time
- time:"${1}"
-snippet truncatewords
- truncatewords:${1}
-snippet truncatewordshtml
- truncatewords_html:${1}
-snippet urlizetrunc
- urlizetrunc:${1}
-snippet wordwrap
- wordwrap:${1}
--- a/vim/snippets/htmljinja.snippets Fri Apr 14 15:01:35 2023 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-/Users/sjl/lib/dotfiles/vim/snippets/jinja.snippets
\ No newline at end of file
--- a/vim/snippets/java.snippets Fri Apr 14 15:01:35 2023 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,78 +0,0 @@
-snippet main
- public static void main (String [] args)
- {
- ${1:/* code */}
- }
-snippet pu
- public
-snippet po
- protected
-snippet pr
- private
-snippet st
- static
-snippet fi
- final
-snippet ab
- abstract
-snippet re
- return
-snippet br
- break;
-snippet de
- default:
- ${1}
-snippet ca
- catch(${1:Exception} ${2:e}) ${3}
-snippet th
- throw
-snippet sy
- synchronized
-snippet im
- import
-snippet j.u
- java.util
-snippet j.i
- java.io.
-snippet j.b
- java.beans.
-snippet j.n
- java.net.
-snippet j.m
- java.math.
-snippet if
- if (${1}) ${2}
-snippet el
- else
-snippet elif
- else if (${1}) ${2}
-snippet wh
- while (${1}) ${2}
-snippet for
- for (${1}; ${2}; ${3}) ${4}
-snippet fore
- for (${1} : ${2}) ${3}
-snippet sw
- switch (${1}) ${2}
-snippet cs
- case ${1}:
- ${2}
- ${3}
-snippet tc
- public class ${1:`Filename()`} extends ${2:TestCase}
-snippet t
- public void test${1:Name}() throws Exception ${2}
-snippet cl
- class ${1:`Filename("", "untitled")`} ${2}
-snippet in
- interface ${1:`Filename("", "untitled")`} ${2:extends Parent}${3}
-snippet m
- ${1:void} ${2:method}(${3}) ${4:throws }${5}
-snippet v
- ${1:String} ${2:var}${3: = null}${4};${5}
-snippet co
- static public final ${1:String} ${2:var} = ${3};${4}
-snippet cos
- static public final String ${1:var} = "${2}";${3}
-snippet as
- assert ${1:test} : "${2:Failure message}";${3}
--- a/vim/snippets/javascript.snippets Fri Apr 14 15:01:35 2023 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,76 +0,0 @@
-# Prototype
-snippet proto
- ${1:class_name}.prototype.${2:method_name} =
- function(${3:first_argument}) {
- ${4:// body...}
- };
-# Function
-snippet fun
- function ${1:function_name} (${2:argument}) {
- ${3:// body...}
- }
-# Anonymous Function
-snippet f
- function(${1}) {${2}};
-# if
-snippet if
- if (${1:true}) {${2}};
-# if ... else
-snippet ife
- if (${1:true}) {${2}}
- else{${3}};
-# tertiary conditional
-snippet t
- ${1:/* condition */} ? ${2:a} : ${3:b}
-# switch
-snippet switch
- switch(${1:expression}) {
- case '${3:case}':
- ${4:// code}
- break;
- ${5}
- default:
- ${2:// code}
- }
-# case
-snippet case
- case '${1:case}':
- ${2:// code}
- break;
- ${3}
-# for (...) {...}
-snippet for
- for (var ${2:i} = 0; $2 < ${1:Things}.length; $2${3:++}) {
- ${4:$1[$2]}
- };
-# for (...) {...} (Improved Native For-Loop)
-snippet forr
- for (var ${2:i} = ${1:Things}.length - 1; $2 >= 0; $2${3:--}) {
- ${4:$1[$2]}
- };
-# while (...) {...}
-snippet wh
- while (${1:/* condition */}) {
- ${2:/* code */}
- }
-# do...while
-snippet do
- do {
- ${2:/* code */}
- } while (${1:/* condition */});
-# Object Method
-snippet :f
- ${1:method_name}: function(${2:attribute}) {
- ${4}
- }${3:,}
-# setTimeout function
-snippet timeout
- setTimeout(function() {${3}}${2}, ${1:10};
-# Get Elements
-snippet get
- getElementsBy${1:TagName}('${2}')${3}
-# Get Element
-snippet gett
- getElementBy${1:Id}('${2}')${3}
-snippet log
- console.log(${1});${2}
--- a/vim/snippets/jinja.snippets Fri Apr 14 15:01:35 2023 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,17 +0,0 @@
-# Generic Tags
-snippet %
- {% ${1} %}${2}
-snippet {
- {{ ${1} }}${2}
-snippet %%
- {% ${1:tag_name} %}
- ${2}
- {% end$1 %}
-
-snippet block
- {% block ${1:content} %}
- ${2}
- {% endblock %}
-snippet blocki
- {% block ${1:content} %}${2}{% endblock %}
-
--- a/vim/snippets/lisp.snippets Fri Apr 14 15:01:35 2023 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,34 +0,0 @@
-snippet defp
- (defparameter ${1} ${2})${3}
-snippet defv
- (defvar ${1} ${2})${3}
-snippet defun
- (defun ${1} (${2})
- ${3})
-snippet defm
- (defmethod ${1} (${2})
- ${3})
-snippet let
- (let ((${1} ${2})${3})
- ${4})
-snippet flet
- (flet ((${1} (${2})
- ${3})${4})
- ${5})
-snippet labels
- (labels ((${1} (${2})
- ${3})${4})
- ${5})
-snippet when
- (when ${1}
- ${2})
-snippet unless
- (unless ${1}
- ${2})
-snippet cond
- (cond (${1} ${2})
- ${3})
-snippet case
- (case ${1}
- (${2} ${3})
- ${4})
--- a/vim/snippets/mako.snippets Fri Apr 14 15:01:35 2023 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,54 +0,0 @@
-snippet def
- <%def name="${1:name}">
- ${2:}
- </%def>
-snippet call
- <%call expr="${1:name}">
- ${2:}
- </%call>
-snippet doc
- <%doc>
- ${1:}
- </%doc>
-snippet text
- <%text>
- ${1:}
- </%text>
-snippet for
- % for ${1:i} in ${2:iter}:
- ${3:}
- % endfor
-snippet if if
- % if ${1:condition}:
- ${2:}
- % endif
-snippet if if/else
- % if ${1:condition}:
- ${2:}
- % else:
- ${3:}
- % endif
-snippet try
- % try:
- ${1:}
- % except${2:}:
- ${3:pass}
- % endtry
-snippet wh
- % while ${1:}:
- ${2:}
- % endwhile
-snippet $
- ${ ${1:} }
-snippet <%
- <% ${1:} %>
-snippet <!%
- <!% ${1:} %>
-snippet inherit
- <%inherit file="${1:filename}" />
-snippet include
- <%include file="${1:filename}" />
-snippet namespace
- <%namespace file="${1:name}" />
-snippet page
- <%page args="${1:}" />
--- a/vim/snippets/markdown.snippets Fri Apr 14 15:01:35 2023 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,10 +0,0 @@
-snippet notice
- <span class="label notice">${1:Notice}</span>
-snippet warning
- <span class="label warning">${1:Warning}</span>
-snippet important
- <span class="label important">${1:Important}</span>
-snippet success
- <span class="label success">${1:Success}</span>
-snippet label
- <span class="label">${1:Note}</span>
--- a/vim/snippets/objc.snippets Fri Apr 14 15:01:35 2023 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,184 +0,0 @@
-# #import <...>
-snippet Imp
- #import <${1:Cocoa/Cocoa.h}>${2}
-# #import "..."
-snippet imp
- #import "${1:`Filename()`.h}"${2}
-# @selector(...)
-snippet sel
- @selector(${1:method}:)${3}
-# @"..." string
-snippet s
- @"${1}"${2}
-# Object
-snippet o
- ${1:NSObject} *${2:foo} = [${3:$1 alloc}]${4};${5}
-# NSLog(...)
-snippet log
- NSLog(@"${1:%@}"${2});${3}
-# Class
-snippet objc
- @interface ${1:`Filename('', 'someClass')`} : ${2:NSObject}
- {
- }
- @end
-
- @implementation $1
- ${3}
- @end
-# Class Interface
-snippet int
- @interface ${1:`Filename('', 'someClass')`} : ${2:NSObject}
- {${3}
- }
- ${4}
- @end
-# Class Implementation
-snippet impl
- @implementation ${1:`Filename('', 'someClass')`}
- ${2}
- @end
-snippet init
- - (id)init
- {
- [super init];
- return self;
- }
-snippet ifself
- if (self = [super init]) {
- ${1:/* code */}
- }
- return self;
-snippet ibo
- IBOutlet ${1:NSSomeClass} *${2:$1};${3}
-# Category
-snippet cat
- @interface ${1:NSObject} (${2:Category})
- @end
-
- @implementation $1 ($2)
- ${3}
- @end
-# Category Interface
-snippet cath
- @interface ${1:NSObject} (${2:Category})
- ${3}
- @end
-# NSArray
-snippet array
- NSMutableArray *${1:array} = [NSMutable array];${2}
-# NSDictionary
-snippet dict
- NSMutableDictionary *${1:dict} = [NSMutableDictionary dictionary];${2}
-# NSBezierPath
-snippet bez
- NSBezierPath *${1:path} = [NSBezierPath bezierPath];${2}
-# Method
-snippet m
- - (${1:id})${2:method}
- {
- ${3}
- }
-# Method declaration
-snippet md
- - (${1:id})${2:method};${3}
-# IBAction declaration
-snippet ibad
- - (IBAction)${1:method}:(${2:id})sender;${3}
-# IBAction method
-snippet iba
- - (IBAction)${1:method}:(${2:id})sender
- {
- ${3}
- }
-# awakeFromNib method
-snippet wake
- - (void)awakeFromNib
- {
- ${1}
- }
-# Class Method
-snippet M
- + (${1:id})${2:method}
- {${3}
- return nil;
- }
-# Sub-method (Call super)
-snippet sm
- - (${1:id})${2:method}
- {
- [super $2];${3}
- return self;
- }
-# Method: Initialize
-snippet I
- + (void) initialize
- {
- [[NSUserDefaults standardUserDefaults] registerDefaults:[NSDictionary dictionaryWIthObjectsAndKeys:
- ${1}@"value", @"key",
- nil]];
- }
-# Accessor Methods For:
-# Object
-snippet objacc
- - (${1:id})${2:thing}
- {
- return $2;
- }
-
- - (void)set$2:($1)${3:new$2}
- {
- [$3 retain];
- [$2 release];
- $2 = $3;
- }${4}
-# for (object in array)
-snippet forin
- for (${1:Class} *${2:some$1} in ${3:array}) {
- ${4}
- }
-snippet forarray
- unsigned int ${1:object}Count = [${2:array} count];
-
- for (unsigned int index = 0; index < $1Count; index++) {
- ${3:id} $1 = [$2 $1AtIndex:index];
- ${4}
- }
-# IBOutlet
-# @property (Objective-C 2.0)
-snippet prop
- @property (${1:retain}) ${2:NSSomeClass} ${3:*$2};${4}
-# @synthesize (Objective-C 2.0)
-snippet syn
- @synthesize ${1:property};${2}
-# [[ alloc] init]
-snippet alloc
- [[${1:foo} alloc] init${2}];${3}
-# retain
-snippet ret
- [${1:foo} retain];${2}
-# release
-snippet rel
- [${1:foo} release];
- ${2:$1 = nil;}
-# autorelease
-snippet arel
- [${1:foo} autorelease];
-# autorelease pool
-snippet pool
- NSAutoreleasePool *${1:pool} = [[NSAutoreleasePool alloc] init];
- ${2:/* code */}
- [$1 drain];
-# Throw an exception
-snippet except
- NSException *${1:badness};
- $1 = [NSException exceptionWithName:@"${2:$1Name}"
- reason:@"${3}"
- userInfo:nil];
- [$1 raise];
-snippet prag
- #pragma mark ${1:foo}
-snippet cl
- @class ${1:Foo};${2}
-snippet color
- [[NSColor ${1:blackColor}] set];
--- a/vim/snippets/perl.snippets Fri Apr 14 15:01:35 2023 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,91 +0,0 @@
-# #!/usr/bin/perl
-snippet #!
- #!/usr/bin/perl
-
-# Hash Pointer
-snippet .
- =>
-# Function
-snippet sub
- sub ${1:function_name} {
- ${2:#body ...}
- }
-# Conditional
-snippet if
- if (${1}) {
- ${2:# body...}
- }
-# Conditional if..else
-snippet ife
- if (${1}) {
- ${2:# body...}
- } else {
- ${3:# else...}
- }
-# Conditional if..elsif..else
-snippet ifee
- if (${1}) {
- ${2:# body...}
- } elsif (${3}) {
- ${4:# elsif...}
- } else {
- ${5:# else...}
- }
-# Conditional One-line
-snippet xif
- ${1:expression} if ${2:condition};${3}
-# Unless conditional
-snippet unless
- unless (${1}) {
- ${2:# body...}
- }
-# Unless conditional One-line
-snippet xunless
- ${1:expression} unless ${2:condition};${3}
-# Try/Except
-snippet eval
- eval {
- ${1:# do something risky...}
- };
- if ($@) {
- ${2:# handle failure...}
- }
-# While Loop
-snippet wh
- while (${1}) {
- ${2:# body...}
- }
-# While Loop One-line
-snippet xwh
- ${1:expression} while ${2:condition};${3}
-# For Loop
-snippet for
- for (my $${2:var} = 0; $$2 < ${1:count}; $$2${3:++}) {
- ${4:# body...}
- }
-# Foreach Loop
-snippet fore
- foreach my $${1:x} (@${2:array}) {
- ${3:# body...}
- }
-# Foreach Loop One-line
-snippet xfore
- ${1:expression} foreach @${2:array};${3}
-# Package
-snippet cl
- package ${1:ClassName};
-
- use base qw(${2:ParentClass});
-
- sub new {
- my $class = shift;
- $class = ref $class if ref $class;
- my $self = bless {}, $class;
- $self;
- }
-
- 1;${3}
-# Read File
-snippet slurp
- my $${1:var};
- { local $/ = undef; local *FILE; open FILE, "<${2:file}"; $$1 = <FILE>; close FILE }${3}
--- a/vim/snippets/php.snippets Fri Apr 14 15:01:35 2023 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,216 +0,0 @@
-snippet php
- <?php
- ${1}
- ?>
-snippet ec
- echo "${1:string}"${2};
-snippet inc
- include '${1:file}';${2}
-snippet inc1
- include_once '${1:file}';${2}
-snippet req
- require '${1:file}';${2}
-snippet req1
- require_once '${1:file}';${2}
-# $GLOBALS['...']
-snippet globals
- $GLOBALS['${1:variable}']${2: = }${3:something}${4:;}${5}
-snippet $_ COOKIE['...']
- $_COOKIE['${1:variable}']${2}
-snippet $_ ENV['...']
- $_ENV['${1:variable}']${2}
-snippet $_ FILES['...']
- $_FILES['${1:variable}']${2}
-snippet $_ Get['...']
- $_GET['${1:variable}']${2}
-snippet $_ POST['...']
- $_POST['${1:variable}']${2}
-snippet $_ REQUEST['...']
- $_REQUEST['${1:variable}']${2}
-snippet $_ SERVER['...']
- $_SERVER['${1:variable}']${2}
-snippet $_ SESSION['...']
- $_SESSION['${1:variable}']${2}
-# Start Docblock
-snippet /*
- /**
- * ${1}
- **/
-# Class - post doc
-snippet doc_cp
- /**
- * ${1:undocumented class}
- *
- * @package ${2:default}
- * @author ${3:`g:snips_author`}
- **/${4}
-# Class Variable - post doc
-snippet doc_vp
- /**
- * ${1:undocumented class variable}
- *
- * @var ${2:string}
- **/${3}
-# Class Variable
-snippet doc_v
- /**
- * ${3:undocumented class variable}
- *
- * @var ${4:string}
- **/
- ${1:var} $${2};${5}
-# Class
-snippet doc_c
- /**
- * ${3:undocumented class}
- *
- * @packaged ${4:default}
- * @author ${5:`g:snips_author`}
- **/
- ${1:}class ${2:}
- {${6}
- } // END $1class $2
-# Constant Definition - post doc
-snippet doc_dp
- /**
- * ${1:undocumented constant}
- **/${2}
-# Constant Definition
-snippet doc_d
- /**
- * ${3:undocumented constant}
- **/
- define(${1}, ${2});${4}
-# Function - post doc
-snippet doc_fp
- /**
- * ${1:undocumented function}
- *
- * @return ${2:void}
- * @author ${3:`g:snips_author`}
- **/${4}
-# Function signature
-snippet doc_s
- /**
- * ${4:undocumented function}
- *
- * @return ${5:void}
- * @author ${6:`g:snips_author`}
- **/
- ${1}function ${2}(${3});${7}
-# Function
-snippet doc_f
- /**
- * ${4:undocumented function}
- *
- * @return ${5:void}
- * @author ${6:`g:snips_author`}
- **/
- ${1}function ${2}(${3})
- {${7}
- }
-# Header
-snippet doc_h
- /**
- * ${1}
- *
- * @author ${2:`g:snips_author`}
- * @version ${3:$Id$}
- * @copyright ${4:$2}, `strftime('%d %B, %Y')`
- * @package ${5:default}
- **/
-
- /**
- * Define DocBlock
- *//
-# Interface
-snippet doc_i
- /**
- * ${2:undocumented class}
- *
- * @package ${3:default}
- * @author ${4:`g:snips_author`}
- **/
- interface ${1:}
- {${5}
- } // END interface $1
-# class ...
-snippet class
- /**
- * ${1}
- **/
- class ${2:ClassName}
- {
- ${3}
- function ${4:__construct}(${5:argument})
- {
- ${6:// code...}
- }
- }
-# define(...)
-snippet def
- define('${1}'${2});${3}
-# defined(...)
-snippet def?
- ${1}defined('${2}')${3}
-snippet wh
- while (${1:/* condition */}) {
- ${2:// code...}
- }
-# do ... while
-snippet do
- do {
- ${2:// code... }
- } while (${1:/* condition */});
-snippet if
- if (${1:/* condition */}) {
- ${2:// code...}
- }
-snippet ife
- if (${1:/* condition */}) {
- ${2:// code...}
- } else {
- ${3:// code...}
- }
- ${4}
-snippet else
- else {
- ${1:// code...}
- }
-snippet elseif
- elseif (${1:/* condition */}) {
- ${2:// code...}
- }
-# Tertiary conditional
-snippet t
- $${1:retVal} = (${2:condition}) ? ${3:a} : ${4:b};${5}
-snippet switch
- switch ($${1:variable}) {
- case '${2:value}':
- ${3:// code...}
- break;
- ${5}
- default:
- ${4:// code...}
- break;
- }
-snippet case
- case '${1:value}':
- ${2:// code...}
- break;${3}
-snippet for
- for ($${2:i} = 0; $$2 < ${1:count}; $$2${3:++}) {
- ${4: // code...}
- }
-snippet foreach
- foreach ($${1:variable} as $${2:key}) {
- ${3:// code...}
- }
-snippet fun
- ${1:public }function ${2:FunctionName}(${3})
- {
- ${4:// code...}
- }
-# $... = array (...)
-snippet array
- $${1:arrayName} = array('${2}' => ${3});${4}
--- a/vim/snippets/python.snippets Fri Apr 14 15:01:35 2023 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,31 +0,0 @@
-snippet #!
- #!/usr/bin/env python
-snippet from
- from ${1:sys} import ${2:*}
-snippet while
- while ${1:True}:
- ${2:pass}
-snippet for
- for ${1:x} in ${2:xs}:
- ${3:pass}
-snippet def
- def ${1:function}(${2}):
- ${3:pass}
-snippet defs
- def ${1:method}(self${2}):
- ${3:pass}
-snippet lam
- lambda ${1:args}: ${2:action}
-snippet ifmain
- if __name__ == '__main__':
- ${1:main()}
-snippet _
- __${1:init}__${2}
-snippet ***
- *args, **kwargs
-snippet af
- assert False, repr(${1})$2
-snippet pdbt
- import pdb; pdb.set_trace()
-snippet pp
- from pprint import pprint; pprint($1)$2
--- a/vim/snippets/ruby.snippets Fri Apr 14 15:01:35 2023 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,420 +0,0 @@
-# #!/usr/bin/ruby
-snippet #!
- #!/usr/bin/ruby
-
-# New Block
-snippet =b
- =begin rdoc
- ${1}
- =end
-snippet y
- :yields: ${1:arguments}
-snippet rb
- #!/usr/bin/env ruby -wKU
-
-snippet req
- require "${1}"${2}
-snippet #
- # =>
-snippet end
- __END__
-snippet case
- case ${1:object}
- when ${2:condition}
- ${3}
- end
-snippet when
- when ${1:condition}
- ${2}
-snippet def
- def ${1:method_name}
- ${2}
- end
-snippet deft
- def test_${1:case_name}
- ${2}
- end
-snippet if
- if ${1:condition}
- ${2}
- end
-snippet ife
- if ${1:condition}
- ${2}
- else
- ${3}
- end
-snippet elsif
- elsif ${1:condition}
- ${2}
-snippet unless
- unless ${1:condition}
- ${2}
- end
-snippet while
- while ${1:condition}
- ${2}
- end
-snippet until
- until ${1:condition}
- ${2}
- end
-snippet cla class .. end
- class ${1:`substitute(Filename(), '^.', '\u&', '')`}
- ${2}
- end
-snippet cla class .. initialize .. end
- class ${1:`substitute(Filename(), '^.', '\u&', '')`}
- def initialize(${2:args})
- ${3}
- end
-
-
- end
-snippet cla class .. < ParentClass .. initialize .. end
- class ${1:`substitute(Filename(), '^.', '\u&', '')`} < ${2:ParentClass}
- def initialize(${3:args})
- ${4}
- end
-
-
- end
-snippet cla ClassName = Struct .. do .. end
- ${1:`substitute(Filename(), '^.', '\u&', '')`} = Struct.new(:${2:attr_names}) do
- def ${3:method_name}
- ${4}
- end
-
-
- end
-snippet cla class BlankSlate .. initialize .. end
- class ${1:BlankSlate}
- instance_methods.each { |meth| undef_method(meth) unless meth =~ /\A__/ }
-snippet cla class << self .. end
- class << ${1:self}
- ${2}
- end
-# class .. < DelegateClass .. initialize .. end
-snippet cla-
- class ${1:`substitute(Filename(), '^.', '\u&', '')`} < DelegateClass(${2:ParentClass})
- def initialize(${3:args})
- super(${4:del_obj})
-
- ${5}
- end
-
-
- end
-snippet mod module .. end
- module ${1:`substitute(Filename(), '^.', '\u&', '')`}
- ${2}
- end
-snippet mod module .. module_function .. end
- module ${1:`substitute(Filename(), '^.', '\u&', '')`}
- module_function
-
- ${2}
- end
-snippet mod module .. ClassMethods .. end
- module ${1:`substitute(Filename(), '^.', '\u&', '')`}
- module ClassMethods
- ${2}
- end
-
- module InstanceMethods
-
- end
-
- def self.included(receiver)
- receiver.extend ClassMethods
- receiver.send :include, InstanceMethods
- end
- end
-# attr_reader
-snippet r
- attr_reader :${1:attr_names}
-# attr_writer
-snippet w
- attr_writer :${1:attr_names}
-# attr_accessor
-snippet rw
- attr_accessor :${1:attr_names}
-# include Enumerable
-snippet Enum
- include Enumerable
-
- def each(&block)
- ${1}
- end
-# include Comparable
-snippet Comp
- include Comparable
-
- def <=>(other)
- ${1}
- end
-# extend Forwardable
-snippet Forw-
- extend Forwardable
-# def self
-snippet defs
- def self.${1:class_method_name}
- ${2}
- end
-# def method_missing
-snippet defmm
- def method_missing(meth, *args, &blk)
- ${1}
- end
-snippet defd
- def_delegator :${1:@del_obj}, :${2:del_meth}, :${3:new_name}
-snippet defds
- def_delegators :${1:@del_obj}, :${2:del_methods}
-snippet am
- alias_method :${1:new_name}, :${2:old_name}
-snippet app
- if __FILE__ == $PROGRAM_NAME
- ${1}
- end
-# usage_if()
-snippet usai
- if ARGV.${1}
- abort "Usage: #{$PROGRAM_NAME} ${2:ARGS_GO_HERE}"${3}
- end
-# usage_unless()
-snippet usau
- unless ARGV.${1}
- abort "Usage: #{$PROGRAM_NAME} ${2:ARGS_GO_HERE}"${3}
- end
-snippet array
- Array.new(${1:10}) { |${2:i}| ${3} }
-snippet hash
- Hash.new { |${1:hash}, ${2:key}| $1[$2] = ${3} }
-snippet file File.foreach() { |line| .. }
- File.foreach(${1:"path/to/file"}) { |${2:line}| ${3} }
-snippet file File.read()
- File.read(${1:"path/to/file"})${2}
-snippet Dir Dir.global() { |file| .. }
- Dir.glob(${1:"dir/glob/*"}) { |${2:file}| ${3} }
-snippet Dir Dir[".."]
- Dir[${1:"glob/**/*.rb"}]${2}
-snippet dir
- Filename.dirname(__FILE__)
-snippet deli
- delete_if { |${1:e}| ${2} }
-snippet fil
- fill(${1:range}) { |${2:i}| ${3} }
-# flatten_once()
-snippet flao
- inject(Array.new) { |${1:arr}, ${2:a}| $1.push(*$2)}${3}
-snippet zip
- zip(${1:enums}) { |${2:row}| ${3} }
-# downto(0) { |n| .. }
-snippet dow
- downto(${1:0}) { |${2:n}| ${3} }
-snippet ste
- step(${1:2}) { |${2:n}| ${3} }
-snippet tim
- times { |${1:n}| ${2} }
-snippet upt
- upto(${1:1.0/0.0}) { |${2:n}| ${3} }
-snippet loo
- loop { ${1} }
-snippet ea
- each { |${1:e}| ${2} }
-snippet eab
- each_byte { |${1:byte}| ${2} }
-snippet eac- each_char { |chr| .. }
- each_char { |${1:chr}| ${2} }
-snippet eac- each_cons(..) { |group| .. }
- each_cons(${1:2}) { |${2:group}| ${3} }
-snippet eai
- each_index { |${1:i}| ${2} }
-snippet eak
- each_key { |${1:key}| ${2} }
-snippet eal
- each_line { |${1:line}| ${2} }
-snippet eap
- each_pair { |${1:name}, ${2:val}| ${3} }
-snippet eas-
- each_slice(${1:2}) { |${2:group}| ${3} }
-snippet eav
- each_value { |${1:val}| ${2} }
-snippet eawi
- each_with_index { |${1:e}, ${2:i}| ${3} }
-snippet reve
- reverse_each { |${1:e}| ${2} }
-snippet inj
- inject(${1:init}) { |${2:mem}, ${3:var}| ${4} }
-snippet map
- map { |${1:e}| ${2} }
-snippet mapwi-
- enum_with_index.map { |${1:e}, ${2:i}| ${3} }
-snippet sor
- sort { |a, b| ${1} }
-snippet sorb
- sort_by { |${1:e}| ${2} }
-snippet ran
- sort_by { rand }
-snippet all
- all? { |${1:e}| ${2} }
-snippet any
- any? { |${1:e}| ${2} }
-snippet cl
- classify { |${1:e}| ${2} }
-snippet col
- collect { |${1:e}| ${2} }
-snippet det
- detect { |${1:e}| ${2} }
-snippet fet
- fetch(${1:name}) { |${2:key}| ${3} }
-snippet fin
- find { |${1:e}| ${2} }
-snippet fina
- find_all { |${1:e}| ${2} }
-snippet gre
- grep(${1:/pattern/}) { |${2:match}| ${3} }
-snippet sub
- ${1:g}sub(${2:/pattern/}) { |${3:match}| ${4} }
-snippet sca
- scan(${1:/pattern/}) { |${2:match}| ${3} }
-snippet max
- max { |a, b|, ${1} }
-snippet min
- min { |a, b|, ${1} }
-snippet par
- partition { |${1:e}|, ${2} }
-snippet rej
- reject { |${1:e}|, ${2} }
-snippet sel
- select { |${1:e}|, ${2} }
-snippet lam
- lambda { |${1:args}| ${2} }
-snippet do
- do |${1:variable}|
- ${2}
- end
-snippet :
- :${1:key} => ${2:"value"}${3}
-snippet ope
- open(${1:"path/or/url/or/pipe"}, "${2:w}") { |${3:io}| ${4} }
-# path_from_here()
-snippet patfh
- File.join(File.dirname(__FILE__), *%2[${1:rel path here}])${2}
-# unix_filter {}
-snippet unif
- ARGF.each_line${1} do |${2:line}|
- ${3}
- end
-# option_parse {}
-snippet optp
- require "optparse"
-
- options = {${1:default => "args"}}
-
- ARGV.options do |opts|
- opts.banner = "Usage: #{File.basename($PROGRAM_NAME)}
-snippet opt
- opts.on( "-${1:o}", "--${2:long-option-name}", ${3:String},
- "${4:Option description.}") do |${5:opt}|
- ${6}
- end
-snippet tc
- require "test/unit"
-
- require "${1:library_file_name}"
-
- class Test${2:$1} < Test::Unit::TestCase
- def test_${3:case_name}
- ${4}
- end
- end
-snippet ts
- require "test/unit"
-
- require "tc_${1:test_case_file}"
- require "tc_${2:test_case_file}"${3}
-snippet as
- assert(${1:test}, "${2:Failure message.}")${3}
-snippet ase
- assert_equal(${1:expected}, ${2:actual})${3}
-snippet asne
- assert_not_equal(${1:unexpected}, ${2:actual})${3}
-snippet asid
- assert_in_delta(${1:expected_float}, ${2:actual_float}, ${3:2 ** -20})${4}
-snippet asio
- assert_instance_of(${1:ExpectedClass}, ${2:actual_instance})${3}
-snippet asko
- assert_kind_of(${1:ExpectedKind}, ${2:actual_instance})${3}
-snippet asn
- assert_nil(${1:instance})${2}
-snippet asnn
- assert_not_nil(${1:instance})${2}
-snippet asm
- assert_match(/${1:expected_pattern}/, ${2:actual_string})${3}
-snippet asnm
- assert_no_match(/${1:unexpected_pattern}/, ${2:actual_string})${3}
-snippet aso
- assert_operator(${1:left}, :${2:operator}, ${3:right})${4}
-snippet asr
- assert_raise(${1:Exception}) { ${2} }
-snippet asnr
- assert_nothing_raised(${1:Exception}) { ${2} }
-snippet asrt
- assert_respond_to(${1:object}, :${2:method})${3}
-snippet ass assert_same(..)
- assert_same(${1:expected}, ${2:actual})${3}
-snippet ass assert_send(..)
- assert_send([${1:object}, :${2:message}, ${3:args}])${4}
-snippet asns
- assert_not_same(${1:unexpected}, ${2:actual})${3}
-snippet ast
- assert_throws(:${1:expected}) { ${2} }
-snippet asnt
- assert_nothing_thrown { ${1} }
-snippet fl
- flunk("${1:Failure message.}")${2}
-# Benchmark.bmbm do .. end
-snippet bm-
- TESTS = ${1:10_000}
- Benchmark.bmbm do |results|
- ${2}
- end
-snippet rep
- results.report("${1:name}:") { TESTS.times { ${2} }}
-# Marshal.dump(.., file)
-snippet Md
- File.open(${1:"path/to/file.dump"}, "wb") { |${2:file}| Marshal.dump(${3:obj}, $2) }${4}
-# Mashal.load(obj)
-snippet Ml
- File.open(${1:"path/to/file.dump"}, "rb") { |${2:file}| Marshal.load($2) }${3}
-# deep_copy(..)
-snippet deec
- Marshal.load(Marshal.dump(${1:obj_to_copy}))${2}
-snippet Pn-
- PStore.new(${1:"file_name.pstore"})${2}
-snippet tra
- transaction(${1:true}) { ${2} }
-# xmlread(..)
-snippet xml-
- REXML::Document.new(File.read(${1:"path/to/file"}))${2}
-# xpath(..) { .. }
-snippet xpa
- elements.each(${1:"//Xpath"}) do |${2:node}|
- ${3}
- end
-# class_from_name()
-snippet clafn
- split("::").inject(Object) { |par, const| par.const_get(const) }
-# singleton_class()
-snippet sinc
- class << self; self end
-snippet nam
- namespace :${1:`Filename()`} do
- ${2}
- end
-snippet tas
- desc "${1:Task description\}"
- task :${2:task_name => [:dependent, :tasks]} do
- ${3}
- end
--- a/vim/snippets/scheme.snippets Fri Apr 14 15:01:35 2023 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-snippet def
- (define (${1:name} ${2:args})
- (${3:body}))
--- a/vim/snippets/sh.snippets Fri Apr 14 15:01:35 2023 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,28 +0,0 @@
-# #!/bin/bash
-snippet #!
- #!/bin/bash
-
-snippet if
- if [[ ${1:condition} ]]; then
- ${2:#statements}
- fi
-snippet elif
- elif [[ ${1:condition} ]]; then
- ${2:#statements}
-snippet for
- for (( ${2:i} = 0; $2 < ${1:count}; $2++ )); do
- ${3:#statements}
- done
-snippet wh
- while [[ ${1:condition} ]]; do
- ${2:#statements}
- done
-snippet until
- until [[ ${1:condition} ]]; do
- ${2:#statements}
- done
-snippet case
- case ${1:word} in
- ${2:pattern})
- ${3};;
- esac
--- a/vim/snippets/snippet.snippets Fri Apr 14 15:01:35 2023 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,7 +0,0 @@
-# snippets for making snippets :)
-snippet snip
- snippet ${1:trigger}
- ${2}
-snippet msnip
- snippet ${1:trigger} ${2:description}
- ${3}
--- a/vim/snippets/tcl.snippets Fri Apr 14 15:01:35 2023 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,92 +0,0 @@
-# #!/usr/bin/tclsh
-snippet #!
- #!/usr/bin/tclsh
-
-# Process
-snippet pro
- proc ${1:function_name} {${2:args}} {
- ${3:#body ...}
- }
-#xif
-snippet xif
- ${1:expr}? ${2:true} : ${3:false}
-# Conditional
-snippet if
- if {${1}} {
- ${2:# body...}
- }
-# Conditional if..else
-snippet ife
- if {${1}} {
- ${2:# body...}
- } else {
- ${3:# else...}
- }
-# Conditional if..elsif..else
-snippet ifee
- if {${1}} {
- ${2:# body...}
- } elseif {${3}} {
- ${4:# elsif...}
- } else {
- ${5:# else...}
- }
-# If catch then
-snippet ifc
- if { [catch {${1:#do something...}} ${2:err}] } {
- ${3:# handle failure...}
- }
-# Catch
-snippet catch
- catch {${1}} ${2:err} ${3:options}
-# While Loop
-snippet wh
- while {${1}} {
- ${2:# body...}
- }
-# For Loop
-snippet for
- for {set ${2:var} 0} {$$2 < ${1:count}} {${3:incr} $2} {
- ${4:# body...}
- }
-# Foreach Loop
-snippet fore
- foreach ${1:x} {${2:#list}} {
- ${3:# body...}
- }
-# after ms script...
-snippet af
- after ${1:ms} ${2:#do something}
-# after cancel id
-snippet afc
- after cancel ${1:id or script}
-# after idle
-snippet afi
- after idle ${1:script}
-# after info id
-snippet afin
- after info ${1:id}
-# Expr
-snippet exp
- expr {${1:#expression here}}
-# Switch
-snippet sw
- switch ${1:var} {
- ${3:pattern 1} {
- ${4:#do something}
- }
- default {
- ${2:#do something}
- }
- }
-# Case
-snippet ca
- ${1:pattern} {
- ${2:#do something}
- }${3}
-# Namespace eval
-snippet ns
- namespace eval ${1:path} {${2:#script...}}
-# Namespace current
-snippet nsc
- namespace current
--- a/vim/snippets/tex.snippets Fri Apr 14 15:01:35 2023 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,115 +0,0 @@
-# \begin{}...\end{}
-snippet begin
- \begin{${1:env}}
- ${2}
- \end{$1}
-# Tabular
-snippet tab
- \begin{${1:tabular}}{${2:c}}
- ${3}
- \end{$1}
-# Align(ed)
-snippet ali
- \begin{align${1:ed}}
- ${2}
- \end{align$1}
-# Gather(ed)
-snippet gat
- \begin{gather${1:ed}}
- ${2}
- \end{gather$1}
-# Equation
-snippet eq
- \begin{equation}
- ${1}
- \end{equation}
-# Unnumbered Equation
-snippet \
- \\[
- ${1}
- \\]
-# Enumerate
-snippet enum
- \begin{enumerate}
- \item ${1}
- \end{enumerate}
-# Itemize
-snippet item
- \begin{itemize}
- \item ${1}
- \end{itemize}
-# Description
-snippet desc
- \begin{description}
- \item[${1}] ${2}
- \end{description}
-# Matrix
-snippet mat
- \begin{${1:p/b/v/V/B/small}matrix}
- ${2}
- \end{$1matrix}
-# Cases
-snippet cas
- \begin{cases}
- ${1:equation}, &\text{ if }${2:case}\\
- ${3}
- \end{cases}
-# Split
-snippet spl
- \begin{split}
- ${1}
- \end{split}
-# Part
-snippet part
- \part{${1:part name}} % (fold)
- \label{prt:${2:$1}}
- ${3}
- % part $2 (end)
-# Chapter
-snippet cha
- \chapter{${1:chapter name}} % (fold)
- \label{cha:${2:$1}}
- ${3}
- % chapter $2 (end)
-# Section
-snippet sec
- \section{${1:section name}} % (fold)
- \label{sec:${2:$1}}
- ${3}
- % section $2 (end)
-# Sub Section
-snippet sub
- \subsection{${1:subsection name}} % (fold)
- \label{sub:${2:$1}}
- ${3}
- % subsection $2 (end)
-# Sub Sub Section
-snippet subs
- \subsubsection{${1:subsubsection name}} % (fold)
- \label{ssub:${2:$1}}
- ${3}
- % subsubsection $2 (end)
-# Paragraph
-snippet par
- \paragraph{${1:paragraph name}} % (fold)
- \label{par:${2:$1}}
- ${3}
- % paragraph $2 (end)
-# Sub Paragraph
-snippet subp
- \subparagraph{${1:subparagraph name}} % (fold)
- \label{subp:${2:$1}}
- ${3}
- % subparagraph $2 (end)
-snippet itd
- \item[${1:description}] ${2:item}
-snippet figure
- ${1:Figure}~\ref{${2:fig:}}${3}
-snippet table
- ${1:Table}~\ref{${2:tab:}}${3}
-snippet listing
- ${1:Listing}~\ref{${2:list}}${3}
-snippet section
- ${1:Section}~\ref{${2:sec:}}${3}
-snippet page
- ${1:page}~\pageref{${2}}${3}
--- a/vim/snippets/vim.snippets Fri Apr 14 15:01:35 2023 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,32 +0,0 @@
-snippet header
- " File: ${1:`expand('%:t')`}
- " Author: ${2:`g:snips_author`}
- " Description: ${3}
- ${4:" Last Modified: `strftime("%B %d, %Y")`}
-snippet guard
- if exists('${1:did_`Filename()`}') || &cp${2: || version < 700}
- finish
- endif
- let $1 = 1${3}
-snippet f
- fun ${1:function_name}(${2})
- ${3:" code}
- endf
-snippet for
- for ${1:needle} in ${2:haystack}
- ${3:" code}
- endfor
-snippet wh
- while ${1:condition}
- ${2:" code}
- endw
-snippet if
- if ${1:condition}
- ${2:" code}
- endif
-snippet ife
- if ${1:condition}
- ${2}
- else
- ${3}
- endif
--- a/vim/snippets/zsh.snippets Fri Apr 14 15:01:35 2023 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,58 +0,0 @@
-# #!/bin/zsh
-snippet #!
- #!/bin/zsh
-
-snippet if
- if ${1:condition}; then
- ${2:# statements}
- fi
-snippet ife
- if ${1:condition}; then
- ${2:# statements}
- else
- ${3:# statements}
- fi
-snippet elif
- elif ${1:condition} ; then
- ${2:# statements}
-snippet for
- for (( ${2:i} = 0; $2 < ${1:count}; $2++ )); do
- ${3:# statements}
- done
-snippet fore
- for ${1:item} in ${2:list}; do
- ${3:# statements}
- done
-snippet wh
- while ${1:condition}; do
- ${2:# statements}
- done
-snippet until
- until ${1:condition}; do
- ${2:# statements}
- done
-snippet repeat
- repeat ${1:integer}; do
- ${2:# statements}
- done
-snippet case
- case ${1:word} in
- ${2:pattern})
- ${3};;
- esac
-snippet select
- select ${1:answer} in ${2:choices}; do
- ${3:# statements}
- done
-snippet (
- ( ${1:#statements} )
-snippet {
- { ${1:#statements} }
-snippet [
- [[ ${1:test} ]]
-snippet always
- { ${1:try} } always { ${2:always} }
-snippet fun
- function ${1:name} (${2:args}) {
- ${3:# body}
- }
--- a/vim/syntax/confluencewiki.vim Fri Apr 14 15:01:35 2023 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,205 +0,0 @@
-"============================================================================
-"
-" Confluence WIKI syntax file
-"
-" Language: Confluence WIKI
-" Version: 0.1.0
-" Maintainer: Daniel Grana <daniel{AT}insophia{DOT}com>
-" Thanks: Ingo Karkat <swdev{AT}ingo-karkat{DOT}de>
-" License: GPL (http://www.gnu.org/licenses/gpl.txt)
-" Copyright (C) 2004 Rainer Thierfelder
-"
-" This program is free software; you can redistribute it and/or modify
-" it under the terms of the GNU General Public License as published by
-" the Free Software Foundation; either version 2 of the License, or
-" (at your option) any later version.
-"
-" This program is distributed in the hope that it will be useful,
-" but WITHOUT ANY WARRANTY; without even the implied warranty of
-" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-" GNU General Public License for more details.
-"
-" You should have received a copy of the GNU General Public License
-" along with this program; if not, write to the Free Software
-" Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-"
-"============================================================================
-"
-" For version 5.x: Clear all syntax items
-" For version 6.x: Quit when a syntax file was already loaded
-if !exists("main_syntax")
- if version < 600
- syntax clear
- elseif exists("b:current_syntax")
- finish
- endif
- let main_syntax = 'confluencewiki'
-endif
-
-" Don't use standard HiLink, it will not work with included syntax files
-if version < 508
- command! -nargs=+ ConfluenceHiLink highlight link <args>
- command! -nargs=+ ConfluenceSynColor highlight <args>
-else
- command! -nargs=+ ConfluenceHiLink highlight default link <args>
- command! -nargs=+ ConfluenceSynColor highlight default <args>
-endif
-
-if v:version >= 700
- syntax spell toplevel
-endif
-
-
-"============================================================================
-" Group Definitions:
-"============================================================================
-
-" Emphasis:
-function! s:ConfluenceCreateEmphasis(token, name)
- execute 'syntax region confluence'.a:name.
- \' oneline start="\(^\|[ ]\)\zs'.a:token.'\%('.a:token.'\)\@!'.
- \'" end="'.a:token.'\ze\([,. ?!()[\]{}:\-]\|$\)"'
-endfunction
-
-syntax region confluenceFixed oneline start="\(^\|[ ]\)\zs{{" end="}}\ze\([,. ?!()[\]{}):\-]\|$\)"
-" Note: Confluence 2.10.1 ignores escaping of \{{monospaced}} (same as {{monospaced}}).
-syntax region confluenceFixed oneline start="{{" end="}}\ze\([,. ?!()[\]{}):\-]\|$\)" contained
-
-call s:ConfluenceCreateEmphasis('\*', 'Bold')
-call s:ConfluenceCreateEmphasis('_', 'Italic')
-call s:ConfluenceCreateEmphasis('??', 'Citation')
-call s:ConfluenceCreateEmphasis('-', 'Strike')
-call s:ConfluenceCreateEmphasis('+', 'Underlined')
-call s:ConfluenceCreateEmphasis('\^', 'Superscript')
-call s:ConfluenceCreateEmphasis('\~', 'Subscript')
-
-
-" Syntax:
-" Note: Confluence 2.10.1 ignores escaping of \{{monospaced}} (same as {{monospaced}}).
-"syntax match confluenceEscaping "\\\%(??\|{{\|[*_\-+^~{!\[(]\)" contains=confluenceEscapeCharacter
-syntax match confluenceEscaping "\\\%(??\|{{\|[*_\-+^~{!\[(]\)" contains=confluenceEscapeCharacter,confluenceFixed
-syntax match confluenceEscapeCharacter "\\" contained
-syntax match confluenceDelimiter "|"
-syntax match confluenceDelimiter "||[^|]" contains=confluenceTableHeader
-syntax match confluenceDelimiter "[^|]||"
-syntax match confluenceTableHeader "||\zs[^|]\+\ze||" contained contains=ALLBUT,confluenceDelimiter
-syntax match confluenceSymbols "\%(^\|\s\)\zs-\{2,3}\ze\%($\|\s\)"
-syntax match confluenceSeparator "^\s*----\s*$"
-syntax match confluenceList "^[*#]\+\ze "
-syntax match confluenceSingleList "^-\ze "
-
-"syntax match confluenceVariable "\([^!]\|^\)\zs%\w\+%"
-
-" tag support is a limited to no white spaces in tag parameters
-syntax match confluenceTagParameterName "[:|]\zs\w\+=\?[^|}]\+" contained contains=@NoSpell,confluenceTagParameterValue
-syntax match confluenceTagParameterValue "\w\+=\zs[^|}]\+" contained contains=@NoSpell
-syntax match confluenceTag "{\%(\w\|-\)\+\(:\(\w\+=\?[^|}]\+|\?\)*\)\?}" contains=@NoSpell,confluenceTagParameterName
-
-syntax region confluenceComment start="{HTMLcomment\%(:hidden\)\?}" end="{HTMLcomment}" keepend contains=TOP
-
-syntax match confluenceCodeTag "{code\(:\(\w\+=\?[^|}]\+|\?\)*\)\?}" contains=confluenceTagParameterName,@NoSpell contained
-syntax region confluenceCode start="{code\(:\(\w\+=\?[^|}]\+|\?\)*\)\?}" end="{code}" keepend contains=confluenceCodeTag
-syntax match confluenceVerbatimTag "{noformat\(:\(\w\+=\?[^|}]\+|\?\)*\)\?}" contains=confluenceTagParameterName,@NoSpell contained
-syntax region confluenceVerbatim start="{noformat\(:\(\w\+=\?[^|}]\+|\?\)*\)\?}" end="{noformat}" keepend contains=confluenceVerbatimTag
-
-syntax match confluenceQuoteMarker "^bq. " contains=@NoSpell contained
-syntax match confluenceQuote "^bq. .*$" contains=confluenceQuoteMarker
-syntax region confluenceQuote start="{quote}" end="{quote}" keepend contains=TOP
-
-syntax match confluenceHeadingMarker "^h[1-6]. " contains=@NoSpell contained
-syntax match confluenceHeading "^h[1-6]. .*$" contains=confluenceHeadingMarker
-
-" Note: Confluence 2.10.1 does not escape smileys \:) \:( \:P \:D \;)
-syntax match confluenceEmoticons "\%(^\|\s\)\zs\%(:)\|:(\|:P\|:D\|;)\)\ze\%($\|\s\)"
-syntax match confluenceEmoticons "\%(^\|[^\\]\)\zs([yni/x!+-?*])\|(\%(on\|off\))"
-
-let s:wikiWord = '\u[a-z0-9]\+\(\u[a-z0-9]\+\)\+'
-
-execute 'syntax match confluenceAnchor +^#'.s:wikiWord.'\ze\(\>\|_\)+'
-execute 'syntax match confluenceWord +\(\s\|^\)\zs\(\u\l\+\.\)\='.s:wikiWord.'\(#'.s:wikiWord.'\)\=\ze\(\>\|_\)+'
-" Regex guide: ^pre ^web name ^wikiword ^anchor ^ post
-
-" Images:
-syntax match confluenceImageParameterName "[,|]\zs\w\+=\?[^,!]\+" contained contains=confluenceImageParameterValue,@NoSpell
-syntax match confluenceImageParameterValue "\w\+=\zs[^,!]\+" contained contains=@NoSpell
-syntax match confluenceImageLink "!\zs\S[^|!]*" contained contains=@NoSpell
-syntax match confluenceImage "!\S[^!]*\S!" contains=confluenceImageLink,confluenceImageParameterName
-
-" Links:
-syntax match confluenceLink "\[[^|\]]\+\]" contains=confluenceLinkStart,confluenceLinkEnd,@NoSpell
-syntax match confluenceLink "\[[^|\]]\+|[^|\]]\+\]" contains=confluenceLinkMarker,confluenceLinkEnd,confluenceLinkLabel,@NoSpell
-syntax match confluenceLink "\[[^|\]]\+|[^|\]]\+|[^|\]]\+\]" contains=confluenceLinkMarker,confluenceLinkLabel,confluenceLinkTip,@NoSpell
-
-syntax match confluenceLinkLabel "\[[^|\]]\+\ze|" contained contains=confluenceLinkStart
-syntax match confluenceLinkTip "[^|\]]\+\]" contained contains=confluenceLinkEnd
-syntax match confluenceLinkMarker "|" contained
-syntax match confluenceLinkStart "\[" contained
-syntax match confluenceLinkEnd "\]" contained
-
-"============================================================================
-" Group Linking:
-"============================================================================
-
-ConfluenceHiLink confluenceEscapeCharacter Type
-ConfluenceHiLink confluenceHeading Title
-ConfluenceHiLink confluenceHeadingMarker Type
-ConfluenceHiLink confluenceVariable PreProc
-ConfluenceHiLink confluenceTagParameterName Type
-ConfluenceHiLink confluenceTagParameterValue Constant
-ConfluenceHiLink confluenceCodeTag PreProc
-ConfluenceHiLink confluenceVerbatimTag PreProc
-ConfluenceHiLink confluenceTag PreProc
-ConfluenceHiLink confluenceQuoteMarker Type
-ConfluenceHiLink confluenceQuote String
-ConfluenceHiLink confluenceComment Comment
-ConfluenceHiLink confluenceWord Tag
-ConfluenceHiLink confluenceAnchor PreProc
-ConfluenceHiLink confluenceVerbatim Constant
-ConfluenceHiLink confluenceCode Constant
-ConfluenceHiLink confluenceList Type
-ConfluenceHiLink confluenceSingleList Type
-ConfluenceSynColor confluenceTableHeader term=bold cterm=bold gui=bold
-
-ConfluenceHiLink confluenceDelimiter Type
-ConfluenceHiLink confluenceSeparator Type
-
-ConfluenceHiLink confluenceEmoticons Special
-ConfluenceHiLink confluenceSymbols Special
-
-" Images
-ConfluenceHiLink confluenceImageParameterName Type
-ConfluenceHiLink confluenceImageParameterValue Constant
-ConfluenceHiLink confluenceImageLink Underlined
-ConfluenceHiLink confluenceImage PreProc
-
-" Links
-ConfluenceHiLink confluenceLinkMarker Type
-ConfluenceHiLink confluenceLinkStart Type
-ConfluenceHiLink confluenceLinkEnd Type
-ConfluenceHiLink confluenceLink Underlined
-ConfluenceHiLink confluenceLinkLabel Identifier
-ConfluenceHiLink confluenceLinkTip NonText
-
-" Emphasis
-ConfluenceHiLink confluenceFixed Constant
-ConfluenceSynColor confluenceBold term=bold cterm=bold gui=bold
-ConfluenceSynColor confluenceItalic term=italic cterm=italic gui=italic
-ConfluenceHiLink confluenceCitation String
-ConfluenceHiLink confluenceStrike Special
-ConfluenceSynColor confluenceUnderlined term=underline cterm=underline gui=underline
-ConfluenceHiLink confluenceSuperscript Special
-ConfluenceHiLink confluenceSubscript Special
-
-"============================================================================}" Clean Up: {{{1
-"============================================================================
-
-delcommand ConfluenceHiLink
-delcommand ConfluenceSynColor
-
-if main_syntax == 'confluencewiki'
- unlet main_syntax
-endif
-
-let b:current_syntax = "confluencewiki"
-
-" vim:fdm=marker
--- a/vim/syntax/creole.vim Fri Apr 14 15:01:35 2023 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,92 +0,0 @@
-" Vim syntax file
-" Language: creole
-" Maintainer: Peter Hoffmann <ph@peter-hoffmann.com>
-" Last Change: 2007 May 31
-
-" This syntax file is based on the wiki.vim syntax file from Andreas Kneib
-
-" Little syntax file to use a wiki-editor with VIM
-" (if your browser allow this action)
-" To use this syntax file:
-" 1. mkdir ~/.vim/syntax
-" 2. mv ~/creole.vim ~/.vim/syntax/creole.vim
-" 3. :set syntax=creole
-"
-
-"Some hints to extend wiki creole editing
-"set path=.,~/wiki/
-"au BufRead,BufNewFile *.txt setfiletype creole
-
-"write current file and open file under cursor in new tab
-"nnoremap gF :w<cr> :tabedit <cfile><cr>
-
-"use the snippetsEmu plugin for wiki code
-"Snippet { {{{<CR><{}><CR>}}}<CR><{}>
-"Snippet * **<{}>** <{}>
-"Snippet _ __<{}>__ <{}>
-"Snippet - --<{}>-- <{}>
-"Snippet [ [[<{}>]] <{}>
-
-
-" Quit if syntax file is already loaded
-if version < 600
- syntax clear
-elseif exists("b:current_syntax")
- finish
-endif
-
-if version < 508
- command! -nargs=+ WikiHiLink hi link <args>
-else
- command! -nargs=+ WikiHiLink hi def link <args>
-endif
-
-syn match wikiLine "^----$"
-"TODO add different markup for [[link|name]] type of links
-syn region wikiLink start=+\[\[+hs=s+2 end=+\]\]+he=e-2
-syn match wikiList "^[*#]* "
-syn region wikiCurly start="{\{3\}" end="}\{3\}"
-syn region wikiHead start="^=" end="$"
-"syn region wikiSubhead start="^== " end="$"
-"TODO add syntax for tables
-
-"try to not get confused with wikiLink
-syn region wikiBold start="\*\*[^ ]" end="\*\*"
-"try to not get confused with http://
-"FIXME does not work at beginning of line
-syn region wikiItalic start="[^:]\/\/"hs=s+1 end="[^:]\/\/"
-syn region wikiUnderline start="__" end="__"
-"syn region wikiStrike start="--" end="--"
-"TODO add regions for mixed markup
-"syn region wikiBoldItalic contained start=+\([^']\|^\)''[^']+ end=+[^']''\([^']\|$\)+
-"syn region wikiItalicBold contained start=+'''+ end=+'''+
-
-" The default highlighting.
-if version >= 508 || !exists("did_wiki_syn_inits")
- if version < 508
- let did_wiki_syn_inits = 1
- endif
-
-WikiHiLink wikiCurly Type
-WikiHiLink wikiHead Statement
-" WikiHiLink wikiSubhead PreProc
-WikiHiLink wikiList String
-WikiHiLink wikiExtLink Identifier
-WikiHiLink wikiLink Identifier
-WikiHiLink wikiLine PreProc
-
-hi def wikiBold term=bold cterm=bold gui=bold
- " hi def wikiBoldItalic term=bold,italic cterm=bold,italic gui=bold,italic
-hi def wikiItalic term=italic cterm=italic gui=italic
- " hi def wikiItalicBold term=bold,italic cterm=bold,italic gui=bold,italic
-hi def wikiUnderline term=underline cterm=underline gui=underline
-"hi def wikiStrike ???
-
-endif
-
-delcommand WikiHiLink
-
-let b:current_syntax = "creole"
-
-"EOF vim: tw=78:ft=vim:ts=8
-
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/syntax/hcl.vim Fri Jul 07 16:11:02 2023 -0400
@@ -0,0 +1,72 @@
+" Forked from Larry Gilbert's syntax file
+" github.com/L2G/vim-syntax-terraform
+if exists('b:current_syntax')
+ finish
+endif
+
+let s:cpo_save = &cpoptions
+set cpoptions&vim
+
+" Identifiers are made up of alphanumeric characters, underscores, and
+" hyphens.
+if has('patch-7.4.1142')
+ syn iskeyword a-z,A-Z,48-57,_,-
+endif
+
+syn case match
+
+" A block is introduced by a type, some number of labels - which are either
+" strings or identifiers - and an opening curly brace. Match the type.
+syn match hclBlockType /^\s*\zs\K\k*\ze\s\+\(\("\K\k*"\|\K\k*\)\s\+\)*{/
+
+" An attribute name is an identifier followed by an equals sign.
+syn match hclAttributeAssignment /\(\K\k*\.\)*\K\k*\s\+=\s/ contains=hclAttributeName
+syn match hclAttributeName /\<\K\k*\>/ contained
+
+syn keyword hclValueBool true false
+
+syn keyword hclTodo contained TODO FIXME XXX BUG
+syn region hclComment start="/\*" end="\*/" contains=hclTodo,@Spell
+syn region hclComment start="#" end="$" contains=hclTodo,@Spell
+syn region hclComment start="//" end="$" contains=hclTodo,@Spell
+
+""" misc.
+syn match hclValueDec "\<[0-9]\+\([kKmMgG]b\?\)\?\>"
+syn match hclValueHexaDec "\<0x[0-9a-f]\+\([kKmMgG]b\?\)\?\>"
+syn match hclBraces "[\[\]]"
+
+""" skip \" and \\ in strings.
+syn region hclValueString start=/"/ skip=/\\\\\|\\"/ end=/"/ contains=hclStringInterp
+syn region hclStringInterp matchgroup=hclBraces start=/\(^\|[^$]\)\$\zs{/ end=/}/ contained contains=ALLBUT,hclAttributeName
+syn region hclHereDocText start=/<<-\?\z([a-z0-9A-Z]\+\)/ end=/^\s*\z1/ contains=hclStringInterp
+
+"" Functions.
+syn match hclFunction "[a-z0-9]\+(\@="
+
+""" HCL2
+syn keyword hclRepeat for in
+syn keyword hclConditional if
+syn keyword hclValueNull null
+
+" enable block folding
+syn region hclBlockBody matchgroup=hclBraces start="{" end="}" fold transparent
+
+hi def link hclComment Comment
+hi def link hclTodo Todo
+hi def link hclBraces Delimiter
+hi def link hclAttributeName Identifier
+hi def link hclBlockType Type
+hi def link hclValueBool Boolean
+hi def link hclValueDec Number
+hi def link hclValueHexaDec Number
+hi def link hclValueString String
+hi def link hclHereDocText String
+hi def link hclFunction Function
+hi def link hclRepeat Repeat
+hi def link hclConditional Conditional
+hi def link hclValueNull Constant
+
+let b:current_syntax = 'hcl'
+
+let &cpoptions = s:cpo_save
+unlet s:cpo_save
--- a/vim/syntax/io.vim Fri Apr 14 15:01:35 2023 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,89 +0,0 @@
-" Vim Syntax File
-" Language: Io
-" Creator: Scott Dunlop <swdunlop@verizon.net>
-" Fixes: Manpreet Singh <junkblocker@yahoo.com>
-" Jonathan Wright <quaggy@gmail.com>
-" Erik Garrison <erik.garrison@gmail.com>
-" Last Change: 2006 Nov 16
-
-if version < 600
- syntax clear
-elseif exists("b:current_syntax")
- finish
-endif
-
-syntax case match
-
-" equivalent to io-mode-prototype-names in io-mode.el
-syntax keyword ioType Array AudioDevice AudioMixer Block Box Buffer CFunction
-syntax keyword ioType CGI Color Curses DBM DNSResolver DOConnection DOProxy
-syntax keyword ioType DOServer Date Directory Duration DynLib Error Exception
-syntax keyword ioType FFT File Fnmatch Font Future GL GLE GLScissor GLU
-syntax keyword ioType GLUCylinder GLUQuadric GLUSphere GLUT Host Image Importer
-syntax keyword ioType LinkList List Lobby Locals MD5 MP3Decoder MP3Encoder Map
-syntax keyword ioType Message Movie Notification Number Object
-syntax keyword ioType OpenGL Point Protos Regex SGML SGMLElement SGMLParser SQLite Server Sequence
-syntax keyword ioType ShowMessage SleepyCat SleepyCatCursor Socket
-syntax keyword ioType SocketManager Sound Soup Store String Tree UDPSender
-syntax keyword ioType UPDReceiver URL User Warning WeakLink
-syntax keyword ioType true false nil Random BigNum Sequence
-
-" equivalent to io-mode-message-names in io-mode.el
-syntax keyword ioKeyword activate activeCoroCount and asString block break
-syntax keyword ioKeyword catch clone collectGarbage compileString continue
-syntax keyword ioKeyword do doFile doMessage doString else elseif exit for
-syntax keyword ioKeyword foreach forward getSlot getEnvironmentVariable hasSlot if ifFalse
-syntax keyword ioKeyword ifNil ifNilEval ifTrue isActive isNil isResumable list message
-syntax keyword ioKeyword method or parent pass pause perform
-syntax keyword ioKeyword performWithArgList print println proto raise raiseResumable
-syntax keyword ioKeyword removeSlot resend resume return
-syntax keyword ioKeyword schedulerSleepSeconds self sender
-syntax keyword ioKeyword setSchedulerSleepSeconds setSlot shallowCopy
-syntax keyword ioKeyword slotNames super system then thisBlock thisContext
-syntax keyword ioKeyword call try type uniqueId updateSlot wait while
-syntax keyword ioKeyword write yield
-
-syntax region ioOperator start=':' end='='
-syntax region ioOperator start='!' end='='
-syntax region ioOperator start='@' end='@'
-syntax region ioOperator start='@' end='[^@]'he=e-1
-syntax region ioOperator start='?' end='?'
-syntax region ioOperator start='?' end='[^?]'he=e-1
-syntax region ioOperator start=';' end=';'
-syntax region ioOperator start=';' end='[^;]'he=e-1
-syntax region ioOperator start='\.' end='\.'
-syntax region ioOperator start='\.' end='[^\.]'he=e-1
-syntax region ioOperator start='=' end='='
-syntax region ioOperator start='=' end=' 'he=e-1
-syntax region ioOperator start='[*/>=+-]' end='[ 0-9]'he=e-1
-
-syntax region ioString start=/"/ skip=/\\./ end=/"/
-syntax region ioString start=/"""/ skip=/\\./ end=/"""/
-
-syn match ioHexNumber "\<0[xX]\x\+[lL]\=\>" display
-syn match ioHexNumber "\<0[xX]\>" display
-syn match ioNumber "\<\d\+[lLjJ]\=\>" display
-syn match ioFloat "\.\d\+\([eE][+-]\=\d\+\)\=[jJ]\=\>" display
-syn match ioFloat "\<\d\+[eE][+-]\=\d\+[jJ]\=\>" display
-syn match ioFloat "\<\d\+\.\d*\([eE][+-]\=\d\+\)\=[jJ]\=" display
-
-syn match ioOctalError "\<0\o*[89]\d*[lL]\=\>" display
-syn match ioError "\<0[xX]\X\+[lL]\=\>" display
-
-syntax region ioComment start='#' end='$' keepend
-syntax region ioComment start=/\/\*/ end=/\*\//
-syntax region ioComment start=/\/\// end=/$/ keepend
-
-highlight link ioType Type
-highlight link ioKeyword Function
-highlight link ioString String
-highlight link ioComment Comment
-highlight link ioOperator Operator
-
-highlight link ioHexNumber Number
-highlight link ioNumber Number
-highlight link ioFloat Float
-highlight link ioOctalError Error
-highlight link ioError Error
-
-let b:current_syntax = "io"
\ No newline at end of file
--- a/vim/syntax/less.vim Fri Apr 14 15:01:35 2023 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,312 +0,0 @@
-" Vim syntax file
-" Language: LESS Cascading Style Sheets
-" Maintainer: Leaf Corcoran <leafot@gmail.com>
-" Modifier: Bryan J Swift <bryan@bryanjswift.com>
-" URL: http://leafo.net/lessphp/vim/less.vim
-" URL: http://gist.github.com/161047
-" Last Change: 2009 August 4
-" LESS by Leaf Corcoran
-" CSS2 by Nikolai Weibull
-" Full CSS2, HTML4 support by Yeti
-
-" For version 5.x: Clear all syntax items
-" For version 6.x: Quit when a syntax file was already loaded
-if !exists("main_syntax")
- if version < 600
- syntax clear
- elseif exists("b:current_syntax")
- finish
-endif
- let main_syntax = 'less'
-endif
-
-syn case ignore
-
-
-
-syn keyword cssTagName abbr acronym address applet area a b base
-syn keyword cssTagName basefont bdo big blockquote body br button
-syn keyword cssTagName caption center cite code col colgroup dd del
-syn keyword cssTagName dfn dir div dl dt em fieldset font form frame
-syn keyword cssTagName frameset h1 h2 h3 h4 h5 h6 head hr html img i
-syn keyword cssTagName iframe img input ins isindex kbd label legend li
-syn keyword cssTagName link map menu meta noframes noscript ol optgroup
-syn keyword cssTagName option p param pre q s samp script select small
-syn keyword cssTagName span strike strong style sub sup tbody td
-syn keyword cssTagName textarea tfoot th thead title tr tt ul u var
-syn match cssTagName "\<table\>"
-syn match cssTagName "\*"
-
-" HTML 5
-syn keyword cssTagName article aside header hgroup footer section nav figure
-syn keyword cssTagName figcaption mark summary command datalist details output
-syn keyword cssTagName progress meter time embed keygen wbr audio video canvas
-
-
-syn match cssTagName "@page\>" nextgroup=cssDefinition
-
-syn match cssSelectorOp "[+>.]"
-syn match cssSelectorOp2 "[~|]\?=" contained
-syn region cssAttributeSelector matchgroup=cssSelectorOp start="\[" end="]" transparent contains=cssUnicodeEscape,cssSelectorOp2,cssStringQ,cssStringQQ
-
-try
-syn match cssIdentifier "#[A-Za-zÀ-ÿ_@][A-Za-zÀ-ÿ0-9_@-]*"
-catch /^.*/
-syn match cssIdentifier "#[A-Za-z_@][A-Za-z0-9_@-]*"
-endtry
-
-syn match cssMedia "@media\>" nextgroup=cssMediaType skipwhite skipnl
-syn keyword cssMediaType contained screen print aural braile embosed handheld projection ty tv all nextgroup=cssMediaComma,cssMediaBlock skipwhite skipnl
-syn match cssMediaComma "," nextgroup=cssMediaType skipwhite skipnl
-syn region cssMediaBlock transparent matchgroup=cssBraces start='{' end='}' contains=cssTagName,cssError,cssComment,cssDefinition,cssURL,cssUnicodeEscape,cssIdentifier
-
-syn match cssValueInteger "[-+]\=\d\+"
-syn match cssValueNumber "[-+]\=\d\+\(\.\d*\)\="
-syn match cssValueLength "[-+]\=\d\+\(\.\d*\)\=\(%\|mm\|cm\|in\|pt\|pc\|em\|ex\|px\)"
-
-syn match cssValueAngle contained "[-+]\=\d\+\(\.\d*\)\=\(deg\|grad\|rad\)"
-syn match cssValueTime contained "+\=\d\+\(\.\d*\)\=\(ms\|s\)"
-syn match cssValueFrequency contained "+\=\d\+\(\.\d*\)\=\(Hz\|kHz\)"
-
-syn match cssFontDescriptor "@font-face\>" nextgroup=cssFontDescriptorBlock skipwhite skipnl
-syn region cssFontDescriptorBlock contained transparent matchgroup=cssBraces start="{" end="}" contains=cssComment,cssError,cssUnicodeEscape,cssFontProp,cssFontAttr,cssCommonAttr,cssStringQ,cssStringQQ,cssFontDescriptorProp,cssValue.*,cssFontDescriptorFunction,cssUnicodeRange,cssFontDescriptorAttr
-syn match cssFontDescriptorProp contained "\<\(unicode-range\|unit-per-em\|panose-1\|cap-height\|x-height\|definition-src\)\>"
-syn keyword cssFontDescriptorProp contained src stemv stemh slope ascent descent widths bbox baseline centerline mathline topline
-syn keyword cssFontDescriptorAttr contained all
-syn region cssFontDescriptorFunction contained matchgroup=cssFunctionName start="\<\(uri\|url\|local\|format\)\s*(" end=")" contains=cssStringQ,cssStringQQ oneline keepend
-syn match cssUnicodeRange contained "U+[0-9A-Fa-f?]\+"
-syn match cssUnicodeRange contained "U+\x\+-\x\+"
-
-syn keyword cssColor contained aqua black blue fuchsia gray green lime maroon navy olive purple red silver teal yellow
-" FIXME: These are actually case-insentivie too, but (a) specs recommend using
-" mixed-case (b) it's hard to highlight the word `Background' correctly in
-" all situations
-syn case match
-syn keyword cssColor contained ActiveBorder ActiveCaption AppWorkspace ButtonFace ButtonHighlight ButtonShadow ButtonText CaptionText GrayText Highlight HighlightText InactiveBorder InactiveCaption InactiveCaptionText InfoBackground InfoText Menu MenuText Scrollbar ThreeDDarkShadow ThreeDFace ThreeDHighlight ThreeDLightShadow ThreeDShadow Window WindowFrame WindowText Background
-syn case ignore
-syn match cssColor contained "\<transparent\>"
-syn match cssColor contained "\<white\>"
-syn match cssColor contained "#[0-9A-Fa-f]\{3\}\>"
-syn match cssColor contained "#[0-9A-Fa-f]\{6\}\>"
-"syn match cssColor contained "\<rgb\s*(\s*\d\+\(\.\d*\)\=%\=\s*,\s*\d\+\(\.\d*\)\=%\=\s*,\s*\d\+\(\.\d*\)\=%\=\s*)"
-syn region cssURL contained matchgroup=cssFunctionName start="\<url\s*(" end=")" oneline keepend
-syn region cssFunction contained matchgroup=cssFunctionName start="\<\(rgb\|clip\|attr\|counter\|rect\)\s*(" end=")" oneline keepend
-
-syn match cssImportant contained "!\s*important\>"
-
-syn keyword cssCommonAttr contained auto none inherit
-syn keyword cssCommonAttr contained top bottom
-syn keyword cssCommonAttr contained medium normal
-
-syn match cssFontProp contained "\<font\>\(-\(family\|style\|variant\|weight\|size\(-adjust\)\=\|stretch\)\>\)\="
-syn match cssFontAttr contained "\<\(sans-\)\=\<serif\>"
-syn match cssFontAttr contained "\<small\>\(-\(caps\|caption\)\>\)\="
-syn match cssFontAttr contained "\<x\{1,2\}-\(large\|small\)\>"
-syn match cssFontAttr contained "\<message-box\>"
-syn match cssFontAttr contained "\<status-bar\>"
-syn match cssFontAttr contained "\<\(\(ultra\|extra\|semi\|status-bar\)-\)\=\(condensed\|expanded\)\>"
-syn keyword cssFontAttr contained cursive fantasy monospace italic oblique
-syn keyword cssFontAttr contained bold bolder lighter larger smaller
-syn keyword cssFontAttr contained icon menu
-syn match cssFontAttr contained "\<caption\>"
-syn keyword cssFontAttr contained large smaller larger
-syn keyword cssFontAttr contained narrower wider
-
-syn keyword cssColorProp contained color
-syn match cssColorProp contained "\<background\(-\(color\|image\|attachment\|position\)\)\="
-syn keyword cssColorAttr contained center scroll fixed
-syn match cssColorAttr contained "\<repeat\(-[xy]\)\=\>"
-syn match cssColorAttr contained "\<no-repeat\>"
-
-syn match cssTextProp "\<\(\(word\|letter\)-spacing\|text\(-\(decoration\|transform\|align\|index\|shadow\)\)\=\|vertical-align\|unicode-bidi\|line-height\)\>"
-syn match cssTextAttr contained "\<line-through\>"
-syn match cssTextAttr contained "\<text-indent\>"
-syn match cssTextAttr contained "\<\(text-\)\=\(top\|bottom\)\>"
-syn keyword cssTextAttr contained underline overline blink sub super middle
-syn keyword cssTextAttr contained capitalize uppercase lowercase center justify baseline sub super
-
-syn match cssBoxProp contained "\<\(margin\|padding\|border\)\(-\(top\|right\|bottom\|left\)\)\=\>"
-syn match cssBoxProp contained "\<border-\(\(\(top\|right\|bottom\|left\)-\)\=\(width\|color\|style\)\)\=\>"
-syn match cssBoxProp contained "\<\(width\|z-index\)\>"
-syn match cssBoxProp contained "\<\(min\|max\)-\(width\|height\)\>"
-syn keyword cssBoxProp contained width height float clear overflow clip visibility
-syn keyword cssBoxAttr contained thin thick both
-syn keyword cssBoxAttr contained dotted dashed solid double groove ridge inset outset
-syn keyword cssBoxAttr contained hidden visible scroll collapse
-
-syn keyword cssGeneratedContentProp contained content quotes
-syn match cssGeneratedContentProp contained "\<counter-\(reset\|increment\)\>"
-syn match cssGeneratedContentProp contained "\<list-style\(-\(type\|position\|image\)\)\=\>"
-syn match cssGeneratedContentAttr contained "\<\(no-\)\=\(open\|close\)-quote\>"
-syn match cssAuralAttr contained "\<lower\>"
-syn match cssGeneratedContentAttr contained "\<\(lower\|upper\)-\(roman\|alpha\|greek\|latin\)\>"
-syn match cssGeneratedContentAttr contained "\<\(hiragana\|katakana\)\(-iroha\)\=\>"
-syn match cssGeneratedContentAttr contained "\<\(decimal\(-leading-zero\)\=\|cjk-ideographic\)\>"
-syn keyword cssGeneratedContentAttr contained disc circle square hebrew armenian georgian
-syn keyword cssGeneratedContentAttr contained inside outside
-
-syn match cssPagingProp contained "\<page\(-break-\(before\|after\|inside\)\)\=\>"
-syn keyword cssPagingProp contained size marks inside orphans widows
-syn keyword cssPagingAttr contained landscape portrait crop cross always avoid
-
-syn keyword cssUIProp contained cursor
-syn match cssUIProp contained "\<outline\(-\(width\|style\|color\)\)\=\>"
-syn match cssUIAttr contained "\<[ns]\=[ew]\=-resize\>"
-syn keyword cssUIAttr contained default crosshair pointer move wait help
-syn keyword cssUIAttr contained thin thick
-syn keyword cssUIAttr contained dotted dashed solid double groove ridge inset outset
-syn keyword cssUIAttr contained invert
-
-syn match cssRenderAttr contained "\<marker\>"
-syn match cssRenderProp contained "\<\(display\|marker-offset\|unicode-bidi\|white-space\|list-item\|run-in\|inline-table\)\>"
-syn keyword cssRenderProp contained position top bottom direction
-syn match cssRenderProp contained "\<\(left\|right\)\>"
-syn keyword cssRenderAttr contained block inline compact
-syn match cssRenderAttr contained "\<table\(-\(row-gorup\|\(header\|footer\)-group\|row\|column\(-group\)\=\|cell\|caption\)\)\=\>"
-syn keyword cssRenderAttr contained static relative absolute fixed
-syn keyword cssRenderAttr contained ltr rtl embed bidi-override pre nowrap
-syn match cssRenderAttr contained "\<bidi-override\>"
-
-syn match cssAuralProp contained "\<\(pause\|cue\)\(-\(before\|after\)\)\=\>"
-syn match cssAuralProp contained "\<\(play-during\|speech-rate\|voice-family\|pitch\(-range\)\=\|speak\(-\(punctuation\|numerals\)\)\=\)\>"
-syn keyword cssAuralProp contained volume during azimuth elevation stress richness
-syn match cssAuralAttr contained "\<\(x-\)\=\(soft\|loud\)\>"
-syn keyword cssAuralAttr contained silent
-syn match cssAuralAttr contained "\<spell-out\>"
-syn keyword cssAuralAttr contained non mix
-syn match cssAuralAttr contained "\<\(left\|right\)-side\>"
-syn match cssAuralAttr contained "\<\(far\|center\)-\(left\|center\|right\)\>"
-syn keyword cssAuralAttr contained leftwards rightwards behind
-syn keyword cssAuralAttr contained below level above higher
-syn match cssAuralAttr contained "\<\(x-\)\=\(slow\|fast\)\>"
-syn keyword cssAuralAttr contained faster slower
-syn keyword cssAuralAttr contained male female child code digits continuous
-
-syn match cssTableProp contained "\<\(caption-side\|table-layout\|border-collapse\|border-spacing\|empty-cells\|speak-header\)\>"
-syn keyword cssTableAttr contained fixed collapse separate show hide once always
-
-
-
-syn match lessComment "//.*$" contains=@Spell
-syn match lessVariable "@[A-Za-z_-][A-Za-z0-9_-]*"
-syn region lessVariableDefinition start="^@" end=";" contains=css.*Attr,css.*Prop,cssComment,cssValue.*,cssColor,cssURL,cssImportant,cssStringQ,cssStringQQ,cssFunction,cssUnicodeEscape,cssDefinition,cssClassName,cssTagName,cssIdentifier,lessComment,lessVariable,lessFunction
-
-" captures both the definition and the call
-syn region lessFunction matchgroup=lessFuncDef start="@[A-Za-z_-][A-Za-z0-9_-]*(" end=")" contains=css.*Attr,css.*Prop,cssComment,cssValue.*,cssColor,cssURL,cssImportant,cssStringQ,cssStringQQ,cssFunction,cssUnicodeEscape,cssDefinition,cssClassName,cssTagName,cssIdentifier,lessComment,lessVariable,lessFunction
-
-
-
-
-
-" FIXME: This allows cssMediaBlock before the semicolon, which is wrong.
-syn region cssInclude start="@import" end=";" contains=cssComment,cssURL,cssUnicodeEscape,cssMediaType
-syn match cssBraces contained "[{}]"
-syn match cssError contained "{@<>"
-syn region cssDefinition transparent matchgroup=cssBraces start='{' end='}' contains=css.*Attr,css.*Prop,cssComment,cssValue.*,cssColor,cssURL,cssImportant,cssStringQ,cssStringQQ,cssFunction,cssUnicodeEscape,cssDefinition,cssClassName,cssTagName,cssIdentifier,lessComment,lessVariable,lessFunction
-" syn match cssBraceError "}"
-
-syn match cssPseudoClass ":\S*" contains=cssPseudoClassId,cssUnicodeEscape
-syn keyword cssPseudoClassId contained link visited active hover focus before after left right
-syn match cssPseudoClassId contained "\<first\(-\(line\|letter\|child\)\)\=\>"
-syn region cssPseudoClassLang matchgroup=cssPseudoClassId start=":lang(" end=")" oneline
-
-syn region cssComment start="/\*" end="\*/" contains=@Spell
-
-syn match cssUnicodeEscape "\\\x\{1,6}\s\?"
-syn match cssSpecialCharQQ +\\"+ contained
-syn match cssSpecialCharQ +\\'+ contained
-syn region cssStringQQ start=+"+ skip=+\\\\\|\\"+ end=+"+ contains=cssUnicodeEscape,cssSpecialCharQQ
-syn region cssStringQ start=+'+ skip=+\\\\\|\\'+ end=+'+ contains=cssUnicodeEscape,cssSpecialCharQ
-syn match cssClassName "\.[A-Za-z][A-Za-z0-9_-]\+"
-
-
-
-
-if main_syntax == "css"
- syn sync minlines=10
-endif
-
-" Define the default highlighting.
-" For version 5.7 and earlier: only when not done already
-" For version 5.8 and later: only when an item doesn't have highlighting yet
-if version >= 508 || !exists("did_less_syn_inits")
- if version < 508
- let did_less_syn_inits = 1
- command -nargs=+ HiLink hi link <args>
- else
- command -nargs=+ HiLink hi def link <args>
- endif
-
- HiLink lessComment Comment
- HiLink lessVariable Special
- HiLink lessFuncDef Function
- HiLink cssComment Comment
- HiLink cssTagName Statement
- HiLink cssSelectorOp Special
- HiLink cssSelectorOp2 Special
- HiLink cssFontProp StorageClass
- HiLink cssColorProp storageClass
- HiLink cssTextProp StorageClass
- HiLink cssBoxProp StorageClass
- HiLink cssRenderProp StorageClass
- HiLink cssAuralProp StorageClass
- HiLink cssRenderProp StorageClass
- HiLink cssGeneratedContentProp StorageClass
- HiLink cssPagingProp StorageClass
- HiLink cssTableProp StorageClass
- HiLink cssUIProp StorageClass
- HiLink cssFontAttr Type
- HiLink cssColorAttr Type
- HiLink cssTextAttr Type
- HiLink cssBoxAttr Type
- HiLink cssRenderAttr Type
- HiLink cssAuralAttr Type
- HiLink cssGeneratedContentAttr Type
- HiLink cssPagingAttr Type
- HiLink cssTableAttr Type
- HiLink cssUIAttr Type
- HiLink cssCommonAttr Type
- HiLink cssPseudoClassId PreProc
- HiLink cssPseudoClassLang Constant
- HiLink cssValueLength Number
- HiLink cssValueInteger Number
- HiLink cssValueNumber Number
- HiLink cssValueAngle Number
- HiLink cssValueTime Number
- HiLink cssValueFrequency Number
- HiLink cssFunction Constant
- HiLink cssURL String
- HiLink cssFunctionName Function
- HiLink cssColor Constant
- HiLink cssIdentifier Function
- HiLink cssInclude Include
- HiLink cssImportant Special
- HiLink cssBraces SpecialChar
- HiLink cssBraceError Error
- HiLink cssError Error
- HiLink cssInclude Include
- HiLink cssUnicodeEscape Special
- HiLink cssStringQQ String
- HiLink cssStringQ String
- HiLink cssMedia Special
- HiLink cssMediaType Special
- HiLink cssMediaComma Normal
- HiLink cssFontDescriptor Special
- HiLink cssFontDescriptorFunction Constant
- HiLink cssFontDescriptorProp StorageClass
- HiLink cssFontDescriptorAttr Type
- HiLink cssUnicodeRange Constant
- HiLink cssClassName Function
- delcommand HiLink
-endif
-
-let b:current_syntax = "less"
-
-if main_syntax == 'less'
- unlet main_syntax
-endif
-
-
-" vim: ts=8
-
-
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/syntax/martian.vim Fri Jul 07 16:11:02 2023 -0400
@@ -0,0 +1,98 @@
+" Martian (MRO) Syntax
+" Author: Matt Sooknah
+
+if exists("b:current_syntax")
+ finish
+endif
+
+syn match include '^\s*@include' nextgroup=mroString skipwhite
+
+syn keyword filetype filetype nextgroup=parType skipwhite
+syn keyword parameter in out nextgroup=parType skipwhite contained
+syn keyword src src nextgroup=srctype skipwhite contained
+syn keyword srctype py comp exe nextgroup=mroString contained skipwhite
+syn keyword restype mem_gb vmem_gb threads special volatile nextgroup=assign contained skipwhite
+syn keyword modifier local preflight volatile nextgroup=modifier,callTarg skipwhite contained
+syn keyword boundMod local preflight volatile disabled nextgroup=assign contained skipwhite
+syn keyword sweep sweep nextgroup=sweepArray contained
+
+syn keyword declaration pipeline stage nextgroup=pipeName skipwhite
+syn keyword call call nextgroup=modifier,callTarg skipwhite
+syn keyword return return nextgroup=callParams skipwhite contained
+
+syn keyword mroNull null contained
+syn keyword mroBool true false contained
+
+syn keyword split split nextgroup=splitUsing,paramBlock skipwhite contained
+syn keyword splitUsing using nextgroup=paramBlock skipwhite contained
+syn keyword using using nextgroup=resParams skipwhite contained
+syn keyword retain retain nextgroup=idList skipwhite contained
+syn keyword callUsing using nextgroup=modBlock skipwhite contained
+syn keyword as as nextgroup=callTarg skipwhite contained
+syn keyword self self nextgroup=dot contained
+
+syn match dot '\.' nextgroup=parName contained
+syn match mapSep ':' nextgroup=mroString,mroNull,mroBool,arrayLit,mapLit skipwhite contained
+syn match assign '=' nextgroup=self,sweep,mroString,mroNumber,mroNull,mroBool,parName,arrayLit,mapLit skipwhite contained
+
+syn match assignment '_\?[A-Za-z][A-Za-z0-9_]*\s*=' contains=parName,assign contained skipwhite nextgroup=self,sweep,mroString,mroNumber,mroNull,mroBool,parName,arrayLit,mapLit
+syn match parType '_\?[A-Za-z][.A-Za-z0-9_]*' nextgroup=arrayDim,parName skipwhite contained
+syn match arrayDim '\[\]' nextgroup=arraydim,parName skipwhite contained
+syn match parName '_\?[A-Za-z][A-Za-z0-9_]*' nextgroup=dot,mroString skipwhite contained
+syn match pipeName '_\?[A-Za-z][A-Za-z0-9_]*' nextgroup=paramBlock contained
+syn match callTarg '_\?[A-Za-z][A-Za-z0-9_]*' nextgroup=as,callParams skipwhite contained
+
+syn match commentLine '#.*$'
+
+syn match mroNumber '\v<\d+>' contained skipwhite nextgroup=mapSep
+syn match mroNumber '\v<\d+\.\d+>' contained skipwhite nextgroup=mapSep
+
+syn region paramBlock start="(" end=")" fold transparent nextgroup=split,using,retain,callBlock skipwhite skipnl contained contains=parameter,src
+syn region callParams start="(" end=")" fold transparent nextgroup=callUsing,retain skipwhite contained contains=assignment
+syn region resParams start="(" end=")" fold transparent nextgroup=retain contained skipwhite skipnl contains=restype
+syn region idList start="(" end=")" fold transparent contained contains=parName
+syn region modBlock start="(" end=")" fold transparent contained contains=boundMod
+syn region callBlock start="{" end="}" fold transparent contains=call,return contained skipwhite
+syn region mroString start=/"/ skip=/\\"/ end=/"/ nextgroup=mapSep skipwhite contained
+syn region arrayLit start='\[' end='\]' transparent contains=mroString,mroNumber,mroNull,mroBool,arrayLit,mapLit,parName contained
+syn region sweepArray start='(' end=')' transparent contains=mroString,mroNumber,mroNull,mroBool,arrayLit,mapLit contained
+syn region mapLit start="{" end="}" transparent contains=mroString,mroNumber contained
+
+let b:current_syntax = "mro"
+
+hi def link commentLine Comment
+
+hi def link include PreProcessor
+hi def link filetype Statement
+hi def link parameter Statement
+hi def link src Statement
+hi def link declaration Statement
+hi def link return Statement
+hi def link call Statement
+hi def link modifier Statement
+hi def link split Statement
+hi def link splitUsing Statement
+hi def link callUsing Statement
+hi def link using Statement
+hi def link as Keyword
+hi def link restype Keyword
+hi def link boundMod Keyword
+hi def link self Keyword
+hi def link sweep Keyword
+hi def link using Statement
+hi def link retain Statement
+
+hi def link parType Type
+hi def link srcType Type
+
+hi def link pipeName Type
+hi def link callTarg Type
+hi def link parName Identifier
+
+hi def link dot Operator
+
+hi def link mroNumber Constant
+hi def link mroString Constant
+hi def link mroNull Constant
+hi def link mroTrue Constant
+hi def link mroFalse Constant
--- a/vim/syntax/pandabt.vim Fri Apr 14 15:01:35 2023 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,13 +0,0 @@
-if version < 600
- syntax clear
-elseif exists("b:current_syntax")
- finish
-endif
-
-syntax region pandabtString start=/"/ skip=/\\./ end=/"/
-syntax region pandabtComment start=/\/\// end=/$/ keepend
-
-highlight link pandabtString String
-highlight link pandabtComment Comment
-
-let b:current_syntax = "pandabt"
--- a/vim/syntax/pentadactyl.vim Fri Apr 14 15:01:35 2023 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,109 +0,0 @@
-" Vim syntax file
-" Language: Pentadactyl configuration file
-" Maintainer: Doug Kearns <dougkearns@gmail.com>
-
-" TODO: make this pentadactyl specific - shared dactyl config?
-
-if exists("b:current_syntax")
- finish
-endif
-
-let s:cpo_save = &cpo
-set cpo&vim
-
-syn include @javascriptTop syntax/javascript.vim
-unlet b:current_syntax
-
-syn include @cssTop syntax/css.vim
-unlet b:current_syntax
-
-syn match pentadactylCommandStart "\%(^\s*:\=\)\@<=" nextgroup=pentadactylCommand,pentadactylAutoCmd
-
-syn keyword pentadactylCommand run ab[breviate] abc[lear] addo[ns] au[tocmd] ba[ck] bd[elete] bw[ipeout] bun[load]
- \ tabc[lose] bma[rk] bmarks b[uffer] buffers files ls tabs ca[bbrev] cabc[lear] cd chd[ir] cm[ap] cmapc[lear] cno[remap]
- \ colo[rscheme] comc[lear] com[mand] contexts cuna[bbrev] cunm[ap] delbm[arks] delc[ommand] delmac[ros] delm[arks] delqm[arks]
- \ dels[tyle] dia[log] doautoa[ll] do[autocmd] downl[oads] dl ec[ho] echoe[rr] echom[sg] em[enu] exe[cute] exta[dd] extde[lete]
- \ extd[isable] exte[nable] extens[ions] exts exto[ptions] extp[references] exu[sage] fini[sh] fo[rward] fw frameo[nly]
- \ ha[rdcopy] h[elp] helpa[ll] hi[ghlight] hist[ory] hs ia[bbrev] iabc[lear] im[ap] imapc[lear] ino[remap] iuna[bbrev] iunm[ap]
- \ javas[cript] js ju[mps] keepa[lt] let loadplugins lpl macros map mapc[lear] ma[rk] marks mes[sages] messc[lear]
- \ mkp[entadactylrc] nm[ap] nmapc[lear] nno[remap] noh[lsearch] no[remap] norm[al] nunm[ap] o[pen] optionu[sage] pa[geinfo]
- \ pagest[yle] pas pref[erences] prefs pw[d] qma[rk] qmarks q[uit] quita[ll] qa[ll] redr[aw] re[load] reloada[ll] res[tart]
- \ runt[ime] sa[nitize] sav[eas] w[rite] sbcl[ose] scrip[tnames] se[t] setg[lobal] setl[ocal] sideb[ar] sb[ar] sbope[n]
- \ sil[ent] so[urce] st[op] stopa[ll] sty[le] styled[isable] styd[isable] stylee[nable] stye[nable] stylet[oggle] styt[oggle]
- \ tab taba[ttach] tabde[tach] tabd[o] bufd[o] tabdu[plicate] tabl[ast] bl[ast] tabm[ove] tabn[ext] tn[ext] bn[ext] tabo[nly]
- \ tabopen t[open] tabnew tabp[revious] tp[revious] tabN[ext] tN[ext] bp[revious] bN[ext] tabr[ewind] tabfir[st] br[ewind]
- \ bf[irst] time toolbarh[ide] tbh[ide] toolbars[how] tbs[how] toolbart[oggle] tbt[oggle] una[bbreviate] u[ndo] undoa[ll]
- \ unl[et] unm[ap] verb[ose] ve[rsion] vie[wsource] viu[sage] vm[ap] vmapc[lear] vno[remap] vunm[ap] winc[lose] wc[lose]
- \ wind[ow] winon[ly] wino[pen] wo[pen] wqa[ll] wq xa[ll] zo[om]
- \ contained
-
-syn match pentadactylCommand "!" contained
-
-syn keyword pentadactylAutoCmd au[tocmd] contained nextgroup=pentadactylAutoEventList skipwhite
-
-syn keyword pentadactylAutoEvent BookmarkAdd BookmarkChange BookmarkRemove ColorScheme DOMLoad DownloadPost Fullscreen
- \ LocationChange PageLoadPre PageLoad PrivateMode Sanitize ShellCmdPost Enter LeavePre Leave
- \ contained
-
-syn match pentadactylAutoEventList "\(\a\+,\)*\a\+" contained contains=pentadactylAutoEvent
-
-syn region pentadactylSet matchgroup=pentadactylCommand start="\%(^\s*:\=\)\@<=\<\%(setl\%[ocal]\|setg\%[lobal]\|set\=\)\=\>"
- \ end="$" keepend oneline contains=pentadactylOption,pentadactylString
-
-syn keyword pentadactylOption activate act altwildmode awim autocomplete au cdpath cd complete cpt cookies ck defsearch ds
- \ editor encoding enc eventignore ei extendedhinttags eht fbwhitelist fbw fileencoding fenc followhints fh guioptions go
- \ helpfile hf hintinputs hin hintkeys hk hintmatching hm hinttags ht hinttimeout hto history hi laststatus ls loadplugins lpl
- \ maxitems messages msgs newtab nextpattern pageinfo pa popups pps previouspattern runtimepath rtp sanitizeitems si
- \ sanitizetimespan sts scroll scr shell sh shellcmdflag shcf showstatuslinks ssli showtabline stal suggestengines titlestring
- \ urlseparator verbose vbs wildanchor wia wildcase wic wildignore wig wildmode wim wildsort wis wordseparators wsp
- \ contained nextgroup=pentadactylSetMod
-
-let s:toggleOptions = ["banghist", "bh", "errorbells", "eb", "exrc", "ex", "flashblock", "fb", "fullscreen", "fs", "hlsearch",
- \ "hls", "ignorecase", "ic", "incsearch", "is", "insertmode", "im", "jsdebugger", "jsd", "linksearch", "lks", "more",
- \ "online", "private", "pornmode", "showmode", "smd", "smartcase", "scs", "strictfocus", "sf", "usermode", "um", "visualbell",
- \ "vb"]
-execute 'syn match pentadactylOption "\<\%(no\|inv\)\=\%(' .
- \ join(s:toggleOptions, '\|') .
- \ '\)\>!\=" contained nextgroup=pentadactylSetMod'
-
-syn match pentadactylSetMod "\%(\<[a-z_]\+\)\@<=&" contained
-
-syn region pentadactylJavaScript start="\%(^\s*\%(javascript\|js\)\s\+\)\@<=" end="$" contains=@javascriptTop keepend oneline
-syn region pentadactylJavaScript matchgroup=pentadactylJavaScriptDelimiter
- \ start="\%(^\s*\%(javascript\|js\)\s\+\)\@<=<<\s*\z(\h\w*\)"hs=s+2 end="^\z1$" contains=@javascriptTop fold
-
-let s:cssRegionStart = '\%(^\s*sty\%[le]!\=\s\+\%(-\%(n\|name\)\%(\s\+\|=\)\S\+\s\+\)\=[^-]\S\+\s\+\)\@<='
-execute 'syn region pentadactylCss start="' . s:cssRegionStart . '" end="$" contains=@cssTop keepend oneline'
-execute 'syn region pentadactylCss matchgroup=pentadactylCssDelimiter'
- \ 'start="' . s:cssRegionStart . '<<\s*\z(\h\w*\)"hs=s+2 end="^\z1$" contains=@cssTop fold'
-
-syn match pentadactylNotation "<[0-9A-Za-z-]\+>"
-
-syn match pentadactylComment +".*$+ contains=pentadactylTodo,@Spell
-syn keyword pentadactylTodo FIXME NOTE TODO XXX contained
-
-syn region pentadactylString start="\z(["']\)" end="\z1" skip="\\\\\|\\\z1" oneline
-
-syn match pentadactylLineComment +^\s*".*$+ contains=pentadactylTodo,@Spell
-
-" NOTE: match vim.vim highlighting group names
-hi def link pentadactylAutoCmd pentadactylCommand
-hi def link pentadactylAutoEvent Type
-hi def link pentadactylCommand Statement
-hi def link pentadactylComment Comment
-hi def link pentadactylJavaScriptDelimiter Delimiter
-hi def link pentadactylCssDelimiter Delimiter
-hi def link pentadactylNotation Special
-hi def link pentadactylLineComment Comment
-hi def link pentadactylOption PreProc
-hi def link pentadactylSetMod pentadactylOption
-hi def link pentadactylString String
-hi def link pentadactylTodo Todo
-
-let b:current_syntax = "pentadactyl"
-
-let &cpo = s:cpo_save
-unlet s:cpo_save
-
-" vim: tw=130 et ts=4 sw=4:
-
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/vim/syntax/terraform.vim Fri Jul 07 16:11:02 2023 -0400
@@ -0,0 +1,11 @@
+if exists('b:current_syntax')
+ finish
+endif
+runtime! syntax/hcl.vim
+unlet b:current_syntax
+
+syn keyword terraType string bool number object tuple list map set any
+
+hi def link terraType Type
+
+let b:current_syntax = 'terraform'
--- a/vim/vimrc Fri Apr 14 15:01:35 2023 -0400
+++ b/vim/vimrc Fri Jul 07 16:11:02 2023 -0400
@@ -63,14 +63,8 @@
set spellfile=~/.vim/custom-dictionary.utf-8.add,~/.vim-local-dictionary.utf-8.add
nnoremap zG 2zg
-" iTerm2 is currently slow as balls at rendering the nice unicode lines, so for
-" now I'll just use ASCII pipes. They're ugly but at least I won't want to kill
-" myself when trying to move around a file.
-set fillchars=diff:⣿,vert:│
-set fillchars=diff:⣿,vert:\|
-
-" Don't try to highlight lines longer than 800 characters.
-set synmaxcol=800
+" Don't try to highlight lines longer than 500 characters.
+set synmaxcol=500
" Time out on key codes but not mappings.
" Basically this makes terminal Vim work sanely.
@@ -89,9 +83,6 @@
" Save when losing focus
au FocusLost * :silent! wall
-" Resize splits when the window is resized
-" au VimResized * :wincmd =
-
" Leader
let mapleader = ","
let maplocalleader = "\\"
@@ -219,39 +210,10 @@
" }}}
" }}}
-" Abbreviations ----------------------------------------------------------- {{{
-
-function! EatChar(pat)
- let c = nr2char(getchar(0))
- return (c =~ a:pat) ? '' : c
-endfunction
-
-function! MakeSpacelessIabbrev(from, to)
- execute "iabbrev <silent> ".a:from." ".a:to."<C-R>=EatChar('\\s')<CR>"
-endfunction
-function! MakeSpacelessBufferIabbrev(from, to)
- execute "iabbrev <silent> <buffer> ".a:from." ".a:to."<C-R>=EatChar('\\s')<CR>"
-endfunction
-
-call MakeSpacelessIabbrev('sl/', 'http://stevelosh.com/')
-call MakeSpacelessIabbrev('bb/', 'http://bitbucket.org/')
-call MakeSpacelessIabbrev('bbs/', 'http://bitbucket.org/sjl/')
-call MakeSpacelessIabbrev('gh/', 'http://github.com/')
-call MakeSpacelessIabbrev('ghs/', 'http://github.com/sjl/')
-
-iabbrev ldis ಠ_ಠ
-iabbrev lsad ಥ_ಥ
-iabbrev lhap ಥ‿ಥ
-iabbrev lmis ಠ‿ಠ
-
-iabbrev c8 CHIP-8
+" Abbreviations & Digraphs ------------------------------------------------ {{{
iabbrev todo TODO
-iabbrev sl@ steve@stevelosh.com
-
-iabbrev spf set -euo pipefail
-
silent! digr -. 8230 "U+2026=… HORIZONTAL ELLIPSIS
silent! digr !, 8816 "U+2270=≰ NEITHER LESS-THAN NOR EQUAL TO
silent! digr !. 8817 "U+2271=≱ NEITHER GREATER-THAN NOR EQUAL TO
@@ -313,7 +275,8 @@
inoremap <c-k><c-k> <esc>:help digraph-table<cr>
" Wrap
-nnoremap <leader>W :set wrap!<cr>
+" mnemonic: less' -S command/option
+nnoremap <leader>S :set wrap!<cr>
" Inserting blank lines
" I never use the default behavior of <cr> and this saves me a keystroke...
@@ -325,6 +288,18 @@
nnoremap <leader>y VV"+y
nnoremap <leader>Y "+y
+" Open
+function Open(thing)
+ call system(['open', a:thing])
+endfunction
+
+nnoremap <leader>o "zyiW:call Open(@z)<cr>
+vnoremap <leader>o "zy:call Open(@z)<cr>
+
+" Delete to black hole register
+nnoremap dD "_dd
+vnoremap D "_d
+
" Yank to end of line
nnoremap Y y$
@@ -427,9 +402,6 @@
nnoremap <c-s> :%s/
vnoremap <c-s> :s/
-" HTML tag closing
-inoremap <C-_> <space><bs><esc>:call InsertCloseTag()<cr>a
-
" Marks and Quotes
noremap ' `
noremap æ '
@@ -454,13 +426,6 @@
" Unfuck my screen
nnoremap U :syntax sync fromstart<cr>:redraw!<cr>
-" Pushing
-nnoremap <leader>Go :Start! git push origin<cr>
-nnoremap <leader>Gu :Start! git push upstream<cr>
-
-" Open current directory in Finder
-nnoremap <leader>O :!open .<cr>
-
" Zip Right
"
" Moves the character under the cursor to the end of the line. Handy when you
@@ -492,6 +457,9 @@
nnoremap ]Z ]Sz=
nnoremap [Z [Sz=
+" Header Lines
+nnoremap <leader>- o<esc>80a-<esc>kJ079lD
+
" Insert Mode Completion {{{
inoremap <c-f> <c-x><c-f>
@@ -694,7 +662,7 @@
call JumpTo("normal! \<c-]>")
endfunction
function! JumpToTagInSplit()
- call JumpToInSplit("normal! \<c-]>")
+ call JumpToInSplit("normal \<c-]>")
endfunction
nnoremap <c-]> :silent! call JumpToTag()<cr>
@@ -787,7 +755,7 @@
" 1. Close all folds.
" 2. Open just the folds containing the current line.
" 3. Move the line to a bit (25 lines) down from the top of the screen.
-" 4. Pulse the cursor line. My eyes are bad.
+" 4. Pulse the line.
"
" This mapping wipes out the z mark, which I never use.
"
@@ -820,17 +788,6 @@
" }}}
" Filetype-specific ------------------------------------------------------- {{{
-" Arduino {{{
-
-augroup ft_arduino
- au!
-
- au FileType arduino setlocal noexpandtab shiftwidth=8 tabstop=8 softtabstop=8 foldmethod=syntax
- au FileType arduino inoremap <buffer> ☃ <esc>A;<cr>
- au FileType arduino inoremap <buffer> ☂ <esc>mzA;<esc>`z
-augroup END
-
-" }}}
" Assembly {{{
augroup ft_asm
@@ -840,6 +797,14 @@
augroup END
" }}}
+" Bazel {{{
+
+augroup ft_bazel
+ au!
+ au FileType bzl nnoremap <buffer> gi :Neoformat buildifier<cr>
+augroup END
+
+" }}}
" C {{{
augroup ft_c
@@ -869,44 +834,12 @@
augroup END
" }}}
-" Clojure {{{
-
-" extra folding {{{
-let g:clojure_fold_extra = [
- \ 'defgauge',
- \ 'defsketch'
- \
- \ ]
-" }}}
-
-augroup ft_clojure
+" Contacts {{{
+
+augroup ft_contacts
au!
-
- au BufNewFile,BufRead *.edn set filetype=clojure
-
- au FileType clojure silent! call TurnOnClojureFolding()
- au FileType clojure compiler clojure
- au FileType clojure setlocal isk-=.
-
- au FileType clojure iabbrev <buffer> defun defn
-
- " Things that should be indented 2-spaced
- au FileType clojure setlocal lispwords+=when-found,defform,when-valid,try,while-let,try+,throw+
-
- au FileType clojure RainbowParenthesesActivate
- au syntax clojure RainbowParenthesesLoadRound
-
- " Paredit
- au FileType clojure call EnableParedit()
- au FileType clojure nnoremap <buffer> <localleader>( :call PareditToggle()<cr>
- " )
-
- " Duplicate
- au FileType clojure nnoremap <buffer> [] :call DuplicateLispForm()<cr>
-
- " Indent top-level form.
- au FileType clojure nmap <buffer> gi mz99[(v%='z
-
+ autocmd BufNewFile,BufRead .contacts setlocal ts=32
+ autocmd BufNewFile,BufRead .contacts setlocal noexpandtab
augroup END
" }}}
@@ -1120,6 +1053,7 @@
\ 'test>',
\ 'eval-when>',
\ 'eval-dammit>',
+ \ 'scratch>',
\
\ 'declaim',
\
@@ -1135,6 +1069,7 @@
au BufNewFile,BufRead .abclrc set filetype=lisp
au BufNewFile,BufRead .lisprc set filetype=lisp
au BufNewFile,BufRead .stumpwmrc set filetype=lisp
+ au BufNewFile,BufRead .stumpwmrc.local set filetype=lisp
au FileType lisp nnoremap <buffer> U :syntax sync fromstart<cr>:redraw!<cr>:call TurnOnLispFolding()<cr>
@@ -1178,6 +1113,7 @@
au FileType lisp nnoremap <buffer> [] :call DuplicateLispForm()<cr>
au FileType lisp nnoremap <buffer> <localleader>( :call PareditToggle()<cr>
")
+ au FileType lisp inoremap <buffer> <c-s> <c-o>:call vlime#plugin#SendToREPL(vlime#ui#CurTopExpr())<cr>
" Navigate trees of sexps with arrows
au FileType lisp call s:vim_sexp_mappings()
@@ -1185,21 +1121,63 @@
au FileType lisp noremap <buffer> <right> :<c-u>call SexpForward()<cr>
au FileType lisp noremap <buffer> <up> :<c-u>call SexpUp()<cr>
au FileType lisp noremap <buffer> <down> :<c-u>call SexpDown()<cr>
+
+ " Writing
+ au FileType lisp noremap <buffer> <localleader>= I; => <esc>
+
+ " April
+ au FileType lisp inoremap <buffer> <c-j>; ⍝
+ au FileType lisp inoremap <buffer> <c-j>i ⍳
+ au FileType lisp inoremap <buffer> <c-j>r ⍴
+ au FileType lisp inoremap <buffer> <c-j>e ∊
+ au FileType lisp inoremap <buffer> <c-j>_i ⍸
+ au FileType lisp inoremap <buffer> <c-j>_, ⍪
+ au FileType lisp inoremap <buffer> <c-j>:~ ⍨
+ au FileType lisp inoremap <buffer> <c-j>:^ ¨
+
+ au FileType lisp inoremap <buffer> <c-j>* ×
+ au FileType lisp inoremap <buffer> <c-j>/ ÷
+ au FileType lisp inoremap <buffer> <c-j>0 ∘
+ au FileType lisp inoremap <buffer> <c-j>- ¯
+
+ au FileType lisp inoremap <buffer> <c-j>c ⌈
+ au FileType lisp inoremap <buffer> <c-j>f ⌊
+
+ au FileType lisp inoremap <buffer> <c-j>< ←
+ au FileType lisp inoremap <buffer> <c-j>> →
+ au FileType lisp inoremap <buffer> <c-j>^ ↑
+ au FileType lisp inoremap <buffer> <c-j>v ↓
+
+ au FileType lisp inoremap <buffer> <c-j>G^ ⍋
+ au FileType lisp inoremap <buffer> <c-j>Gv ⍒
+
+ au FileType lisp inoremap <buffer> <c-j>o\| ⌽
+ au FileType lisp inoremap <buffer> <c-j>o/ ⍉
+ au FileType lisp inoremap <buffer> <c-j>o- ⊖
+
+ au FileType lisp inoremap <buffer> <c-j>A ∧
+ au FileType lisp inoremap <buffer> <c-j>O ∨
+
+ au FileType lisp inoremap <buffer> <c-j>=< ≤
+ au FileType lisp inoremap <buffer> <c-j>=< ≥
+ au FileType lisp inoremap <buffer> <c-j>=/ ≠
+ au FileType lisp inoremap <buffer> <c-j>=== ≡
+ au FileType lisp inoremap <buffer> <c-j>==/ ≢
+
+ au FileType lisp inoremap <buffer> <c-j>q ⎕
+ au FileType lisp inoremap <buffer> <c-j>Q ⌷
+ au FileType lisp inoremap <buffer> <c-j>t ⊢
+
+ au FileType lisp inoremap <buffer> <c-j>u ∪
+ au FileType lisp inoremap <buffer> <c-j>U ∩
+ au FileType lisp inoremap <buffer> <c-j>+ ⌿
+ au FileType lisp inoremap <buffer> <c-j>[ ⊂
+ au FileType lisp inoremap <buffer> <c-j>] ⊃
+
+ au FileType lisp inoremap <buffer> <c-j>z ⍬
augroup END " }}}
" }}}
-" Confluence {{{
-
-augroup ft_c
- au!
-
- au BufRead,BufNewFile *.confluencewiki setlocal filetype=confluencewiki
-
- " Wiki pages should be soft-wrapped.
- au FileType confluencewiki setlocal wrap linebreak nolist
-augroup END
-
-" }}}
" Cram {{{
let cram_fold=1
@@ -1350,29 +1328,12 @@
augroup END
" }}}
-" GDL {{{
-
-augroup ft_gdl
+" Git {{{
+
+augroup ft_git
au!
- au FileType gdl nnoremap <localleader>= mzvap=`z
-
- au FileType gdl RainbowParenthesesActivate
- au syntax gdl RainbowParenthesesLoadRound
-
- au FileType gdl call EnableParedit()
-augroup END
-
-" }}}
-" GLSL {{{
-
-augroup ft_glsl
- au!
-
- au BufNewFile,BufRead *.shader setlocal filetype=glsl
-
- au FileType glsl setlocal foldmethod=marker foldmarker={,}
- au FileType glsl setlocal ts=8 sts=8 sw=8 noexpandtab
+ au FileType gitcommit nnoremap <buffer> <localleader>j /On branch sjl<cr>f/l"zyt/gg0P:nohl<cr>$a <esc>a
augroup END
" }}}
@@ -1485,6 +1446,11 @@
return '='
endfunction
+func Eatchar(pat)
+ let c = nr2char(getchar(0))
+ return (c =~ a:pat) ? '' : c
+endfunc
+
augroup ft_go
au!
@@ -1497,6 +1463,7 @@
au FileType go nnoremap <buffer> <localleader>t :GoInfo<cr>
au FileType go nnoremap <buffer> <localleader>h :GoDocBrowser<cr>
au FileType go nnoremap <buffer> <localleader>c :GoBuild<cr>
+ au FileType go nnoremap <buffer> <localleader>xc :GoCallers<cr>
au FileType go inoremap <c-n> <c-x><c-o>
@@ -1504,6 +1471,18 @@
au FileType go iabbrev <buffer> enil if err != nil
au FileType go iabbrev <buffer> rete return err
au FileType go iabbrev <buffer> retne return nil, err
+ au FileType go iabbrev <buffer> retse return "", err
+ au FileType go iabbrev <buffer> retze return "", err
+
+ au FileType go iabbrev <buffer> enilre if err != nil {<cr>return err<down>
+ au FileType go iabbrev <buffer> enilrn if err != nil {<cr>return nil, err<down>
+ au FileType go iabbrev <buffer> enilrs if err != nil {<cr>return "", err<down>
+ au FileType go iabbrev <buffer> enilrz if err != nil {<cr>return 0, err<down>
+
+ au FileType go iabbrev <buffer> enilrw if err != nil {<cr>return fmt.Errorf(": %w", err<left><left><left><left><left><left><left><left><left><left><C-R>=Eatchar('\s')<cr>
+ au FileType go iabbrev <buffer> enilrwn if err != nil {<cr>return nil, fmt.Errorf(": %w", err<left><left><left><left><left><left><left><left><left><left><C-R>=Eatchar('\s')<cr>
+ au FileType go iabbrev <buffer> enilrws if err != nil {<cr>return "", fmt.Errorf(": %w", err<left><left><left><left><left><left><left><left><left><left><C-R>=Eatchar('\s')<cr>
+ au FileType go iabbrev <buffer> enilrwz if err != nil {<cr>return 0, fmt.Errorf(": %w", err<left><left><left><left><left><left><left><left><left><left><C-R>=Eatchar('\s')<cr>
au FileType gohtmltmpl setlocal shiftwidth=4
augroup END
@@ -1548,16 +1527,6 @@
augroup END
" }}}
-" Jade Templates {{{
-
-augroup ft_jade
- au!
-
- au BufRead,BufNewFile *.jade setlocal filetype=jade
- au FileType jade setlocal foldmethod=indent
-augroup END
-
-" }}}
" Java {{{
augroup ft_java
@@ -1576,7 +1545,6 @@
au FileType javascript setlocal foldmethod=marker
au FileType javascript setlocal foldmarker={,}
- au FileType javascript call MakeSpacelessBufferIabbrev('clog', 'console.log();<left><left>')
" Make {<cr> insert a pair of brackets in such a way that the cursor is correctly
" positioned inside of them AND the following code doesn't get unfolded.
@@ -1598,15 +1566,6 @@
augroup END
" }}}
-" Lilypond {{{
-
-augroup ft_lilypond
- au!
-
- au FileType lilypond setlocal foldmethod=marker foldmarker={,}
-augroup END
-
-" }}}
" Mail {{{
augroup ft_mail
@@ -1702,6 +1661,15 @@
augroup END
" }}}
+" Martian {{{
+
+augroup ft_martian
+ au!
+
+ au Filetype markdown inoremap <buffer> <c-n> <c-x><c-n>
+augroup END
+
+" }}}
" Mercurial {{{
augroup ft_mercurial
@@ -1722,48 +1690,18 @@
augroup END
" }}}
-" Nand2Tetris HDL {{{
-
-augroup ft_n2thdl
- au!
-
- au BufNewFile,BufRead *.hdl set filetype=n2thdl
-augroup END
-
-" }}}
" Nginx {{{
augroup ft_nginx
au!
- au BufRead,BufNewFile /etc/nginx/conf/* set ft=nginx
- au BufRead,BufNewFile /etc/nginx/sites-available/* set ft=nginx
- au BufRead,BufNewFile /usr/local/etc/nginx/sites-available/* set ft=nginx
- au BufRead,BufNewFile vhost.nginx set ft=nginx
+ au BufRead,BufNewFile nginx.conf set ft=nginx
+ au BufRead,BufNewFile *.nginx.conf set ft=nginx
au FileType nginx setlocal foldmethod=marker foldmarker={,}
augroup END
" }}}
-" PandaBT {{{
-
-augroup ft_pandabt
- au!
- au BufNewFile,BufRead *.BT.txt set filetype=pandabt
-
- au FileType pandabt setlocal noexpandtab shiftwidth=8
-augroup END
-
-" }}}
-" Pentadactyl {{{
-
-augroup ft_pentadactyl
- au!
- au BufNewFile,BufRead .pentadactylrc set filetype=pentadactyl
- au BufNewFile,BufRead ~/Library/Caches/TemporaryItems/pentadactyl-*.tmp set nolist wrap linebreak columns=100 colorcolumn=0
-augroup END
-
-" }}}
" .plan {{{
function! PlanLinkPaste()
@@ -1788,7 +1726,7 @@
au BufNewFile,BufRead *.pgsql set filetype=pgsql
au FileType pgsql set foldmethod=marker foldmarker=\ $$,$$\
- au FileType pgsql set softtabstop=2 shiftwidth=2
+ au FileType pgsql set softtabstop=4 shiftwidth=4
au FileType pgsql setlocal commentstring=--\ %s comments=:--
" Set up some basic neorepl mappings.
@@ -1820,116 +1758,17 @@
" }}}
" Python {{{
-function! SelectTopLevelPythonHunk() "{{{
- " oh darling what have I done
-
- " if we're on toplevel line that ends in a :, drop down one line before
- " we move on. this is bad and i feel bad.
- let line = getline(".")
- if len(line) > 0 && line[0] != " " && line[len(line) - 1] == ":"
- normal! j
- endif
-
- normal! v
-
- " use the non-bang version of normal here because we need to use the
- " indentation script. this is also bad and i still feel bad.
- normal ai
-
- " keep chomping upwards in the indentation stack til we get to something
- " that's at the top level. its bad.
- while getline(".")[0] == " "
- normal ai
- endwhile
-endfunction "}}}
-
-function! OpenPythonRepl() "{{{
- "fucking kill me
- NeoRepl fish
-endfunction "}}}
-
-function! SendPythonParagraph() "{{{
- let view = winsaveview()
-
- execute "normal! ^vip\<esc>"
- call NeoReplSendSelection()
-
- call winrestview(view)
-endfunction "}}}
-function! SendPythonTopLevelHunk() "{{{
- let view = winsaveview()
- let old_z = @z
-
- call SelectTopLevelPythonHunk()
- normal! gv"zy
- call NeoReplSendRaw("%cpaste\n" . @z . "\n--\n")
-
- let @z = old_z
- call winrestview(view)
-endfunction "}}}
-function! SendPythonSelection() "{{{
- let view = winsaveview()
- let old_z = @z
-
- normal! gv"zy
- call NeoReplSendRaw("%cpaste\n" . @z . "\n--\n")
-
- let @z = old_z
- call winrestview(view)
-endfunction "}}}
-function! SendPythonBuffer() "{{{
- let view = winsaveview()
-
- execute "normal! ggVG\<esc>"
-
- normal! gv"zy
- call NeoReplSendRaw("%cpaste\n" . @z . "\n--\n")
-
- call winrestview(view)
-endfunction "}}}
-
augroup ft_python
au!
au FileType python setlocal define=^\s*\\(def\\\\|class\\)
+ au FileType python setlocal textwidth=100
" Jesus tapdancing Christ, built-in Python syntax, you couldn't let me
" override this in a normal way, could you?
au FileType python if exists("python_space_error_highlight") | unlet python_space_error_highlight | endif
- " Strip REPL-session marks from just-pasted text
- au FileType python nnoremap <localleader>s mz`[v`]:v/\v^(\>\>\>\|[.][.][.])/d<cr>gv:s/\v^(\>\>\> \|[.][.][.] \|[.][.][.]$)//<cr>:noh<cr>`z
-
- " Set up some basic neorepl mappings.
- "
- " key desc mnemonic
- " \o - connect neorepl [o]pen repl
- " \l - send current line [l]ine
- " \p - send current paragraph [p]aragraph
- " \e - send top-level hunk [e]val
- " \e - send selected hunk [e]val
- " \r - send entire file [r]eload file
- " \c - send ctrl-l [c]lear
-
- au FileType python nnoremap <buffer> <silent> <localleader>o :call OpenPythonRepl()<cr>
-
- " Send the current line to the REPL
- au FileType python nnoremap <buffer> <silent> <localleader>l :call NeoReplSendCurrentLine()<cr>
-
- " Send the current paragraph to the REPL
- au FileType python nnoremap <buffer> <silent> <localleader>p :call SendPythonParagraph()<cr>
-
- " " Send the current top-level hunk to the REPL
- au FileType python nnoremap <buffer> <silent> <localleader>e :call SendPythonTopLevelHunk()<cr>
-
- " Send the current selection to the REPL
- au FileType python vnoremap <buffer> <silent> <localleader>e :<c-u>call SendPythonSelection()<cr>
-
- " Send the entire buffer to the REPL ([r]eload)
- au FileType python nnoremap <buffer> <silent> <localleader>r :call SendPythonBuffer()<cr>
-
- " Clear the REPL
- au FileType python nnoremap <buffer> <silent> <localleader>c :call NeoReplSendRaw("")<cr>
+ au FileType python nnoremap <buffer> gi :Neoformat black<cr>zx
augroup END
" }}}
@@ -1944,46 +1783,6 @@
augroup END
" }}}
-" ReStructuredText {{{
-
-augroup ft_rest
- au!
-
- au Filetype rst nnoremap <buffer> <localleader>1 yypVr=:redraw<cr>
- au Filetype rst nnoremap <buffer> <localleader>2 yypVr-:redraw<cr>
- au Filetype rst nnoremap <buffer> <localleader>3 yypVr~:redraw<cr>
- au Filetype rst nnoremap <buffer> <localleader>4 yypVr`:redraw<cr>
-augroup END
-
-" }}}
-" Rubby {{{
-
-augroup ft_ruby
- au!
- au Filetype ruby setlocal foldmethod=syntax
- au BufRead,BufNewFile Capfile setlocal filetype=ruby
-augroup END
-
-" }}}
-" Scala {{{
-
-augroup ft_scala
- au!
-
- au FileType scala setlocal foldmethod=syntax
- au FileType scala setlocal foldlevel=1
- au FileType scala setlocal cc=100 tw=100
- au FileType scala setlocal expandtab
-
- au FileType scala nnoremap <buffer> <leader>s :SortSimpleScalaImports<cr>
- au FileType scala nnoremap <buffer> <c-]> :call LanguageClient_textDocument_definition()<CR>
- au FileType scala nnoremap <buffer> <localleader>r :call LanguageClient_textDocument_references()<CR>
- au FileType scala inoremap <buffer> <c-n> <c-x><c-o>
-
- au FileType scala setlocal omnifunc=LanguageClient#complete
-augroup END
-
-" }}}
" Sh {{{
function! SendShellParagraph() "{{{
@@ -2001,16 +1800,6 @@
augroup END
" }}}
-" ShaderLab {{{
-
-augroup ft_shaderlab " {{{
- au!
-
- au FileType shaderlab setlocal shiftwidth=4
- au FileType shaderlab setlocal expandtab
-augroup END " }}}
-
-" }}}
" Standard In {{{
augroup ft_stdin
@@ -2021,15 +1810,6 @@
augroup END
" }}}
-" stevelosh.com Blog Entries {{{
-
-augroup ft_steveloshcom
- au!
- au BufRead,BufNewFile */stevelosh/content/blog/20*/*/*.html set ft=markdown
- au BufRead,BufNewFile */stevelosh/content/projects/*.html set ft=markdown
-augroup END
-
-" }}}
" Terminal {{{
augroup ft_terminal
@@ -2038,6 +1818,15 @@
augroup END
" }}}
+" Terraform {{{
+
+augroup ft_terraform
+ au!
+
+ au FileType terraform setlocal foldmethod=syntax
+augroup END
+
+" }}}
" Vagrant {{{
augroup ft_vagrant
@@ -2058,7 +1847,7 @@
au FileType vim vnoremap <localleader>S y:@"<CR>
au FileType vim nnoremap <localleader>S ^vg_y:execute @@<cr>:echo 'Sourced line.'<cr>
- au FileType vim inoremap <c-n> <c-x><c-n>
+ au FileType vim inoremap <buffer> <c-n> <c-x><c-n>
augroup END
" }}}
@@ -2071,15 +1860,6 @@
augroup END
" }}}
-" Wisp {{{
-
-augroup ft_wisp
- au!
-
- au BufRead,BufNewFile *.wisp set ft=clojure
-augroup END
-
-" }}}
" XML {{{
augroup ft_xml
@@ -2193,6 +1973,8 @@
nnoremap <leader>gci :Gcommit<cr>
nnoremap <leader>gm :Gmove<cr>
nnoremap <leader>gr :Gremove<cr>
+nnoremap <leader>gpo :!git push origin<cr>
+nnoremap <leader>gpu :!git push upstream<cr>
nnoremap <leader>gl :Clam git gll -100 \| stripcolor<cr>
@@ -2246,26 +2028,12 @@
let g:atia_attributes_complete = 0
" }}}
-" Language Server Protocol {{{
-
-let g:LanguageClient_serverCommands = {
- \ 'scala': ['netcat', 'localhost', '62831'],
- \ 'java': ['netcat', 'localhost', '62831'],
- \ }
-let g:LanguageClient_autoStart = 1
-
-nnoremap <silent> gd :call LanguageClient_textDocument_definition()<CR>
-
-" nnoremap <silent> K :call LanguageClient_textDocument_hover()<CR>
-" nnoremap <silent> <F2> :call LanguageClient_textDocument_rename()<CR>
-
-" }}}
" MiniYank {{{
-map p <Plug>(miniyank-autoput)
-map P <Plug>(miniyank-autoPut)
-nmap gp <Plug>(miniyank-cycle)
-nnoremap gP g-
+" map p <Plug>(miniyank-autoput)
+" map P <Plug>(miniyank-autoPut)
+" nmap gp <Plug>(miniyank-cycle)
+" nnoremap gP g-
" }}}
" NeoFormat {{{
@@ -2309,6 +2077,8 @@
noremap <F2> :NERDTreeToggle<cr>
inoremap <F2> <esc>:NERDTreeToggle<cr>
+noremap <F14> :NERDTreeFind<cr>
+inoremap <F14> <esc>:NERDTreeFind<cr>
noremap <S-F2> :NERDTreeFind<cr>
inoremap <S-F2> <esc>:NERDTreeFind<cr>
@@ -2338,13 +2108,14 @@
let NERDChristmasTree = 1
let NERDTreeChDirMode = 2
let NERDTreeMapJumpFirstChild = 'gK'
+let g:NERDTreeMinimalMenu = 1
" }}}
" Paredit {{{
let g:paredit_smartjump = 1
let g:paredit_shortmaps = 0
-let g:paredit_electric_return = 1
+let g:paredit_electric_return = 0
let g:paredit_matchlines = 200
let g:paredit_disable_lisp = 1
@@ -2430,12 +2201,6 @@
let g:rbpt_max = 1
" }}}
-" Scala {{{
-
-let g:scala_use_builtin_tagbar_defs = 0
-let g:scala_use_default_keymappings = 0
-
-" }}}
" Scratch {{{
command! ScratchToggle call ScratchToggle()
@@ -2610,13 +2375,6 @@
endfunction
" }}}
-" Supertab {{{
-
-let g:SuperTabDefaultCompletionType = "<c-n>"
-let g:SuperTabLongestHighlight = 1
-let g:SuperTabCrMapping = 1
-
-"}}}
" Splice {{{
let g:splice_prefix = "-"
@@ -2684,6 +2442,18 @@
\ "SPEED": 1
\ }
+let g:vlime_contribs = [
+ \ "SWANK-ASDF",
+ \ "SWANK-PACKAGE-FU",
+ \ "SWANK-PRESENTATIONS",
+ \ "SWANK-FANCY-INSPECTOR",
+ \ "SWANK-C-P-C",
+ \ "SWANK-ARGLISTS",
+ \ "SWANK-REPL",
+ \ "SWANK-FUZZY",
+ \ "SWANK-TRACE-DIALOG"
+ \ ]
+
" let g:vlime_indent_keywords = {"defsystem": 1}
function! CleanVlimeWindows()
@@ -2760,7 +2530,7 @@
" Windowswap {{{
let g:windowswap_map_keys = 0 "prevent default bindings
-nnoremap <silent> <leader>W :call WindowSwap#EasyWindowSwap()<CR>
+nnoremap <silent> <leader>ws :call WindowSwap#EasyWindowSwap()<CR>
" }}}
@@ -2831,6 +2601,15 @@
" Stuff that should probably be broken out into plugins, but hasn't proved to be
" worth the time to do so just yet.
+" HTTP Statuses {{{
+
+function! HTTPStatuses()
+ call termopen('w3m /home/sjl/Dropbox/docs/httpstatuses/httpstatuses.com/index.html')
+endfunc
+
+command! HTTPStatuses call HTTPStatuses()
+
+" }}}
" Synstack {{{
" Show the stack of syntax hilighting classes affecting whatever is under the
@@ -2878,9 +2657,6 @@
nnoremap <leader>V :call ToggleVirtualEdit()<cr>
-" TODO: Figure out the diffexpr shit necessary to make this buffer-local.
-" nnoremap <leader>W :call ToggleDiffWhitespace()<CR>
-
" }}}
" Error Toggles {{{
@@ -3006,15 +2782,6 @@
nnoremap <leader>h<space> :!hg<space>
" }}}
-" J {{{
-
-function! s:JumpTo(dest)
- call system("tmux split-window -h 'j " . a:dest . "; and myctags &; and nvim .'")
-endfunction
-
-command! -nargs=1 J call s:JumpTo(<f-args>)
-
-" }}}
" Ack motions {{{
" Motions to Ack for things. Works with pretty much everything, including:
@@ -3088,6 +2855,7 @@
execute 'hi ' . old_hi
endfunction " }}}
+
command! -nargs=0 Pulse call s:Pulse()
" }}}
@@ -3171,56 +2939,7 @@
if has('gui_running')
" GUI Vim
-
- set guifont=Menlo\ Regular\ for\ Powerline:h12
-
- " Remove all the UI cruft
- set go-=T
- set go-=l
- set go-=L
- set go-=r
- set go-=R
-
- highlight SpellBad term=underline gui=undercurl guisp=Orange
-
- " Different cursors for different modes.
- set guicursor=n-c:block-Cursor-blinkon0
- set guicursor+=v:block-vCursor-blinkon0
- set guicursor+=i-ci:ver20-iCursor
-
- if has("gui_macvim")
- " Full screen means FULL screen
- set fuoptions=maxvert,maxhorz
-
- " Use the normal HIG movements, except for M-Up/Down
- let macvim_skip_cmd_opt_movement = 1
- no <D-Left> <Home>
- no! <D-Left> <Home>
- no <M-Left> <C-Left>
- no! <M-Left> <C-Left>
-
- no <D-Right> <End>
- no! <D-Right> <End>
- no <M-Right> <C-Right>
- no! <M-Right> <C-Right>
-
- no <D-Up> <C-Home>
- ino <D-Up> <C-Home>
- imap <M-Up> <C-o>{
-
- no <D-Down> <C-End>
- ino <D-Down> <C-End>
- imap <M-Down> <C-o>}
-
- imap <M-BS> <C-w>
- inoremap <D-BS> <esc>my0c`y
- else
- " Non-MacVim GUI, like Gvim
- end
else
- " Console Vim
- " For me, this means iTerm2, possibly through tmux
-
" Mouse support
set mouse=a
endif
--- a/weechat/alias.conf Fri Apr 14 15:01:35 2023 -0400
+++ b/weechat/alias.conf Fri Jul 07 16:11:02 2023 -0400
@@ -4,9 +4,9 @@
# WARNING: It is NOT recommended to edit this file by hand,
# especially if WeeChat is running.
#
-# Use /set or similar command to change settings in WeeChat.
+# Use commands like /set or /fset to change settings in WeeChat.
#
-# For more info, see: https://weechat.org/doc/quickstart
+# For more info, see: https://weechat.org/doc/quickstart/
#
[cmd]
--- a/weechat/autosort.conf Fri Apr 14 15:01:35 2023 -0400
+++ b/weechat/autosort.conf Fri Jul 07 16:11:02 2023 -0400
@@ -4,15 +4,21 @@
# WARNING: It is NOT recommended to edit this file by hand,
# especially if WeeChat is running.
#
-# Use /set or similar command to change settings in WeeChat.
+# Use commands like /set or /fset to change settings in WeeChat.
#
-# For more info, see: https://weechat.org/doc/quickstart
+# For more info, see: https://weechat.org/doc/quickstart/
#
[sorting]
case_sensitive = off
-group_irc = on
+debug_log = off
replacements = "[]"
rules = "[["core", 0], ["irc", 2], ["*", 1], ["irc.irc_raw", 0], ["irc.server", 1]]"
+signal_delay = 5
signals = "buffer_opened buffer_merged buffer_unmerged buffer_renamed"
+sort_limit = 100
sort_on_config_change = on
+
+[v3]
+helpers = "{"core_first": "${if:${buffer.full_name}!=core.weechat}", "irc_raw_first": "${if:${buffer.full_name}!=irc.irc_raw}", "irc_raw_last": "${if:${buffer.full_name}==irc.irc_raw}", "hashless_name": "${info:autosort_replace,#,,${info:autosort_escape,${buffer.name}}}", "script_or_plugin": "${if:${script_name}?${script_name}:${plugin}}"}"
+rules = "["${core_first}", "${info:autosort_order,${info:autosort_escape,${script_or_plugin}},core,*,irc,bitlbee,matrix,slack}", "${script_or_plugin}", "${irc_raw_first}", "${server}", "${info:autosort_order,${type},server,*,channel,private}", "${hashless_name}", "${buffer.full_name}"]"
--- a/weechat/buflist.conf Fri Apr 14 15:01:35 2023 -0400
+++ b/weechat/buflist.conf Fri Jul 07 16:11:02 2023 -0400
@@ -4,9 +4,9 @@
# WARNING: It is NOT recommended to edit this file by hand,
# especially if WeeChat is running.
#
-# Use /set or similar command to change settings in WeeChat.
+# Use commands like /set or /fset to change settings in WeeChat.
#
-# For more info, see: https://weechat.org/doc/quickstart
+# For more info, see: https://weechat.org/doc/quickstart/
#
[look]
@@ -21,6 +21,7 @@
nick_prefix_empty = on
signals_refresh = ""
sort = "number,-active"
+use_items = 1
[format]
buffer = "${format_number}${indent}${format_nick_prefix}${color_hotlist}${format_name}"
@@ -37,3 +38,4 @@
name = "${name}"
nick_prefix = "${color_nick_prefix}${nick_prefix}"
number = "${color:green}${number}${if:${number_displayed}?.: }"
+tls_version = " ${color:default}(${if:${tls_version}==TLS1.3?${color:green}:${if:${tls_version}==TLS1.2?${color:yellow}:${color:red}}}${translate:${tls_version}}${color:default})"
--- a/weechat/charset.conf Fri Apr 14 15:01:35 2023 -0400
+++ b/weechat/charset.conf Fri Jul 07 16:11:02 2023 -0400
@@ -4,9 +4,9 @@
# WARNING: It is NOT recommended to edit this file by hand,
# especially if WeeChat is running.
#
-# Use /set or similar command to change settings in WeeChat.
+# Use commands like /set or /fset to change settings in WeeChat.
#
-# For more info, see: https://weechat.org/doc/quickstart
+# For more info, see: https://weechat.org/doc/quickstart/
#
[default]
--- a/weechat/exec.conf Fri Apr 14 15:01:35 2023 -0400
+++ b/weechat/exec.conf Fri Jul 07 16:11:02 2023 -0400
@@ -4,14 +4,15 @@
# WARNING: It is NOT recommended to edit this file by hand,
# especially if WeeChat is running.
#
-# Use /set or similar command to change settings in WeeChat.
+# Use commands like /set or /fset to change settings in WeeChat.
#
-# For more info, see: https://weechat.org/doc/quickstart
+# For more info, see: https://weechat.org/doc/quickstart/
#
[command]
default_options = ""
purge_delay = 0
+shell = "${env:SHELL}"
[color]
flag_finished = lightred
--- a/weechat/fifo.conf Fri Apr 14 15:01:35 2023 -0400
+++ b/weechat/fifo.conf Fri Jul 07 16:11:02 2023 -0400
@@ -4,9 +4,9 @@
# WARNING: It is NOT recommended to edit this file by hand,
# especially if WeeChat is running.
#
-# Use /set or similar command to change settings in WeeChat.
+# Use commands like /set or /fset to change settings in WeeChat.
#
-# For more info, see: https://weechat.org/doc/quickstart
+# For more info, see: https://weechat.org/doc/quickstart/
#
[file]
--- a/weechat/fset.conf Fri Apr 14 15:01:35 2023 -0400
+++ b/weechat/fset.conf Fri Jul 07 16:11:02 2023 -0400
@@ -4,12 +4,13 @@
# WARNING: It is NOT recommended to edit this file by hand,
# especially if WeeChat is running.
#
-# Use /set or similar command to change settings in WeeChat.
+# Use commands like /set or /fset to change settings in WeeChat.
#
-# For more info, see: https://weechat.org/doc/quickstart
+# For more info, see: https://weechat.org/doc/quickstart/
#
[look]
+auto_refresh = "*"
auto_unmark = off
condition_catch_set = "${count} >= 1"
export_help_default = on
--- a/weechat/logger.conf Fri Apr 14 15:01:35 2023 -0400
+++ b/weechat/logger.conf Fri Jul 07 16:11:02 2023 -0400
@@ -4,9 +4,9 @@
# WARNING: It is NOT recommended to edit this file by hand,
# especially if WeeChat is running.
#
-# Use /set or similar command to change settings in WeeChat.
+# Use commands like /set or /fset to change settings in WeeChat.
#
-# For more info, see: https://weechat.org/doc/quickstart
+# For more info, see: https://weechat.org/doc/quickstart/
#
[look]
@@ -19,6 +19,7 @@
[file]
auto_log = on
+color_lines = off
flush_delay = 120
fsync = off
info_lines = off
--- a/weechat/perl.conf Fri Apr 14 15:01:35 2023 -0400
+++ b/weechat/perl.conf Fri Jul 07 16:11:02 2023 -0400
@@ -4,7 +4,7 @@
# WARNING: It is NOT recommended to edit this file by hand,
# especially if WeeChat is running.
#
-# Use /set or similar command to change settings in WeeChat.
+# Use commands like /set or /fset to change settings in WeeChat.
#
# For more info, see: https://weechat.org/doc/quickstart
#
--- a/weechat/python.conf Fri Apr 14 15:01:35 2023 -0400
+++ b/weechat/python.conf Fri Jul 07 16:11:02 2023 -0400
@@ -4,9 +4,9 @@
# WARNING: It is NOT recommended to edit this file by hand,
# especially if WeeChat is running.
#
-# Use /set or similar command to change settings in WeeChat.
+# Use commands like /set or /fset to change settings in WeeChat.
#
-# For more info, see: https://weechat.org/doc/quickstart
+# For more info, see: https://weechat.org/doc/quickstart/
#
[look]
--- a/weechat/python/autoload/autosort.py Fri Apr 14 15:01:35 2023 -0400
+++ b/weechat/python/autoload/autosort.py Fri Jul 07 16:11:02 2023 -0400
@@ -1,860 +1,1 @@
-# -*- coding: utf-8 -*-
-#
-# Copyright (C) 2013-2014 Maarten de Vries <maarten@de-vri.es>
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-#
-
-#
-# Autosort automatically keeps your buffers sorted and grouped by server.
-# You can define your own sorting rules. See /help autosort for more details.
-#
-# http://github.com/de-vri.es/weechat-autosort
-#
-
-#
-# Changelog:
-# 2.5:
-# * Fix handling unicode buffer names.
-# * Add hint to set irc.look.server_buffer to independent and buffers.look.indenting to on.
-# 2.4:
-# * Make script python3 compatible.
-# 2.3:
-# * Fix sorting items without score last (regressed in 2.2).
-# 2.2:
-# * Add configuration option for signals that trigger a sort.
-# * Add command to manually trigger a sort (/autosort sort).
-# * Add replacement patterns to apply before sorting.
-# 2.1:
-# * Fix some minor style issues.
-# 2.0:
-# * Allow for custom sort rules.
-#
-
-
-import weechat
-import re
-import json
-
-SCRIPT_NAME = 'autosort'
-SCRIPT_AUTHOR = 'Maarten de Vries <maarten@de-vri.es>'
-SCRIPT_VERSION = '2.5'
-SCRIPT_LICENSE = 'GPL3'
-SCRIPT_DESC = 'Automatically or manually keep your buffers sorted and grouped by server.'
-
-
-config = None
-hooks = []
-
-class HumanReadableError(Exception):
- pass
-
-
-def parse_int(arg, arg_name = 'argument'):
- ''' Parse an integer and provide a more human readable error. '''
- arg = arg.strip()
- try:
- return int(arg)
- except ValueError:
- raise HumanReadableError('Invalid {0}: expected integer, got "{1}".'.format(arg_name, arg))
-
-
-class Pattern:
- ''' A simple glob-like pattern for matching buffer names. '''
-
- def __init__(self, pattern):
- ''' Construct a pattern from a string. '''
- escaped = False
- char_class = 0
- chars = ''
- regex = ''
- for c in pattern:
- if escaped and char_class:
- escaped = False
- chars += re.escape(c)
- elif escaped:
- escaped = False
- regex += re.escape(c)
- elif c == '\\':
- escaped = True
- elif c == '*' and not char_class:
- regex += '[^.]*'
- elif c == '?' and not char_class:
- regex += '[^.]'
- elif c == '[' and not char_class:
- char_class = 1
- chars = ''
- elif c == '^' and char_class and not chars:
- chars += '^'
- elif c == ']' and char_class and chars not in ('', '^'):
- char_class = False
- regex += '[' + chars + ']'
- elif c == '-' and char_class:
- chars += '-'
- elif char_class:
- chars += re.escape(c)
- else:
- regex += re.escape(c)
-
- if char_class:
- raise ValueError("unmatched opening '['")
- if escaped:
- raise ValueError("unexpected trailing '\\'")
-
- self.regex = re.compile('^' + regex + '$')
- self.pattern = pattern
-
- def match(self, input):
- ''' Match the pattern against a string. '''
- return self.regex.match(input)
-
-
-class FriendlyList(object):
- ''' A list with human readable errors. '''
-
- def __init__(self):
- self.__data = []
-
- def raw(self):
- return self.__data
-
- def append(self, value):
- ''' Add a rule to the list. '''
- self.__data.append(value)
-
- def insert(self, index, value):
- ''' Add a rule to the list. '''
- if not 0 <= index <= len(self): raise HumanReadableError('Index out of range: expected an integer in the range [0, {0}], got {1}.'.format(len(self), index))
- self.__data.insert(index, value)
-
- def pop(self, index):
- ''' Remove a rule from the list and return it. '''
- if not 0 <= index < len(self): raise HumanReadableError('Index out of range: expected an integer in the range [0, {0}), got {1}.'.format(len(self), index))
- return self.__data.pop(index)
-
- def move(self, index_a, index_b):
- ''' Move a rule to a new position in the list. '''
- self.insert(index_b, self.pop(index_a))
-
- def swap(self, index_a, index_b):
- ''' Swap two elements in the list. '''
- self[index_a], self[index_b] = self[index_b], self[index_a]
-
- def __len__(self):
- return len(self.__data)
-
- def __getitem__(self, index):
- if not 0 <= index < len(self): raise HumanReadableError('Index out of range: expected an integer in the range [0, {0}), got {1}.'.format(len(self), index))
- return self.__data[index]
-
- def __setitem__(self, index, value):
- if not 0 <= index < len(self): raise HumanReadableError('Index out of range: expected an integer in the range [0, {0}), got {1}.'.format(len(self), index))
- self.__data[index] = value
-
- def __iter__(self):
- return iter(self.__data)
-
-
-class RuleList(FriendlyList):
- ''' A list of rules to test buffer names against. '''
- rule_regex = re.compile(r'^(.*)=\s*([+-]?[^=]*)$')
-
- def __init__(self, rules):
- ''' Construct a RuleList from a list of rules. '''
- super(RuleList, self).__init__()
- for rule in rules: self.append(rule)
-
- def get_score(self, name, rules):
- ''' Get the sort score of a partial name according to a rule list. '''
- for rule in self:
- if rule[0].match(name): return rule[1]
- return 999999999
-
- def encode(self):
- ''' Encode the rules for storage. '''
- return json.dumps(list(map(lambda x: (x[0].pattern, x[1]), self)))
-
- @staticmethod
- def decode(blob):
- ''' Parse rules from a string blob. '''
- result = []
-
- try:
- decoded = json.loads(blob)
- except ValueError:
- log('Invalid rules: expected JSON encoded list of pairs, got "{0}".'.format(blob))
- return [], 0
-
- for rule in decoded:
- # Rules must be a pattern,score pair.
- if len(rule) != 2:
- log('Invalid rule: expected (pattern, score), got "{0}". Rule ignored.'.format(rule))
- continue
-
- # Rules must have a valid pattern.
- try:
- pattern = Pattern(rule[0])
- except ValueError as e:
- log('Invalid pattern: {0} in "{1}". Rule ignored.'.format(e, rule[0]))
- continue
-
- # Rules must have a valid score.
- try:
- score = int(rule[1])
- except ValueError as e:
- log('Invalid score: expected an integer, got "{0}". Rule ignored.'.format(score))
- continue
-
- result.append((pattern, score))
-
- return RuleList(result)
-
- @staticmethod
- def parse_rule(arg):
- ''' Parse a rule argument. '''
- arg = arg.strip()
- match = RuleList.rule_regex.match(arg)
- if not match:
- raise HumanReadableError('Invalid rule: expected "<pattern> = <score>", got "{0}".'.format(arg))
-
- pattern = match.group(1).strip()
- try:
- pattern = Pattern(pattern)
- except ValueError as e:
- raise HumanReadableError('Invalid pattern: {0} in "{1}".'.format(e, pattern))
-
- score = parse_int(match.group(2), 'score')
- return (pattern, score)
-
-
-def decode_replacements(blob):
- ''' Decode a replacement list encoded as JSON. '''
- result = FriendlyList()
- try:
- decoded = json.loads(blob)
- except ValueError:
- log('Invalid replacement list: expected JSON encoded list of pairs, got "{0}".'.format(blob))
- return [], 0
-
- for replacement in decoded:
- # Replacements must be a (string, string) pair.
- if len(replacement) != 2:
- log('Invalid replacement pattern: expected (pattern, replacement), got "{0}". Replacement ignored.'.format(rule))
- continue
- result.append(replacement)
-
- return result
-
-
-def encode_replacements(replacements):
- ''' Encode a list of replacement patterns as JSON. '''
- return json.dumps(replacements.raw())
-
-
-class Config:
- ''' The autosort configuration. '''
-
- default_rules = json.dumps([
- ('core', 0),
- ('irc', 2),
- ('*', 1),
-
- ('irc.irc_raw', 0),
- ('irc.server', 1),
- ])
-
- default_replacements = '[]'
- default_signals = 'buffer_opened buffer_merged buffer_unmerged buffer_renamed'
-
- def __init__(self, filename):
- ''' Initialize the configuration. '''
-
- self.filename = filename
- self.config_file = weechat.config_new(self.filename, '', '')
- self.sorting_section = None
-
- self.case_sensitive = False
- self.group_irc = True
- self.rules = []
- self.replacements = []
- self.signals = []
- self.sort_on_config = True
-
- self.__case_sensitive = None
- self.__group_irc = None
- self.__rules = None
- self.__replacements = None
- self.__signals = None
- self.__sort_on_config = None
-
- if not self.config_file:
- log('Failed to initialize configuration file "{0}".'.format(self.filename))
- return
-
- self.sorting_section = weechat.config_new_section(self.config_file, 'sorting', False, False, '', '', '', '', '', '', '', '', '', '')
-
- if not self.sorting_section:
- log('Failed to initialize section "sorting" of configuration file.')
- weechat.config_free(self.config_file)
- return
-
- self.__case_sensitive = weechat.config_new_option(
- self.config_file, self.sorting_section,
- 'case_sensitive', 'boolean',
- 'If this option is on, sorting is case sensitive.',
- '', 0, 0, 'off', 'off', 0,
- '', '', '', '', '', ''
- )
-
- self.__group_irc = weechat.config_new_option(
- self.config_file, self.sorting_section,
- 'group_irc', 'boolean',
- 'If this option is on, the script pretends that IRC channel/private buffers are renamed to "irc.server.{network}.{channel}" rather than "irc.{network}.{channel}".' +
- 'This ensures that these buffers are grouped with their respective server buffer.',
- '', 0, 0, 'on', 'on', 0,
- '', '', '', '', '', ''
- )
-
- self.__rules = weechat.config_new_option(
- self.config_file, self.sorting_section,
- 'rules', 'string',
- 'An ordered list of sorting rules encoded as JSON. See /help autosort for commands to manipulate these rules.',
- '', 0, 0, Config.default_rules, Config.default_rules, 0,
- '', '', '', '', '', ''
- )
-
- self.__replacements = weechat.config_new_option(
- self.config_file, self.sorting_section,
- 'replacements', 'string',
- 'An ordered list of replacement patterns to use on buffer name components, encoded as JSON. See /help autosort for commands to manipulate these replacements.',
- '', 0, 0, Config.default_replacements, Config.default_replacements, 0,
- '', '', '', '', '', ''
- )
-
- self.__signals = weechat.config_new_option(
- self.config_file, self.sorting_section,
- 'signals', 'string',
- 'The signals that will cause autosort to resort your buffer list. Seperate signals with spaces.',
- '', 0, 0, Config.default_signals, Config.default_signals, 0,
- '', '', '', '', '', ''
- )
-
- self.__sort_on_config = weechat.config_new_option(
- self.config_file, self.sorting_section,
- 'sort_on_config_change', 'boolean',
- 'Decides if the buffer list should be sorted when autosort configuration changes.',
- '', 0, 0, 'on', 'on', 0,
- '', '', '', '', '', ''
- )
-
- if weechat.config_read(self.config_file) != weechat.WEECHAT_RC_OK:
- log('Failed to load configuration file.')
-
- if weechat.config_write(self.config_file) != weechat.WEECHAT_RC_OK:
- log('Failed to write configuration file.')
-
- self.reload()
-
- def reload(self):
- ''' Load configuration variables. '''
-
- self.case_sensitive = weechat.config_boolean(self.__case_sensitive)
- self.group_irc = weechat.config_boolean(self.__group_irc)
-
- rules_blob = weechat.config_string(self.__rules)
- replacements_blob = weechat.config_string(self.__replacements)
- signals_blob = weechat.config_string(self.__signals)
-
- self.rules = RuleList.decode(rules_blob)
- self.replacements = decode_replacements(replacements_blob)
- self.signals = signals_blob.split()
- self.sort_on_config = weechat.config_boolean(self.__sort_on_config)
-
- def save_rules(self, run_callback = True):
- ''' Save the current rules to the configuration. '''
- weechat.config_option_set(self.__rules, RuleList.encode(self.rules), run_callback)
-
- def save_replacements(self, run_callback = True):
- ''' Save the current replacement patterns to the configuration. '''
- weechat.config_option_set(self.__replacements, encode_replacements(self.replacements), run_callback)
-
-
-def pad(sequence, length, padding = None):
- ''' Pad a list until is has a certain length. '''
- return sequence + [padding] * max(0, (length - len(sequence)))
-
-
-def log(message, buffer = 'NULL'):
- weechat.prnt(buffer, 'autosort: {0}'.format(message))
-
-
-def get_buffers():
- ''' Get a list of all the buffers in weechat. '''
- buffers = []
-
- buffer_list = weechat.infolist_get('buffer', '', '')
-
- while weechat.infolist_next(buffer_list):
- name = weechat.infolist_string (buffer_list, 'full_name')
- number = weechat.infolist_integer(buffer_list, 'number')
-
- # Buffer is merged with one we already have in the list, skip it.
- if number <= len(buffers):
- continue
- buffers.append(name)
-
- weechat.infolist_free(buffer_list)
- return buffers
-
-
-def preprocess(buffer, config):
- '''
- Preprocess a buffers names.
- '''
- if not config.case_sensitive:
- buffer = buffer.lower()
-
- for replacement in config.replacements:
- buffer = buffer.replace(replacement[0], replacement[1])
-
- buffer = buffer.split('.')
- if config.group_irc and len(buffer) >= 2 and buffer[0] == 'irc' and buffer[1] not in ('server', 'irc_raw'):
- buffer.insert(1, 'server')
-
- return buffer
-
-
-def buffer_sort_key(rules):
- ''' Create a sort key function for a buffer list from a rule list. '''
- def key(buffer):
- result = []
- name = ''
- for word in preprocess(buffer.decode('utf-8'), config):
- name += ('.' if name else '') + word
- result.append((rules.get_score(name, rules), word))
- return result
-
- return key
-
-
-def apply_buffer_order(buffers):
- ''' Sort the buffers in weechat according to the order in the input list. '''
- for i, buffer in enumerate(buffers):
- weechat.command('', '/buffer swap {0} {1}'.format(buffer, i + 1))
-
-
-def split_args(args, expected, optional = 0):
- ''' Split an argument string in the desired number of arguments. '''
- split = args.split(' ', expected - 1)
- if (len(split) < expected):
- raise HumanReadableError('Expected at least {0} arguments, got {1}.'.format(expected, len(split)))
- return split[:-1] + pad(split[-1].split(' ', optional), optional + 1, '')
-
-
-def command_sort(buffer, command, args):
- ''' Sort the buffers and print a confirmation. '''
- on_buffers_changed()
- log("Finished sorting buffers.", buffer)
- return weechat.WEECHAT_RC_OK
-
-
-def command_rule_list(buffer, command, args):
- ''' Show the list of sorting rules. '''
- output = 'Sorting rules:\n'
- for i, rule in enumerate(config.rules):
- output += ' {0}: {1} = {2}\n'.format(i, rule[0].pattern, rule[1])
- if not len(config.rules):
- output += ' No sorting rules configured.\n'
- log(output, buffer)
-
- return weechat.WEECHAT_RC_OK
-
-
-def command_rule_add(buffer, command, args):
- ''' Add a rule to the rule list. '''
- rule = RuleList.parse_rule(args)
-
- config.rules.append(rule)
- config.save_rules()
- command_rule_list(buffer, command, '')
-
- return weechat.WEECHAT_RC_OK
-
-
-def command_rule_insert(buffer, command, args):
- ''' Insert a rule at the desired position in the rule list. '''
- index, rule = split_args(args, 2)
- index = parse_int(index, 'index')
- rule = RuleList.parse_rule(rule)
-
- config.rules.insert(index, rule)
- config.save_rules()
- command_rule_list(buffer, command, '')
- return weechat.WEECHAT_RC_OK
-
-
-def command_rule_update(buffer, command, args):
- ''' Update a rule in the rule list. '''
- index, rule = split_args(args, 2)
- index = parse_int(index, 'index')
- rule = RuleList.parse_rule(rule)
-
- config.rules[index] = rule
- config.save_rules()
- command_rule_list(buffer, command, '')
- return weechat.WEECHAT_RC_OK
-
-
-def command_rule_delete(buffer, command, args):
- ''' Delete a rule from the rule list. '''
- index = args.strip()
- index = parse_int(index, 'index')
-
- config.rules.pop(index)
- config.save_rules()
- command_rule_list(buffer, command, '')
- return weechat.WEECHAT_RC_OK
-
-
-def command_rule_move(buffer, command, args):
- ''' Move a rule to a new position. '''
- index_a, index_b = split_args(args, 2)
- index_a = parse_int(index_a, 'index')
- index_b = parse_int(index_b, 'index')
-
- config.rules.move(index_a, index_b)
- config.save_rules()
- command_rule_list(buffer, command, '')
- return weechat.WEECHAT_RC_OK
-
-
-def command_rule_swap(buffer, command, args):
- ''' Swap two rules. '''
- index_a, index_b = split_args(args, 2)
- index_a = parse_int(index_a, 'index')
- index_b = parse_int(index_b, 'index')
-
- config.rules.swap(index_a, index_b)
- config.save_rules()
- command_rule_list(buffer, command, '')
- return weechat.WEECHAT_RC_OK
-
-
-def command_replacement_list(buffer, command, args):
- ''' Show the list of sorting rules. '''
- output = 'Replacement patterns:\n'
- for i, pattern in enumerate(config.replacements):
- output += ' {0}: {1} -> {2}\n'.format(i, pattern[0], pattern[1])
- if not len(config.replacements):
- output += ' No replacement patterns configured.'
- log(output, buffer)
-
- return weechat.WEECHAT_RC_OK
-
-
-def command_replacement_add(buffer, command, args):
- ''' Add a rule to the rule list. '''
- pattern, replacement = split_args(args, 1, 1)
-
- config.replacements.append((pattern, replacement))
- config.save_replacements()
- command_replacement_list(buffer, command, '')
-
- return weechat.WEECHAT_RC_OK
-
-
-def command_replacement_insert(buffer, command, args):
- ''' Insert a rule at the desired position in the rule list. '''
- index, pattern, replacement = split_args(args, 2, 1)
- index = parse_int(index, 'index')
-
- config.replacements.insert(index, (pattern, replacement))
- config.save_replacements()
- command_replacement_list(buffer, command, '')
- return weechat.WEECHAT_RC_OK
-
-
-def command_replacement_update(buffer, command, args):
- ''' Update a rule in the rule list. '''
- index, pattern, replacement = split_args(args, 2, 1)
- index = parse_int(index, 'index')
-
- config.replacements[index] = (pattern, replacement)
- config.save_replacements()
- command_replacement_list(buffer, command, '')
- return weechat.WEECHAT_RC_OK
-
-
-def command_replacement_delete(buffer, command, args):
- ''' Delete a rule from the rule list. '''
- index = args.strip()
- index = parse_int(index, 'index')
-
- config.replacements.pop(index)
- config.save_replacements()
- command_replacement_list(buffer, command, '')
- return weechat.WEECHAT_RC_OK
-
-
-def command_replacement_move(buffer, command, args):
- ''' Move a rule to a new position. '''
- index_a, index_b = split_args(args, 2)
- index_a = parse_int(index_a, 'index')
- index_b = parse_int(index_b, 'index')
-
- config.replacements.move(index_a, index_b)
- config.save_replacements()
- command_replacement_list(buffer, command, '')
- return weechat.WEECHAT_RC_OK
-
-
-def command_replacement_swap(buffer, command, args):
- ''' Swap two rules. '''
- index_a, index_b = split_args(args, 2)
- index_a = parse_int(index_a, 'index')
- index_b = parse_int(index_b, 'index')
-
- config.replacements.swap(index_a, index_b)
- config.save_replacements()
- command_replacement_list(buffer, command, '')
- return weechat.WEECHAT_RC_OK
-
-
-
-
-def call_command(buffer, command, args, subcommands):
- ''' Call a subccommand from a dictionary. '''
- subcommand, tail = pad(args.split(' ', 1), 2, '')
- subcommand = subcommand.strip()
- if (subcommand == ''):
- child = subcommands.get(' ')
- else:
- command = command + [subcommand]
- child = subcommands.get(subcommand)
-
- if isinstance(child, dict):
- return call_command(buffer, command, tail, child)
- elif callable(child):
- return child(buffer, command, tail)
-
- log('{0}: command not found'.format(' '.join(command)))
- return weechat.WEECHAT_RC_ERROR
-
-
-def on_buffers_changed(*args, **kwargs):
- ''' Called whenever the buffer list changes. '''
- buffers = get_buffers()
- buffers.sort(key=buffer_sort_key(config.rules))
- apply_buffer_order(buffers)
- return weechat.WEECHAT_RC_OK
-
-
-def on_config_changed(*args, **kwargs):
- ''' Called whenever the configuration changes. '''
- config.reload()
-
- # Unhook all signals and hook the new ones.
- for hook in hooks:
- weechat.unhook(hook)
- for signal in config.signals:
- hooks.append(weechat.hook_signal(signal, 'on_buffers_changed', ''))
-
- if config.sort_on_config:
- on_buffers_changed()
-
- return weechat.WEECHAT_RC_OK
-
-
-def on_autosort_command(data, buffer, args):
- ''' Called when the autosort command is invoked. '''
- try:
- return call_command(buffer, ['/autosort'], args, {
- ' ': command_sort,
- 'sort': command_sort,
-
- 'rules': {
- ' ': command_rule_list,
- 'list': command_rule_list,
- 'add': command_rule_add,
- 'insert': command_rule_insert,
- 'update': command_rule_update,
- 'delete': command_rule_delete,
- 'move': command_rule_move,
- 'swap': command_rule_swap,
- },
- 'replacements': {
- ' ': command_replacement_list,
- 'list': command_replacement_list,
- 'add': command_replacement_add,
- 'insert': command_replacement_insert,
- 'update': command_replacement_update,
- 'delete': command_replacement_delete,
- 'move': command_replacement_move,
- 'swap': command_replacement_swap,
- },
- 'sort': on_buffers_changed,
- })
- except HumanReadableError as e:
- log(e, buffer)
- return weechat.WEECHAT_RC_ERROR
-
-
-command_description = r'''
-NOTE: For the best effect, you may want to consider setting the option irc.look.server_buffer to independent and buffers.look.indenting to on.
-
-# Commands
-
-## Miscellaneous
-/autosort sort
-Manually trigger the buffer sorting.
-
-
-## Sorting rules
-
-/autosort rules list
-Print the list of sort rules.
-
-/autosort rules add <pattern> = <score>
-Add a new rule at the end of the list.
-
-/autosort rules insert <index> <pattern> = <score>
-Insert a new rule at the given index in the list.
-
-/autosort rules update <index> <pattern> = <score>
-Update a rule in the list with a new pattern and score.
-
-/autosort rules delete <index>
-Delete a rule from the list.
-
-/autosort rules move <index_from> <index_to>
-Move a rule from one position in the list to another.
-
-/autosort rules swap <index_a> <index_b>
-Swap two rules in the list
-
-
-## Replacement patterns
-
-/autosort replacements list
-Print the list of replacement patterns.
-
-/autosort replacements add <pattern> <replacement>
-Add a new replacement pattern at the end of the list.
-
-/autosort replacements insert <index> <pattern> <replacement>
-Insert a new replacement pattern at the given index in the list.
-
-/autosort replacements update <index> <pattern> <replacement>
-Update a replacement pattern in the list.
-
-/autosort replacements delete <index>
-Delete a replacement pattern from the list.
-
-/autosort replacements move <index_from> <index_to>
-Move a replacement pattern from one position in the list to another.
-
-/autosort replacements swap <index_a> <index_b>
-Swap two replacement pattern in the list
-
-
-# Introduction
-Autosort is a weechat script to automatically keep your buffers sorted.
-The sort order can be customized by defining your own sort rules,
-but the default should be sane enough for most people.
-It can also group IRC channel/private buffers under their server buffer if you like.
-
-Autosort first turns buffer names into a list of their components by splitting on them on the period character.
-For example, the buffer name "irc.server.freenode" is turned into ['irc', 'server', 'freenode'].
-The list of buffers is then lexicographically sorted.
-
-To facilitate custom sort orders, it is possible to assign a score to each component individually before the sorting is done.
-Any name component that did not get a score assigned will be sorted after those that did receive a score.
-Components are always sorted on their score first and on their name second.
-Lower scores are sorted first.
-
-## Automatic or manual sorting
-By default, autosort will automatically sort your buffer list whenever a buffer is opened, merged, unmerged or renamed.
-This should keep your buffers sorted in almost all situations.
-However, you may wish to change the list of signals that cause your buffer list to be sorted.
-Simply edit the "autosort.sorting.signals" option to add or remove any signal you like.
-If you remove all signals you can still sort your buffers manually with the "/autosort sort" command.
-To prevent all automatic sorting, "autosort.sorting.sort_on_config_change" should also be set to off.
-
-## Grouping IRC buffers
-In weechat, IRC channel/private buffers are named "irc.<network>.<#channel>",
-and IRC server buffers are named "irc.server.<network>".
-This does not work very well with lexicographical sorting if you want all buffers for one network grouped together.
-That is why autosort comes with the "autosort.sorting.group_irc" option,
-which secretly pretends IRC channel/private buffers are called "irc.server.<network>.<#channel>".
-The buffers are not actually renamed, autosort simply pretends they are for sorting purposes.
-
-## Replacement patterns
-Sometimes you may want to ignore some characters for sorting purposes.
-On Freenode for example, you may wish to ignore the difference between channels starting with a double or a single hash sign.
-To do so, simply add a replacement pattern that replaces ## with # with the following command:
-/autosort replacements add ## #
-
-Replacement patterns do not support wildcards or special characters at the moment.
-
-## Sort rules
-You can assign scores to name components by defining sort rules.
-The first rule that matches a component decides the score.
-Further rules are not examined.
-Sort rules use the following syntax:
-<glob-pattern> = <score>
-
-You can use the "/autosort rules" command to show and manipulate the list of sort rules.
-
-
-Allowed special characters in the glob patterns are:
-
-Pattern | Meaning
---------|--------
-* | Matches a sequence of any characters except for periods.
-? | Matches a single character, but not a period.
-[a-z] | Matches a single character in the given regex-like character class.
-[^ab] | A negated regex-like character class.
-\* | A backslash escapes the next characters and removes its special meaning.
-\\ | A literal backslash.
-
-
-## Example
-As an example, consider the following rule list:
-0: core = 0
-1: irc = 2
-2: * = 1
-
-3: irc.server.*.#* = 1
-4: irc.server.*.* = 0
-
-Rule 0 ensures the core buffer is always sorted first.
-Rule 1 sorts IRC buffers last and rule 2 puts all remaining buffers in between the two.
-
-Rule 3 and 4 would make no sense with the group_irc option off.
-With the option on though, these rules will sort private buffers before regular channel buffers.
-Rule 3 matches channel buffers and assigns them a higher score,
-while rule 4 matches the buffers that remain and assigns them a lower score.
-The same effect could also be achieved with a single rule:
-irc.server.*.[^#]* = 0
-'''
-
-command_completion = 'sort||rules list|add|insert|update|delete|move|swap||replacements list|add|insert|update|delete|move|swap'
-
-
-if weechat.register(SCRIPT_NAME, SCRIPT_AUTHOR, SCRIPT_VERSION, SCRIPT_LICENSE, SCRIPT_DESC, "", ""):
- config = Config('autosort')
-
- weechat.hook_config('autosort.*', 'on_config_changed', '')
- weechat.hook_command('autosort', command_description, '', '', command_completion, 'on_autosort_command', 'NULL')
- on_config_changed()
+../autosort.py
\ No newline at end of file
--- a/weechat/python/autoload/brows.py Fri Apr 14 15:01:35 2023 -0400
+++ b/weechat/python/autoload/brows.py Fri Jul 07 16:11:02 2023 -0400
@@ -15,7 +15,7 @@
try:
import weechat
except ImportError:
- print 'This is a weechat script, what are you doing, run it in weechat, jesus'
+ print('This is a weechat script, what are you doing, run it in weechat, jesus')
import_ok = False
weechat_version = 0
--- a/weechat/python/autoload/colon_complete.py Fri Apr 14 15:01:35 2023 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,69 +0,0 @@
-SCRIPT_NAME='coloncomplete'
-SCRIPT_AUTHOR='Steve Losh <steve@stevelosh.com>'
-SCRIPT_VERSION='1.0'
-SCRIPT_LICENSE='MIT/X11'
-SCRIPT_DESC='Add a colon after nick completion when all the previous words in the input are also nicks.'
-
-EXTRA_NICKS = ['all', 'backend', 'clojerks', 'ops', 'support']
-
-import_ok=True
-
-try:
- import weechat
-except ImportError:
- print 'This script must be run under WeeChat'
- print 'You can obtain a copy of WeeChat, for free, at http://www.weechat.org'
- import_ok=False
-
-weechat_version=0
-
-def get_nicks(buffer, prefix=''):
- channel = weechat.buffer_get_string(buffer, 'localvar_channel')
- server = weechat.buffer_get_string(buffer, 'localvar_server')
- prefix = prefix.lower()
-
- matches = []
-
- infolist = weechat.infolist_get('irc_nick', '', '%s,%s' % (server, channel))
- while weechat.infolist_next(infolist):
- nick = weechat.infolist_string(infolist, 'name')
- if nick != 'localhost' and nick.lower().startswith(prefix):
- matches.append(nick)
- weechat.infolist_free(infolist)
-
- for nick in EXTRA_NICKS:
- if nick.lower().startswith(prefix):
- matches.append(nick)
-
- return matches
-
-def completer(data, buffer, command):
- cb = weechat.current_buffer()
- if command == "/input complete_next":
- line = weechat.buffer_get_string(cb, "input")
- words = line.split(' ')
- prefix = words[-1]
- if prefix and words and all([s.endswith(':') for s in words[:-1] if s]):
- nicks = get_nicks(cb, prefix)
- if len(nicks) == 1:
- for _ in range(len(prefix)):
- weechat.command(buffer, "/input delete_previous_char")
- weechat.command(buffer, "/input insert " + nicks[-1] + ":\\x20")
- elif len(nicks) > 1:
- l = min(len(nick) for nick in nicks)
- for i in range(len(prefix), l):
- if len(set(nick[i] for nick in nicks)) > 1:
- break
- else:
- weechat.command(buffer, "/input insert " + nicks[0][i])
-
- for nick in nicks:
- weechat.prnt(cb, "==> " + nick)
- return weechat.WEECHAT_RC_OK_EAT
-
- return weechat.WEECHAT_RC_OK
-
-if __name__ == "__main__" and import_ok:
- if weechat.register(SCRIPT_NAME, SCRIPT_AUTHOR, SCRIPT_VERSION, SCRIPT_LICENSE, SCRIPT_DESC, "", ""):
- weechat_version = weechat.info_get("version_number", "") or 0
- weechat.hook_command_run('/input complete*', 'completer', '')
--- a/weechat/python/autoload/editor.py Fri Apr 14 15:01:35 2023 -0400
+++ b/weechat/python/autoload/editor.py Fri Jul 07 16:11:02 2023 -0400
@@ -16,7 +16,7 @@
try:
import weechat
except ImportError:
- print 'This is a weechat script, what are you doing, run it in weechat, jesus'
+ print('This is a weechat script, what are you doing, run it in weechat, jesus')
import_ok = False
weechat_version = 0
@@ -33,9 +33,8 @@
# Reopen, because most editors do atomic write-tmp+rename saves which
# fucks with Python here.
tf.file.close()
- tf = file(tf.name)
-
- return tf.read()
+ with open(tf.name) as tf2:
+ return tf2.read()
def editor(data, buffer, args):
suffix = args or "tmp"
--- a/weechat/python/autoload/quotes.py Fri Apr 14 15:01:35 2023 -0400
+++ b/weechat/python/autoload/quotes.py Fri Jul 07 16:11:02 2023 -0400
@@ -18,7 +18,7 @@
try:
import weechat
except ImportError:
- print 'This is a weechat script, what are you doing, run it in weechat, jesus'
+ print('This is a weechat script, what are you doing, run it in weechat, jesus')
import_ok = False
weechat_version = 0
--- a/weechat/python/autoload/sanitize_jira.py Fri Apr 14 15:01:35 2023 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +0,0 @@
-import re, weechat, subprocess
-
-SCRIPT_NAME = 'sanitize_jira'
-SCRIPT_AUTHOR = 'Steve Losh <steve@stevelosh.com>'
-SCRIPT_VERSION = '0.0.1'
-SCRIPT_LICENSE = 'MIT'
-SCRIPT_DESC = 'clean up the garbage jirabot sends to channels into something readable'
-
-weechat.register(SCRIPT_NAME, SCRIPT_AUTHOR, SCRIPT_VERSION, SCRIPT_LICENSE, SCRIPT_DESC, '', '')
-
-weechat.hook_line('*', '', 'nick_Jira_Cloud', 'sanitize_jira', '')
-
-first_line_re = re.compile(
- r'(?P<link>https://[^/]+/browse/[^?]+)[?]atlOrigin=[^ ]+ [(](?P<title>.+)[)]'
-)
-
-detail_line_re = re.compile(
- r'''Status: \x1a\x01[*](?P<status>[^*]+)[*]\x1b\x01.*Type: \x1a\x01[*](?P<type>[^*]+)[*]\x1b\x01.*Assignee: \x1a\x01[*](?P<assignee>[^*]+)[*]\x1b\x01.*Priority: \x1a\x01[*](?P<priority>[^*]+)[*]\x1b\x01'''
-)
-
-def sanitize_jira(data, line):
- if 'sign up for an Atlassian account to view this link' in line['message']:
- return {'message': ' '}
-
- m = first_line_re.search(line['message'])
- if m:
- return {'message': '%s | %s' % (m.group('title'), m.group('link'))}
-
- m = detail_line_re.search(line['message'])
- if m:
- return {'message': '%s / %s / %s' % (m.group('type'), m.group('status'), m.group('assignee'))}
-
- return {}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/weechat/python/autosort.py Fri Jul 07 16:11:02 2023 -0400
@@ -0,0 +1,1075 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2013-2017 Maarten de Vries <maarten@de-vri.es>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+#
+# Autosort automatically keeps your buffers sorted and grouped by server.
+# You can define your own sorting rules. See /help autosort for more details.
+#
+# https://github.com/de-vri-es/weechat-autosort
+#
+
+#
+# Changelog:
+# 3.9:
+# * Remove `buffers.pl` from recommended settings.
+# 3,8:
+# * Fix relative sorting on script name in default rules.
+# * Document a useful property of stable sort algorithms.
+# 3.7:
+# * Make default rules work with bitlbee, matrix and slack.
+# 3.6:
+# * Add more documentation on provided info hooks.
+# 3.5:
+# * Add ${info:autosort_escape,...} to escape arguments for other info hooks.
+# 3.4:
+# * Fix rate-limit of sorting to prevent high CPU load and lock-ups.
+# * Fix bug in parsing empty arguments for info hooks.
+# * Add debug_log option to aid with debugging.
+# * Correct a few typos.
+# 3.3:
+# * Fix the /autosort debug command for unicode.
+# * Update the default rules to work better with Slack.
+# 3.2:
+# * Fix python3 compatiblity.
+# 3.1:
+# * Use colors to format the help text.
+# 3.0:
+# * Switch to evaluated expressions for sorting.
+# * Add `/autosort debug` command.
+# * Add ${info:autosort_replace,from,to,text} to replace substrings in sort rules.
+# * Add ${info:autosort_order,value,first,second,third} to ease writing sort rules.
+# * Make tab completion context aware.
+# 2.8:
+# * Fix compatibility with python 3 regarding unicode handling.
+# 2.7:
+# * Fix sorting of buffers with spaces in their name.
+# 2.6:
+# * Ignore case in rules when doing case insensitive sorting.
+# 2.5:
+# * Fix handling unicode buffer names.
+# * Add hint to set irc.look.server_buffer to independent and buffers.look.indenting to on.
+# 2.4:
+# * Make script python3 compatible.
+# 2.3:
+# * Fix sorting items without score last (regressed in 2.2).
+# 2.2:
+# * Add configuration option for signals that trigger a sort.
+# * Add command to manually trigger a sort (/autosort sort).
+# * Add replacement patterns to apply before sorting.
+# 2.1:
+# * Fix some minor style issues.
+# 2.0:
+# * Allow for custom sort rules.
+#
+
+
+import json
+import math
+import re
+import sys
+import time
+import weechat
+
+SCRIPT_NAME = 'autosort'
+SCRIPT_AUTHOR = 'Maarten de Vries <maarten@de-vri.es>'
+SCRIPT_VERSION = '3.9'
+SCRIPT_LICENSE = 'GPL3'
+SCRIPT_DESC = 'Flexible automatic (or manual) buffer sorting based on eval expressions.'
+
+
+config = None
+hooks = []
+signal_delay_timer = None
+sort_limit_timer = None
+sort_queued = False
+
+
+# Make sure that unicode, bytes and str are always available in python2 and 3.
+# For python 2, str == bytes
+# For python 3, str == unicode
+if sys.version_info[0] >= 3:
+ unicode = str
+
+def ensure_str(input):
+ '''
+ Make sure the given type if the correct string type for the current python version.
+ That means bytes for python2 and unicode for python3.
+ '''
+ if not isinstance(input, str):
+ if isinstance(input, bytes):
+ return input.encode('utf-8')
+ if isinstance(input, unicode):
+ return input.decode('utf-8')
+ return input
+
+
+if hasattr(time, 'perf_counter'):
+ perf_counter = time.perf_counter
+else:
+ perf_counter = time.clock
+
+def casefold(string):
+ if hasattr(string, 'casefold'): return string.casefold()
+ # Fall back to lowercasing for python2.
+ return string.lower()
+
+def list_swap(values, a, b):
+ values[a], values[b] = values[b], values[a]
+
+def list_move(values, old_index, new_index):
+ values.insert(new_index, values.pop(old_index))
+
+def list_find(collection, value):
+ for i, elem in enumerate(collection):
+ if elem == value: return i
+ return None
+
+class HumanReadableError(Exception):
+ pass
+
+def parse_int(arg, arg_name = 'argument'):
+ ''' Parse an integer and provide a more human readable error. '''
+ arg = arg.strip()
+ try:
+ return int(arg)
+ except ValueError:
+ raise HumanReadableError('Invalid {0}: expected integer, got "{1}".'.format(arg_name, arg))
+
+def decode_rules(blob):
+ parsed = json.loads(blob)
+ if not isinstance(parsed, list):
+ log('Malformed rules, expected a JSON encoded list of strings, but got a {0}. No rules have been loaded. Please fix the setting manually.'.format(type(parsed)))
+ return []
+
+ for i, entry in enumerate(parsed):
+ if not isinstance(entry, (str, unicode)):
+ log('Rule #{0} is not a string but a {1}. No rules have been loaded. Please fix the setting manually.'.format(i, type(entry)))
+ return []
+
+ return parsed
+
+def decode_helpers(blob):
+ parsed = json.loads(blob)
+ if not isinstance(parsed, dict):
+ log('Malformed helpers, expected a JSON encoded dictionary but got a {0}. No helpers have been loaded. Please fix the setting manually.'.format(type(parsed)))
+ return {}
+
+ for key, value in parsed.items():
+ if not isinstance(value, (str, unicode)):
+ log('Helper "{0}" is not a string but a {1}. No helpers have been loaded. Please fix setting manually.'.format(key, type(value)))
+ return {}
+ return parsed
+
+class Config:
+ ''' The autosort configuration. '''
+
+ default_rules = json.dumps([
+ '${core_first}',
+ '${info:autosort_order,${info:autosort_escape,${script_or_plugin}},core,*,irc,bitlbee,matrix,slack}',
+ '${script_or_plugin}',
+ '${irc_raw_first}',
+ '${server}',
+ '${info:autosort_order,${type},server,*,channel,private}',
+ '${hashless_name}',
+ '${buffer.full_name}',
+ ])
+
+ default_helpers = json.dumps({
+ 'core_first': '${if:${buffer.full_name}!=core.weechat}',
+ 'irc_raw_first': '${if:${buffer.full_name}!=irc.irc_raw}',
+ 'irc_raw_last': '${if:${buffer.full_name}==irc.irc_raw}',
+ 'hashless_name': '${info:autosort_replace,#,,${info:autosort_escape,${buffer.name}}}',
+ 'script_or_plugin': '${if:${script_name}?${script_name}:${plugin}}',
+ })
+
+ default_signal_delay = 5
+ default_sort_limit = 100
+
+ default_signals = 'buffer_opened buffer_merged buffer_unmerged buffer_renamed'
+
+ def __init__(self, filename):
+ ''' Initialize the configuration. '''
+
+ self.filename = filename
+ self.config_file = weechat.config_new(self.filename, '', '')
+ self.sorting_section = None
+ self.v3_section = None
+
+ self.case_sensitive = False
+ self.rules = []
+ self.helpers = {}
+ self.signals = []
+ self.signal_delay = Config.default_signal_delay,
+ self.sort_limit = Config.default_sort_limit,
+ self.sort_on_config = True
+ self.debug_log = False
+
+ self.__case_sensitive = None
+ self.__rules = None
+ self.__helpers = None
+ self.__signals = None
+ self.__signal_delay = None
+ self.__sort_limit = None
+ self.__sort_on_config = None
+ self.__debug_log = None
+
+ if not self.config_file:
+ log('Failed to initialize configuration file "{0}".'.format(self.filename))
+ return
+
+ self.sorting_section = weechat.config_new_section(self.config_file, 'sorting', False, False, '', '', '', '', '', '', '', '', '', '')
+ self.v3_section = weechat.config_new_section(self.config_file, 'v3', False, False, '', '', '', '', '', '', '', '', '', '')
+
+ if not self.sorting_section:
+ log('Failed to initialize section "sorting" of configuration file.')
+ weechat.config_free(self.config_file)
+ return
+
+ self.__case_sensitive = weechat.config_new_option(
+ self.config_file, self.sorting_section,
+ 'case_sensitive', 'boolean',
+ 'If this option is on, sorting is case sensitive.',
+ '', 0, 0, 'off', 'off', 0,
+ '', '', '', '', '', ''
+ )
+
+ weechat.config_new_option(
+ self.config_file, self.sorting_section,
+ 'rules', 'string',
+ 'Sort rules used by autosort v2.x and below. Not used by autosort anymore.',
+ '', 0, 0, '', '', 0,
+ '', '', '', '', '', ''
+ )
+
+ weechat.config_new_option(
+ self.config_file, self.sorting_section,
+ 'replacements', 'string',
+ 'Replacement patterns used by autosort v2.x and below. Not used by autosort anymore.',
+ '', 0, 0, '', '', 0,
+ '', '', '', '', '', ''
+ )
+
+ self.__rules = weechat.config_new_option(
+ self.config_file, self.v3_section,
+ 'rules', 'string',
+ 'An ordered list of sorting rules encoded as JSON. See /help autosort for commands to manipulate these rules.',
+ '', 0, 0, Config.default_rules, Config.default_rules, 0,
+ '', '', '', '', '', ''
+ )
+
+ self.__helpers = weechat.config_new_option(
+ self.config_file, self.v3_section,
+ 'helpers', 'string',
+ 'A dictionary helper variables to use in the sorting rules, encoded as JSON. See /help autosort for commands to manipulate these helpers.',
+ '', 0, 0, Config.default_helpers, Config.default_helpers, 0,
+ '', '', '', '', '', ''
+ )
+
+ self.__signals = weechat.config_new_option(
+ self.config_file, self.sorting_section,
+ 'signals', 'string',
+ 'A space separated list of signals that will cause autosort to resort your buffer list.',
+ '', 0, 0, Config.default_signals, Config.default_signals, 0,
+ '', '', '', '', '', ''
+ )
+
+ self.__signal_delay = weechat.config_new_option(
+ self.config_file, self.sorting_section,
+ 'signal_delay', 'integer',
+ 'Delay in milliseconds to wait after a signal before sorting the buffer list. This prevents triggering many times if multiple signals arrive in a short time. It can also be needed to wait for buffer localvars to be available.',
+ '', 0, 1000, str(Config.default_signal_delay), str(Config.default_signal_delay), 0,
+ '', '', '', '', '', ''
+ )
+
+ self.__sort_limit = weechat.config_new_option(
+ self.config_file, self.sorting_section,
+ 'sort_limit', 'integer',
+ 'Minimum delay in milliseconds to wait after sorting before signals can trigger a sort again. This is effectively a rate limit on sorting. Keeping signal_delay low while setting this higher can reduce excessive sorting without a long initial delay.',
+ '', 0, 1000, str(Config.default_sort_limit), str(Config.default_sort_limit), 0,
+ '', '', '', '', '', ''
+ )
+
+ self.__sort_on_config = weechat.config_new_option(
+ self.config_file, self.sorting_section,
+ 'sort_on_config_change', 'boolean',
+ 'Decides if the buffer list should be sorted when autosort configuration changes.',
+ '', 0, 0, 'on', 'on', 0,
+ '', '', '', '', '', ''
+ )
+
+ self.__debug_log = weechat.config_new_option(
+ self.config_file, self.sorting_section,
+ 'debug_log', 'boolean',
+ 'If enabled, print more debug messages. Not recommended for normal usage.',
+ '', 0, 0, 'off', 'off', 0,
+ '', '', '', '', '', ''
+ )
+
+ if weechat.config_read(self.config_file) != weechat.WEECHAT_RC_OK:
+ log('Failed to load configuration file.')
+
+ if weechat.config_write(self.config_file) != weechat.WEECHAT_RC_OK:
+ log('Failed to write configuration file.')
+
+ self.reload()
+
+ def reload(self):
+ ''' Load configuration variables. '''
+
+ self.case_sensitive = weechat.config_boolean(self.__case_sensitive)
+
+ rules_blob = weechat.config_string(self.__rules)
+ helpers_blob = weechat.config_string(self.__helpers)
+ signals_blob = weechat.config_string(self.__signals)
+
+ self.rules = decode_rules(rules_blob)
+ self.helpers = decode_helpers(helpers_blob)
+ self.signals = signals_blob.split()
+ self.signal_delay = weechat.config_integer(self.__signal_delay)
+ self.sort_limit = weechat.config_integer(self.__sort_limit)
+ self.sort_on_config = weechat.config_boolean(self.__sort_on_config)
+ self.debug_log = weechat.config_boolean(self.__debug_log)
+
+ def save_rules(self, run_callback = True):
+ ''' Save the current rules to the configuration. '''
+ weechat.config_option_set(self.__rules, json.dumps(self.rules), run_callback)
+
+ def save_helpers(self, run_callback = True):
+ ''' Save the current helpers to the configuration. '''
+ weechat.config_option_set(self.__helpers, json.dumps(self.helpers), run_callback)
+
+
+def pad(sequence, length, padding = None):
+ ''' Pad a list until is has a certain length. '''
+ return sequence + [padding] * max(0, (length - len(sequence)))
+
+def log(message, buffer = 'NULL'):
+ weechat.prnt(buffer, 'autosort: {0}'.format(message))
+
+def debug(message, buffer = 'NULL'):
+ if config.debug_log:
+ weechat.prnt(buffer, 'autosort: debug: {0}'.format(message))
+
+def get_buffers():
+ ''' Get a list of all the buffers in weechat. '''
+ hdata = weechat.hdata_get('buffer')
+ buffer = weechat.hdata_get_list(hdata, "gui_buffers");
+
+ result = []
+ while buffer:
+ number = weechat.hdata_integer(hdata, buffer, 'number')
+ result.append((number, buffer))
+ buffer = weechat.hdata_pointer(hdata, buffer, 'next_buffer')
+ return hdata, result
+
+class MergedBuffers(list):
+ """ A list of merged buffers, possibly of size 1. """
+ def __init__(self, number):
+ super(MergedBuffers, self).__init__()
+ self.number = number
+
+def merge_buffer_list(buffers):
+ '''
+ Group merged buffers together.
+ The output is a list of MergedBuffers.
+ '''
+ if not buffers: return []
+ result = {}
+ for number, buffer in buffers:
+ if number not in result: result[number] = MergedBuffers(number)
+ result[number].append(buffer)
+ return result.values()
+
+def sort_buffers(hdata, buffers, rules, helpers, case_sensitive):
+ for merged in buffers:
+ for buffer in merged:
+ name = weechat.hdata_string(hdata, buffer, 'name')
+
+ return sorted(buffers, key=merged_sort_key(rules, helpers, case_sensitive))
+
+def buffer_sort_key(rules, helpers, case_sensitive):
+ ''' Create a sort key function for a list of lists of merged buffers. '''
+ def key(buffer):
+ extra_vars = {}
+ for helper_name, helper in sorted(helpers.items()):
+ expanded = weechat.string_eval_expression(helper, {"buffer": buffer}, {}, {})
+ extra_vars[helper_name] = expanded if case_sensitive else casefold(expanded)
+ result = []
+ for rule in rules:
+ expanded = weechat.string_eval_expression(rule, {"buffer": buffer}, extra_vars, {})
+ result.append(expanded if case_sensitive else casefold(expanded))
+ return result
+
+ return key
+
+def merged_sort_key(rules, helpers, case_sensitive):
+ buffer_key = buffer_sort_key(rules, helpers, case_sensitive)
+ def key(merged):
+ best = None
+ for buffer in merged:
+ this = buffer_key(buffer)
+ if best is None or this < best: best = this
+ return best
+ return key
+
+def apply_buffer_order(buffers):
+ ''' Sort the buffers in weechat according to the given order. '''
+ for i, buffer in enumerate(buffers):
+ weechat.buffer_set(buffer[0], "number", str(i + 1))
+
+def split_args(args, expected, optional = 0):
+ ''' Split an argument string in the desired number of arguments. '''
+ split = args.split(' ', expected - 1)
+ if (len(split) < expected):
+ raise HumanReadableError('Expected at least {0} arguments, got {1}.'.format(expected, len(split)))
+ return split[:-1] + pad(split[-1].split(' ', optional), optional + 1, '')
+
+def do_sort(verbose = False):
+ start = perf_counter()
+
+ hdata, buffers = get_buffers()
+ buffers = merge_buffer_list(buffers)
+ buffers = sort_buffers(hdata, buffers, config.rules, config.helpers, config.case_sensitive)
+ apply_buffer_order(buffers)
+
+ elapsed = perf_counter() - start
+ if verbose:
+ log("Finished sorting buffers in {0:.4f} seconds.".format(elapsed))
+ else:
+ debug("Finished sorting buffers in {0:.4f} seconds.".format(elapsed))
+
+def command_sort(buffer, command, args):
+ ''' Sort the buffers and print a confirmation. '''
+ do_sort(True)
+ return weechat.WEECHAT_RC_OK
+
+def command_debug(buffer, command, args):
+ hdata, buffers = get_buffers()
+ buffers = merge_buffer_list(buffers)
+
+ # Show evaluation results.
+ log('Individual evaluation results:')
+ start = perf_counter()
+ key = buffer_sort_key(config.rules, config.helpers, config.case_sensitive)
+ results = []
+ for merged in buffers:
+ for buffer in merged:
+ fullname = weechat.hdata_string(hdata, buffer, 'full_name')
+ results.append((fullname, key(buffer)))
+ elapsed = perf_counter() - start
+
+ for fullname, result in results:
+ fullname = ensure_str(fullname)
+ result = [ensure_str(x) for x in result]
+ log('{0}: {1}'.format(fullname, result))
+ log('Computing evaluation results took {0:.4f} seconds.'.format(elapsed))
+
+ return weechat.WEECHAT_RC_OK
+
+def command_rule_list(buffer, command, args):
+ ''' Show the list of sorting rules. '''
+ output = 'Sorting rules:\n'
+ for i, rule in enumerate(config.rules):
+ output += ' {0}: {1}\n'.format(i, rule)
+ if not len(config.rules):
+ output += ' No sorting rules configured.\n'
+ log(output )
+
+ return weechat.WEECHAT_RC_OK
+
+
+def command_rule_add(buffer, command, args):
+ ''' Add a rule to the rule list. '''
+ config.rules.append(args)
+ config.save_rules()
+ command_rule_list(buffer, command, '')
+
+ return weechat.WEECHAT_RC_OK
+
+
+def command_rule_insert(buffer, command, args):
+ ''' Insert a rule at the desired position in the rule list. '''
+ index, rule = split_args(args, 2)
+ index = parse_int(index, 'index')
+
+ config.rules.insert(index, rule)
+ config.save_rules()
+ command_rule_list(buffer, command, '')
+ return weechat.WEECHAT_RC_OK
+
+
+def command_rule_update(buffer, command, args):
+ ''' Update a rule in the rule list. '''
+ index, rule = split_args(args, 2)
+ index = parse_int(index, 'index')
+
+ config.rules[index] = rule
+ config.save_rules()
+ command_rule_list(buffer, command, '')
+ return weechat.WEECHAT_RC_OK
+
+
+def command_rule_delete(buffer, command, args):
+ ''' Delete a rule from the rule list. '''
+ index = args.strip()
+ index = parse_int(index, 'index')
+
+ config.rules.pop(index)
+ config.save_rules()
+ command_rule_list(buffer, command, '')
+ return weechat.WEECHAT_RC_OK
+
+
+def command_rule_move(buffer, command, args):
+ ''' Move a rule to a new position. '''
+ index_a, index_b = split_args(args, 2)
+ index_a = parse_int(index_a, 'index')
+ index_b = parse_int(index_b, 'index')
+
+ list_move(config.rules, index_a, index_b)
+ config.save_rules()
+ command_rule_list(buffer, command, '')
+ return weechat.WEECHAT_RC_OK
+
+
+def command_rule_swap(buffer, command, args):
+ ''' Swap two rules. '''
+ index_a, index_b = split_args(args, 2)
+ index_a = parse_int(index_a, 'index')
+ index_b = parse_int(index_b, 'index')
+
+ list_swap(config.rules, index_a, index_b)
+ config.save_rules()
+ command_rule_list(buffer, command, '')
+ return weechat.WEECHAT_RC_OK
+
+
+def command_helper_list(buffer, command, args):
+ ''' Show the list of helpers. '''
+ output = 'Helper variables:\n'
+
+ width = max(map(lambda x: len(x) if len(x) <= 30 else 0, config.helpers.keys()))
+
+ for name, expression in sorted(config.helpers.items()):
+ output += ' {0:>{width}}: {1}\n'.format(name, expression, width=width)
+ if not len(config.helpers):
+ output += ' No helper variables configured.'
+ log(output)
+
+ return weechat.WEECHAT_RC_OK
+
+
+def command_helper_set(buffer, command, args):
+ ''' Add/update a helper to the helper list. '''
+ name, expression = split_args(args, 2)
+
+ config.helpers[name] = expression
+ config.save_helpers()
+ command_helper_list(buffer, command, '')
+
+ return weechat.WEECHAT_RC_OK
+
+def command_helper_delete(buffer, command, args):
+ ''' Delete a helper from the helper list. '''
+ name = args.strip()
+
+ del config.helpers[name]
+ config.save_helpers()
+ command_helper_list(buffer, command, '')
+ return weechat.WEECHAT_RC_OK
+
+
+def command_helper_rename(buffer, command, args):
+ ''' Rename a helper to a new position. '''
+ old_name, new_name = split_args(args, 2)
+
+ try:
+ config.helpers[new_name] = config.helpers[old_name]
+ del config.helpers[old_name]
+ except KeyError:
+ raise HumanReadableError('No such helper: {0}'.format(old_name))
+ config.save_helpers()
+ command_helper_list(buffer, command, '')
+ return weechat.WEECHAT_RC_OK
+
+
+def command_helper_swap(buffer, command, args):
+ ''' Swap two helpers. '''
+ a, b = split_args(args, 2)
+ try:
+ config.helpers[b], config.helpers[a] = config.helpers[a], config.helpers[b]
+ except KeyError as e:
+ raise HumanReadableError('No such helper: {0}'.format(e.args[0]))
+
+ config.helpers.swap(index_a, index_b)
+ config.save_helpers()
+ command_helper_list(buffer, command, '')
+ return weechat.WEECHAT_RC_OK
+
+def call_command(buffer, command, args, subcommands):
+ ''' Call a subcommand from a dictionary. '''
+ subcommand, tail = pad(args.split(' ', 1), 2, '')
+ subcommand = subcommand.strip()
+ if (subcommand == ''):
+ child = subcommands.get(' ')
+ else:
+ command = command + [subcommand]
+ child = subcommands.get(subcommand)
+
+ if isinstance(child, dict):
+ return call_command(buffer, command, tail, child)
+ elif callable(child):
+ return child(buffer, command, tail)
+
+ log('{0}: command not found'.format(' '.join(command)))
+ return weechat.WEECHAT_RC_ERROR
+
+def on_signal(data, signal, signal_data):
+ global signal_delay_timer
+ global sort_queued
+
+ # If the sort limit timeout is started, we're in the hold-off time after sorting, just queue a sort.
+ if sort_limit_timer is not None:
+ if sort_queued:
+ debug('Signal {0} ignored, sort limit timeout is active and sort is already queued.'.format(signal))
+ else:
+ debug('Signal {0} received but sort limit timeout is active, sort is now queued.'.format(signal))
+ sort_queued = True
+ return weechat.WEECHAT_RC_OK
+
+ # If the signal delay timeout is started, a signal was recently received, so ignore this signal.
+ if signal_delay_timer is not None:
+ debug('Signal {0} ignored, signal delay timeout active.'.format(signal))
+ return weechat.WEECHAT_RC_OK
+
+ # Otherwise, start the signal delay timeout.
+ debug('Signal {0} received, starting signal delay timeout of {1} ms.'.format(signal, config.signal_delay))
+ weechat.hook_timer(config.signal_delay, 0, 1, "on_signal_delay_timeout", "")
+ return weechat.WEECHAT_RC_OK
+
+def on_signal_delay_timeout(pointer, remaining_calls):
+ """ Called when the signal_delay_timer triggers. """
+ global signal_delay_timer
+ global sort_limit_timer
+ global sort_queued
+
+ signal_delay_timer = None
+
+ # If the sort limit timeout was started, we're still in the no-sort period, so just queue a sort.
+ if sort_limit_timer is not None:
+ debug('Signal delay timeout expired, but sort limit timeout is active, sort is now queued.')
+ sort_queued = True
+ return weechat.WEECHAT_RC_OK
+
+ # Time to sort!
+ debug('Signal delay timeout expired, starting sort.')
+ do_sort()
+
+ # Start the sort limit timeout if not disabled.
+ if config.sort_limit > 0:
+ debug('Starting sort limit timeout of {0} ms.'.format(config.sort_limit))
+ sort_limit_timer = weechat.hook_timer(config.sort_limit, 0, 1, "on_sort_limit_timeout", "")
+
+ return weechat.WEECHAT_RC_OK
+
+def on_sort_limit_timeout(pointer, remainin_calls):
+ """ Called when de sort_limit_timer triggers. """
+ global sort_limit_timer
+ global sort_queued
+
+ # If no signal was received during the timeout, we're done.
+ if not sort_queued:
+ debug('Sort limit timeout expired without receiving a signal.')
+ sort_limit_timer = None
+ return weechat.WEECHAT_RC_OK
+
+ # Otherwise it's time to sort.
+ debug('Signal received during sort limit timeout, starting queued sort.')
+ do_sort()
+ sort_queued = False
+
+ # Start the sort limit timeout again if not disabled.
+ if config.sort_limit > 0:
+ debug('Starting sort limit timeout of {0} ms.'.format(config.sort_limit))
+ sort_limit_timer = weechat.hook_timer(config.sort_limit, 0, 1, "on_sort_limit_timeout", "")
+
+ return weechat.WEECHAT_RC_OK
+
+
+def apply_config():
+ # Unhook all signals and hook the new ones.
+ for hook in hooks:
+ weechat.unhook(hook)
+ for signal in config.signals:
+ hooks.append(weechat.hook_signal(signal, 'on_signal', ''))
+
+ if config.sort_on_config:
+ debug('Sorting because configuration changed.')
+ do_sort()
+
+def on_config_changed(*args, **kwargs):
+ ''' Called whenever the configuration changes. '''
+ config.reload()
+ apply_config()
+
+ return weechat.WEECHAT_RC_OK
+
+def parse_arg(args):
+ if not args: return '', None
+
+ result = ''
+ escaped = False
+ for i, c in enumerate(args):
+ if not escaped:
+ if c == '\\':
+ escaped = True
+ continue
+ elif c == ',':
+ return result, args[i+1:]
+ result += c
+ escaped = False
+ return result, None
+
+def parse_args(args, max = None):
+ result = []
+ i = 0
+ while max is None or i < max:
+ i += 1
+ arg, args = parse_arg(args)
+ if arg is None: break
+ result.append(arg)
+ if args is None: break
+ return result, args
+
+def on_info_escape(pointer, name, arguments):
+ result = ''
+ for c in arguments:
+ if c == '\\':
+ result += '\\\\'
+ elif c == ',':
+ result += '\\,'
+ else:
+ result +=c
+ return result
+
+def on_info_replace(pointer, name, arguments):
+ arguments, rest = parse_args(arguments, 3)
+ if rest or len(arguments) < 3:
+ log('usage: ${{info:{0},old,new,text}}'.format(name))
+ return ''
+ old, new, text = arguments
+
+ return text.replace(old, new)
+
+def on_info_order(pointer, name, arguments):
+ arguments, rest = parse_args(arguments)
+ if len(arguments) < 1:
+ log('usage: ${{info:{0},value,first,second,third,...}}'.format(name))
+ return ''
+
+ value = arguments[0]
+ keys = arguments[1:]
+ if not keys: return '0'
+
+ # Find the value in the keys (or '*' if we can't find it)
+ result = list_find(keys, value)
+ if result is None: result = list_find(keys, '*')
+ if result is None: result = len(keys)
+
+ # Pad result with leading zero to make sure string sorting works.
+ width = int(math.log10(len(keys))) + 1
+ return '{0:0{1}}'.format(result, width)
+
+
+def on_autosort_command(data, buffer, args):
+ ''' Called when the autosort command is invoked. '''
+ try:
+ return call_command(buffer, ['/autosort'], args, {
+ ' ': command_sort,
+ 'sort': command_sort,
+ 'debug': command_debug,
+
+ 'rules': {
+ ' ': command_rule_list,
+ 'list': command_rule_list,
+ 'add': command_rule_add,
+ 'insert': command_rule_insert,
+ 'update': command_rule_update,
+ 'delete': command_rule_delete,
+ 'move': command_rule_move,
+ 'swap': command_rule_swap,
+ },
+ 'helpers': {
+ ' ': command_helper_list,
+ 'list': command_helper_list,
+ 'set': command_helper_set,
+ 'delete': command_helper_delete,
+ 'rename': command_helper_rename,
+ 'swap': command_helper_swap,
+ },
+ })
+ except HumanReadableError as e:
+ log(e)
+ return weechat.WEECHAT_RC_ERROR
+
+def add_completions(completion, words):
+ for word in words:
+ weechat.hook_completion_list_add(completion, word, 0, weechat.WEECHAT_LIST_POS_END)
+
+def autosort_complete_rules(words, completion):
+ if len(words) == 0:
+ add_completions(completion, ['add', 'delete', 'insert', 'list', 'move', 'swap', 'update'])
+ if len(words) == 1 and words[0] in ('delete', 'insert', 'move', 'swap', 'update'):
+ add_completions(completion, map(str, range(len(config.rules))))
+ if len(words) == 2 and words[0] in ('move', 'swap'):
+ add_completions(completion, map(str, range(len(config.rules))))
+ if len(words) == 2 and words[0] in ('update'):
+ try:
+ add_completions(completion, [config.rules[int(words[1])]])
+ except KeyError: pass
+ except ValueError: pass
+ else:
+ add_completions(completion, [''])
+ return weechat.WEECHAT_RC_OK
+
+def autosort_complete_helpers(words, completion):
+ if len(words) == 0:
+ add_completions(completion, ['delete', 'list', 'rename', 'set', 'swap'])
+ elif len(words) == 1 and words[0] in ('delete', 'rename', 'set', 'swap'):
+ add_completions(completion, sorted(config.helpers.keys()))
+ elif len(words) == 2 and words[0] == 'swap':
+ add_completions(completion, sorted(config.helpers.keys()))
+ elif len(words) == 2 and words[0] == 'rename':
+ add_completions(completion, sorted(config.helpers.keys()))
+ elif len(words) == 2 and words[0] == 'set':
+ try:
+ add_completions(completion, [config.helpers[words[1]]])
+ except KeyError: pass
+ return weechat.WEECHAT_RC_OK
+
+def on_autosort_complete(data, name, buffer, completion):
+ cmdline = weechat.buffer_get_string(buffer, "input")
+ cursor = weechat.buffer_get_integer(buffer, "input_pos")
+ prefix = cmdline[:cursor]
+ words = prefix.split()[1:]
+
+ # If the current word isn't finished yet,
+ # ignore it for coming up with completion suggestions.
+ if prefix[-1] != ' ': words = words[:-1]
+
+ if len(words) == 0:
+ add_completions(completion, ['debug', 'helpers', 'rules', 'sort'])
+ elif words[0] == 'rules':
+ return autosort_complete_rules(words[1:], completion)
+ elif words[0] == 'helpers':
+ return autosort_complete_helpers(words[1:], completion)
+ return weechat.WEECHAT_RC_OK
+
+command_description = r'''{*white}# General commands{reset}
+
+{*white}/autosort {brown}sort{reset}
+Manually trigger the buffer sorting.
+
+{*white}/autosort {brown}debug{reset}
+Show the evaluation results of the sort rules for each buffer.
+
+
+{*white}# Sorting rule commands{reset}
+
+{*white}/autosort{brown} rules list{reset}
+Print the list of sort rules.
+
+{*white}/autosort {brown}rules add {cyan}<expression>{reset}
+Add a new rule at the end of the list.
+
+{*white}/autosort {brown}rules insert {cyan}<index> <expression>{reset}
+Insert a new rule at the given index in the list.
+
+{*white}/autosort {brown}rules update {cyan}<index> <expression>{reset}
+Update a rule in the list with a new expression.
+
+{*white}/autosort {brown}rules delete {cyan}<index>
+Delete a rule from the list.
+
+{*white}/autosort {brown}rules move {cyan}<index_from> <index_to>{reset}
+Move a rule from one position in the list to another.
+
+{*white}/autosort {brown}rules swap {cyan}<index_a> <index_b>{reset}
+Swap two rules in the list
+
+
+{*white}# Helper variable commands{reset}
+
+{*white}/autosort {brown}helpers list
+Print the list of helper variables.
+
+{*white}/autosort {brown}helpers set {cyan}<name> <expression>
+Add or update a helper variable with the given name.
+
+{*white}/autosort {brown}helpers delete {cyan}<name>
+Delete a helper variable.
+
+{*white}/autosort {brown}helpers rename {cyan}<old_name> <new_name>
+Rename a helper variable.
+
+{*white}/autosort {brown}helpers swap {cyan}<name_a> <name_b>
+Swap the expressions of two helper variables in the list.
+
+
+{*white}# Info hooks{reset}
+Autosort comes with a number of info hooks to add some extra functionality to regular weechat eval strings.
+Info hooks can be used in eval strings in the form of {cyan}${{info:some_hook,arguments}}{reset}.
+
+Commas and backslashes in arguments to autosort info hooks (except for {cyan}${{info:autosort_escape}}{reset}) must be escaped with a backslash.
+
+{*white}${{info:{brown}autosort_replace{white},{cyan}pattern{white},{cyan}replacement{white},{cyan}source{white}}}{reset}
+Replace all occurrences of {cyan}pattern{reset} with {cyan}replacement{reset} in the string {cyan}source{reset}.
+Can be used to ignore certain strings when sorting by replacing them with an empty string.
+
+For example: {cyan}${{info:autosort_replace,cat,dog,the dog is meowing}}{reset} expands to "the cat is meowing".
+
+{*white}${{info:{brown}autosort_order{white},{cyan}value{white},{cyan}option0{white},{cyan}option1{white},{cyan}option2{white},{cyan}...{white}}}
+Generate a zero-padded number that corresponds to the index of {cyan}value{reset} in the list of options.
+If one of the options is the special value {brown}*{reset}, then any value not explicitly mentioned will be sorted at that position.
+Otherwise, any value that does not match an option is assigned the highest number available.
+Can be used to easily sort buffers based on a manual sequence.
+
+For example: {cyan}${{info:autosort_order,${{server}},freenode,oftc,efnet}}{reset} will sort freenode before oftc, followed by efnet and then any remaining servers.
+Alternatively, {cyan}${{info:autosort_order,${{server}},freenode,oftc,*,efnet}}{reset} will sort any unlisted servers after freenode and oftc, but before efnet.
+
+{*white}${{info:{brown}autosort_escape{white},{cyan}text{white}}}{reset}
+Escape commas and backslashes in {cyan}text{reset} by prepending them with a backslash.
+This is mainly useful to pass arbitrary eval strings as arguments to other autosort info hooks.
+Otherwise, an eval string that expands to something with a comma would be interpreted as multiple arguments.
+
+For example, it can be used to safely pass buffer names to {cyan}${{info:autosort_replace}}{reset} like so:
+{cyan}${{info:autosort_replace,##,#,${{info:autosort_escape,${{buffer.name}}}}}}{reset}.
+
+
+{*white}# Description
+Autosort is a weechat script to automatically keep your buffers sorted. The sort
+order can be customized by defining your own sort rules, but the default should
+be sane enough for most people. It can also group IRC channel/private buffers
+under their server buffer if you like.
+
+Autosort uses a stable sorting algorithm, meaning that you can manually move buffers
+to change their relative order, if they sort equal with your rule set.
+
+{*white}# Sort rules{reset}
+Autosort evaluates a list of eval expressions (see {*default}/help eval{reset}) and sorts the
+buffers based on evaluated result. Earlier rules will be considered first. Only
+if earlier rules produced identical results is the result of the next rule
+considered for sorting purposes.
+
+You can debug your sort rules with the `{*default}/autosort debug{reset}` command, which will
+print the evaluation results of each rule for each buffer.
+
+{*brown}NOTE:{reset} The sort rules for version 3 are not compatible with version 2 or vice
+versa. You will have to manually port your old rules to version 3 if you have any.
+
+{*white}# Helper variables{reset}
+You may define helper variables for the main sort rules to keep your rules
+readable. They can be used in the main sort rules as variables. For example,
+a helper variable named `{cyan}foo{reset}` can be accessed in a main rule with the
+string `{cyan}${{foo}}{reset}`.
+
+{*white}# Automatic or manual sorting{reset}
+By default, autosort will automatically sort your buffer list whenever a buffer
+is opened, merged, unmerged or renamed. This should keep your buffers sorted in
+almost all situations. However, you may wish to change the list of signals that
+cause your buffer list to be sorted. Simply edit the `{cyan}autosort.sorting.signals{reset}`
+option to add or remove any signal you like.
+
+If you remove all signals you can still sort your buffers manually with the
+`{*default}/autosort sort{reset}` command. To prevent all automatic sorting, the option
+`{cyan}autosort.sorting.sort_on_config_change{reset}` should also be disabled.
+
+{*white}# Recommended settings
+For the best visual effect, consider setting the following options:
+ {*white}/set {cyan}irc.look.server_buffer{reset} {brown}independent{reset}
+
+This setting allows server buffers to be sorted independently, which is
+needed to create a hierarchical tree view of the server and channel buffers.
+
+If you are using the {*default}buflist{reset} plugin you can (ab)use Unicode to draw a tree
+structure with the following setting (modify to suit your need):
+ {*white}/set {cyan}buflist.format.indent {brown}"${{color:237}}${{if:${{buffer.next_buffer.local_variables.type}}=~^(channel|private)$?├─:└─}}"{reset}
+'''
+
+command_completion = '%(plugin_autosort) %(plugin_autosort) %(plugin_autosort) %(plugin_autosort) %(plugin_autosort)'
+
+info_replace_description = (
+ 'Replace all occurrences of `pattern` with `replacement` in the string `source`. '
+ 'Can be used to ignore certain strings when sorting by replacing them with an empty string. '
+ 'See /help autosort for examples.'
+)
+info_replace_arguments = 'pattern,replacement,source'
+
+info_order_description = (
+ 'Generate a zero-padded number that corresponds to the index of `value` in the list of options. '
+ 'If one of the options is the special value `*`, then any value not explicitly mentioned will be sorted at that position. '
+ 'Otherwise, any value that does not match an option is assigned the highest number available. '
+ 'Can be used to easily sort buffers based on a manual sequence. '
+ 'See /help autosort for examples.'
+)
+info_order_arguments = 'value,first,second,third,...'
+
+info_escape_description = (
+ 'Escape commas and backslashes in `text` by prepending them with a backslash. '
+ 'This is mainly useful to pass arbitrary eval strings as arguments to other autosort info hooks. '
+ 'Otherwise, an eval string that expands to something with a comma would be interpreted as multiple arguments.'
+ 'See /help autosort for examples.'
+)
+info_escape_arguments = 'text'
+
+
+if weechat.register(SCRIPT_NAME, SCRIPT_AUTHOR, SCRIPT_VERSION, SCRIPT_LICENSE, SCRIPT_DESC, "", ""):
+ config = Config('autosort')
+
+ colors = {
+ 'default': weechat.color('default'),
+ 'reset': weechat.color('reset'),
+ 'black': weechat.color('black'),
+ 'red': weechat.color('red'),
+ 'green': weechat.color('green'),
+ 'brown': weechat.color('brown'),
+ 'yellow': weechat.color('yellow'),
+ 'blue': weechat.color('blue'),
+ 'magenta': weechat.color('magenta'),
+ 'cyan': weechat.color('cyan'),
+ 'white': weechat.color('white'),
+ '*default': weechat.color('*default'),
+ '*black': weechat.color('*black'),
+ '*red': weechat.color('*red'),
+ '*green': weechat.color('*green'),
+ '*brown': weechat.color('*brown'),
+ '*yellow': weechat.color('*yellow'),
+ '*blue': weechat.color('*blue'),
+ '*magenta': weechat.color('*magenta'),
+ '*cyan': weechat.color('*cyan'),
+ '*white': weechat.color('*white'),
+ }
+
+ weechat.hook_config('autosort.*', 'on_config_changed', '')
+ weechat.hook_completion('plugin_autosort', '', 'on_autosort_complete', '')
+ weechat.hook_command('autosort', command_description.format(**colors), '', '', command_completion, 'on_autosort_command', '')
+ weechat.hook_info('autosort_escape', info_escape_description, info_escape_arguments, 'on_info_escape', '')
+ weechat.hook_info('autosort_replace', info_replace_description, info_replace_arguments, 'on_info_replace', '')
+ weechat.hook_info('autosort_order', info_order_description, info_order_arguments, 'on_info_order', '')
+
+ apply_config()
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/weechat/python/colon_complete.py Fri Jul 07 16:11:02 2023 -0400
@@ -0,0 +1,69 @@
+SCRIPT_NAME='coloncomplete'
+SCRIPT_AUTHOR='Steve Losh <steve@stevelosh.com>'
+SCRIPT_VERSION='1.0'
+SCRIPT_LICENSE='MIT/X11'
+SCRIPT_DESC='Add a colon after nick completion when all the previous words in the input are also nicks.'
+
+EXTRA_NICKS = ['all', 'backend', 'clojerks', 'ops', 'support']
+
+import_ok=True
+
+try:
+ import weechat
+except ImportError:
+ print 'This script must be run under WeeChat'
+ print 'You can obtain a copy of WeeChat, for free, at http://www.weechat.org'
+ import_ok=False
+
+weechat_version=0
+
+def get_nicks(buffer, prefix=''):
+ channel = weechat.buffer_get_string(buffer, 'localvar_channel')
+ server = weechat.buffer_get_string(buffer, 'localvar_server')
+ prefix = prefix.lower()
+
+ matches = []
+
+ infolist = weechat.infolist_get('irc_nick', '', '%s,%s' % (server, channel))
+ while weechat.infolist_next(infolist):
+ nick = weechat.infolist_string(infolist, 'name')
+ if nick != 'localhost' and nick.lower().startswith(prefix):
+ matches.append(nick)
+ weechat.infolist_free(infolist)
+
+ for nick in EXTRA_NICKS:
+ if nick.lower().startswith(prefix):
+ matches.append(nick)
+
+ return matches
+
+def completer(data, buffer, command):
+ cb = weechat.current_buffer()
+ if command == "/input complete_next":
+ line = weechat.buffer_get_string(cb, "input")
+ words = line.split(' ')
+ prefix = words[-1]
+ if prefix and words and all([s.endswith(':') for s in words[:-1] if s]):
+ nicks = get_nicks(cb, prefix)
+ if len(nicks) == 1:
+ for _ in range(len(prefix)):
+ weechat.command(buffer, "/input delete_previous_char")
+ weechat.command(buffer, "/input insert " + nicks[-1] + ":\\x20")
+ elif len(nicks) > 1:
+ l = min(len(nick) for nick in nicks)
+ for i in range(len(prefix), l):
+ if len(set(nick[i] for nick in nicks)) > 1:
+ break
+ else:
+ weechat.command(buffer, "/input insert " + nicks[0][i])
+
+ for nick in nicks:
+ weechat.prnt(cb, "==> " + nick)
+ return weechat.WEECHAT_RC_OK_EAT
+
+ return weechat.WEECHAT_RC_OK
+
+if __name__ == "__main__" and import_ok:
+ if weechat.register(SCRIPT_NAME, SCRIPT_AUTHOR, SCRIPT_VERSION, SCRIPT_LICENSE, SCRIPT_DESC, "", ""):
+ weechat_version = weechat.info_get("version_number", "") or 0
+ weechat.hook_command_run('/input complete*', 'completer', '')
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/weechat/python/sanitize_jira.py Fri Jul 07 16:11:02 2023 -0400
@@ -0,0 +1,33 @@
+import re, weechat, subprocess
+
+SCRIPT_NAME = 'sanitize_jira'
+SCRIPT_AUTHOR = 'Steve Losh <steve@stevelosh.com>'
+SCRIPT_VERSION = '0.0.1'
+SCRIPT_LICENSE = 'MIT'
+SCRIPT_DESC = 'clean up the garbage jirabot sends to channels into something readable'
+
+weechat.register(SCRIPT_NAME, SCRIPT_AUTHOR, SCRIPT_VERSION, SCRIPT_LICENSE, SCRIPT_DESC, '', '')
+
+weechat.hook_line('*', '', 'nick_Jira_Cloud', 'sanitize_jira', '')
+
+first_line_re = re.compile(
+ r'(?P<link>https://[^/]+/browse/[^?]+)[?]atlOrigin=[^ ]+ [(](?P<title>.+)[)]'
+)
+
+detail_line_re = re.compile(
+ r'''Status: \x1a\x01[*](?P<status>[^*]+)[*]\x1b\x01.*Type: \x1a\x01[*](?P<type>[^*]+)[*]\x1b\x01.*Assignee: \x1a\x01[*](?P<assignee>[^*]+)[*]\x1b\x01.*Priority: \x1a\x01[*](?P<priority>[^*]+)[*]\x1b\x01'''
+)
+
+def sanitize_jira(data, line):
+ if 'sign up for an Atlassian account to view this link' in line['message']:
+ return {'message': ' '}
+
+ m = first_line_re.search(line['message'])
+ if m:
+ return {'message': '%s | %s' % (m.group('title'), m.group('link'))}
+
+ m = detail_line_re.search(line['message'])
+ if m:
+ return {'message': '%s / %s / %s' % (m.group('type'), m.group('status'), m.group('assignee'))}
+
+ return {}
--- a/weechat/relay.conf Fri Apr 14 15:01:35 2023 -0400
+++ b/weechat/relay.conf Fri Jul 07 16:11:02 2023 -0400
@@ -4,9 +4,9 @@
# WARNING: It is NOT recommended to edit this file by hand,
# especially if WeeChat is running.
#
-# Use /set or similar command to change settings in WeeChat.
+# Use commands like /set or /fset to change settings in WeeChat.
#
-# For more info, see: https://weechat.org/doc/quickstart
+# For more info, see: https://weechat.org/doc/quickstart/
#
[look]
@@ -27,14 +27,20 @@
[network]
allow_empty_password = off
allowed_ips = ""
+auth_timeout = 60
bind_address = ""
clients_purge_delay = 0
-compression_level = 6
+compression = 20
ipv6 = on
max_clients = 5
+nonce_size = 16
password = ""
+password_hash_algo = "*"
+password_hash_iterations = 100000
ssl_cert_key = "%h/ssl/relay.pem"
ssl_priorities = "NORMAL:-VERS-SSL3.0"
+totp_secret = ""
+totp_window = 0
websocket_allowed_origins = ""
[irc]
@@ -45,4 +51,9 @@
backlog_tags = "irc_privmsg"
backlog_time_format = "[%H:%M] "
+[weechat]
+commands = ""
+
[port]
+
+[path]
--- a/weechat/ruby.conf Fri Apr 14 15:01:35 2023 -0400
+++ b/weechat/ruby.conf Fri Jul 07 16:11:02 2023 -0400
@@ -4,7 +4,7 @@
# WARNING: It is NOT recommended to edit this file by hand,
# especially if WeeChat is running.
#
-# Use /set or similar command to change settings in WeeChat.
+# Use commands like /set or /fset to change settings in WeeChat.
#
# For more info, see: https://weechat.org/doc/quickstart
#
--- a/weechat/script.conf Fri Apr 14 15:01:35 2023 -0400
+++ b/weechat/script.conf Fri Jul 07 16:11:02 2023 -0400
@@ -4,9 +4,9 @@
# WARNING: It is NOT recommended to edit this file by hand,
# especially if WeeChat is running.
#
-# Use /set or similar command to change settings in WeeChat.
+# Use commands like /set or /fset to change settings in WeeChat.
#
-# For more info, see: https://weechat.org/doc/quickstart
+# For more info, see: https://weechat.org/doc/quickstart/
#
[look]
@@ -50,6 +50,7 @@
[scripts]
autoload = on
cache_expire = 60
+download_enabled = on
download_timeout = 30
hold = ""
path = "%h/script"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/weechat/spell.conf Fri Jul 07 16:11:02 2023 -0400
@@ -0,0 +1,33 @@
+#
+# weechat -- spell.conf
+#
+# WARNING: It is NOT recommended to edit this file by hand,
+# especially if WeeChat is running.
+#
+# Use commands like /set or /fset to change settings in WeeChat.
+#
+# For more info, see: https://weechat.org/doc/quickstart
+#
+
+[color]
+misspelled = lightred
+suggestion = default
+suggestion_delimiter_dict = cyan
+suggestion_delimiter_word = cyan
+
+[check]
+commands = "away,command,cycle,kick,kickban,me,msg,notice,part,query,quit,topic"
+default_dict = ""
+during_search = off
+enabled = off
+real_time = off
+suggestions = -1
+word_min_length = 2
+
+[dict]
+
+[look]
+suggestion_delimiter_dict = " / "
+suggestion_delimiter_word = ","
+
+[option]
--- a/weechat/trigger.conf Fri Apr 14 15:01:35 2023 -0400
+++ b/weechat/trigger.conf Fri Jul 07 16:11:02 2023 -0400
@@ -4,9 +4,9 @@
# WARNING: It is NOT recommended to edit this file by hand,
# especially if WeeChat is running.
#
-# Use /set or similar command to change settings in WeeChat.
+# Use commands like /set or /fset to change settings in WeeChat.
#
-# For more info, see: https://weechat.org/doc/quickstart
+# For more info, see: https://weechat.org/doc/quickstart/
#
[look]
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/weechat/typing.conf Fri Jul 07 16:11:02 2023 -0400
@@ -0,0 +1,19 @@
+#
+# weechat -- typing.conf
+#
+# WARNING: It is NOT recommended to edit this file by hand,
+# especially if WeeChat is running.
+#
+# Use commands like /set or /fset to change settings in WeeChat.
+#
+# For more info, see: https://weechat.org/doc/quickstart/
+#
+
+[look]
+delay_purge_paused = 30
+delay_purge_typing = 6
+delay_set_paused = 10
+enabled_nicks = off
+enabled_self = off
+input_min_chars = 4
+item_max_length = 0
--- a/weechat/urlgrab.conf Fri Apr 14 15:01:35 2023 -0400
+++ b/weechat/urlgrab.conf Fri Jul 07 16:11:02 2023 -0400
@@ -4,9 +4,9 @@
# WARNING: It is NOT recommended to edit this file by hand,
# especially if WeeChat is running.
#
-# Use /set or similar command to change settings in WeeChat.
+# Use commands like /set or /fset to change settings in WeeChat.
#
-# For more info, see: https://weechat.org/doc/quickstart
+# For more info, see: https://weechat.org/doc/quickstart/
#
[color]
--- a/weechat/weechat.conf Fri Apr 14 15:01:35 2023 -0400
+++ b/weechat/weechat.conf Fri Jul 07 16:11:02 2023 -0400
@@ -1,10 +1,10 @@
#
-# weechat -- weechat.conf
+# WeeChat -- weechat.conf
#
# WARNING: It is NOT recommended to edit this file by hand,
# especially if WeeChat is running.
#
-# Use /set or similar command to change settings in WeeChat.
+# Use commands like /set or /fset to change settings in WeeChat.
#
# For more info, see: https://weechat.org/doc/quickstart
#
@@ -35,6 +35,7 @@
buffer_search_regex = off
buffer_search_where = prefix_message
buffer_time_format = "%H:%M"
+buffer_time_same = ""
color_basic_force_bold = off
color_inactive_buffer = off
color_inactive_message = on
@@ -71,6 +72,7 @@
hotlist_sort = group_time_asc
hotlist_suffix = ""
hotlist_unique_numbers = on
+hotlist_update_on_buffer_switch = on
input_cursor_scroll = 20
input_share = none
input_share_overwrite = off
@@ -89,6 +91,7 @@
mouse_timer_delay = 100
nick_color_force = ""
nick_color_hash = djb2
+nick_color_hash_salt = ""
nick_color_stop_chars = "_|["
nick_prefix = ""
nick_suffix = ""
@@ -111,6 +114,7 @@
prefix_network = "--"
prefix_quit = "✘"
prefix_same_nick = ""
+prefix_same_nick_middle = ""
prefix_suffix = "|"
quote_nick_prefix = "<"
quote_nick_suffix = ">"
@@ -118,6 +122,7 @@
read_marker = line
read_marker_always_show = on
read_marker_string = "─"
+read_marker_update_on_buffer_switch = on
save_config_on_exit = off
save_config_with_fsync = off
save_layout_on_exit = all
@@ -231,7 +236,8 @@
[network]
connection_timeout = 60
-gnutls_ca_file = "/etc/ssl/certs/ca-certificates.crt"
+gnutls_ca_system = on
+gnutls_ca_user = ""
gnutls_handshake_timeout = 30
proxy_curl = ""
@@ -242,8 +248,16 @@
path = "%h/plugins"
save_config_on_unload = on
+[signal]
+sighup = "${if:${info:weechat_headless}?/reload:/quit -yes}"
+sigquit = "/quit -yes"
+sigterm = "/quit -yes"
+sigusr1 = ""
+sigusr2 = ""
+
[bar]
buffers.color_bg = default
+buffers.color_bg_inactive = default
buffers.color_delim = default
buffers.color_fg = default
buffers.conditions = ""
@@ -258,6 +272,7 @@
buffers.size_max = 0
buffers.type = root
buflist.color_bg = default
+buflist.color_bg_inactive = default
buflist.color_delim = default
buflist.color_fg = default
buflist.conditions = ""
@@ -272,6 +287,7 @@
buflist.size_max = 25
buflist.type = root
fset.color_bg = default
+fset.color_bg_inactive = default
fset.color_delim = cyan
fset.color_fg = default
fset.conditions = "${buffer.full_name} == fset.fset"
@@ -286,6 +302,7 @@
fset.size_max = 3
fset.type = window
input.color_bg = default
+input.color_bg_inactive = default
input.color_delim = green
input.color_fg = default
input.conditions = ""
@@ -300,6 +317,7 @@
input.size_max = 0
input.type = window
nicklist.color_bg = default
+nicklist.color_bg_inactive = default
nicklist.color_delim = cyan
nicklist.color_fg = default
nicklist.conditions = "nicklist"
@@ -314,6 +332,7 @@
nicklist.size_max = 0
nicklist.type = window
status.color_bg = green
+status.color_bg_inactive = default
status.color_delim = 0
status.color_fg = 0
status.conditions = ""
@@ -328,6 +347,7 @@
status.size_max = 0
status.type = window
title.color_bg = green
+title.color_bg_inactive = default
title.color_delim = cyan
title.color_fg = 16
title.conditions = ""
@@ -345,6 +365,11 @@
[layout]
[notify]
+python.slack.10xgenomics.&cloud-alerts-pagerduty = highlight
+python.slack.10xgenomics.&cloud-sumo-prod-support-alerts = highlight
+python.slack.10xgenomics.&lacework-10xdev = highlight
+python.slack.10xgenomics.&lacework-10xprod = highlight
+python.slack.10xgenomics.&testing1234 = highlight
[filter]
irc_smart = on;*;irc_smart_filter;*
@@ -381,6 +406,8 @@
ctrl-Y = "/input clipboard_paste"
meta-meta-OP = "/bar scroll buflist * b"
meta-meta-OQ = "/bar scroll buflist * e"
+meta-meta2-11~ = "/bar scroll buflist * b"
+meta-meta2-12~ = "/bar scroll buflist * e"
meta-meta2-1~ = "/window scroll_top"
meta-meta2-23~ = "/bar scroll nicklist * yb"
meta-meta2-24~ = "/bar scroll nicklist * ye"
@@ -406,6 +433,7 @@
meta-< = "/input jump_previously_visited_buffer"
meta-= = "/filter toggle"
meta-> = "/input jump_next_visited_buffer"
+meta-B = "/buflist toggle"
meta-OA = "/input history_global_previous"
meta-OB = "/input history_global_next"
meta-OC = "/input move_next_word"
@@ -418,6 +446,10 @@
meta-Ob = "/input history_global_next"
meta-Oc = "/input move_next_word"
meta-Od = "/input move_previous_word"
+meta2-11^ = "/bar scroll buflist * -100%"
+meta2-11~ = "/bar scroll buflist * -100%"
+meta2-12^ = "/bar scroll buflist * +100%"
+meta2-12~ = "/bar scroll buflist * +100%"
meta2-15~ = "/bar scroll nicklist * y-100%"
meta2-17~ = "/bar scroll nicklist * y+100%"
meta2-18~ = "/window -1"
@@ -426,8 +458,12 @@
meta2-1;3B = "/buffer +1"
meta2-1;3C = "/buffer +1"
meta2-1;3D = "/buffer -1"
+meta2-1;3P = "/bar scroll buflist * b"
+meta2-1;3Q = "/bar scroll buflist * e"
meta2-1;5A = "/input history_global_previous"
meta2-1;5B = "/input history_global_next"
+meta2-1;5P = "/bar scroll buflist * -100%"
+meta2-1;5Q = "/bar scroll buflist * +100%"
meta2-1;9A = "/buffer move -1"
meta2-1;9B = "/buffer move +1"
meta2-1~ = "/input move_beginning_of_line"
@@ -601,6 +637,11 @@
meta2-B = "/cursor move down"
meta2-C = "/cursor move right"
meta2-D = "/cursor move left"
+@chat(python.*):D = "hsignal:slack_cursor_delete"
+@chat(python.*):L = "hsignal:slack_cursor_linkarchive"
+@chat(python.*):M = "hsignal:slack_cursor_message"
+@chat(python.*):R = "hsignal:slack_cursor_reply"
+@chat(python.*):T = "hsignal:slack_cursor_thread"
@item(buffer_nicklist):K = "/window ${_window_number};/kickban ${nick}"
@item(buffer_nicklist):b = "/window ${_window_number};/ban ${nick}"
@item(buffer_nicklist):k = "/window ${_window_number};/kick ${nick}"
@@ -622,6 +663,7 @@
@chat(fset.fset):button2* = "hsignal:fset_mouse"
@chat(fset.fset):wheeldown = "/fset -down 5"
@chat(fset.fset):wheelup = "/fset -up 5"
+@chat(python.*):button2 = "hsignal:slack_mouse"
@chat(script.scripts):button1 = "/window ${_window_number};/script go ${_chat_line_y}"
@chat(script.scripts):button2 = "/window ${_window_number};/script go ${_chat_line_y};/script installremove -q ${script_name_with_extension}"
@chat(script.scripts):wheeldown = "/script down 5"
--- a/weechat/xfer.conf Fri Apr 14 15:01:35 2023 -0400
+++ b/weechat/xfer.conf Fri Jul 07 16:11:02 2023 -0400
@@ -4,9 +4,9 @@
# WARNING: It is NOT recommended to edit this file by hand,
# especially if WeeChat is running.
#
-# Use /set or similar command to change settings in WeeChat.
+# Use commands like /set or /fset to change settings in WeeChat.
#
-# For more info, see: https://weechat.org/doc/quickstart
+# For more info, see: https://weechat.org/doc/quickstart/
#
[look]
@@ -31,7 +31,8 @@
own_ip = ""
port_range = ""
send_ack = on
-speed_limit = 0
+speed_limit_recv = 0
+speed_limit_send = 0
timeout = 300
[file]
@@ -43,5 +44,6 @@
auto_resume = on
convert_spaces = on
download_path = "%h/xfer"
+download_temporary_suffix = ".part"
upload_path = "~"
use_nick_in_filename = on
--- a/xsessionrc Fri Apr 14 15:01:35 2023 -0400
+++ b/xsessionrc Fri Jul 07 16:11:02 2023 -0400
@@ -23,5 +23,9 @@
# /usr/bin/dunst -config $HOME/.dunstrc &
+# Fix the fucking GTK scrolling bullshit
+# God bless you https://mmk2410.org/2018/02/15/scrolling-doesnt-work-in-gtk-3-apps-in-stumpwm/
+export GDK_CORE_DEVICE_EVENTS=1
+
# exec gpg-agent --daemon --enable-ssh-support /usr/local/bin/stumpwm
exec /usr/local/bin/stumpwm > .stump-xsession-log.out 2> .stump-xsession-log.err