Comparison

util/human/io.lua @ 11896:93e9f7ae2f9b

util.human.io: Fix cutting of UTF-8 into pieces Down the rabbit hole we go...
author Kim Alvefur <zash@zash.se>
date Fri, 12 Nov 2021 14:21:15 +0100
parent 11895:d278a4c6da7f
child 11897:e84ea5b58b29
comparison
equal deleted inserted replaced
11895:d278a4c6da7f 11896:93e9f7ae2f9b
1 local array = require "util.array"; 1 local array = require "util.array";
2 local utf8 = rawget(_G,"utf8") or require"util.encodings".utf8; 2 local utf8 = rawget(_G, "utf8") or require"util.encodings".utf8;
3 local len = utf8.len or function(s)
4 local _, count = s:gsub("[%z\001-\127\194-\253][\128-\191]*", "");
5 return count;
6 end;
3 7
4 local function getchar(n) 8 local function getchar(n)
5 local stty_ret = os.execute("stty raw -echo 2>/dev/null"); 9 local stty_ret = os.execute("stty raw -echo 2>/dev/null");
6 local ok, char; 10 local ok, char;
7 if stty_ret == true or stty_ret == 0 then 11 if stty_ret == true or stty_ret == 0 then
94 98
95 local function padleft(s, width) 99 local function padleft(s, width)
96 return string.rep(" ", width-#s)..s; 100 return string.rep(" ", width-#s)..s;
97 end 101 end
98 102
103 local pat = "[%z\001-\127\194-\253][\128-\191]*";
104 local function utf8_cut(s, pos)
105 return s:match("^"..pat:rep(pos)) or s;
106 end
107
108 if utf8.len and utf8.offset then
109 function utf8_cut(s, pos)
110 return s:sub(1, utf8.offset(s, pos+1)-1);
111 end
112 end
113
99 local function ellipsis(s, width) 114 local function ellipsis(s, width)
100 if #s <= width then return s; end 115 if len(s) <= width then return s; end
101 s = s:sub(1, width - 1) 116 if width == 1 then return "…"; end
102 while not utf8.len(s) do s = s:sub(1, -2); end 117 return utf8_cut(s, width - 1) .. "…";
103 return s .. "…";
104 end 118 end
105 119
106 local function new_table(col_specs, max_width) 120 local function new_table(col_specs, max_width)
107 max_width = max_width or tonumber(os.getenv("COLUMNS")) or 80; 121 max_width = max_width or tonumber(os.getenv("COLUMNS")) or 80;
108 local separator = " | "; 122 local separator = " | ";
146 if v == nil then 160 if v == nil then
147 v = column.default or ""; 161 v = column.default or "";
148 else 162 else
149 v = tostring(v); 163 v = tostring(v);
150 end 164 end
151 if #v < width then 165 if len(v) < width then
152 if column.align == "right" then 166 if column.align == "right" then
153 v = padleft(v, width); 167 v = padleft(v, width);
154 else 168 else
155 v = padright(v, width); 169 v = padright(v, width);
156 end 170 end
157 elseif #v > width then 171 elseif len(v) > width then
158 v = ellipsis(v, width); 172 v = ellipsis(v, width);
159 end 173 end
160 table.insert(output, v); 174 table.insert(output, v);
161 end 175 end
162 return table.concat(output, separator); 176 return table.concat(output, separator);