# HG changeset patch # User Steve Losh # Date 1598822865 14400 # Node ID 7c341a980eda20dfb42d681b4294be1ffda1b41a # Parent bb1f0bc31860df0178acf91f1002eacc1581e986# Parent 9097174b115d0e1898613456d02d350b7c665efc Merge diff -r 9097174b115d -r 7c341a980eda .hgsub --- a/.hgsub Sun Aug 30 17:26:18 2020 -0400 +++ b/.hgsub Sun Aug 30 17:27:45 2020 -0400 @@ -21,7 +21,7 @@ vim/bundle/markdown = [git]https://github.com/sjl/vim-markdown vim/bundle/miniyank = [git]https://github.com/bfredl/nvim-miniyank vim/bundle/nerdtree = [git]https://github.com/scrooloose/nerdtree -vim/bundle/paredit = [hg]https://bitbucket.org/kovisoft/paredit/ +vim/bundle/paredit = [git]https://github.com/kovisoft/paredit vim/bundle/pgsql = [git]https://github.com/exu/pgsql.vim vim/bundle/python-mode = [git]https://github.com/klen/python-mode vim/bundle/rainbow-parentheses = [git]https://github.com/kien/rainbow_parentheses.vim @@ -31,6 +31,7 @@ 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/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 diff -r 9097174b115d -r 7c341a980eda .hgsubstate --- a/.hgsubstate Sun Aug 30 17:26:18 2020 -0400 +++ b/.hgsubstate Sun Aug 30 17:27:45 2020 -0400 @@ -21,7 +21,7 @@ e2d7fcd682a461a3951e8b5067cc8a0083e75e35 vim/bundle/markdown 1362fdc7c32855794659cafe6e65d3239843d9df vim/bundle/miniyank d6032c876c6d6932ab7f07e262a16c9a85a31d5b vim/bundle/nerdtree -f506af01e84e53643e0760b7f43c74069ce16c85 vim/bundle/paredit +c76e0987ec45c84103b408691ec0506e7b99cb30 vim/bundle/paredit 1a436f7d875b4ec630da081b041c73264235c7e7 vim/bundle/pgsql d241974f40e8d206f9970e51fb0069951862ba35 vim/bundle/python-mode eb8baa5428bde10ecc1cb14eed1d6e16f5f24695 vim/bundle/rainbow-parentheses @@ -31,6 +31,7 @@ b4398689f7483b01684044ab6b55bf369744c9b3 vim/bundle/sexp e02c3e218c51c1e2ea1821a3fe412d4e09ca1502 vim/bundle/shaderhighlight 4346419ac57ef341a15aa39c827c0848f17c6faf vim/bundle/shellcheck +d400a570bf64b0c216aa7c8e1795820b911a7404 vim/bundle/sparkup 062b18eebd153c13e6f36577707acb17893cd959 vim/bundle/splice 26fbdd7d1f1aa5600d2ebf39bbdd292c38aac16e vim/bundle/strftimedammit aa1f120ad3a29c27cc41d581cda3751c59343cce vim/bundle/surround diff -r 9097174b115d -r 7c341a980eda bin/b --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/bin/b Sun Aug 30 17:27:45 2020 -0400 @@ -0,0 +1,5 @@ +#!/usr/bin/env bash + +set -euo pipefail + +python ~/src/t/t.py --task-dir ./ --list TODO "$@" diff -r 9097174b115d -r 7c341a980eda bin/bootstrap.sh --- a/bin/bootstrap.sh Sun Aug 30 17:26:18 2020 -0400 +++ b/bin/bootstrap.sh Sun Aug 30 17:27:45 2020 -0400 @@ -56,6 +56,7 @@ ensure_link "src/dotfiles/vim" ".vim" ensure_link "src/dotfiles/vim/vimrc" ".vimrc" ensure_link "src/dotfiles/w3m-keymap" ".w3m/keymap" +ensure_link "src/dotfiles/w3m-config" ".w3m/config" ensure_link "src/dotfiles/weechat" ".weechat" ensure_link "src/dotfiles/xbindkeysrc" ".xbindkeysrc" ensure_link "src/dotfiles/xsessionrc" ".xsessionrc" diff -r 9097174b115d -r 7c341a980eda bin/confirm --- a/bin/confirm Sun Aug 30 17:26:18 2020 -0400 +++ b/bin/confirm Sun Aug 30 17:27:45 2020 -0400 @@ -1,6 +1,11 @@ #!/usr/bin/env bash -read -p "Are you sure? " -r +if test "$1" == ""; then + read -p "Are you sure? " -r +else + read -p "$1 " -r +fi + if [[ $REPLY =~ ^[Yy](es)?$ ]] then exit 0 diff -r 9097174b115d -r 7c341a980eda bin/doc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/bin/doc Sun Aug 30 17:27:45 2020 -0400 @@ -0,0 +1,14 @@ +#!/usr/bin/env bash + +set -euo pipefail + +LANG=$1 +shift + +if test "$LANG" -eq "go"; then + LANG=golang +fi + +QUERY=$(echo -n "$@" | urlencode) + +w3m "https://duckduckgo.com/?q=$LANG+$QUERY" diff -r 9097174b115d -r 7c341a980eda bin/mark --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/bin/mark Sun Aug 30 17:27:45 2020 -0400 @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +set -euo pipefail + +EVENT="$1" +shift + +mkdir -p "$HOME/.marks" +echo "$(date --iso-8601=seconds --utc)" "$@" >> "$HOME/.marks/$EVENT" diff -r 9097174b115d -r 7c341a980eda gitconfig --- a/gitconfig Sun Aug 30 17:26:18 2020 -0400 +++ b/gitconfig Sun Aug 30 17:27:45 2020 -0400 @@ -33,6 +33,9 @@ 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" diff -r 9097174b115d -r 7c341a980eda gnuplot --- a/gnuplot Sun Aug 30 17:26:18 2020 -0400 +++ b/gnuplot Sun Aug 30 17:27:45 2020 -0400 @@ -23,6 +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." # }}} # Utility Functions ------------------------------------------------------- {{{ diff -r 9097174b115d -r 7c341a980eda hgrc --- a/hgrc Sun Aug 30 17:26:18 2020 -0400 +++ b/hgrc Sun Aug 30 17:27:45 2020 -0400 @@ -122,9 +122,10 @@ # Commit message shortcuts. cm = commit -m -cus = commit -m 'Update subrepository state.' -cmm = commit -m 'Merge.' -cb = commit -m 'Close branch.' --close-branch +cus = commit -m 'Update subrepository state' +cmm = commit -m 'Merge' +ct = commit -m 'Update TODO' TODO .TODO.done +cb = commit -m 'Close branch' --close-branch # Merge shortcuts. mergelocal = !$HG --config ui.merge=internal:local merge $@ diff -r 9097174b115d -r 7c341a980eda lisp/gtp.lisp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lisp/gtp.lisp Sun Aug 30 17:27:45 2020 -0400 @@ -0,0 +1,351 @@ +(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) diff -r 9097174b115d -r 7c341a980eda lispwords --- a/lispwords Sun Aug 30 17:26:18 2020 -0400 +++ b/lispwords Sun Aug 30 17:27:45 2020 -0400 @@ -17,6 +17,7 @@ (1 restart-case) (1 handler-bind) (0 tagbody) +(1 multiple-value-prog1) ; my own weird things (1 make-array) diff -r 9097174b115d -r 7c341a980eda vim/custom-dictionary.utf-8.add --- a/vim/custom-dictionary.utf-8.add Sun Aug 30 17:26:18 2020 -0400 +++ b/vim/custom-dictionary.utf-8.add Sun Aug 30 17:27:45 2020 -0400 @@ -307,4 +307,6 @@ Hox deduplication deduplicating +passlist +golang unapplied diff -r 9097174b115d -r 7c341a980eda vim/vimrc --- a/vim/vimrc Sun Aug 30 17:26:18 2020 -0400 +++ b/vim/vimrc Sun Aug 30 17:27:45 2020 -0400 @@ -948,11 +948,11 @@ NeoRepl ccl-vlime endfunction "}}} function! OpenLispReplECL() "{{{ - NeoRepl ecl-nrepl + NeoRepl ecl-vlime call InitializeLispRepl() endfunction "}}} function! OpenLispReplABCL() "{{{ - NeoRepl abcl-nrepl + NeoRepl abcl-vlime call InitializeLispRepl() endfunction "}}} @@ -1497,6 +1497,8 @@ au FileType go nnoremap h :GoDocBrowser au FileType go nnoremap c :GoBuild + au FileType go inoremap + " this language is incredible au FileType go iabbrev ernil if err != nil {return nil, errjA au FileType go iabbrev erstr if err != nil {return "", errjA @@ -1515,26 +1517,26 @@ augroup END " }}} -" HTML, Django, Jinja, Dram {{{ +" HTML, Django, Jinja, Dram, Go, Kill Me {{{ let g:html_indent_tags = ['p', 'li'] augroup ft_html au! - au BufNewFile,BufRead *.html setlocal filetype=htmldjango + au BufNewFile,BufRead *.html setlocal filetype=gohtmltmpl au BufNewFile,BufRead *.dram setlocal filetype=htmldjango - au FileType html,jinja,htmldjango setlocal foldmethod=manual + au FileType html,jinja,htmldjango,gohtmltmpl setlocal foldmethod=manual " Use f to fold the current tag. - au FileType html,jinja,htmldjango nnoremap f Vatzf + au FileType html,jinja,htmldjango,gohtmltmpl nnoremap f Vatzf " Use t to fold the current templatetag. au FileType html,jinja,htmldjango nmap t viikojozf " Indent tag - au FileType html,jinja,htmldjango nnoremap = Vat= + au FileType html,jinja,htmldjango,gohtmltmpl nnoremap = Vat= " Django tags au FileType jinja,htmldjango inoremap {%%} @@ -2219,6 +2221,10 @@ let g:go_doc_keywordprg_enabled = 0 let g:go_def_mode = "godef" +let g:go_diagnostics_enabled = 0 +let g:go_highlight_diagnostic_errors = 0 +let g:go_highlight_diagnostic_warnings = 0 + " }}} " Gundo {{{ diff -r 9097174b115d -r 7c341a980eda w3m-config --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/w3m-config Sun Aug 30 17:27:45 2020 -0400 @@ -0,0 +1,1 @@ +meta_refresh 1