bb1f0bc31860

Merge
[view raw] [browse files]
author Steve Losh <steve@stevelosh.com>
date Thu, 27 Aug 2020 22:46:44 -0400
parents f89078a3dc08 (diff) 9bad13b2ff57 (current diff)
children 7c341a980eda
branches/tags (none)
files vim/vimrc

Changes

--- a/.hgsub	Thu Aug 27 22:45:20 2020 -0400
+++ b/.hgsub	Thu Aug 27 22:46:44 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
--- a/.hgsubstate	Thu Aug 27 22:45:20 2020 -0400
+++ b/.hgsubstate	Thu Aug 27 22:46:44 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
--- a/bin/bootstrap.sh	Thu Aug 27 22:45:20 2020 -0400
+++ b/bin/bootstrap.sh	Thu Aug 27 22:46:44 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"
--- a/bin/confirm	Thu Aug 27 22:45:20 2020 -0400
+++ b/bin/confirm	Thu Aug 27 22:46:44 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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bin/doc	Thu Aug 27 22:46:44 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"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bin/mark	Thu Aug 27 22:46:44 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"
--- a/gitconfig	Thu Aug 27 22:45:20 2020 -0400
+++ b/gitconfig	Thu Aug 27 22:46:44 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"
--- a/gnuplot	Thu Aug 27 22:45:20 2020 -0400
+++ b/gnuplot	Thu Aug 27 22:46:44 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 ------------------------------------------------------- {{{
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lisp/gtp.lisp	Thu Aug 27 22:46:44 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)
--- a/lispwords	Thu Aug 27 22:45:20 2020 -0400
+++ b/lispwords	Thu Aug 27 22:46:44 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)
--- a/vim/custom-dictionary.utf-8.add	Thu Aug 27 22:45:20 2020 -0400
+++ b/vim/custom-dictionary.utf-8.add	Thu Aug 27 22:46:44 2020 -0400
@@ -307,3 +307,5 @@
 Hox
 deduplication
 deduplicating
+passlist
+golang
--- a/vim/vimrc	Thu Aug 27 22:45:20 2020 -0400
+++ b/vim/vimrc	Thu Aug 27 22:46:44 2020 -0400
@@ -1497,6 +1497,8 @@
     au FileType go nnoremap <buffer> <localleader>h :GoDocBrowser<cr>
     au FileType go nnoremap <buffer> <localleader>c :GoBuild<cr>
 
+    au FileType go inoremap <c-n> <c-x><c-o>
+
     " this language is incredible
     au FileType go iabbrev <buffer> ernil if err != nil {<cr>return nil, err<esc>jA
     au FileType go iabbrev <buffer> erstr if err != nil {<cr>return "", err<esc>jA
@@ -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 <localleader>f to fold the current tag.
-    au FileType html,jinja,htmldjango nnoremap <buffer> <localleader>f Vatzf
+    au FileType html,jinja,htmldjango,gohtmltmpl nnoremap <buffer> <localleader>f Vatzf
 
     " Use <localleader>t to fold the current templatetag.
     au FileType html,jinja,htmldjango nmap <buffer> <localleader>t viikojozf
 
     " Indent tag
-    au FileType html,jinja,htmldjango nnoremap <buffer> <localleader>= Vat=
+    au FileType html,jinja,htmldjango,gohtmltmpl nnoremap <buffer> <localleader>= Vat=
 
     " Django tags
     au FileType jinja,htmldjango inoremap <buffer> <c-t> {%<space><space>%}<left><left><left>
@@ -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 {{{
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/w3m-config	Thu Aug 27 22:46:44 2020 -0400
@@ -0,0 +1,1 @@
+meta_refresh 1