From a8dbb4e325e9fce15f96de8e77bdbb7c9af6e51d Mon Sep 17 00:00:00 2001 From: Austin Horstman Date: Fri, 26 Sep 2025 16:43:31 -0500 Subject: [PATCH] lib/shell: add formatShellArrayContent function for intelligent width optimization Add shared utility function that formats shell arrays with smart width optimization. Packs multiple items per line based on available width (~78 chars per line) while maintaining readability. Includes helper functions wrapLines and formatMultiLine. Signed-off-by: Austin Horstman --- modules/lib/shell.nix | 53 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/modules/lib/shell.nix b/modules/lib/shell.nix index 3ab50111e..1680e1c31 100644 --- a/modules/lib/shell.nix +++ b/modules/lib/shell.nix @@ -41,6 +41,59 @@ rec { # statement for each set entry. exportAll = vars: lib.concatStringsSep "\n" (lib.mapAttrsToList export vars); + # Wrap a list of strings to a given line width. + # Packs as many items as possible per line without exceeding maxWidth. + # Returns a list of strings, each representing a line. + # + # Example: wrapLines ["item1" "item2" "very-long-item" "item3"] 20 + # => ["item1 item2" "very-long-item" "item3"] + wrapLines = + items: maxWidth: + let + step = + acc: item: + let + potentialLine = if acc.currentLine == "" then item else "${acc.currentLine} ${item}"; + in + if lib.stringLength potentialLine <= maxWidth then + acc // { currentLine = potentialLine; } + else + acc + // { + finishedLines = acc.finishedLines ++ [ acc.currentLine ]; + currentLine = item; + }; + foldResult = lib.foldl' step { + finishedLines = [ ]; + currentLine = ""; + } items; + in + foldResult.finishedLines ++ lib.optional (foldResult.currentLine != "") foldResult.currentLine; + + # Formats a list of items for shell array content with intelligent width optimization. + # IMPORTANT: This formats the CONTENTS of an array (what goes inside parentheses), + # not a complete array definition. Use lib.hm.zsh.define for complete definitions. + # + # Uses lib.escapeShellArg for robust shell escaping (handles spaces, quotes, special chars). + # Packs multiple items per line to optimize terminal width (~78 chars per line). + # Short arrays (≤3 items, ≤80 chars total) use single-line format. + # + # Example outputs: + # Empty: "" + # Simple: item1 item2 item3 + # With spaces: 'item one' 'item two' 'item three' + # Long arrays: \n item1 item2 item3\n item4 item5\n + # + # Built from composable helpers: wrapLines, formatMultiLine + formatShellArrayContent = + items: + let + quotedItems = lib.map lib.escapeShellArg items; + formatMultiLine = lines: "\n ${lib.concatStringsSep "\n " lines}\n"; + wrapped = wrapLines quotedItems 78; + in + formatMultiLine wrapped; + mkBashIntegrationOption = mkShellIntegrationOption "Bash"; mkFishIntegrationOption = mkShellIntegrationOption "Fish"; mkIonIntegrationOption = mkShellIntegrationOption "Ion";