# This script indents Lisp files # Sometimes it even results in something reasonable # Run it as: # ed file.lisp < /path/to/indent.ed # Notice that it prints the result of indentation to standard output. # If you want in-place file editing, replace the ",p" below with "w" H # Mark all the lines with end-of-line separator and join them g/$/s//|||/ ,j # Split every toplevel form on its own line. g/|||(/s//\ (/g # Remove all the prior indentation g/|||[[:space:]]*/s//|||/g # Add "more indent" to special forms # Ordered as per https://www.lispworks.com/documentation/HyperSpec/Body/03_ababa.htm g/(block/s//(^^block/g g/(\(\(\(symbol-\)\{0,1\}f\{0,1\}\(macro\)\{0,1\}\)let\**\)/s//(^^\1/g g/(if/s//(^^if/g g/(labels/s//(^^labels/g g/(multiple-value/s//(^^multiple-value/g g/(prog\(n*v*\)/s//(^^prog\1/g g/(tagbody/s//(^^tagbody/g # Derived yet frequently used macros g/(loop/s//(^^^^^^^^^^loop/g g/(when/s//(^^when/g g/(unless/s//(^^unless/g # Indent idioms g/(def/s//(^^def/g g/(do/s//(^^do/g g/(with/s//(^^with/g g/\(#.(\)/s//\1^^^^/g g/\(['`#](\)/s//\1^^/g # Add "more indent" marker to opening parens etc. g/(/s//(^^/g # Add "less indent" to closing ones g/)/s//)__/g # Eliminate the same line lists g/[\^]^\([^^_|]*\)__/s//\1/g g/[\^]^\([^^_|]*\)__/s//\1/g g/[\^]^\([^^_|]*\)__/s//\1/g g/[\^]^\([^^_|]*\)__/s//\1/g g/[\^]^\([^^_|]*\)__/s//\1/g # Now to indentation: add spaces to lines after "more indent marker" g/[\^]^\([^|]*\)|||\([^|]*\)|||\([^|]*\)|||\([^|]*\)|||\([^|]*\)|||\([^|]*\)|||\([^|]*\)|||\([^|]*\)|||\([^|]*\)/s//\1||| \2||| \3||| \4||| \5||| \6||| \7||| \8||| \9/g g/[\^]^\([^|]*\)|||\([^|]*\)|||\([^|]*\)|||\([^|]*\)|||\([^|]*\)|||\([^|]*\)|||\([^|]*\)|||\([^|]*\)|||\([^|]*\)/s//\1||| \2||| \3||| \4||| \5||| \6||| \7||| \8||| \9/g g/[\^]^\([^|]*\)|||\([^|]*\)|||\([^|]*\)|||\([^|]*\)|||\([^|]*\)|||\([^|]*\)|||\([^|]*\)|||\([^|]*\)|||\([^|]*\)/s//\1||| \2||| \3||| \4||| \5||| \6||| \7||| \8||| \9/g g/[\^]^\([^|]*\)|||\([^|]*\)|||\([^|]*\)|||\([^|]*\)|||\([^|]*\)|||\([^|]*\)|||\([^|]*\)|||\([^|]*\)/s//\1||| \2||| \3||| \4||| \5||| \6||| \7||| \8/g g/[\^]^\([^|]*\)|||\([^|]*\)|||\([^|]*\)|||\([^|]*\)|||\([^|]*\)|||\([^|]*\)|||\([^|]*\)|||\([^|]*\)/s//\1||| \2||| \3||| \4||| \5||| \6||| \7||| \8/g g/[\^]^\([^|]*\)|||\([^|]*\)|||\([^|]*\)|||\([^|]*\)|||\([^|]*\)|||\([^|]*\)|||\([^|]*\)|||\([^|]*\)/s//\1||| \2||| \3||| \4||| \5||| \6||| \7||| \8/g g/[\^]^\([^|]*\)|||\([^|]*\)|||\([^|]*\)|||\([^|]*\)|||\([^|]*\)|||\([^|]*\)|||\([^|]*\)/s//\1||| \2||| \3||| \4||| \5||| \6||| \7/g g/[\^]^\([^|]*\)|||\([^|]*\)|||\([^|]*\)|||\([^|]*\)|||\([^|]*\)|||\([^|]*\)|||\([^|]*\)/s//\1||| \2||| \3||| \4||| \5||| \6||| \7/g g/[\^]^\([^|]*\)|||\([^|]*\)|||\([^|]*\)|||\([^|]*\)|||\([^|]*\)|||\([^|]*\)|||\([^|]*\)/s//\1||| \2||| \3||| \4||| \5||| \6||| \7/g g/[\^]^\([^|]*\)|||\([^|]*\)|||\([^|]*\)|||\([^|]*\)|||\([^|]*\)|||\([^|]*\)/s//\1||| \2||| \3||| \4||| \5||| \6/g g/[\^]^\([^|]*\)|||\([^|]*\)|||\([^|]*\)|||\([^|]*\)|||\([^|]*\)|||\([^|]*\)/s//\1||| \2||| \3||| \4||| \5||| \6/g g/[\^]^\([^|]*\)|||\([^|]*\)|||\([^|]*\)|||\([^|]*\)|||\([^|]*\)|||\([^|]*\)/s//\1||| \2||| \3||| \4||| \5||| \6/g g/[\^]^\([^|]*\)|||\([^|]*\)|||\([^|]*\)|||\([^|]*\)|||\([^|]*\)/s//\1||| \2||| \3||| \4||| \5/g g/[\^]^\([^|]*\)|||\([^|]*\)|||\([^|]*\)|||\([^|]*\)|||\([^|]*\)/s//\1||| \2||| \3||| \4||| \5/g g/[\^]^\([^|]*\)|||\([^|]*\)|||\([^|]*\)|||\([^|]*\)|||\([^|]*\)/s//\1||| \2||| \3||| \4||| \5/g g/[\^]^\([^|]*\)|||\([^|]*\)|||\([^|]*\)|||\([^|]*\)/s//\1||| \2||| \3||| \4/g g/[\^]^\([^|]*\)|||\([^|]*\)|||\([^|]*\)|||\([^|]*\)/s//\1||| \2||| \3||| \4/g g/[\^]^\([^|]*\)|||\([^|]*\)|||\([^|]*\)|||\([^|]*\)/s//\1||| \2||| \3||| \4/g g/[\^]^\([^|]*\)|||\([^|]*\)|||\([^|]*\)/s//\1||| \2||| \3/g g/[\^]^\([^|]*\)|||\([^|]*\)|||\([^|]*\)/s//\1||| \2||| \3/g g/[\^]^\([^|]*\)|||\([^|]*\)|||\([^|]*\)/s//\1||| \2||| \3/g g/[\^]^\([^|]*\)|||\([^|]*\)/s//\1||| \2/g g/[\^]^\([^|]*\)|||\([^|]*\)/s//\1||| \2/g g/[\^]^\([^|]*\)|||\([^|]*\)/s//\1||| \2/g g/[\^]^\([^|]*\)/s//\1/g g/[\^]^\([^|]*\)/s//\1/g g/[\^]^\([^|]*\)/s//\1/g # Remove indentation for lines after "less indentation" marker g/__\([^|]*\)||| \([^|]*\)||| \([^|]*\)||| \([^|]*\)||| \([^|]*\)||| \([^|]*\)||| \([^|]*\)||| \([^|]*\)||| \([^|]*\)/s//\1|||\2|||\3|||\4|||\5|||\6|||\7|||\8|||\9/g g/__\([^|]*\)||| \([^|]*\)||| \([^|]*\)||| \([^|]*\)||| \([^|]*\)||| \([^|]*\)||| \([^|]*\)||| \([^|]*\)||| \([^|]*\)/s//\1|||\2|||\3|||\4|||\5|||\6|||\7|||\8|||\9/g g/__\([^|]*\)||| \([^|]*\)||| \([^|]*\)||| \([^|]*\)||| \([^|]*\)||| \([^|]*\)||| \([^|]*\)||| \([^|]*\)||| \([^|]*\)/s//\1|||\2|||\3|||\4|||\5|||\6|||\7|||\8|||\9/g g/__\([^|]*\)||| \([^|]*\)||| \([^|]*\)||| \([^|]*\)||| \([^|]*\)||| \([^|]*\)||| \([^|]*\)||| \([^|]*\)/s//\1|||\2|||\3|||\4|||\5|||\6|||\7|||\8/g g/__\([^|]*\)||| \([^|]*\)||| \([^|]*\)||| \([^|]*\)||| \([^|]*\)||| \([^|]*\)||| \([^|]*\)||| \([^|]*\)/s//\1|||\2|||\3|||\4|||\5|||\6|||\7|||\8/g g/__\([^|]*\)||| \([^|]*\)||| \([^|]*\)||| \([^|]*\)||| \([^|]*\)||| \([^|]*\)||| \([^|]*\)||| \([^|]*\)/s//\1|||\2|||\3|||\4|||\5|||\6|||\7|||\8/g g/__\([^|]*\)||| \([^|]*\)||| \([^|]*\)||| \([^|]*\)||| \([^|]*\)||| \([^|]*\)||| \([^|]*\)/s//\1|||\2|||\3|||\4|||\5|||\6|||\7/g g/__\([^|]*\)||| \([^|]*\)||| \([^|]*\)||| \([^|]*\)||| \([^|]*\)||| \([^|]*\)||| \([^|]*\)/s//\1|||\2|||\3|||\4|||\5|||\6|||\7/g g/__\([^|]*\)||| \([^|]*\)||| \([^|]*\)||| \([^|]*\)||| \([^|]*\)||| \([^|]*\)||| \([^|]*\)/s//\1|||\2|||\3|||\4|||\5|||\6|||\7/g g/__\([^|]*\)||| \([^|]*\)||| \([^|]*\)||| \([^|]*\)||| \([^|]*\)||| \([^|]*\)/s//\1|||\2|||\3|||\4|||\5|||\6/g g/__\([^|]*\)||| \([^|]*\)||| \([^|]*\)||| \([^|]*\)||| \([^|]*\)||| \([^|]*\)/s//\1|||\2|||\3|||\4|||\5|||\6/g g/__\([^|]*\)||| \([^|]*\)||| \([^|]*\)||| \([^|]*\)||| \([^|]*\)||| \([^|]*\)/s//\1|||\2|||\3|||\4|||\5|||\6/g g/__\([^|]*\)||| \([^|]*\)||| \([^|]*\)||| \([^|]*\)||| \([^|]*\)/s//\1|||\2|||\3|||\4|||\5/g g/__\([^|]*\)||| \([^|]*\)||| \([^|]*\)||| \([^|]*\)||| \([^|]*\)/s//\1|||\2|||\3|||\4|||\5/g g/__\([^|]*\)||| \([^|]*\)||| \([^|]*\)||| \([^|]*\)||| \([^|]*\)/s//\1|||\2|||\3|||\4|||\5/g g/__\([^|]*\)||| \([^|]*\)||| \([^|]*\)||| \([^|]*\)/s//\1|||\2|||\3|||\4/g g/__\([^|]*\)||| \([^|]*\)||| \([^|]*\)||| \([^|]*\)/s//\1|||\2|||\3|||\4/g g/__\([^|]*\)||| \([^|]*\)||| \([^|]*\)||| \([^|]*\)/s//\1|||\2|||\3|||\4/g g/__\([^|]*\)||| \([^|]*\)||| \([^|]*\)/s//\1|||\2|||\3/g g/__\([^|]*\)||| \([^|]*\)||| \([^|]*\)/s//\1|||\2|||\3/g g/__\([^|]*\)||| \([^|]*\)||| \([^|]*\)/s//\1|||\2|||\3/g g/__\([^|]*\)||| \([^|]*\)/s//\1|||\2/g g/__\([^|]*\)||| \([^|]*\)/s//\1|||\2/g g/__\([^|]*\)||| \([^|]*\)/s//\1|||\2/g g/__\([^|]*\)/s//\1/g g/__\([^|]*\)/s//\1/g g/__\([^|]*\)/s//\1/g # Remove remaining underscores g/__/s///g # Split lines again g/|||/s//\ /g # Fix indented comments g/^[[:space:]]\{1,\};/s//;/ ,p Q