Skip to content

Instantly share code, notes, and snippets.

@JSuder-xx
Last active February 13, 2026 03:00
Show Gist options
  • Select an option

  • Save JSuder-xx/b866fbee1b0cc5ecbf10e84388132060 to your computer and use it in GitHub Desktop.

Select an option

Save JSuder-xx/b866fbee1b0cc5ecbf10e84388132060 to your computer and use it in GitHub Desktop.
ElmCondense Sketch
// This script takes Elm code that has been formatted with Elm-Format on stdin and console logs it out condensed.
// Modifications
// - Linefeed removal
// - THREE lines before comments collapsed to ONE.
// - TWO lines between top-level declarations collapsed to ONE.
// - ONE line after case variant expressions and one line after if/then/else REMOVED.
// - Single line comments move the closing -} up so that the comment fits on one line.
// - CONTENTIOUS: Top level declarations where the declaration and body fit in 60 characters or less represented as ONE line.
// - CONTENTIOUS: Replaces 4 spaces with 2.
//
// One could wire this up in VS Code by
// 1. Turning off Elm-Format
// 2. Using a custom script runner that
// a. First manually runs Elm-Format for a file on save.
// b. And then pipes it through this utility and writes it back out.
(async () => {
let data = "";
for await (const chunk of process.stdin) {
data += chunk;
}
console.log(condense(data));
})();
// @ts-check
/** @type {(selection: string) => string} */
function condense(selection) {
const input = selection.split("\n");
/** @type {string[]} */
const output = []
let inputLineIdx = 0;
// seek past the module header and imports
while (notAtEnd()
&& (
startsWith("module ") ||
startsWith("import ") ||
isEmpty(0) ||
startsComment() ||
startsIndented(0)
)) {
if (startsComment())
fitSingleLineCommentsOnOneLine();
else
eatLine();
}
// process module body
while (notAtEnd()) {
// Collapse the THREE lines before a standalone comment to ONE.
if (isEmpty(0) && isEmpty(1) && isEmpty(2)) {
emitEmptyLine();
skipLines(2);
}
// Collapse the TWO lines between top-level bindings to ONE.
else if (isEmpty(0) && isEmpty(1)) {
emitEmptyLine();
skipLines(1);
}
// Remove linefeed between case variants and let bindings
else if (isEmpty(0)) {
skipLines(1);
}
else if (startsComment()) {
fitSingleLineCommentsOnOneLine();
}
// Represent top level declaration that could fit in less than 60 characters as a single line rather than a declaration line and a body line.
else if (
!startsIndented(0) // declaration
&& startsIndented(1) // body
&& isEmpty(2) // line feed after body means single line body
&& (relative(0).length + relative(1).length) <= 60 // declaration + body is less than 60 characters
) {
output.push(relative(0) + " " + relative(1).trim());
skipLines(2);
}
else
eatLine();
}
return output.join("\n");
// WHERE-CLAUSE
/** @type {(skipCount: number) => void} */
function skipLines(n) {
inputLineIdx += n;
}
function notAtEnd() {
return inputLineIdx < input.length;
}
function eatLine() {
output.push(relative(0).replace(/ /g, ' '));
inputLineIdx++
}
/** @type {(relativeIdx: number) => boolean} */
function startsIndented(relativeLineIndex) {
const lineText = relative(relativeLineIndex);
return lineText.length > 0 && lineText[0] === " ";
}
function emitEmptyLine() {
output.push("")
inputLineIdx++;
}
function fitSingleLineCommentsOnOneLine() {
if (!startsComment()) throw new Error("Expecting start of comment");
// Single line comment is two lines in Elm format.
if (relative(1).startsWith("-}")) {
output.push(`${relative(0)} -}`);
inputLineIdx += 2;
} else {
// multiline comment - leave this alone
eatLine();
while (relative(0).trim() !== "-}") eatLine();
}
}
/** @type {(relativeIdx: number) => string} */
function relative(relativeIdx) {
return input[inputLineIdx + relativeIdx] || ""
}
/** @type {(relativeIdx: number) => boolean} */
function isEmpty(relativeIdx) {
return relative(relativeIdx) === ""
}
/** @type {(prefix: string) => boolean} */
function startsWith(s) {
return relative(0).startsWith(s)
}
function startsComment() {
return startsWith("{-|")
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment