# HG changeset patch
# User Matthew Wild <mwild1@gmail.com>
# Date 1680789112 -3600
# Node ID 1f89a2a9f532e8a4a21e78a2f16676590607574f
# Parent  8ad432953300f028546d6a7d69e3188c42adabf6
util.human.io: Support for dynamic "proportional" columns

Instead of a percentage, this allows you to specify e.g. `width="[N]p"`, where
a width="2p" will be twice the width of a width="1p" column.

Compatibility with the old %-based widths is preserved, and percentages adding
up to more than 100 are handled more gracefully.

diff -r 8ad432953300 -r 1f89a2a9f532 util/human/io.lua
--- a/util/human/io.lua	Thu Apr 06 14:49:11 2023 +0100
+++ b/util/human/io.lua	Thu Apr 06 14:51:52 2023 +0100
@@ -124,7 +124,7 @@
 	-- Calculate width of fixed-size columns
 	for i = 1, #col_specs do
 		local width = col_specs[i].width or "0";
-		if not(type(width) == "string" and width:sub(-1) == "%") then
+		if not (type(width) == "string" and width:match("[p%%]$")) then
 			local title = col_specs[i].title;
 			width = math.max(tonumber(width), title and (#title+1) or 0);
 			widths[i] = width;
@@ -134,11 +134,21 @@
 			end
 		end
 	end
-	-- Calculate width of %-based columns
+
+	-- Calculate width of proportional columns
+	local total_proportional_width = 0;
 	for i = 1, #col_specs do
 		if not widths[i] then
-			local pc_width = tonumber((col_specs[i].width:gsub("%%$", "")));
-			widths[i] = math.floor(free_width*(pc_width/100));
+			local width_spec = col_specs[i].width:match("(%d+)[p%%]");
+			total_proportional_width = total_proportional_width + tonumber(width_spec);
+		end
+	end
+
+	for i = 1, #col_specs do
+		if not widths[i] then
+			local width_spec = col_specs[i].width:match("(%d+)[p%%]");
+			local rel_width = tonumber(width_spec);
+			widths[i] = math.floor(free_width*(rel_width/total_proportional_width));
 		end
 	end