--- a/bash_profile Wed Oct 22 15:48:44 2025 -0400
+++ b/bash_profile Mon Nov 03 14:55:17 2025 -0500
@@ -55,6 +55,8 @@
alias .....="cd ../../../.."
alias ......="cd ../../../../.."
+alias -- -="cd -"
+
function mcd {
mkdir "$1" && cd "$1"
}
--- a/bin/sb Wed Oct 22 15:48:44 2025 -0400
+++ b/bin/sb Mon Nov 03 14:55:17 2025 -0500
@@ -2,4 +2,4 @@
set -e
-sbcl --eval '(ql:quickload :losh :silent t)' --eval '(in-package :losh-user)' "$@"
+sbcl --eval '(ql:quickload '"'"'(:losh :str) :silent t)' --eval '(in-package :losh-user)' "$@"
--- a/fish/config.fish Wed Oct 22 15:48:44 2025 -0400
+++ b/fish/config.fish Mon Nov 03 14:55:17 2025 -0500
@@ -21,6 +21,7 @@
function histgrep; history | grep "$argv" | tac; end
+abbr -a - cd -
function ..; cd ..; end
function ...; cd ../..; end
function ....; cd ../../..; end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/lisp/combos.lisp Mon Nov 03 14:55:17 2025 -0500
@@ -0,0 +1,218 @@
+(eval-when (:compile-toplevel :load-toplevel :execute)
+ (ql:quickload '(:adopt :str :alexandria) :silent t))
+
+(defpackage :combos
+ (:use :cl)
+ (:export :toplevel :*ui*))
+
+(in-package :combos)
+
+
+;;;; Configuration ------------------------------------------------------------
+(defparameter *n* 2)
+(defparameter *trim* t)
+(defparameter *mode* nil)
+(defparameter *output-sep-field* " ")
+(defparameter *output-sep-record* (string #\newline))
+(defparameter *input-sep* (string #\newline))
+
+(defvar *first* t)
+
+;;;; Functionality ------------------------------------------------------------
+(defun print-record (fields)
+ (if *first*
+ (setf *first* nil)
+ (write-string *output-sep-record*))
+ (write-string (str:join *output-sep-field* fields)))
+
+(defun print-record% (&rest fields)
+ (print-record fields))
+
+(defun run/permutations (lines) (alexandria:map-permutations #'print-record lines :length *n*))
+(defun run/combinations (lines) (alexandria:map-combinations #'print-record lines :length *n*))
+(defun run/derangements (lines) (alexandria:map-derangements #'print-record lines))
+(defun run/product (lines)
+ (apply #'alexandria:map-product #'print-record% (loop :repeat *n* :collect lines)))
+
+(defun run ()
+ (let* ((input (alexandria:read-stream-content-into-string *standard-input*))
+ (lines (str:split *input-sep* input :omit-nulls t)))
+ (when *trim*
+ (setf lines (mapcar #'str:trim lines)))
+ (setf *first* t)
+ (funcall (ecase *mode*
+ (:permutations #'run/permutations)
+ (:combinations #'run/combinations)
+ (:derangements #'run/derangements)
+ (:product #'run/product))
+ lines)))
+
+
+;;;; 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/n*
+ (adopt:make-option 'n
+ :help "Size of permutations/combinations/derangements (default 2)."
+ :parameter "N"
+ :long "length"
+ :short #\n
+ :reduce #'adopt:last
+ :initial-value 2
+ :key #'parse-integer))
+
+(defparameter *option/mode/permutations*
+ (adopt:make-option 'mode
+ :help "Output permutations of the input lines."
+ :long "permutations"
+ :short #\P
+ :reduce (constantly :permutations)))
+
+(defparameter *option/mode/combinations*
+ (adopt:make-option 'mode
+ :help "Output combinations of the input lines."
+ :long "combinations"
+ :short #\C
+ :reduce (constantly :combinations)))
+
+(defparameter *option/mode/derangements*
+ (adopt:make-option 'mode
+ :help "Output derangements of the input lines (ignores -n)."
+ :long "derangements"
+ :short #\D
+ :reduce (constantly :derangements)))
+
+(defparameter *option/mode/product*
+ (adopt:make-option 'mode
+ :help "Output cartesian product of the input lines."
+ :long "cartesian-product"
+ :short #\X
+ :reduce (constantly :product)))
+
+(defparameter *option/input-sep*
+ (adopt:make-option 'input-sep
+ :help "Input separator (default newline)."
+ :parameter "SEP"
+ :long "input-separator"
+ :short #\i
+ :reduce #'adopt:last
+ :initial-value (string #\newline)))
+
+(defparameter *option/input-sep-nul*
+ (adopt:make-option 'input-sep-nul
+ :result-key 'input-sep
+ :help "Use NUL byte as input separator."
+ :long "input-separator-0"
+ :reduce (constantly (string #\nul))))
+
+(defparameter *option/output-sep/field*
+ (adopt:make-option 'output-sep/field
+ :help "Output field separator (default \" \")."
+ :parameter "SEP"
+ :long "output-field-separator"
+ :short #\f
+ :reduce #'adopt:last
+ :initial-value " "))
+
+(defparameter *option/output-sep/field-nul*
+ (adopt:make-option 'output-sep/field-nul
+ :result-key 'output-sep/field
+ :help "Use NUL byte as field separator."
+ :long "output-field-separator-0"
+ :reduce (constantly (string #\nul))))
+
+(defparameter *option/output-sep/record*
+ (adopt:make-option 'output-sep/record
+ :help "Output record separator (default newline)."
+ :parameter "SEP"
+ :long "output-record-separator"
+ :short #\r
+ :reduce #'adopt:last
+ :initial-value (string #\newline)))
+
+(defparameter *option/output-sep/record-nul*
+ (adopt:make-option 'output-sep/record-nul
+ :result-key 'output-sep/record
+ :help "Use NUL byte as record separator."
+ :long "output-record-separator-0"
+ :reduce (constantly (string #\nul))))
+
+(adopt:defparameters (*option/trim* *option/no-trim*)
+ (adopt:make-boolean-options 'trim
+ :short #\t
+ :long "trim"
+ :help "Trim whitespace from input (the default)."
+ :help-no "Do not trim whitespace from input."
+ :initial-value t))
+
+
+(adopt:define-string *help-text*
+ "combos takes entries from standard input, combines them (as permutations, ~
+ combinations, derangements, or the cartesian product) and outputs the ~
+ resulting combos to standard output.")
+
+(defparameter *examples*
+ '(("Print 2-length permutations of 1..4:"
+ . "seq 4 | combos --permutations -n 2")
+ ("Print comma-separated 3-length combinations of 1..5:"
+ . "seq 5 | combos --combinations -n 3 -f ,")
+ ("Print every possible pairing of NUL delimited input:"
+ . "find . -name '*.lisp' -print0 | combos --cartesian-product --input-separator-0 -n 2")))
+
+(defparameter *ui*
+ (adopt:make-interface
+ :name "combos"
+ :usage "MODE [OPTIONS]"
+ :summary "combine and output lines of input"
+ :help *help-text*
+ :examples *examples*
+ :contents (list
+ *option/help*
+ *option/version*
+ (adopt:make-group 'input-options
+ :title "Input Options"
+ :options (list *option/input-sep*
+ *option/input-sep-nul*
+ *option/trim*
+ *option/no-trim*))
+ (adopt:make-group 'output-options
+ :title "Output Options"
+ :options (list *option/mode/permutations*
+ *option/mode/combinations*
+ *option/mode/derangements*
+ *option/mode/product*
+ *option/n*
+ *option/output-sep/field*
+ *option/output-sep/field-nul*
+ *option/output-sep/record*
+ *option/output-sep/record-nul*)))))
+
+
+(defun toplevel ()
+ (adopt::quit-on-ctrl-c ()
+ (multiple-value-bind (arguments options) (adopt:parse-options-or-exit *ui*)
+ (when (gethash 'help options)
+ (adopt:print-help-and-exit *ui*))
+ (let ((*mode* (gethash 'mode options))
+ (*n* (gethash 'n options))
+ (*output-sep-field* (gethash 'output-sep/field options))
+ (*output-sep-record* (gethash 'output-sep/record options))
+ (*input-sep* (gethash 'input-sep options))
+ (*trim* (gethash 'trim options)))
+ (handler-case
+ (progn
+ (assert (null arguments) () "No arguments accepted.")
+ (run))
+ (error (e)
+ (adopt:print-error-and-exit e)))))))
--- a/remote/bash_profile Wed Oct 22 15:48:44 2025 -0400
+++ b/remote/bash_profile Mon Nov 03 14:55:17 2025 -0500
@@ -66,6 +66,8 @@
alias .....="cd ../../../.."
alias ......="cd ../../../../.."
+alias -- -="cd -"
+
alias :q=exit
alias :qa=exit
alias :wqa=exit
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/remote/bin/chars-to-phred Mon Nov 03 14:55:17 2025 -0500
@@ -0,0 +1,1 @@
+../../bin/chars-to-phred
\ No newline at end of file
--- a/remote/bin/collapse Wed Oct 22 15:48:44 2025 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-../../bin/collapse
\ No newline at end of file
--- a/remote/bin/cvs Wed Oct 22 15:48:44 2025 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-../../bin/cvs
\ No newline at end of file
--- a/remote/bin/hank Wed Oct 22 15:48:44 2025 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-../../bin/hank
\ No newline at end of file
--- a/remote/bin/nicedate Wed Oct 22 15:48:44 2025 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-../../bin/nicedate
\ No newline at end of file
--- a/remote/bin/run-igv Wed Oct 22 15:48:44 2025 -0400
+++ b/remote/bin/run-igv Mon Nov 03 14:55:17 2025 -0500
@@ -2,4 +2,4 @@
set -euo pipefail
-~/src/igv/build/IGV-dist/igv.sh
+XDG_RUNTIME_DIR='' ~/src/igv/build/IGV-dist/igv.sh
--- a/remote/bin/trst Wed Oct 22 15:48:44 2025 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-../../bin/trst
\ No newline at end of file
--- a/remote/bin/tvs Wed Oct 22 15:48:44 2025 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-../../bin/tvs
\ No newline at end of file
--- a/remote/bin/u Wed Oct 22 15:48:44 2025 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-../../bin/u
\ No newline at end of file
--- a/stumpwm/applications.lisp Wed Oct 22 15:48:44 2025 -0400
+++ b/stumpwm/applications.lisp Mon Nov 03 14:55:17 2025 -0500
@@ -55,6 +55,16 @@
(gather (process-info child)))))))
+(defcommand vsplit-terminal-here () ()
+ (let ((cwd (dwim-cwd)))
+ (sane-vsplit)
+ (terminal-in cwd)))
+
+(defcommand hsplit-terminal-here () ()
+ (let ((cwd (dwim-cwd)))
+ (sane-hsplit)
+ (terminal-in cwd)))
+
(defcommand terminal-here () ()
(terminal-in (dwim-cwd)))
--- a/stumpwm/external-screens.lisp Wed Oct 22 15:48:44 2025 -0400
+++ b/stumpwm/external-screens.lisp Mon Nov 03 14:55:17 2025 -0500
@@ -24,7 +24,7 @@
:do (uiop:run-program `("xrandr" "--output" ,output ,@commands))))
(t (message "Not configured on this system."))))
-(defcommand screen-alan () ()
+(defcommand screen-alan-single () ()
(hostcase
((:juss) (loop :with laptop = "eDP"
:with extern = "DisplayPort-0"
@@ -33,3 +33,12 @@
:do (uiop:run-program `("xrandr" "--output" ,output ,@commands))))
(t (message "Not configured on this system."))))
+(defcommand screen-alan-two () ()
+ (hostcase
+ ((:juss) (loop :with laptop = "eDP"
+ :with extern = "DisplayPort-0"
+ :for (output commands) :in `((,laptop ("--auto"))
+ (,extern ("--mode" "1920x1080" "--right-of" "eDP")))
+ :do (uiop:run-program `("xrandr" "--output" ,output ,@commands))))
+ (t (message "Not configured on this system."))))
+
--- a/stumpwm/key-mapping.lisp Wed Oct 22 15:48:44 2025 -0400
+++ b/stumpwm/key-mapping.lisp Mon Nov 03 14:55:17 2025 -0500
@@ -48,7 +48,6 @@
("H-y" "screenshot")
("H-Y" "delayed-screenshot")
("H-r" "rain")
- ("H-V" "vlc")
("H-e" "budget")
("H-E" "spend")
("S-XF86AudioMute" "terminal-font-size-show")
@@ -119,11 +118,13 @@
("H-," "pull-from-windowlist")
("H-." "ggo")
- ("H-SPC" "ggo"))
+ ("H-SPC" "gother"))
(define-top-keys ;; splitting
("H-s" "sane-vsplit")
+ ("H-S" "vsplit-terminal-here")
("H-v" "sane-hsplit")
+ ("H-V" "hsplit-terminal-here")
("H-=" "balance-frames"))
(define-top-keys ;; killing