# HG changeset patch # User Steve Losh # Date 1580826252 18000 # Node ID 5deecedda0bb06ff4015a53d2a2053b4e0a8c62c # Parent 71b4b4adee33d5d7fab5e6176281518d0d548ac2# Parent 8d1c68b94471173d1092e5d1f2d21b509f87a924 Merge. diff -r 71b4b4adee33 -r 5deecedda0bb bash_profile --- a/bash_profile Tue Feb 04 09:23:46 2020 -0500 +++ b/bash_profile Tue Feb 04 09:24:12 2020 -0500 @@ -23,7 +23,7 @@ ORANGE=$'\e[33m' BLUE=$'\e[34m' PINK=$'\e[35m' -CYAN=$'\e[36m' +# CYAN=$'\e[36m' function last_return_value() { x="$?" @@ -67,8 +67,37 @@ } fi -export PATH=~/bin:~/src/dotfiles/bin:~/src/dotfiles/lisp/bin:/usr/local/bin/:$PATH -export PAGER=less +function prepend_to_path { + if test -d "$1"; then + PATH="$1":"$PATH" + fi +} + +PATH="/sbin" +prepend_to_path "/bin" +prepend_to_path "/usr/bin" +prepend_to_path "/usr/sbin" +prepend_to_path "/usr/local/bin" +prepend_to_path "/usr/local/sbin" +prepend_to_path "/usr/local/go/bin" +prepend_to_path "/usr/games" +prepend_to_path "/snap/bin" +prepend_to_path "$HOME/.local/bin" +prepend_to_path "$HOME/.go/bin" +prepend_to_path "$HOME/src/dotfiles/lisp/bin" +prepend_to_path "$HOME/src/dotfiles/bin" +prepend_to_path "$HOME/src/hg" +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- diff -r 71b4b4adee33 -r 5deecedda0bb bin/backup-backblaze --- a/bin/backup-backblaze Tue Feb 04 09:23:46 2020 -0500 +++ b/bin/backup-backblaze Tue Feb 04 09:24:12 2020 -0500 @@ -2,6 +2,9 @@ set -euo pipefail + +ban "Backblaze" + source /home/sjl/.restic-backblaze-creds restic --repo b2:backups-ouroboros:restic-repo \ diff -r 71b4b4adee33 -r 5deecedda0bb bin/backup-local --- a/bin/backup-local Tue Feb 04 09:23:46 2020 -0500 +++ b/bin/backup-local Tue Feb 04 09:24:12 2020 -0500 @@ -2,6 +2,8 @@ set -euo pipefail +ban -F metal "NAS" + restic --repo /mnt/cryo/restic-ouroboros/repo \ --exclude-file=/home/sjl/src/dotfiles/restic/excludes.txt \ --password-file /home/sjl/.restic-password-local \ diff -r 71b4b4adee33 -r 5deecedda0bb bin/bootstrap.sh --- a/bin/bootstrap.sh Tue Feb 04 09:23:46 2020 -0500 +++ b/bin/bootstrap.sh Tue Feb 04 09:24:12 2020 -0500 @@ -39,6 +39,7 @@ ensure_link "src/dotfiles/fish/functions" ".config/fish/functions" ensure_link "src/dotfiles/gitconfig" ".gitconfig" ensure_link "src/dotfiles/gitignore" ".gitignore" +ensure_link "src/dotfiles/gnuplot" ".gnuplot" ensure_link "src/dotfiles/hgignore" ".hgignore" ensure_link "src/dotfiles/lisprc" ".lisprc" ensure_link "src/dotfiles/lispwords" ".lispwords" diff -r 71b4b4adee33 -r 5deecedda0bb bin/disks --- a/bin/disks Tue Feb 04 09:23:46 2020 -0500 +++ b/bin/disks Tue Feb 04 09:24:12 2020 -0500 @@ -2,7 +2,15 @@ set -euo pipefail -lsblk -o name,mountpoint,model,label,size,fstype | egrep -v "^loop" +lsblk -o name,mountpoint,model,label,size,fstype | grep -Pv "^loop" | awk ' +NR>1 && /^[a-zA-Z]/ { print "-----------------------------------------------------------------------------------------------------------------------" } + { print $0 } +' echo echo -df -h | egrep -v '^/dev/loop' | egrep -v tmpfs +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 diff -r 71b4b4adee33 -r 5deecedda0bb bin/e --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/bin/e Tue Feb 04 09:24:12 2020 -0500 @@ -0,0 +1,5 @@ +#!/usr/bin/env bash + +set -euo pipefail + +"$EDITOR" "$@" diff -r 71b4b4adee33 -r 5deecedda0bb bin/external-ip --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/bin/external-ip Tue Feb 04 09:24:12 2020 -0500 @@ -0,0 +1,6 @@ +#!/usr/bin/env bash + +set -euo pipefail + +dig @resolver1.opendns.com ANY myip.opendns.com +short + diff -r 71b4b4adee33 -r 5deecedda0bb bin/mangle-signature --- a/bin/mangle-signature Tue Feb 04 09:23:46 2020 -0500 +++ b/bin/mangle-signature Tue Feb 04 09:24:12 2020 -0500 @@ -1,3 +1,3 @@ #!/usr/bin/env bash -cat +sed -Ee 's/^-- $/-- /' diff -r 71b4b4adee33 -r 5deecedda0bb bin/nnl --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/bin/nnl Tue Feb 04 09:24:12 2020 -0500 @@ -0,0 +1,5 @@ +#!/usr/bin/env bash + +set -euo pipefail + +tr -d '\n' diff -r 71b4b4adee33 -r 5deecedda0bb bin/pastebin --- a/bin/pastebin Tue Feb 04 09:23:46 2020 -0500 +++ b/bin/pastebin Tue Feb 04 09:24:12 2020 -0500 @@ -2,11 +2,8 @@ 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/`sha1sum tmppaste | cut -d" " -f1`') +URL="https://paste.stevelosh.com/$PASTE_SHA" -echo -n "https://paste.stevelosh.com/$PASTE_SHA" | pbcopy -echo -n 'Copied ' -tput bold -pbpaste -tput sgr0 -echo ' to the clipboard.' +echo -n "$URL" | pbcopy +echo "Copied $URL to the clipboard." diff -r 71b4b4adee33 -r 5deecedda0bb bin/pbc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/bin/pbc Tue Feb 04 09:24:12 2020 -0500 @@ -0,0 +1,1 @@ +pbcopy \ No newline at end of file diff -r 71b4b4adee33 -r 5deecedda0bb bin/pbcopy --- a/bin/pbcopy Tue Feb 04 09:23:46 2020 -0500 +++ b/bin/pbcopy Tue Feb 04 09:24:12 2020 -0500 @@ -1,3 +1,5 @@ #!/usr/bin/env bash -xclip -selection clipboard -i +set -euo pipefail + +xsel --clipboard --input diff -r 71b4b4adee33 -r 5deecedda0bb bin/pbp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/bin/pbp Tue Feb 04 09:24:12 2020 -0500 @@ -0,0 +1,1 @@ +pbpaste \ No newline at end of file diff -r 71b4b4adee33 -r 5deecedda0bb bin/pbpaste --- a/bin/pbpaste Tue Feb 04 09:23:46 2020 -0500 +++ b/bin/pbpaste Tue Feb 04 09:24:12 2020 -0500 @@ -1,3 +1,5 @@ #!/usr/bin/env bash -xclip -selection clipboard -o +set -euo pipefail + +xsel --clipboard --output diff -r 71b4b4adee33 -r 5deecedda0bb bin/u --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/bin/u Tue Feb 04 09:24:12 2020 -0500 @@ -0,0 +1,5 @@ +#!/usr/bin/env bash + +set -euo pipefail + +du -hd1 "$@" diff -r 71b4b4adee33 -r 5deecedda0bb fish/config.fish --- a/fish/config.fish Tue Feb 04 09:23:46 2020 -0500 +++ b/fish/config.fish Tue Feb 04 09:24:12 2020 -0500 @@ -13,6 +13,7 @@ function essh; nvim ~/.ssh/config; end function js; cd ~/scratch; end +function jd; cd /dump; end function histgrep; history | grep "$argv" | tac; end @@ -85,6 +86,7 @@ end end end + set -gx PATH "/sbin" prepend_to_path "/snap/bin" prepend_to_path "/usr/sbin" @@ -107,7 +109,7 @@ set -g -x EDITOR nvim set -g -x COMMAND_MODE unix2003 set -g -x RUBYOPT rubygems -set -g -x PAGER 'less -X' +set -g -x PAGER 'less -iX' # set -g -x _JAVA_OPTIONS "-Djava.awt.headless=true" set -g -x GPG_TTY (tty) @@ -143,32 +145,47 @@ # }}} # Prompt {{{ -set normal (set_color normal) -set magenta (set_color magenta) -set yellow (set_color yellow) -set green (set_color green) -set cyan (set_color cyan) -set gray (set_color -o black) +if status --is-interactive + set normal (set_color normal) + set magenta (set_color magenta) + set yellow (set_color yellow) + set green (set_color green) + set cyan (set_color cyan) + set gray (set_color -o black) -set hg_promptstring "\ + set hg_promptstring "\ < on $magenta$normal>\ < at $cyan$normal>\ $green$normal\ " 2>/dev/null + if test -n "$SSH_CLIENT" + or test -n "$SSH_TTY" + set host_color (set_color cyan) + set want_vcs_prompts 0 + else + set host_color (set_color yellow) + set want_vcs_prompts 1 + end +end + function hg_prompt - hg prompt --angle-brackets $hg_promptstring 2>/dev/null + if test -z "$NOVCSPROMPT" + hg prompt --angle-brackets $hg_promptstring 2>/dev/null + end end function git_prompt - if git root >/dev/null 2>&1 - set_color normal - printf ' on ' - set_color magenta - printf '%s' (git current-branch ^/dev/null) - set_color green - git_prompt_status - set_color normal + if test -z "$NOVCSPROMPT" + if git root >/dev/null 2>&1 + set_color normal + printf ' on ' + set_color magenta + printf '%s' (git current-branch ^/dev/null) + set_color green + git_prompt_status + set_color normal + end end end @@ -176,14 +193,6 @@ echo $PWD | sed -e "s|^$HOME|~|" end -if test -n "$SSH_CLIENT" - or test -n "$SSH_TTY" - set host_color (set_color cyan) - set want_vcs_prompts 0 -else - set host_color (set_color yellow) - set want_vcs_prompts 1 -end function fish_prompt set last_status $status diff -r 71b4b4adee33 -r 5deecedda0bb fish/functions/pbc.fish --- a/fish/functions/pbc.fish Tue Feb 04 09:23:46 2020 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,3 +0,0 @@ -function pbc -d "pbcopy" - xsel --clipboard --input -end diff -r 71b4b4adee33 -r 5deecedda0bb fish/functions/pbp.fish --- a/fish/functions/pbp.fish Tue Feb 04 09:23:46 2020 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,3 +0,0 @@ -function pbp -d "pbpaste" - xsel --clipboard -end diff -r 71b4b4adee33 -r 5deecedda0bb fish/functions/pbpb.fish --- a/fish/functions/pbpb.fish Tue Feb 04 09:23:46 2020 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,3 +0,0 @@ -function pbpb -d "pbpaste to pastebin site" - pbp | pb -end diff -r 71b4b4adee33 -r 5deecedda0bb gnuplot --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnuplot Tue Feb 04 09:24:12 2020 -0500 @@ -0,0 +1,51 @@ +# Basic Settings ---------------------------------------------------------- {{{ + +set encoding utf8 +set terminal qt noraise +set samples 1000 + +# }}} +# Constants --------------------------------------------------------------- {{{ + +tau = 2 * pi +e = 2.71828182845905 +r2 = sqrt(2.0) + +# }}} +# Utility Functions ------------------------------------------------------- {{{ + +min(a, b) = (ab) ? a : b + +# }}} +# Exporting --------------------------------------------------------------- {{{ + +export(file, terminal) = sprintf( \ + "set terminal push;" . \ + "set terminal %s;" . \ + "set output '%s';" . \ + "replot;" . \ + "set output;" . \ + "set terminal pop;" . \ + "print system('realpath %s | nnl | pbcopy');" \ + , terminal, file, file) + +export_pdf(file) = export(file . '.pdf', "pdfcairo") +export_png(file) = export(file . '.png', "pngcairo") + +pdf = "eval export_pdf('graph')" +png = "eval export_png('graph')" + +# }}} +# Other ------------------------------------------------------------------- {{{ + +kdens(file, column, bandwidth) = sprintf( \ + "stats '%s' using %d;" . \ + "plot '%s' using %d:(1.0/STATS_records) smooth kdensity bandwidth %f;" \ + , file, column, file, column, bandwidth) + +cdf(file, column) = sprintf( \ + "plot '%s' using %d:(1.0) smooth cnormal;" \ + , file, column) + +# }}} diff -r 71b4b4adee33 -r 5deecedda0bb lisp/lines.lisp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lisp/lines.lisp Tue Feb 04 09:24:12 2020 -0500 @@ -0,0 +1,477 @@ +(eval-when (:compile-toplevel :load-toplevel :execute) + (ql:quickload '(:adopt :cl-ppcre :with-user-abort) :silent t)) + +(defpackage :lines + (:use :cl) + (:export :toplevel :*ui*)) + +(in-package :lines) + +;; TODO: Optimize by eliminating collection when all matchers are in order. + +;;;; Configuration ------------------------------------------------------------ +(defparameter *version* "1.0.0") +(defparameter *index-base* 0) +(defparameter *include-numbers* nil) +(defparameter *limit* nil) + + +;;;; Functionality ------------------------------------------------------------ +(defclass matcher () + ((designator :type string :initarg :designator :accessor designator))) + +(defmethod print-object ((o matcher) stream) + (print-unreadable-object (o stream :type t) + (format stream "~S" (designator o)))) + +(defgeneric matches-line-p (matcher line-number)) +(defgeneric map-matching-lines (matcher function min max)) +(defgeneric maximum (matcher)) + + +(defclass single-line-matcher (matcher) + ((n :type (integer 0) :initarg :n :accessor n))) + +(defmethod matches-line-p ((matcher single-line-matcher) i) + (= (n matcher) i)) + +(defmethod map-matching-lines ((matcher single-line-matcher) function min max) + (when (<= min (n matcher) max) + (funcall function (n matcher)))) + +(defmethod maximum ((matcher single-line-matcher)) + (n matcher)) + + +(defclass range-matcher (matcher) + ((m :type (or null (integer 0)) :initarg :m :accessor m) + (n :type (or null (integer 0)) :initarg :n :accessor n))) + +(defmethod matches-line-p ((matcher range-matcher) i) + (let ((m (m matcher)) + (n (n matcher))) + (cond ((null m) (if (null n) + t + (<= i n))) + ((null n) (<= m i)) + (t (<= m i n))))) + +(defmethod map-matching-lines ((matcher range-matcher) function min max) + (loop :with m = (or (m matcher) min) + :with n = (or (n matcher) max) + :for i :from (max m min) :to (min n max) + :do (funcall function i))) + +(defmethod maximum ((matcher range-matcher)) + (n matcher)) + + +(defclass modulo-matcher (matcher) + ((n :type (integer 0) :initarg :n :accessor n) + (modulus :type (integer 1) :initarg :modulus :accessor modulus))) + +(defmethod matches-line-p ((matcher modulo-matcher) i) + (= (mod i (modulus matcher)) + (n matcher))) + +(defmethod map-matching-lines ((matcher modulo-matcher) function min max) + (loop + :with n = (n matcher) + :with modulus = (modulus matcher) + :with start = (if (< n min) + (+ n modulus) + n) + :for i :from start :to max :by modulus + :do (funcall function i))) + +(defmethod maximum ((matcher modulo-matcher)) + nil) + + +(defun parse-single-line-designator (designator) + (ppcre:register-groups-bind + ((#'parse-integer n)) + ("^(\\d+)$" designator) + (make-instance 'single-line-matcher :designator designator :n n))) + +(defun parse-range-designator (designator) + (ppcre:register-groups-bind + ((#'parse-integer m n)) + ("^(\\d+)?-(\\d+)?$" designator) + (when (and m n) + (assert (<= m n) () + "Bad line range designator ~S: start (~D) must not be greater than end (~D)." + designator m n)) + (make-instance 'range-matcher :designator designator :m m :n n))) + +(defun parse-modulo-designator (designator) + (ppcre:register-groups-bind + ((#'parse-integer n modulus)) + ("^(\\d+)?m(\\d+)$" designator) + (when (null n) + (setf n 0)) + (assert (< n modulus) () + "Bad modulo designator ~S: offset (~D) must be less than modulus (~D)." + designator n modulus) + (make-instance 'modulo-matcher :designator designator :n n :modulus modulus))) + +(defun parse-line-designator (designator) + (or (parse-single-line-designator designator) + (parse-range-designator designator) + (parse-modulo-designator designator) + (error "Could not parse line designator ~S" designator))) + +(defun parse-line-designators (designators) + (mapcar #'parse-line-designator (ppcre:split "," designators))) + + +(defun dbg (&rest args) + (apply #'format *error-output* args) + (finish-output *error-output*)) + +(defun compute-limit (matchers) + (let ((maxes (mapcar #'maximum matchers))) + (unless (some #'null maxes) + (reduce #'max maxes)))) + +(defun collect-lines (matchers) + (loop + :with limit = (compute-limit matchers) + :with min = *index-base* + :with max = nil + :with lines = (make-hash-table) + :for i :from min + :for line = (read-line *standard-input* nil) + :while line + :while (or (null limit) (<= i limit)) + :do (progn (setf max i) + (dolist (matcher matchers) + (when (matches-line-p matcher i) + (setf (gethash i lines) line)))) + :finally (return (values lines min max)))) + + +(defun output-line (line i) + (when i + (format *standard-output* "~D " i)) + (write-line line)) + +(defun run-slow (matchers) + (let ((include-numbers *include-numbers*)) + (multiple-value-bind (lines min max) (collect-lines matchers) + (dolist (matcher matchers) + (map-matching-lines + matcher + (lambda (i) + (output-line (gethash i lines) + (when include-numbers i))) + min max))))) + +(defun run-fast (matcher) + (loop + :with limit = (when *limit* (+ *index-base* *limit*)) + :with include-numbers = *include-numbers* + :for i :from *index-base* + :for line = (read-line *standard-input* nil) + :while (or (null limit) (< i limit)) + :while line + :when (zerop (mod i 100000)) + :do (progn #+sbcl (sb-ext:gc)) + :when (matches-line-p matcher i) + :do (output-line line (when include-numbers i)))) + +(defun run (line-designators) + (let ((matchers (parse-line-designators line-designators))) + (if (= 1 (length matchers)) + (run-fast (first matchers)) + (run-slow matchers))) + (values)) + + +;;;; User Interface ----------------------------------------------------------- +(defmacro defparameters (parameters values-form) + `(progn + ,@(loop :for parameter :in parameters + :collect `(defparameter ,parameter nil)) + (setf (values ,@parameters) ,values-form) + ',parameters)) + +(defun make-boolean-options + (name &key + (name-no (intern (concatenate 'string (string 'no-) (string name)))) + long + (long-no (when long (format nil "no-~A" long))) + short + (short-no (when short (char-upcase short))) + (result-key name) + help + help-no + manual + manual-no + initial-value) + (values (adopt:make-option name + :result-key result-key + :long long + :short short + :help help + :manual manual + :initial-value initial-value + :reduce (constantly t)) + (adopt:make-option name-no + :result-key result-key + :long long-no + :short short-no + :help help-no + :manual manual-no + :reduce (constantly nil)))) + + +(defparameters (*option-debug* *option-no-debug*) + (make-boolean-options 'debug + :long "debug" + :short #\d + :help "Enable the Lisp debugger." + :help-no "Disable the Lisp debugger (default).")) + +(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-one-based* + (adopt:make-option 'one-based + :result-key 'index-base + :help "Start numbering lines at 1 (default)." + :short #\1 + :long "one" + :reduce (constantly 1))) + +(defparameter *option-zero-based* + (adopt:make-option 'zero-based + :result-key 'index-base + :help "Start numbering lines at 0." + :short #\0 + :long "zero" + :reduce (constantly 0))) + +(defparameter *option-other-base* + (adopt:make-option 'other-base + :result-key 'index-base + :initial-value 0 + :help "Start numbering lines at N." + :parameter "N" + :short #\s + :long "start" + :key #'parse-integer + :reduce #'adopt:last)) + +(defparameters (*option-include-numbers* *option-no-include-numbers*) + (make-boolean-options 'include-numbers + :long "number" + :short #\n + :help "Add line numbers to the output." + :help-no "Do not add line number to the output (default).")) + + +(defparameter *option-limit* + (adopt:make-option 'limit + :help "Read at most N lines." + :parameter "N" + :short #\l + :long "limit" + :key #'parse-integer + :reduce #'adopt:last)) + +(defparameter *option-no-limit* + (adopt:make-option 'no-limit + :result-key 'limit + :help "Read all lines (default)." + :short #\L + :long "no-limit" + :reduce (constantly nil))) + + +(defparameter *option-input-encoding* + (adopt:make-option 'input-encoding + :help "Treat input as being encoded with ENC (default utf-8)." + :parameter "ENC" + :short #\i + :long "input-encoding" + :initial-value "utf-8" + :reduce #'adopt:last)) + +(defparameter *option-output-encoding* + (adopt:make-option 'output-encoding + :help "Output text encoded with ENC (default utf-8)." + :parameter "ENC" + :short #\o + :long "output-encoding" + :initial-value "utf-8" + :reduce #'adopt:last)) + +(defparameter *option-input-replacement* + (adopt:make-option 'input-replacement + :help "If an input character is not valid in the selected encoding, replace it with REP." + :parameter "REP" + :short #\r + :long "input-replacement" + :reduce #'adopt:last)) + +(defparameter *option-no-input-replacement* + (adopt:make-option 'no-input-replacement + :result-key 'input-replacement + :help "If an input character is not valid in the selected encoding, return an error (default)." + :short #\R + :long "no-input-replacement" + :reduce (constantly nil))) + +(defparameter *option-output-replacement* + (adopt:make-option 'output-replacement + :help "If an output character would not be not valid in the selected encoding, replace it with REP." + :parameter "REP" + :short #\q + :long "output-replacement" + :reduce #'adopt:last)) + +(defparameter *option-no-output-replacement* + (adopt:make-option 'no-output-replacement + :result-key 'output-replacement + :help "If an output character would not be valid in the selected encoding, return an error (default)." + :short #\Q + :long "no-output-replacement" + :reduce (constantly nil))) + + +(adopt:define-string *help-text* + "lines takes a string denoting which lines to print, and prints those lines ~ + of standard input.") + +(defparameter *examples* + '(("Print line 1234:" + . "cat log.txt | lines 1234") + ("Print line 2, then line 1:" + . "cat log.txt | lines 2,1") + ("Print lines 6, 12, 100-200, and 999+ (1-indexed):" + . "cat log.txt | lines -1 6,12,100-200,999-") + ("Print lines 0, 2, 4, 6, …:" + . "cat log.txt | lines m2") + ("Print the third line of every set of four lines:" + . "cat foo.fastq | lines 3m4"))) + + +(defparameter *ui* + (adopt:make-interface + :name "lines" + :usage "[OPTIONS] LINE-DESIGNATORS" + :summary "print designated lines of standard input" + :help *help-text* + :examples *examples* + :contents (list + *option-limit* + *option-no-limit* + *option-help* + *option-version* + *option-debug* + *option-no-debug* + (adopt:make-group 'character-encodings + :title "Character Encodings" + :options (list + *option-input-encoding* + *option-input-replacement* + *option-no-input-replacement* + *option-output-encoding* + *option-output-replacement* + *option-no-output-replacement*)) + (adopt:make-group 'line-numbering + :title "Line Numbering" + :options (list + *option-one-based* + *option-zero-based* + *option-other-base* + *option-include-numbers* + *option-no-include-numbers*))))) + + +(defmacro without-debugger (&body body) + `(multiple-value-prog1 + (progn + #+sbcl (sb-ext:disable-debugger) + (progn ,@body)) + (progn + #+sbcl (sb-ext:enable-debugger)))) + +(defmacro exit-on-error (&body body) + `(without-debugger + (handler-case (progn ,@body) + #+sbcl (sb-int:broken-pipe () (adopt:exit)) + (error (c) (adopt:print-error-and-exit c))))) + +(defmacro exit-on-error-unless (expr &body body) + `(if ,expr + (progn ,@body) + (exit-on-error ,@body))) + +(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 determine-external-format (encoding replacement) + (let ((encoding (intern (string-upcase encoding) :keyword))) + (if (null replacement) + encoding + (list encoding :replacement replacement)))) + +(defun toplevel () + (exit-on-ctrl-c + (multiple-value-bind (arguments options) (adopt:parse-options-or-exit *ui*) + (exit-on-error-unless (gethash 'debug options) + (cond + ((gethash 'help options) (adopt:print-help-and-exit *ui*)) + ((gethash 'version options) (write-line *version*) (adopt:exit)) + ((null arguments) (error "LINE-DESIGNATORS are required.")) + (t (destructuring-bind (line-designators . more) arguments + (when more + (error "Unrecognized command line arguments: ~S" more)) + (let ((*index-base* (gethash 'index-base options)) + (*include-numbers* (gethash 'include-numbers options)) + (*limit* (gethash 'limit options)) + (input-format (determine-external-format + (gethash 'input-encoding options) + (gethash 'input-replacement options))) + (output-format (determine-external-format + (gethash 'output-encoding options) + (gethash 'output-replacement options)))) + (with-open-file (*standard-input* "/dev/stdin" + :external-format input-format) + (with-open-file (*standard-output* "/dev/stdout" + :external-format output-format + :direction :output + :if-exists :append) + (run line-designators))))))))))) + + +#; Scratch -------------------------------------------------------------------- + +(let ((*standard-input* (make-string-input-stream +"0 a foo +1 b bar +2 c baz +3 d hello +4 a world +5 b yes +6 c this +7 d is +8 a cat +9 b meow"))) + (run "4m4")) diff -r 71b4b4adee33 -r 5deecedda0bb psqlrc --- a/psqlrc Tue Feb 04 09:23:46 2020 -0500 +++ b/psqlrc Tue Feb 04 09:24:12 2020 -0500 @@ -7,3 +7,6 @@ \set PROMPT1 '%[%033[1;34m%]%M:%> %n@%/%R%#%x%[%033[0m%] ' \timing + +\setenv PAGER less +\setenv LESS -iS diff -r 71b4b4adee33 -r 5deecedda0bb remote/bin/e --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/remote/bin/e Tue Feb 04 09:24:12 2020 -0500 @@ -0,0 +1,1 @@ +../../bin/e \ No newline at end of file diff -r 71b4b4adee33 -r 5deecedda0bb remote/bin/lines --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/remote/bin/lines Tue Feb 04 09:24:12 2020 -0500 @@ -0,0 +1,1 @@ +../../lisp/bin/lines \ No newline at end of file diff -r 71b4b4adee33 -r 5deecedda0bb remote/bin/u --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/remote/bin/u Tue Feb 04 09:24:12 2020 -0500 @@ -0,0 +1,1 @@ +../../bin/u \ No newline at end of file diff -r 71b4b4adee33 -r 5deecedda0bb restic/excludes.txt --- a/restic/excludes.txt Tue Feb 04 09:23:46 2020 -0500 +++ b/restic/excludes.txt Tue Feb 04 09:24:12 2020 -0500 @@ -1,20 +1,31 @@ +*.fasl .cache -cache2 +/home/sjl/.arduino15 +/home/sjl/.config/chromium +/home/sjl/.config/discord +/home/sjl/.config/google-chrome +/home/sjl/.config/libreoffice +/home/sjl/.config/unity3d +/home/sjl/.crawl /home/sjl/.dbus -/home/sjl/src/dotfiles/vim/tmp -/home/sjl/snap +/home/sjl/.dropbox +/home/sjl/.dropbox-dist +/home/sjl/.gimp-* +/home/sjl/.go +/home/sjl/.hg-git +/home/sjl/.local/lib/python* +/home/sjl/.local/share +/home/sjl/.mozilla +/home/sjl/.quicklisp +/home/sjl/.rlwrap +/home/sjl/.slime +/home/sjl/.steam +/home/sjl/.virtualenvs +/home/sjl/Dropbox/.dropbox.cache /home/sjl/Videos /home/sjl/dwhelper -/home/sjl/.mozilla -/home/sjl/.dropbox -/home/sjl/.steam -/home/sjl/.quicklisp -/home/sjl/.virtualenvs -/home/sjl/.local/share -/home/sjl/.local/lib/python* -/home/sjl/.config/chromium -/home/sjl/.config/libreoffice -/home/sjl/.config/discord -/home/sjl/.dropbox-dist -/home/sjl/Dropbox/.dropbox.cache - +/home/sjl/snap +/home/sjl/src/abcl +/home/sjl/src/arduino +/home/sjl/src/dotfiles/vim/tmp +cache2 diff -r 71b4b4adee33 -r 5deecedda0bb servers/bash_profile --- a/servers/bash_profile Tue Feb 04 09:23:46 2020 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,30 +0,0 @@ -#!/usr/bin/env bash - -shopt -s expand_aliases - -export PATH=~/bin:~/dotfiles/bin:$PATH - -alias l='ls -1 --color=auto' -alias ll='ls -la1 --color=auto' -alias h='hg' -alias g='git' -alias pj='python -m json.tool' -alias ..='cd ..' -alias ...='cd ../..' -alias ....='cd ../../..' -alias .....='cd ../../../..' -alias ......='cd ../../../../..' -alias nvim=vim - -function psg() { - ps auxww | grep --color=always $* | grep -v grep | collapse | cuts -f 2,11- -} - -export EDITOR=vim - -D=$'\e[37m' -PINK=$'\e[35m' -GREEN=$'\e[32m' -ORANGE=$'\e[33m' - -export PS1='\n${PINK}\u ${D}at ${ORANGE}\h ${D}in ${GREEN}\w${D}\n$ ' diff -r 71b4b4adee33 -r 5deecedda0bb servers/bin/collapse --- a/servers/bin/collapse Tue Feb 04 09:23:46 2020 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -../../bin/collapse \ No newline at end of file diff -r 71b4b4adee33 -r 5deecedda0bb servers/bin/cuts --- a/servers/bin/cuts Tue Feb 04 09:23:46 2020 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -../../bin/cuts \ No newline at end of file diff -r 71b4b4adee33 -r 5deecedda0bb servers/bin/f --- a/servers/bin/f Tue Feb 04 09:23:46 2020 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -../../bin/f \ No newline at end of file diff -r 71b4b4adee33 -r 5deecedda0bb vim/custom-dictionary.utf-8.add --- a/vim/custom-dictionary.utf-8.add Tue Feb 04 09:23:46 2020 -0500 +++ b/vim/custom-dictionary.utf-8.add Tue Feb 04 09:24:12 2020 -0500 @@ -299,3 +299,7 @@ Phosphorylation iterate's memoization +gnuplot +Illumina +Phred +FastQC diff -r 71b4b4adee33 -r 5deecedda0bb vim/vimrc --- a/vim/vimrc Tue Feb 04 09:23:46 2020 -0500 +++ b/vim/vimrc Tue Feb 04 09:24:12 2020 -0500 @@ -1405,7 +1405,7 @@ augroup ft_gnuplot au! - au BufNewFile,BufRead *.gp setlocal filetype=gnuplot + au BufNewFile,BufRead *.gp,.gnuplot setlocal filetype=gnuplot au FileType gnuplot nnoremap o :call OpenGnuplotRepl() @@ -1627,6 +1627,7 @@ au! au Filetype make setlocal shiftwidth=8 + au Filetype make setlocal foldmethod=marker foldmarker={{{,}}} augroup END " }}} @@ -1790,7 +1791,7 @@ au BufNewFile,BufRead *.sql set filetype=pgsql au BufNewFile,BufRead *.pgsql set filetype=pgsql - au FileType pgsql set foldmethod=indent + au FileType pgsql set foldmethod=marker foldmarker=\ $$,$$\ au FileType pgsql set softtabstop=2 shiftwidth=2 au FileType pgsql setlocal commentstring=--\ %s comments=:--