Software / code / prosody
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); |