util/human/io.lua
author Matthew Wild <mwild1@gmail.com>
Tue, 11 Oct 2022 11:37:55 +0100
changeset 12767 d26eefe98d09
parent 12577 0f4feaf9ca64
child 12787 d513e4bd4928
permissions -rw-r--r--
util.dbuffer: Add efficient shortcuts for discard() in certain cases If the buffer is already empty, nothing to do. If we're throwing away the whole buffer, we can just empty it and avoid read_chunk() (which in turn may collapse()). These shortcuts are much more efficient.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
10898
d15a4284fdf8 util.human.io: table: Return title row when no row data passed
Matthew Wild <mwild1@gmail.com>
parents: 10897
diff changeset
     1
local array = require "util.array";
11900
93e9f7ae2f9b util.human.io: Fix cutting of UTF-8 into pieces
Kim Alvefur <zash@zash.se>
parents: 11899
diff changeset
     2
local utf8 = rawget(_G, "utf8") or require"util.encodings".utf8;
93e9f7ae2f9b util.human.io: Fix cutting of UTF-8 into pieces
Kim Alvefur <zash@zash.se>
parents: 11899
diff changeset
     3
local len = utf8.len or function(s)
93e9f7ae2f9b util.human.io: Fix cutting of UTF-8 into pieces
Kim Alvefur <zash@zash.se>
parents: 11899
diff changeset
     4
	local _, count = s:gsub("[%z\001-\127\194-\253][\128-\191]*", "");
93e9f7ae2f9b util.human.io: Fix cutting of UTF-8 into pieces
Kim Alvefur <zash@zash.se>
parents: 11899
diff changeset
     5
	return count;
93e9f7ae2f9b util.human.io: Fix cutting of UTF-8 into pieces
Kim Alvefur <zash@zash.se>
parents: 11899
diff changeset
     6
end;
10898
d15a4284fdf8 util.human.io: table: Return title row when no row data passed
Matthew Wild <mwild1@gmail.com>
parents: 10897
diff changeset
     7
10874
3f1889608f3e util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     8
local function getchar(n)
3f1889608f3e util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     9
	local stty_ret = os.execute("stty raw -echo 2>/dev/null");
3f1889608f3e util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    10
	local ok, char;
3f1889608f3e util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    11
	if stty_ret == true or stty_ret == 0 then
3f1889608f3e util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    12
		ok, char = pcall(io.read, n or 1);
3f1889608f3e util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    13
		os.execute("stty sane");
3f1889608f3e util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    14
	else
3f1889608f3e util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    15
		ok, char = pcall(io.read, "*l");
3f1889608f3e util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    16
		if ok then
3f1889608f3e util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    17
			char = char:sub(1, n or 1);
3f1889608f3e util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    18
		end
3f1889608f3e util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    19
	end
3f1889608f3e util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    20
	if ok then
3f1889608f3e util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    21
		return char;
3f1889608f3e util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    22
	end
3f1889608f3e util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    23
end
3f1889608f3e util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    24
3f1889608f3e util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    25
local function getline()
3f1889608f3e util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    26
	local ok, line = pcall(io.read, "*l");
3f1889608f3e util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    27
	if ok then
3f1889608f3e util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    28
		return line;
3f1889608f3e util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    29
	end
3f1889608f3e util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    30
end
3f1889608f3e util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    31
3f1889608f3e util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    32
local function getpass()
12577
0f4feaf9ca64 util: Remove various Lua 5.1 compatibility hacks
Kim Alvefur <zash@zash.se>
parents: 11901
diff changeset
    33
	local stty_ret = os.execute("stty -echo 2>/dev/null");
10874
3f1889608f3e util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    34
	if stty_ret ~= 0 then
3f1889608f3e util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    35
		io.write("\027[08m"); -- ANSI 'hidden' text attribute
3f1889608f3e util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    36
	end
3f1889608f3e util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    37
	local ok, pass = pcall(io.read, "*l");
3f1889608f3e util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    38
	if stty_ret == 0 then
3f1889608f3e util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    39
		os.execute("stty sane");
3f1889608f3e util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    40
	else
3f1889608f3e util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    41
		io.write("\027[00m");
3f1889608f3e util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    42
	end
3f1889608f3e util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    43
	io.write("\n");
3f1889608f3e util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    44
	if ok then
3f1889608f3e util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    45
		return pass;
3f1889608f3e util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    46
	end
3f1889608f3e util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    47
end
3f1889608f3e util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    48
3f1889608f3e util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    49
local function show_yesno(prompt)
3f1889608f3e util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    50
	io.write(prompt, " ");
3f1889608f3e util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    51
	local choice = getchar():lower();
3f1889608f3e util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    52
	io.write("\n");
3f1889608f3e util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    53
	if not choice:match("%a") then
3f1889608f3e util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    54
		choice = prompt:match("%[.-(%U).-%]$");
3f1889608f3e util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    55
		if not choice then return nil; end
3f1889608f3e util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    56
	end
3f1889608f3e util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    57
	return (choice == "y");
3f1889608f3e util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    58
end
3f1889608f3e util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    59
3f1889608f3e util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    60
local function read_password()
3f1889608f3e util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    61
	local password;
3f1889608f3e util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    62
	while true do
3f1889608f3e util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    63
		io.write("Enter new password: ");
3f1889608f3e util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    64
		password = getpass();
3f1889608f3e util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    65
		if not password then
3f1889608f3e util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    66
			print("No password - cancelled");
3f1889608f3e util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    67
			return;
3f1889608f3e util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    68
		end
3f1889608f3e util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    69
		io.write("Retype new password: ");
3f1889608f3e util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    70
		if getpass() ~= password then
3f1889608f3e util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    71
			if not show_yesno [=[Passwords did not match, try again? [Y/n]]=] then
3f1889608f3e util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    72
				return;
3f1889608f3e util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    73
			end
3f1889608f3e util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    74
		else
3f1889608f3e util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    75
			break;
3f1889608f3e util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    76
		end
3f1889608f3e util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    77
	end
3f1889608f3e util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    78
	return password;
3f1889608f3e util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    79
end
3f1889608f3e util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    80
3f1889608f3e util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    81
local function show_prompt(prompt)
3f1889608f3e util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    82
	io.write(prompt, " ");
3f1889608f3e util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    83
	local line = getline();
3f1889608f3e util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    84
	line = line and line:gsub("\n$","");
3f1889608f3e util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    85
	return (line and #line > 0) and line or nil;
3f1889608f3e util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    86
end
3f1889608f3e util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    87
3f1889608f3e util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    88
local function printf(fmt, ...)
10876
a3f3f42736f2 util.human.io: Fix variable name [luacheck]
Matthew Wild <mwild1@gmail.com>
parents: 10874
diff changeset
    89
	print(fmt:format(...));
10874
3f1889608f3e util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    90
end
3f1889608f3e util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    91
10895
8d47858805c9 util.human.io: Add padleft, padright and a table printing function
Matthew Wild <mwild1@gmail.com>
parents: 10876
diff changeset
    92
local function padright(s, width)
11901
e84ea5b58b29 util.human.io: Use UTF-8-aware length check in padding functions
Kim Alvefur <zash@zash.se>
parents: 11900
diff changeset
    93
	return s..string.rep(" ", width-len(s));
10895
8d47858805c9 util.human.io: Add padleft, padright and a table printing function
Matthew Wild <mwild1@gmail.com>
parents: 10876
diff changeset
    94
end
8d47858805c9 util.human.io: Add padleft, padright and a table printing function
Matthew Wild <mwild1@gmail.com>
parents: 10876
diff changeset
    95
8d47858805c9 util.human.io: Add padleft, padright and a table printing function
Matthew Wild <mwild1@gmail.com>
parents: 10876
diff changeset
    96
local function padleft(s, width)
11901
e84ea5b58b29 util.human.io: Use UTF-8-aware length check in padding functions
Kim Alvefur <zash@zash.se>
parents: 11900
diff changeset
    97
	return string.rep(" ", width-len(s))..s;
10895
8d47858805c9 util.human.io: Add padleft, padright and a table printing function
Matthew Wild <mwild1@gmail.com>
parents: 10876
diff changeset
    98
end
8d47858805c9 util.human.io: Add padleft, padright and a table printing function
Matthew Wild <mwild1@gmail.com>
parents: 10876
diff changeset
    99
11900
93e9f7ae2f9b util.human.io: Fix cutting of UTF-8 into pieces
Kim Alvefur <zash@zash.se>
parents: 11899
diff changeset
   100
local pat = "[%z\001-\127\194-\253][\128-\191]*";
93e9f7ae2f9b util.human.io: Fix cutting of UTF-8 into pieces
Kim Alvefur <zash@zash.se>
parents: 11899
diff changeset
   101
local function utf8_cut(s, pos)
93e9f7ae2f9b util.human.io: Fix cutting of UTF-8 into pieces
Kim Alvefur <zash@zash.se>
parents: 11899
diff changeset
   102
	return s:match("^"..pat:rep(pos)) or s;
93e9f7ae2f9b util.human.io: Fix cutting of UTF-8 into pieces
Kim Alvefur <zash@zash.se>
parents: 11899
diff changeset
   103
end
93e9f7ae2f9b util.human.io: Fix cutting of UTF-8 into pieces
Kim Alvefur <zash@zash.se>
parents: 11899
diff changeset
   104
93e9f7ae2f9b util.human.io: Fix cutting of UTF-8 into pieces
Kim Alvefur <zash@zash.se>
parents: 11899
diff changeset
   105
if utf8.len and utf8.offset then
93e9f7ae2f9b util.human.io: Fix cutting of UTF-8 into pieces
Kim Alvefur <zash@zash.se>
parents: 11899
diff changeset
   106
	function utf8_cut(s, pos)
93e9f7ae2f9b util.human.io: Fix cutting of UTF-8 into pieces
Kim Alvefur <zash@zash.se>
parents: 11899
diff changeset
   107
		return s:sub(1, utf8.offset(s, pos+1)-1);
93e9f7ae2f9b util.human.io: Fix cutting of UTF-8 into pieces
Kim Alvefur <zash@zash.se>
parents: 11899
diff changeset
   108
	end
93e9f7ae2f9b util.human.io: Fix cutting of UTF-8 into pieces
Kim Alvefur <zash@zash.se>
parents: 11899
diff changeset
   109
end
93e9f7ae2f9b util.human.io: Fix cutting of UTF-8 into pieces
Kim Alvefur <zash@zash.se>
parents: 11899
diff changeset
   110
11898
57106c61d104 util.human.io: Factor out ellipsis function
Kim Alvefur <zash@zash.se>
parents: 11897
diff changeset
   111
local function ellipsis(s, width)
11900
93e9f7ae2f9b util.human.io: Fix cutting of UTF-8 into pieces
Kim Alvefur <zash@zash.se>
parents: 11899
diff changeset
   112
	if len(s) <= width then return s; end
93e9f7ae2f9b util.human.io: Fix cutting of UTF-8 into pieces
Kim Alvefur <zash@zash.se>
parents: 11899
diff changeset
   113
	if width == 1 then return "…"; end
93e9f7ae2f9b util.human.io: Fix cutting of UTF-8 into pieces
Kim Alvefur <zash@zash.se>
parents: 11899
diff changeset
   114
	return utf8_cut(s, width - 1) .. "…";
11898
57106c61d104 util.human.io: Factor out ellipsis function
Kim Alvefur <zash@zash.se>
parents: 11897
diff changeset
   115
end
57106c61d104 util.human.io: Factor out ellipsis function
Kim Alvefur <zash@zash.se>
parents: 11897
diff changeset
   116
10908
d009a79f723a util.human.io: Remove padding option and use $COLUMNS as default width
Matthew Wild <mwild1@gmail.com>
parents: 10900
diff changeset
   117
local function new_table(col_specs, max_width)
d009a79f723a util.human.io: Remove padding option and use $COLUMNS as default width
Matthew Wild <mwild1@gmail.com>
parents: 10900
diff changeset
   118
	max_width = max_width or tonumber(os.getenv("COLUMNS")) or 80;
10911
6af28c756752 util.human.io: Draw a separator between columns
Kim Alvefur <zash@zash.se>
parents: 10908
diff changeset
   119
	local separator = " | ";
10895
8d47858805c9 util.human.io: Add padleft, padright and a table printing function
Matthew Wild <mwild1@gmail.com>
parents: 10876
diff changeset
   120
8d47858805c9 util.human.io: Add padleft, padright and a table printing function
Matthew Wild <mwild1@gmail.com>
parents: 10876
diff changeset
   121
	local widths = {};
10911
6af28c756752 util.human.io: Draw a separator between columns
Kim Alvefur <zash@zash.se>
parents: 10908
diff changeset
   122
	local total_width = max_width - #separator * (#col_specs-1);
10895
8d47858805c9 util.human.io: Add padleft, padright and a table printing function
Matthew Wild <mwild1@gmail.com>
parents: 10876
diff changeset
   123
	local free_width = total_width;
8d47858805c9 util.human.io: Add padleft, padright and a table printing function
Matthew Wild <mwild1@gmail.com>
parents: 10876
diff changeset
   124
	-- Calculate width of fixed-size columns
8d47858805c9 util.human.io: Add padleft, padright and a table printing function
Matthew Wild <mwild1@gmail.com>
parents: 10876
diff changeset
   125
	for i = 1, #col_specs do
8d47858805c9 util.human.io: Add padleft, padright and a table printing function
Matthew Wild <mwild1@gmail.com>
parents: 10876
diff changeset
   126
		local width = col_specs[i].width or "0";
8d47858805c9 util.human.io: Add padleft, padright and a table printing function
Matthew Wild <mwild1@gmail.com>
parents: 10876
diff changeset
   127
		if not(type(width) == "string" and width:sub(-1) == "%") then
8d47858805c9 util.human.io: Add padleft, padright and a table printing function
Matthew Wild <mwild1@gmail.com>
parents: 10876
diff changeset
   128
			local title = col_specs[i].title;
8d47858805c9 util.human.io: Add padleft, padright and a table printing function
Matthew Wild <mwild1@gmail.com>
parents: 10876
diff changeset
   129
			width = math.max(tonumber(width), title and (#title+1) or 0);
8d47858805c9 util.human.io: Add padleft, padright and a table printing function
Matthew Wild <mwild1@gmail.com>
parents: 10876
diff changeset
   130
			widths[i] = width;
8d47858805c9 util.human.io: Add padleft, padright and a table printing function
Matthew Wild <mwild1@gmail.com>
parents: 10876
diff changeset
   131
			free_width = free_width - width;
10914
e890b83f08cf util.human.io: Consider separator when calculating remaining width
Kim Alvefur <zash@zash.se>
parents: 10913
diff changeset
   132
			if i > 1 then
e890b83f08cf util.human.io: Consider separator when calculating remaining width
Kim Alvefur <zash@zash.se>
parents: 10913
diff changeset
   133
				free_width = free_width - #separator;
e890b83f08cf util.human.io: Consider separator when calculating remaining width
Kim Alvefur <zash@zash.se>
parents: 10913
diff changeset
   134
			end
10895
8d47858805c9 util.human.io: Add padleft, padright and a table printing function
Matthew Wild <mwild1@gmail.com>
parents: 10876
diff changeset
   135
		end
8d47858805c9 util.human.io: Add padleft, padright and a table printing function
Matthew Wild <mwild1@gmail.com>
parents: 10876
diff changeset
   136
	end
8d47858805c9 util.human.io: Add padleft, padright and a table printing function
Matthew Wild <mwild1@gmail.com>
parents: 10876
diff changeset
   137
	-- Calculate width of %-based columns
8d47858805c9 util.human.io: Add padleft, padright and a table printing function
Matthew Wild <mwild1@gmail.com>
parents: 10876
diff changeset
   138
	for i = 1, #col_specs do
8d47858805c9 util.human.io: Add padleft, padright and a table printing function
Matthew Wild <mwild1@gmail.com>
parents: 10876
diff changeset
   139
		if not widths[i] then
8d47858805c9 util.human.io: Add padleft, padright and a table printing function
Matthew Wild <mwild1@gmail.com>
parents: 10876
diff changeset
   140
			local pc_width = tonumber((col_specs[i].width:gsub("%%$", "")));
8d47858805c9 util.human.io: Add padleft, padright and a table printing function
Matthew Wild <mwild1@gmail.com>
parents: 10876
diff changeset
   141
			widths[i] = math.floor(free_width*(pc_width/100));
8d47858805c9 util.human.io: Add padleft, padright and a table printing function
Matthew Wild <mwild1@gmail.com>
parents: 10876
diff changeset
   142
		end
8d47858805c9 util.human.io: Add padleft, padright and a table printing function
Matthew Wild <mwild1@gmail.com>
parents: 10876
diff changeset
   143
	end
8d47858805c9 util.human.io: Add padleft, padright and a table printing function
Matthew Wild <mwild1@gmail.com>
parents: 10876
diff changeset
   144
10897
a256044c1d12 util.human.io: table: switch row function to simply returning prepared row string
Matthew Wild <mwild1@gmail.com>
parents: 10895
diff changeset
   145
	return function (row)
10900
c7a0eab27165 util.human.io: table: Fix title printing when columns use named keys
Matthew Wild <mwild1@gmail.com>
parents: 10898
diff changeset
   146
		local titles;
10898
d15a4284fdf8 util.human.io: table: Return title row when no row data passed
Matthew Wild <mwild1@gmail.com>
parents: 10897
diff changeset
   147
		if not row then
10900
c7a0eab27165 util.human.io: table: Fix title printing when columns use named keys
Matthew Wild <mwild1@gmail.com>
parents: 10898
diff changeset
   148
			titles, row = true, array.pluck(col_specs, "title", "");
10898
d15a4284fdf8 util.human.io: table: Return title row when no row data passed
Matthew Wild <mwild1@gmail.com>
parents: 10897
diff changeset
   149
		end
10897
a256044c1d12 util.human.io: table: switch row function to simply returning prepared row string
Matthew Wild <mwild1@gmail.com>
parents: 10895
diff changeset
   150
		local output = {};
10895
8d47858805c9 util.human.io: Add padleft, padright and a table printing function
Matthew Wild <mwild1@gmail.com>
parents: 10876
diff changeset
   151
		for i, column in ipairs(col_specs) do
8d47858805c9 util.human.io: Add padleft, padright and a table printing function
Matthew Wild <mwild1@gmail.com>
parents: 10876
diff changeset
   152
			local width = widths[i];
11896
e712133b4de1 util.human.io: Pass nil to cell mapper to signal missing value
Kim Alvefur <zash@zash.se>
parents: 10921
diff changeset
   153
			local v = row[not titles and column.key or i];
e712133b4de1 util.human.io: Pass nil to cell mapper to signal missing value
Kim Alvefur <zash@zash.se>
parents: 10921
diff changeset
   154
			if not titles and column.mapper then
e712133b4de1 util.human.io: Pass nil to cell mapper to signal missing value
Kim Alvefur <zash@zash.se>
parents: 10921
diff changeset
   155
				v = column.mapper(v, row);
e712133b4de1 util.human.io: Pass nil to cell mapper to signal missing value
Kim Alvefur <zash@zash.se>
parents: 10921
diff changeset
   156
			end
e712133b4de1 util.human.io: Pass nil to cell mapper to signal missing value
Kim Alvefur <zash@zash.se>
parents: 10921
diff changeset
   157
			if v == nil then
11897
afef1e170de7 util.human.io: Support specifying column defaults in tables
Kim Alvefur <zash@zash.se>
parents: 11896
diff changeset
   158
				v = column.default or "";
11896
e712133b4de1 util.human.io: Pass nil to cell mapper to signal missing value
Kim Alvefur <zash@zash.se>
parents: 10921
diff changeset
   159
			else
e712133b4de1 util.human.io: Pass nil to cell mapper to signal missing value
Kim Alvefur <zash@zash.se>
parents: 10921
diff changeset
   160
				v = tostring(v);
e712133b4de1 util.human.io: Pass nil to cell mapper to signal missing value
Kim Alvefur <zash@zash.se>
parents: 10921
diff changeset
   161
			end
11900
93e9f7ae2f9b util.human.io: Fix cutting of UTF-8 into pieces
Kim Alvefur <zash@zash.se>
parents: 11899
diff changeset
   162
			if len(v) < width then
10895
8d47858805c9 util.human.io: Add padleft, padright and a table printing function
Matthew Wild <mwild1@gmail.com>
parents: 10876
diff changeset
   163
				if column.align == "right" then
10921
1eb83bc6f706 util.human.io: Fix right-alignment
Kim Alvefur <zash@zash.se>
parents: 10915
diff changeset
   164
					v = padleft(v, width);
10895
8d47858805c9 util.human.io: Add padleft, padright and a table printing function
Matthew Wild <mwild1@gmail.com>
parents: 10876
diff changeset
   165
				else
8d47858805c9 util.human.io: Add padleft, padright and a table printing function
Matthew Wild <mwild1@gmail.com>
parents: 10876
diff changeset
   166
					v = padright(v, width);
8d47858805c9 util.human.io: Add padleft, padright and a table printing function
Matthew Wild <mwild1@gmail.com>
parents: 10876
diff changeset
   167
				end
11900
93e9f7ae2f9b util.human.io: Fix cutting of UTF-8 into pieces
Kim Alvefur <zash@zash.se>
parents: 11899
diff changeset
   168
			elseif len(v) > width then
11898
57106c61d104 util.human.io: Factor out ellipsis function
Kim Alvefur <zash@zash.se>
parents: 11897
diff changeset
   169
				v = ellipsis(v, width);
10895
8d47858805c9 util.human.io: Add padleft, padright and a table printing function
Matthew Wild <mwild1@gmail.com>
parents: 10876
diff changeset
   170
			end
10897
a256044c1d12 util.human.io: table: switch row function to simply returning prepared row string
Matthew Wild <mwild1@gmail.com>
parents: 10895
diff changeset
   171
			table.insert(output, v);
10895
8d47858805c9 util.human.io: Add padleft, padright and a table printing function
Matthew Wild <mwild1@gmail.com>
parents: 10876
diff changeset
   172
		end
10911
6af28c756752 util.human.io: Draw a separator between columns
Kim Alvefur <zash@zash.se>
parents: 10908
diff changeset
   173
		return table.concat(output, separator);
10895
8d47858805c9 util.human.io: Add padleft, padright and a table printing function
Matthew Wild <mwild1@gmail.com>
parents: 10876
diff changeset
   174
	end;
8d47858805c9 util.human.io: Add padleft, padright and a table printing function
Matthew Wild <mwild1@gmail.com>
parents: 10876
diff changeset
   175
end
8d47858805c9 util.human.io: Add padleft, padright and a table printing function
Matthew Wild <mwild1@gmail.com>
parents: 10876
diff changeset
   176
10874
3f1889608f3e util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   177
return {
3f1889608f3e util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   178
	getchar = getchar;
3f1889608f3e util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   179
	getline = getline;
3f1889608f3e util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   180
	getpass = getpass;
3f1889608f3e util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   181
	show_yesno = show_yesno;
3f1889608f3e util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   182
	read_password = read_password;
3f1889608f3e util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   183
	show_prompt = show_prompt;
3f1889608f3e util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   184
	printf = printf;
10895
8d47858805c9 util.human.io: Add padleft, padright and a table printing function
Matthew Wild <mwild1@gmail.com>
parents: 10876
diff changeset
   185
	padleft = padleft;
8d47858805c9 util.human.io: Add padleft, padright and a table printing function
Matthew Wild <mwild1@gmail.com>
parents: 10876
diff changeset
   186
	padright = padright;
11898
57106c61d104 util.human.io: Factor out ellipsis function
Kim Alvefur <zash@zash.se>
parents: 11897
diff changeset
   187
	ellipsis = ellipsis;
10897
a256044c1d12 util.human.io: table: switch row function to simply returning prepared row string
Matthew Wild <mwild1@gmail.com>
parents: 10895
diff changeset
   188
	table = new_table;
10874
3f1889608f3e util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   189
};