Software /
code /
prosody
Annotate
util/human/io.lua @ 13047:d939bf469057
util.human.io: Prefer using the $COLUMNS environment variable if set (by readline)
Feels like it should be faster.
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Fri, 07 Apr 2023 13:42:20 +0200 |
parent | 13045:da0b3cb9a2ec |
child | 13048:946442df65d3 |
rev | line source |
---|---|
12975
d10957394a3c
util: Prefix module imports with prosody namespace
Kim Alvefur <zash@zash.se>
parents:
12783
diff
changeset
|
1 local array = require "prosody.util.array"; |
d10957394a3c
util: Prefix module imports with prosody namespace
Kim Alvefur <zash@zash.se>
parents:
12783
diff
changeset
|
2 local utf8 = rawget(_G, "utf8") or require"prosody.util.encodings".utf8; |
11896
93e9f7ae2f9b
util.human.io: Fix cutting of UTF-8 into pieces
Kim Alvefur <zash@zash.se>
parents:
11895
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:
11895
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:
11895
diff
changeset
|
5 return count; |
93e9f7ae2f9b
util.human.io: Fix cutting of UTF-8 into pieces
Kim Alvefur <zash@zash.se>
parents:
11895
diff
changeset
|
6 end; |
10894
d15a4284fdf8
util.human.io: table: Return title row when no row data passed
Matthew Wild <mwild1@gmail.com>
parents:
10893
diff
changeset
|
7 |
10870
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; |
12783
d513e4bd4928
util.human.io: Fix handling of os.execute() return values in Lua 5.2+
Kim Alvefur <zash@zash.se>
parents:
12573
diff
changeset
|
11 if stty_ret then |
10870
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() |
12573
0f4feaf9ca64
util: Remove various Lua 5.1 compatibility hacks
Kim Alvefur <zash@zash.se>
parents:
11897
diff
changeset
|
33 local stty_ret = os.execute("stty -echo 2>/dev/null"); |
12783
d513e4bd4928
util.human.io: Fix handling of os.execute() return values in Lua 5.2+
Kim Alvefur <zash@zash.se>
parents:
12573
diff
changeset
|
34 if not stty_ret then |
10870
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"); |
12783
d513e4bd4928
util.human.io: Fix handling of os.execute() return values in Lua 5.2+
Kim Alvefur <zash@zash.se>
parents:
12573
diff
changeset
|
38 if stty_ret then |
10870
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, ...) |
10872
a3f3f42736f2
util.human.io: Fix variable name [luacheck]
Matthew Wild <mwild1@gmail.com>
parents:
10870
diff
changeset
|
89 print(fmt:format(...)); |
10870
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 |
10891
8d47858805c9
util.human.io: Add padleft, padright and a table printing function
Matthew Wild <mwild1@gmail.com>
parents:
10872
diff
changeset
|
92 local function padright(s, width) |
11897
e84ea5b58b29
util.human.io: Use UTF-8-aware length check in padding functions
Kim Alvefur <zash@zash.se>
parents:
11896
diff
changeset
|
93 return s..string.rep(" ", width-len(s)); |
10891
8d47858805c9
util.human.io: Add padleft, padright and a table printing function
Matthew Wild <mwild1@gmail.com>
parents:
10872
diff
changeset
|
94 end |
8d47858805c9
util.human.io: Add padleft, padright and a table printing function
Matthew Wild <mwild1@gmail.com>
parents:
10872
diff
changeset
|
95 |
8d47858805c9
util.human.io: Add padleft, padright and a table printing function
Matthew Wild <mwild1@gmail.com>
parents:
10872
diff
changeset
|
96 local function padleft(s, width) |
11897
e84ea5b58b29
util.human.io: Use UTF-8-aware length check in padding functions
Kim Alvefur <zash@zash.se>
parents:
11896
diff
changeset
|
97 return string.rep(" ", width-len(s))..s; |
10891
8d47858805c9
util.human.io: Add padleft, padright and a table printing function
Matthew Wild <mwild1@gmail.com>
parents:
10872
diff
changeset
|
98 end |
8d47858805c9
util.human.io: Add padleft, padright and a table printing function
Matthew Wild <mwild1@gmail.com>
parents:
10872
diff
changeset
|
99 |
11896
93e9f7ae2f9b
util.human.io: Fix cutting of UTF-8 into pieces
Kim Alvefur <zash@zash.se>
parents:
11895
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:
11895
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:
11895
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:
11895
diff
changeset
|
103 end |
93e9f7ae2f9b
util.human.io: Fix cutting of UTF-8 into pieces
Kim Alvefur <zash@zash.se>
parents:
11895
diff
changeset
|
104 |
93e9f7ae2f9b
util.human.io: Fix cutting of UTF-8 into pieces
Kim Alvefur <zash@zash.se>
parents:
11895
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:
11895
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:
11895
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:
11895
diff
changeset
|
108 end |
93e9f7ae2f9b
util.human.io: Fix cutting of UTF-8 into pieces
Kim Alvefur <zash@zash.se>
parents:
11895
diff
changeset
|
109 end |
93e9f7ae2f9b
util.human.io: Fix cutting of UTF-8 into pieces
Kim Alvefur <zash@zash.se>
parents:
11895
diff
changeset
|
110 |
13044
5bd272095388
util.human.io: Add term_width() method to discover the terminal width
Matthew Wild <mwild1@gmail.com>
parents:
13040
diff
changeset
|
111 local function term_width(default) |
13047
d939bf469057
util.human.io: Prefer using the $COLUMNS environment variable if set (by readline)
Kim Alvefur <zash@zash.se>
parents:
13045
diff
changeset
|
112 local env_cols = os.getenv "COLUMNS"; |
d939bf469057
util.human.io: Prefer using the $COLUMNS environment variable if set (by readline)
Kim Alvefur <zash@zash.se>
parents:
13045
diff
changeset
|
113 if env_cols then return env_cols; end |
13044
5bd272095388
util.human.io: Add term_width() method to discover the terminal width
Matthew Wild <mwild1@gmail.com>
parents:
13040
diff
changeset
|
114 local stty = io.popen("stty -a"); |
5bd272095388
util.human.io: Add term_width() method to discover the terminal width
Matthew Wild <mwild1@gmail.com>
parents:
13040
diff
changeset
|
115 if not stty then return default; end |
5bd272095388
util.human.io: Add term_width() method to discover the terminal width
Matthew Wild <mwild1@gmail.com>
parents:
13040
diff
changeset
|
116 local result = stty:read("*a"); |
5bd272095388
util.human.io: Add term_width() method to discover the terminal width
Matthew Wild <mwild1@gmail.com>
parents:
13040
diff
changeset
|
117 if result then |
5bd272095388
util.human.io: Add term_width() method to discover the terminal width
Matthew Wild <mwild1@gmail.com>
parents:
13040
diff
changeset
|
118 result = result:match("%f[%w]columns[ =]*(%d+)"); |
5bd272095388
util.human.io: Add term_width() method to discover the terminal width
Matthew Wild <mwild1@gmail.com>
parents:
13040
diff
changeset
|
119 end |
5bd272095388
util.human.io: Add term_width() method to discover the terminal width
Matthew Wild <mwild1@gmail.com>
parents:
13040
diff
changeset
|
120 stty:close(); |
5bd272095388
util.human.io: Add term_width() method to discover the terminal width
Matthew Wild <mwild1@gmail.com>
parents:
13040
diff
changeset
|
121 return tonumber(result or default); |
5bd272095388
util.human.io: Add term_width() method to discover the terminal width
Matthew Wild <mwild1@gmail.com>
parents:
13040
diff
changeset
|
122 end |
5bd272095388
util.human.io: Add term_width() method to discover the terminal width
Matthew Wild <mwild1@gmail.com>
parents:
13040
diff
changeset
|
123 |
11894
57106c61d104
util.human.io: Factor out ellipsis function
Kim Alvefur <zash@zash.se>
parents:
11893
diff
changeset
|
124 local function ellipsis(s, width) |
11896
93e9f7ae2f9b
util.human.io: Fix cutting of UTF-8 into pieces
Kim Alvefur <zash@zash.se>
parents:
11895
diff
changeset
|
125 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:
11895
diff
changeset
|
126 if width == 1 then return "…"; end |
93e9f7ae2f9b
util.human.io: Fix cutting of UTF-8 into pieces
Kim Alvefur <zash@zash.se>
parents:
11895
diff
changeset
|
127 return utf8_cut(s, width - 1) .. "…"; |
11894
57106c61d104
util.human.io: Factor out ellipsis function
Kim Alvefur <zash@zash.se>
parents:
11893
diff
changeset
|
128 end |
57106c61d104
util.human.io: Factor out ellipsis function
Kim Alvefur <zash@zash.se>
parents:
11893
diff
changeset
|
129 |
10904
d009a79f723a
util.human.io: Remove padding option and use $COLUMNS as default width
Matthew Wild <mwild1@gmail.com>
parents:
10896
diff
changeset
|
130 local function new_table(col_specs, max_width) |
13045
da0b3cb9a2ec
util.human.io: table: use term_width() to discover terminal width
Matthew Wild <mwild1@gmail.com>
parents:
13044
diff
changeset
|
131 max_width = max_width or term_width(os.getenv("COLUMNS") or 80); |
10907
6af28c756752
util.human.io: Draw a separator between columns
Kim Alvefur <zash@zash.se>
parents:
10904
diff
changeset
|
132 local separator = " | "; |
10891
8d47858805c9
util.human.io: Add padleft, padright and a table printing function
Matthew Wild <mwild1@gmail.com>
parents:
10872
diff
changeset
|
133 |
8d47858805c9
util.human.io: Add padleft, padright and a table printing function
Matthew Wild <mwild1@gmail.com>
parents:
10872
diff
changeset
|
134 local widths = {}; |
10907
6af28c756752
util.human.io: Draw a separator between columns
Kim Alvefur <zash@zash.se>
parents:
10904
diff
changeset
|
135 local total_width = max_width - #separator * (#col_specs-1); |
10891
8d47858805c9
util.human.io: Add padleft, padright and a table printing function
Matthew Wild <mwild1@gmail.com>
parents:
10872
diff
changeset
|
136 local free_width = total_width; |
8d47858805c9
util.human.io: Add padleft, padright and a table printing function
Matthew Wild <mwild1@gmail.com>
parents:
10872
diff
changeset
|
137 -- Calculate width of fixed-size columns |
8d47858805c9
util.human.io: Add padleft, padright and a table printing function
Matthew Wild <mwild1@gmail.com>
parents:
10872
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:
10872
diff
changeset
|
139 local width = col_specs[i].width or "0"; |
13030
1f89a2a9f532
util.human.io: Support for dynamic "proportional" columns
Matthew Wild <mwild1@gmail.com>
parents:
12975
diff
changeset
|
140 if not (type(width) == "string" and width:match("[p%%]$")) then |
10891
8d47858805c9
util.human.io: Add padleft, padright and a table printing function
Matthew Wild <mwild1@gmail.com>
parents:
10872
diff
changeset
|
141 local title = col_specs[i].title; |
8d47858805c9
util.human.io: Add padleft, padright and a table printing function
Matthew Wild <mwild1@gmail.com>
parents:
10872
diff
changeset
|
142 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:
10872
diff
changeset
|
143 widths[i] = width; |
8d47858805c9
util.human.io: Add padleft, padright and a table printing function
Matthew Wild <mwild1@gmail.com>
parents:
10872
diff
changeset
|
144 free_width = free_width - width; |
10910
e890b83f08cf
util.human.io: Consider separator when calculating remaining width
Kim Alvefur <zash@zash.se>
parents:
10909
diff
changeset
|
145 if i > 1 then |
e890b83f08cf
util.human.io: Consider separator when calculating remaining width
Kim Alvefur <zash@zash.se>
parents:
10909
diff
changeset
|
146 free_width = free_width - #separator; |
e890b83f08cf
util.human.io: Consider separator when calculating remaining width
Kim Alvefur <zash@zash.se>
parents:
10909
diff
changeset
|
147 end |
10891
8d47858805c9
util.human.io: Add padleft, padright and a table printing function
Matthew Wild <mwild1@gmail.com>
parents:
10872
diff
changeset
|
148 end |
8d47858805c9
util.human.io: Add padleft, padright and a table printing function
Matthew Wild <mwild1@gmail.com>
parents:
10872
diff
changeset
|
149 end |
13030
1f89a2a9f532
util.human.io: Support for dynamic "proportional" columns
Matthew Wild <mwild1@gmail.com>
parents:
12975
diff
changeset
|
150 |
1f89a2a9f532
util.human.io: Support for dynamic "proportional" columns
Matthew Wild <mwild1@gmail.com>
parents:
12975
diff
changeset
|
151 -- Calculate width of proportional columns |
1f89a2a9f532
util.human.io: Support for dynamic "proportional" columns
Matthew Wild <mwild1@gmail.com>
parents:
12975
diff
changeset
|
152 local total_proportional_width = 0; |
10891
8d47858805c9
util.human.io: Add padleft, padright and a table printing function
Matthew Wild <mwild1@gmail.com>
parents:
10872
diff
changeset
|
153 for i = 1, #col_specs do |
8d47858805c9
util.human.io: Add padleft, padright and a table printing function
Matthew Wild <mwild1@gmail.com>
parents:
10872
diff
changeset
|
154 if not widths[i] then |
13031
1023c3faffac
util.human.io: Fix pattern to support fractional proportions
Matthew Wild <mwild1@gmail.com>
parents:
13030
diff
changeset
|
155 local width_spec = col_specs[i].width:match("([%d%.]+)[p%%]"); |
13030
1f89a2a9f532
util.human.io: Support for dynamic "proportional" columns
Matthew Wild <mwild1@gmail.com>
parents:
12975
diff
changeset
|
156 total_proportional_width = total_proportional_width + tonumber(width_spec); |
1f89a2a9f532
util.human.io: Support for dynamic "proportional" columns
Matthew Wild <mwild1@gmail.com>
parents:
12975
diff
changeset
|
157 end |
1f89a2a9f532
util.human.io: Support for dynamic "proportional" columns
Matthew Wild <mwild1@gmail.com>
parents:
12975
diff
changeset
|
158 end |
1f89a2a9f532
util.human.io: Support for dynamic "proportional" columns
Matthew Wild <mwild1@gmail.com>
parents:
12975
diff
changeset
|
159 |
1f89a2a9f532
util.human.io: Support for dynamic "proportional" columns
Matthew Wild <mwild1@gmail.com>
parents:
12975
diff
changeset
|
160 for i = 1, #col_specs do |
1f89a2a9f532
util.human.io: Support for dynamic "proportional" columns
Matthew Wild <mwild1@gmail.com>
parents:
12975
diff
changeset
|
161 if not widths[i] then |
13031
1023c3faffac
util.human.io: Fix pattern to support fractional proportions
Matthew Wild <mwild1@gmail.com>
parents:
13030
diff
changeset
|
162 local width_spec = col_specs[i].width:match("([%d%.]+)[p%%]"); |
13030
1f89a2a9f532
util.human.io: Support for dynamic "proportional" columns
Matthew Wild <mwild1@gmail.com>
parents:
12975
diff
changeset
|
163 local rel_width = tonumber(width_spec); |
1f89a2a9f532
util.human.io: Support for dynamic "proportional" columns
Matthew Wild <mwild1@gmail.com>
parents:
12975
diff
changeset
|
164 widths[i] = math.floor(free_width*(rel_width/total_proportional_width)); |
10891
8d47858805c9
util.human.io: Add padleft, padright and a table printing function
Matthew Wild <mwild1@gmail.com>
parents:
10872
diff
changeset
|
165 end |
8d47858805c9
util.human.io: Add padleft, padright and a table printing function
Matthew Wild <mwild1@gmail.com>
parents:
10872
diff
changeset
|
166 end |
8d47858805c9
util.human.io: Add padleft, padright and a table printing function
Matthew Wild <mwild1@gmail.com>
parents:
10872
diff
changeset
|
167 |
10893
a256044c1d12
util.human.io: table: switch row function to simply returning prepared row string
Matthew Wild <mwild1@gmail.com>
parents:
10891
diff
changeset
|
168 return function (row) |
10896
c7a0eab27165
util.human.io: table: Fix title printing when columns use named keys
Matthew Wild <mwild1@gmail.com>
parents:
10894
diff
changeset
|
169 local titles; |
10894
d15a4284fdf8
util.human.io: table: Return title row when no row data passed
Matthew Wild <mwild1@gmail.com>
parents:
10893
diff
changeset
|
170 if not row then |
10896
c7a0eab27165
util.human.io: table: Fix title printing when columns use named keys
Matthew Wild <mwild1@gmail.com>
parents:
10894
diff
changeset
|
171 titles, row = true, array.pluck(col_specs, "title", ""); |
10894
d15a4284fdf8
util.human.io: table: Return title row when no row data passed
Matthew Wild <mwild1@gmail.com>
parents:
10893
diff
changeset
|
172 end |
10893
a256044c1d12
util.human.io: table: switch row function to simply returning prepared row string
Matthew Wild <mwild1@gmail.com>
parents:
10891
diff
changeset
|
173 local output = {}; |
10891
8d47858805c9
util.human.io: Add padleft, padright and a table printing function
Matthew Wild <mwild1@gmail.com>
parents:
10872
diff
changeset
|
174 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:
10872
diff
changeset
|
175 local width = widths[i]; |
11892
e712133b4de1
util.human.io: Pass nil to cell mapper to signal missing value
Kim Alvefur <zash@zash.se>
parents:
10917
diff
changeset
|
176 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:
10917
diff
changeset
|
177 if not titles and column.mapper then |
13040
0cbe400ebab4
util.human.io: Pass the whole column definition to mapper function
Kim Alvefur <zash@zash.se>
parents:
13039
diff
changeset
|
178 v = column.mapper(v, row, width, column); |
11892
e712133b4de1
util.human.io: Pass nil to cell mapper to signal missing value
Kim Alvefur <zash@zash.se>
parents:
10917
diff
changeset
|
179 end |
e712133b4de1
util.human.io: Pass nil to cell mapper to signal missing value
Kim Alvefur <zash@zash.se>
parents:
10917
diff
changeset
|
180 if v == nil then |
11893
afef1e170de7
util.human.io: Support specifying column defaults in tables
Kim Alvefur <zash@zash.se>
parents:
11892
diff
changeset
|
181 v = column.default or ""; |
11892
e712133b4de1
util.human.io: Pass nil to cell mapper to signal missing value
Kim Alvefur <zash@zash.se>
parents:
10917
diff
changeset
|
182 else |
e712133b4de1
util.human.io: Pass nil to cell mapper to signal missing value
Kim Alvefur <zash@zash.se>
parents:
10917
diff
changeset
|
183 v = tostring(v); |
e712133b4de1
util.human.io: Pass nil to cell mapper to signal missing value
Kim Alvefur <zash@zash.se>
parents:
10917
diff
changeset
|
184 end |
11896
93e9f7ae2f9b
util.human.io: Fix cutting of UTF-8 into pieces
Kim Alvefur <zash@zash.se>
parents:
11895
diff
changeset
|
185 if len(v) < width then |
10891
8d47858805c9
util.human.io: Add padleft, padright and a table printing function
Matthew Wild <mwild1@gmail.com>
parents:
10872
diff
changeset
|
186 if column.align == "right" then |
10917
1eb83bc6f706
util.human.io: Fix right-alignment
Kim Alvefur <zash@zash.se>
parents:
10911
diff
changeset
|
187 v = padleft(v, width); |
10891
8d47858805c9
util.human.io: Add padleft, padright and a table printing function
Matthew Wild <mwild1@gmail.com>
parents:
10872
diff
changeset
|
188 else |
8d47858805c9
util.human.io: Add padleft, padright and a table printing function
Matthew Wild <mwild1@gmail.com>
parents:
10872
diff
changeset
|
189 v = padright(v, width); |
8d47858805c9
util.human.io: Add padleft, padright and a table printing function
Matthew Wild <mwild1@gmail.com>
parents:
10872
diff
changeset
|
190 end |
11896
93e9f7ae2f9b
util.human.io: Fix cutting of UTF-8 into pieces
Kim Alvefur <zash@zash.se>
parents:
11895
diff
changeset
|
191 elseif len(v) > width then |
13039
9ddb344b9fab
util.human.io: Allow defining per column ellipsis function
Kim Alvefur <zash@zash.se>
parents:
13038
diff
changeset
|
192 v = (column.ellipsis or ellipsis)(v, width); |
10891
8d47858805c9
util.human.io: Add padleft, padright and a table printing function
Matthew Wild <mwild1@gmail.com>
parents:
10872
diff
changeset
|
193 end |
10893
a256044c1d12
util.human.io: table: switch row function to simply returning prepared row string
Matthew Wild <mwild1@gmail.com>
parents:
10891
diff
changeset
|
194 table.insert(output, v); |
10891
8d47858805c9
util.human.io: Add padleft, padright and a table printing function
Matthew Wild <mwild1@gmail.com>
parents:
10872
diff
changeset
|
195 end |
10907
6af28c756752
util.human.io: Draw a separator between columns
Kim Alvefur <zash@zash.se>
parents:
10904
diff
changeset
|
196 return table.concat(output, separator); |
10891
8d47858805c9
util.human.io: Add padleft, padright and a table printing function
Matthew Wild <mwild1@gmail.com>
parents:
10872
diff
changeset
|
197 end; |
8d47858805c9
util.human.io: Add padleft, padright and a table printing function
Matthew Wild <mwild1@gmail.com>
parents:
10872
diff
changeset
|
198 end |
8d47858805c9
util.human.io: Add padleft, padright and a table printing function
Matthew Wild <mwild1@gmail.com>
parents:
10872
diff
changeset
|
199 |
10870
3f1889608f3e
util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
200 return { |
3f1889608f3e
util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
201 getchar = getchar; |
3f1889608f3e
util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
202 getline = getline; |
3f1889608f3e
util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
203 getpass = getpass; |
3f1889608f3e
util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
204 show_yesno = show_yesno; |
3f1889608f3e
util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
205 read_password = read_password; |
3f1889608f3e
util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
206 show_prompt = show_prompt; |
3f1889608f3e
util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
207 printf = printf; |
10891
8d47858805c9
util.human.io: Add padleft, padright and a table printing function
Matthew Wild <mwild1@gmail.com>
parents:
10872
diff
changeset
|
208 padleft = padleft; |
8d47858805c9
util.human.io: Add padleft, padright and a table printing function
Matthew Wild <mwild1@gmail.com>
parents:
10872
diff
changeset
|
209 padright = padright; |
13044
5bd272095388
util.human.io: Add term_width() method to discover the terminal width
Matthew Wild <mwild1@gmail.com>
parents:
13040
diff
changeset
|
210 term_width = term_width; |
11894
57106c61d104
util.human.io: Factor out ellipsis function
Kim Alvefur <zash@zash.se>
parents:
11893
diff
changeset
|
211 ellipsis = ellipsis; |
10893
a256044c1d12
util.human.io: table: switch row function to simply returning prepared row string
Matthew Wild <mwild1@gmail.com>
parents:
10891
diff
changeset
|
212 table = new_table; |
10870
3f1889608f3e
util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
213 }; |