Mercurial > prosody-hg
annotate util/human/io.lua @ 13946:f5e8ab42c708
mod_http_file_share: Check that files are still there with correct size
Failed uploads can leave behind unused slots. Files shouldn't change
size after they have been successfully uploaded, but might as well
double check it.
| author | Kim Alvefur <zash@zash.se> |
|---|---|
| date | Sat, 04 Dec 2021 18:56:51 +0100 |
| parents | cfe3e85e715f |
| children | 7008869fcce2 |
| 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"; |
|
13210
8dbe693ded6b
util.human.io: Fix stray 'stty' error by only querying width of real ttys
Kim Alvefur <zash@zash.se>
parents:
13199
diff
changeset
|
2 local pposix = require "prosody.util.pposix"; |
|
12975
d10957394a3c
util: Prefix module imports with prosody namespace
Kim Alvefur <zash@zash.se>
parents:
12783
diff
changeset
|
3 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
|
4 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
|
5 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
|
6 return count; |
|
93e9f7ae2f9b
util.human.io: Fix cutting of UTF-8 into pieces
Kim Alvefur <zash@zash.se>
parents:
11895
diff
changeset
|
7 end; |
|
10894
d15a4284fdf8
util.human.io: table: Return title row when no row data passed
Matthew Wild <mwild1@gmail.com>
parents:
10893
diff
changeset
|
8 |
|
10870
3f1889608f3e
util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
9 local function getchar(n) |
|
3f1889608f3e
util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
10 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
|
11 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
|
12 if stty_ret then |
|
10870
3f1889608f3e
util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
13 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
|
14 os.execute("stty sane"); |
|
3f1889608f3e
util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
15 else |
|
3f1889608f3e
util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
16 ok, char = pcall(io.read, "*l"); |
|
3f1889608f3e
util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
17 if ok then |
|
3f1889608f3e
util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
18 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
|
19 end |
|
3f1889608f3e
util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
20 end |
|
3f1889608f3e
util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
21 if ok then |
|
3f1889608f3e
util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
22 return char; |
|
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 end |
|
3f1889608f3e
util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
25 |
|
3f1889608f3e
util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
26 local function getline() |
|
3f1889608f3e
util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
27 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
|
28 if ok then |
|
3f1889608f3e
util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
29 return line; |
|
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 end |
|
3f1889608f3e
util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
32 |
|
3f1889608f3e
util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
33 local function getpass() |
|
12573
0f4feaf9ca64
util: Remove various Lua 5.1 compatibility hacks
Kim Alvefur <zash@zash.se>
parents:
11897
diff
changeset
|
34 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
|
35 if not stty_ret then |
|
10870
3f1889608f3e
util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
36 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
|
37 end |
|
3f1889608f3e
util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
38 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
|
39 if stty_ret then |
|
10870
3f1889608f3e
util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
40 os.execute("stty sane"); |
|
3f1889608f3e
util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
41 else |
|
3f1889608f3e
util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
42 io.write("\027[00m"); |
|
3f1889608f3e
util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
43 end |
|
3f1889608f3e
util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
44 io.write("\n"); |
|
3f1889608f3e
util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
45 if ok then |
|
3f1889608f3e
util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
46 return pass; |
|
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 end |
|
3f1889608f3e
util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
49 |
|
3f1889608f3e
util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
50 local function show_yesno(prompt) |
|
3f1889608f3e
util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
51 io.write(prompt, " "); |
|
3f1889608f3e
util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
52 local choice = getchar():lower(); |
|
3f1889608f3e
util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
53 io.write("\n"); |
|
3f1889608f3e
util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
54 if not choice:match("%a") then |
|
3f1889608f3e
util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
55 choice = prompt:match("%[.-(%U).-%]$"); |
|
3f1889608f3e
util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
56 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
|
57 end |
|
3f1889608f3e
util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
58 return (choice == "y"); |
|
3f1889608f3e
util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
59 end |
|
3f1889608f3e
util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
60 |
|
3f1889608f3e
util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
61 local function read_password() |
|
3f1889608f3e
util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
62 local password; |
|
3f1889608f3e
util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
63 while true do |
|
3f1889608f3e
util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
64 io.write("Enter new password: "); |
|
3f1889608f3e
util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
65 password = getpass(); |
|
3f1889608f3e
util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
66 if not password then |
|
3f1889608f3e
util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
67 print("No password - cancelled"); |
|
3f1889608f3e
util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
68 return; |
|
3f1889608f3e
util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
69 end |
|
3f1889608f3e
util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
70 io.write("Retype new password: "); |
|
3f1889608f3e
util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
71 if getpass() ~= password then |
|
3f1889608f3e
util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
72 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
|
73 return; |
|
3f1889608f3e
util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
74 end |
|
3f1889608f3e
util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
75 else |
|
3f1889608f3e
util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
76 break; |
|
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 end |
|
3f1889608f3e
util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
79 return password; |
|
3f1889608f3e
util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
80 end |
|
3f1889608f3e
util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
81 |
|
3f1889608f3e
util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
82 local function show_prompt(prompt) |
|
3f1889608f3e
util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
83 io.write(prompt, " "); |
|
3f1889608f3e
util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
84 local line = getline(); |
|
3f1889608f3e
util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
85 line = line and line:gsub("\n$",""); |
|
3f1889608f3e
util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
86 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
|
87 end |
|
3f1889608f3e
util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
88 |
|
3f1889608f3e
util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
89 local function printf(fmt, ...) |
|
10872
a3f3f42736f2
util.human.io: Fix variable name [luacheck]
Matthew Wild <mwild1@gmail.com>
parents:
10870
diff
changeset
|
90 print(fmt:format(...)); |
|
10870
3f1889608f3e
util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
91 end |
|
3f1889608f3e
util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
92 |
|
10891
8d47858805c9
util.human.io: Add padleft, padright and a table printing function
Matthew Wild <mwild1@gmail.com>
parents:
10872
diff
changeset
|
93 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
|
94 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
|
95 end |
|
8d47858805c9
util.human.io: Add padleft, padright and a table printing function
Matthew Wild <mwild1@gmail.com>
parents:
10872
diff
changeset
|
96 |
|
8d47858805c9
util.human.io: Add padleft, padright and a table printing function
Matthew Wild <mwild1@gmail.com>
parents:
10872
diff
changeset
|
97 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
|
98 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
|
99 end |
|
8d47858805c9
util.human.io: Add padleft, padright and a table printing function
Matthew Wild <mwild1@gmail.com>
parents:
10872
diff
changeset
|
100 |
|
11896
93e9f7ae2f9b
util.human.io: Fix cutting of UTF-8 into pieces
Kim Alvefur <zash@zash.se>
parents:
11895
diff
changeset
|
101 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
|
102 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
|
103 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
|
104 end |
|
93e9f7ae2f9b
util.human.io: Fix cutting of UTF-8 into pieces
Kim Alvefur <zash@zash.se>
parents:
11895
diff
changeset
|
105 |
|
93e9f7ae2f9b
util.human.io: Fix cutting of UTF-8 into pieces
Kim Alvefur <zash@zash.se>
parents:
11895
diff
changeset
|
106 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
|
107 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
|
108 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
|
109 end |
|
93e9f7ae2f9b
util.human.io: Fix cutting of UTF-8 into pieces
Kim Alvefur <zash@zash.se>
parents:
11895
diff
changeset
|
110 end |
|
93e9f7ae2f9b
util.human.io: Fix cutting of UTF-8 into pieces
Kim Alvefur <zash@zash.se>
parents:
11895
diff
changeset
|
111 |
|
13044
5bd272095388
util.human.io: Add term_width() method to discover the terminal width
Matthew Wild <mwild1@gmail.com>
parents:
13040
diff
changeset
|
112 local function term_width(default) |
|
13051
164c2787901a
util.human.io: Coerce $COLUMNS to number
Kim Alvefur <zash@zash.se>
parents:
13049
diff
changeset
|
113 local env_cols = tonumber(os.getenv "COLUMNS"); |
|
13047
d939bf469057
util.human.io: Prefer using the $COLUMNS environment variable if set (by readline)
Kim Alvefur <zash@zash.se>
parents:
13045
diff
changeset
|
114 if env_cols then return env_cols; end |
|
13210
8dbe693ded6b
util.human.io: Fix stray 'stty' error by only querying width of real ttys
Kim Alvefur <zash@zash.se>
parents:
13199
diff
changeset
|
115 if not pposix.isatty(io.stdout) then |
|
8dbe693ded6b
util.human.io: Fix stray 'stty' error by only querying width of real ttys
Kim Alvefur <zash@zash.se>
parents:
13199
diff
changeset
|
116 return default; |
|
8dbe693ded6b
util.human.io: Fix stray 'stty' error by only querying width of real ttys
Kim Alvefur <zash@zash.se>
parents:
13199
diff
changeset
|
117 end |
|
13044
5bd272095388
util.human.io: Add term_width() method to discover the terminal width
Matthew Wild <mwild1@gmail.com>
parents:
13040
diff
changeset
|
118 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
|
119 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
|
120 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
|
121 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
|
122 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
|
123 end |
|
5bd272095388
util.human.io: Add term_width() method to discover the terminal width
Matthew Wild <mwild1@gmail.com>
parents:
13040
diff
changeset
|
124 stty:close(); |
|
5bd272095388
util.human.io: Add term_width() method to discover the terminal width
Matthew Wild <mwild1@gmail.com>
parents:
13040
diff
changeset
|
125 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
|
126 end |
|
5bd272095388
util.human.io: Add term_width() method to discover the terminal width
Matthew Wild <mwild1@gmail.com>
parents:
13040
diff
changeset
|
127 |
|
11894
57106c61d104
util.human.io: Factor out ellipsis function
Kim Alvefur <zash@zash.se>
parents:
11893
diff
changeset
|
128 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
|
129 if len(s) <= width then return s; end |
|
13067
386ca97bec5b
util.human.io: Fix error with ellipsis to negative length
Kim Alvefur <zash@zash.se>
parents:
13054
diff
changeset
|
130 if width <= 1 then return "…"; end |
|
11896
93e9f7ae2f9b
util.human.io: Fix cutting of UTF-8 into pieces
Kim Alvefur <zash@zash.se>
parents:
11895
diff
changeset
|
131 return utf8_cut(s, width - 1) .. "…"; |
|
11894
57106c61d104
util.human.io: Factor out ellipsis function
Kim Alvefur <zash@zash.se>
parents:
11893
diff
changeset
|
132 end |
|
57106c61d104
util.human.io: Factor out ellipsis function
Kim Alvefur <zash@zash.se>
parents:
11893
diff
changeset
|
133 |
|
13935
6a493e41c2cc
util.human.io: Factor out column width calculation
Kim Alvefur <zash@zash.se>
parents:
13367
diff
changeset
|
134 local function calculate_column_widths(col_specs, separator, max_width) |
|
10891
8d47858805c9
util.human.io: Add padleft, padright and a table printing function
Matthew Wild <mwild1@gmail.com>
parents:
10872
diff
changeset
|
135 local widths = {}; |
|
10907
6af28c756752
util.human.io: Draw a separator between columns
Kim Alvefur <zash@zash.se>
parents:
10904
diff
changeset
|
136 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
|
137 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
|
138 -- 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
|
139 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
|
140 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
|
141 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
|
142 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
|
143 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
|
144 widths[i] = width; |
|
8d47858805c9
util.human.io: Add padleft, padright and a table printing function
Matthew Wild <mwild1@gmail.com>
parents:
10872
diff
changeset
|
145 free_width = free_width - width; |
|
8d47858805c9
util.human.io: Add padleft, padright and a table printing function
Matthew Wild <mwild1@gmail.com>
parents:
10872
diff
changeset
|
146 end |
|
8d47858805c9
util.human.io: Add padleft, padright and a table printing function
Matthew Wild <mwild1@gmail.com>
parents:
10872
diff
changeset
|
147 end |
|
13030
1f89a2a9f532
util.human.io: Support for dynamic "proportional" columns
Matthew Wild <mwild1@gmail.com>
parents:
12975
diff
changeset
|
148 |
|
1f89a2a9f532
util.human.io: Support for dynamic "proportional" columns
Matthew Wild <mwild1@gmail.com>
parents:
12975
diff
changeset
|
149 -- Calculate width of proportional columns |
|
1f89a2a9f532
util.human.io: Support for dynamic "proportional" columns
Matthew Wild <mwild1@gmail.com>
parents:
12975
diff
changeset
|
150 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
|
151 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
|
152 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
|
153 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
|
154 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
|
155 end |
|
1f89a2a9f532
util.human.io: Support for dynamic "proportional" columns
Matthew Wild <mwild1@gmail.com>
parents:
12975
diff
changeset
|
156 end |
|
1f89a2a9f532
util.human.io: Support for dynamic "proportional" columns
Matthew Wild <mwild1@gmail.com>
parents:
12975
diff
changeset
|
157 |
|
1f89a2a9f532
util.human.io: Support for dynamic "proportional" columns
Matthew Wild <mwild1@gmail.com>
parents:
12975
diff
changeset
|
158 for i = 1, #col_specs do |
|
1f89a2a9f532
util.human.io: Support for dynamic "proportional" columns
Matthew Wild <mwild1@gmail.com>
parents:
12975
diff
changeset
|
159 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
|
160 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
|
161 local rel_width = tonumber(width_spec); |
|
1f89a2a9f532
util.human.io: Support for dynamic "proportional" columns
Matthew Wild <mwild1@gmail.com>
parents:
12975
diff
changeset
|
162 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
|
163 end |
|
8d47858805c9
util.human.io: Add padleft, padright and a table printing function
Matthew Wild <mwild1@gmail.com>
parents:
10872
diff
changeset
|
164 end |
|
8d47858805c9
util.human.io: Add padleft, padright and a table printing function
Matthew Wild <mwild1@gmail.com>
parents:
10872
diff
changeset
|
165 |
|
13935
6a493e41c2cc
util.human.io: Factor out column width calculation
Kim Alvefur <zash@zash.se>
parents:
13367
diff
changeset
|
166 return widths; |
|
6a493e41c2cc
util.human.io: Factor out column width calculation
Kim Alvefur <zash@zash.se>
parents:
13367
diff
changeset
|
167 end |
|
6a493e41c2cc
util.human.io: Factor out column width calculation
Kim Alvefur <zash@zash.se>
parents:
13367
diff
changeset
|
168 |
|
13936
4f1b6f6e68c0
util.human.io: Allow specifying a different column separator
Kim Alvefur <zash@zash.se>
parents:
13935
diff
changeset
|
169 local function new_table(col_specs, max_width, separator) |
|
4f1b6f6e68c0
util.human.io: Allow specifying a different column separator
Kim Alvefur <zash@zash.se>
parents:
13935
diff
changeset
|
170 separator = separator or " | "; |
|
13935
6a493e41c2cc
util.human.io: Factor out column width calculation
Kim Alvefur <zash@zash.se>
parents:
13367
diff
changeset
|
171 |
|
13937
cfe3e85e715f
util.human.io: Support disabling column widths
Kim Alvefur <zash@zash.se>
parents:
13936
diff
changeset
|
172 local widths; |
|
cfe3e85e715f
util.human.io: Support disabling column widths
Kim Alvefur <zash@zash.se>
parents:
13936
diff
changeset
|
173 if max_width ~= -1 then |
|
cfe3e85e715f
util.human.io: Support disabling column widths
Kim Alvefur <zash@zash.se>
parents:
13936
diff
changeset
|
174 max_width = max_width or term_width(80); |
|
cfe3e85e715f
util.human.io: Support disabling column widths
Kim Alvefur <zash@zash.se>
parents:
13936
diff
changeset
|
175 widths = calculate_column_widths(col_specs, separator, max_width) |
|
cfe3e85e715f
util.human.io: Support disabling column widths
Kim Alvefur <zash@zash.se>
parents:
13936
diff
changeset
|
176 else |
|
cfe3e85e715f
util.human.io: Support disabling column widths
Kim Alvefur <zash@zash.se>
parents:
13936
diff
changeset
|
177 widths = {}; |
|
cfe3e85e715f
util.human.io: Support disabling column widths
Kim Alvefur <zash@zash.se>
parents:
13936
diff
changeset
|
178 end |
|
13935
6a493e41c2cc
util.human.io: Factor out column width calculation
Kim Alvefur <zash@zash.se>
parents:
13367
diff
changeset
|
179 |
|
10893
a256044c1d12
util.human.io: table: switch row function to simply returning prepared row string
Matthew Wild <mwild1@gmail.com>
parents:
10891
diff
changeset
|
180 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
|
181 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
|
182 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
|
183 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
|
184 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
|
185 local output = {}; |
|
10891
8d47858805c9
util.human.io: Add padleft, padright and a table printing function
Matthew Wild <mwild1@gmail.com>
parents:
10872
diff
changeset
|
186 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
|
187 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
|
188 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
|
189 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
|
190 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
|
191 end |
|
e712133b4de1
util.human.io: Pass nil to cell mapper to signal missing value
Kim Alvefur <zash@zash.se>
parents:
10917
diff
changeset
|
192 if v == nil then |
|
11893
afef1e170de7
util.human.io: Support specifying column defaults in tables
Kim Alvefur <zash@zash.se>
parents:
11892
diff
changeset
|
193 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
|
194 else |
|
e712133b4de1
util.human.io: Pass nil to cell mapper to signal missing value
Kim Alvefur <zash@zash.se>
parents:
10917
diff
changeset
|
195 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
|
196 end |
|
13937
cfe3e85e715f
util.human.io: Support disabling column widths
Kim Alvefur <zash@zash.se>
parents:
13936
diff
changeset
|
197 if width then |
|
cfe3e85e715f
util.human.io: Support disabling column widths
Kim Alvefur <zash@zash.se>
parents:
13936
diff
changeset
|
198 if len(v) < width then |
|
cfe3e85e715f
util.human.io: Support disabling column widths
Kim Alvefur <zash@zash.se>
parents:
13936
diff
changeset
|
199 if column.align == "right" then |
|
cfe3e85e715f
util.human.io: Support disabling column widths
Kim Alvefur <zash@zash.se>
parents:
13936
diff
changeset
|
200 v = padleft(v, width); |
|
cfe3e85e715f
util.human.io: Support disabling column widths
Kim Alvefur <zash@zash.se>
parents:
13936
diff
changeset
|
201 else |
|
cfe3e85e715f
util.human.io: Support disabling column widths
Kim Alvefur <zash@zash.se>
parents:
13936
diff
changeset
|
202 v = padright(v, width); |
|
cfe3e85e715f
util.human.io: Support disabling column widths
Kim Alvefur <zash@zash.se>
parents:
13936
diff
changeset
|
203 end |
|
cfe3e85e715f
util.human.io: Support disabling column widths
Kim Alvefur <zash@zash.se>
parents:
13936
diff
changeset
|
204 elseif len(v) > width then |
|
cfe3e85e715f
util.human.io: Support disabling column widths
Kim Alvefur <zash@zash.se>
parents:
13936
diff
changeset
|
205 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
|
206 end |
|
8d47858805c9
util.human.io: Add padleft, padright and a table printing function
Matthew Wild <mwild1@gmail.com>
parents:
10872
diff
changeset
|
207 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
|
208 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
|
209 end |
|
10907
6af28c756752
util.human.io: Draw a separator between columns
Kim Alvefur <zash@zash.se>
parents:
10904
diff
changeset
|
210 return table.concat(output, separator); |
|
13048
946442df65d3
util.human.io: table: Return determined width as a second result
Matthew Wild <mwild1@gmail.com>
parents:
13047
diff
changeset
|
211 end, max_width; |
|
10891
8d47858805c9
util.human.io: Add padleft, padright and a table printing function
Matthew Wild <mwild1@gmail.com>
parents:
10872
diff
changeset
|
212 end |
|
8d47858805c9
util.human.io: Add padleft, padright and a table printing function
Matthew Wild <mwild1@gmail.com>
parents:
10872
diff
changeset
|
213 |
|
13054
f4d7fe919969
util.human.io: Add parse_duration() method to parse a duration string
Matthew Wild <mwild1@gmail.com>
parents:
13051
diff
changeset
|
214 local day = 86400; |
|
f4d7fe919969
util.human.io: Add parse_duration() method to parse a duration string
Matthew Wild <mwild1@gmail.com>
parents:
13051
diff
changeset
|
215 local multipliers = { |
|
13367
82513890a1d8
util.human.io: Don't accept ambiguous durations by default
Matthew Wild <mwild1@gmail.com>
parents:
13210
diff
changeset
|
216 d = day, w = day * 7, mon = 31 * day, y = 365.2425 * day; |
|
82513890a1d8
util.human.io: Don't accept ambiguous durations by default
Matthew Wild <mwild1@gmail.com>
parents:
13210
diff
changeset
|
217 s = 1, min = 60, h = 3600, ho = 3600 |
|
13054
f4d7fe919969
util.human.io: Add parse_duration() method to parse a duration string
Matthew Wild <mwild1@gmail.com>
parents:
13051
diff
changeset
|
218 }; |
|
13367
82513890a1d8
util.human.io: Don't accept ambiguous durations by default
Matthew Wild <mwild1@gmail.com>
parents:
13210
diff
changeset
|
219 |
|
13054
f4d7fe919969
util.human.io: Add parse_duration() method to parse a duration string
Matthew Wild <mwild1@gmail.com>
parents:
13051
diff
changeset
|
220 local function parse_duration(duration_string) |
|
13367
82513890a1d8
util.human.io: Don't accept ambiguous durations by default
Matthew Wild <mwild1@gmail.com>
parents:
13210
diff
changeset
|
221 local n, m = duration_string:lower():match("(%d+)%s*([smhdwy]?[io]?n?)"); |
|
82513890a1d8
util.human.io: Don't accept ambiguous durations by default
Matthew Wild <mwild1@gmail.com>
parents:
13210
diff
changeset
|
222 if not n or not multipliers[m] then return nil; end |
|
82513890a1d8
util.human.io: Don't accept ambiguous durations by default
Matthew Wild <mwild1@gmail.com>
parents:
13210
diff
changeset
|
223 return tonumber(n) * ( multipliers[m] or 1 ); |
|
82513890a1d8
util.human.io: Don't accept ambiguous durations by default
Matthew Wild <mwild1@gmail.com>
parents:
13210
diff
changeset
|
224 end |
|
82513890a1d8
util.human.io: Don't accept ambiguous durations by default
Matthew Wild <mwild1@gmail.com>
parents:
13210
diff
changeset
|
225 |
|
82513890a1d8
util.human.io: Don't accept ambiguous durations by default
Matthew Wild <mwild1@gmail.com>
parents:
13210
diff
changeset
|
226 local multipliers_lax = setmetatable({ |
|
82513890a1d8
util.human.io: Don't accept ambiguous durations by default
Matthew Wild <mwild1@gmail.com>
parents:
13210
diff
changeset
|
227 m = multipliers.mon; |
|
82513890a1d8
util.human.io: Don't accept ambiguous durations by default
Matthew Wild <mwild1@gmail.com>
parents:
13210
diff
changeset
|
228 mo = multipliers.mon; |
|
82513890a1d8
util.human.io: Don't accept ambiguous durations by default
Matthew Wild <mwild1@gmail.com>
parents:
13210
diff
changeset
|
229 mi = multipliers.min; |
|
82513890a1d8
util.human.io: Don't accept ambiguous durations by default
Matthew Wild <mwild1@gmail.com>
parents:
13210
diff
changeset
|
230 }, { __index = multipliers }); |
|
82513890a1d8
util.human.io: Don't accept ambiguous durations by default
Matthew Wild <mwild1@gmail.com>
parents:
13210
diff
changeset
|
231 |
|
82513890a1d8
util.human.io: Don't accept ambiguous durations by default
Matthew Wild <mwild1@gmail.com>
parents:
13210
diff
changeset
|
232 local function parse_duration_lax(duration_string) |
|
13199
278920294dfe
util.human.io: Fix pattern in parse_duration() to cover all used letters
Kim Alvefur <zash@zash.se>
parents:
13068
diff
changeset
|
233 local n, m = duration_string:lower():match("(%d+)%s*([smhdwy]?[io]?)"); |
|
13054
f4d7fe919969
util.human.io: Add parse_duration() method to parse a duration string
Matthew Wild <mwild1@gmail.com>
parents:
13051
diff
changeset
|
234 if not n then return nil; end |
|
13367
82513890a1d8
util.human.io: Don't accept ambiguous durations by default
Matthew Wild <mwild1@gmail.com>
parents:
13210
diff
changeset
|
235 return tonumber(n) * ( multipliers_lax[m] or 1 ); |
|
13054
f4d7fe919969
util.human.io: Add parse_duration() method to parse a duration string
Matthew Wild <mwild1@gmail.com>
parents:
13051
diff
changeset
|
236 end |
|
f4d7fe919969
util.human.io: Add parse_duration() method to parse a duration string
Matthew Wild <mwild1@gmail.com>
parents:
13051
diff
changeset
|
237 |
|
10870
3f1889608f3e
util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
238 return { |
|
3f1889608f3e
util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
239 getchar = getchar; |
|
3f1889608f3e
util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
240 getline = getline; |
|
3f1889608f3e
util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
241 getpass = getpass; |
|
3f1889608f3e
util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
242 show_yesno = show_yesno; |
|
3f1889608f3e
util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
243 read_password = read_password; |
|
3f1889608f3e
util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
244 show_prompt = show_prompt; |
|
3f1889608f3e
util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
245 printf = printf; |
|
10891
8d47858805c9
util.human.io: Add padleft, padright and a table printing function
Matthew Wild <mwild1@gmail.com>
parents:
10872
diff
changeset
|
246 padleft = padleft; |
|
8d47858805c9
util.human.io: Add padleft, padright and a table printing function
Matthew Wild <mwild1@gmail.com>
parents:
10872
diff
changeset
|
247 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
|
248 term_width = term_width; |
|
11894
57106c61d104
util.human.io: Factor out ellipsis function
Kim Alvefur <zash@zash.se>
parents:
11893
diff
changeset
|
249 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
|
250 table = new_table; |
|
13054
f4d7fe919969
util.human.io: Add parse_duration() method to parse a duration string
Matthew Wild <mwild1@gmail.com>
parents:
13051
diff
changeset
|
251 parse_duration = parse_duration; |
|
13367
82513890a1d8
util.human.io: Don't accept ambiguous durations by default
Matthew Wild <mwild1@gmail.com>
parents:
13210
diff
changeset
|
252 parse_duration_lax = parse_duration_lax; |
|
10870
3f1889608f3e
util.human.io: New central place for UI helpers
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
253 }; |
