summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAvi Halachmi (:avih) <avihpit@yahoo.com>2021-07-30 09:23:56 +0300
committeravih <avih@users.noreply.github.com>2021-07-31 11:00:07 +0300
commit416668d3c8bb5d09ebb3d5e3dbe715856165898b (patch)
treee34b2d282ceba458f7ed10b69851b6b2e8a89f76
parent6857600c47f069aeb68232a745bc8f81d45c9967 (diff)
downloadmpv-416668d3c8bb5d09ebb3d5e3dbe715856165898b.tar.bz2
mpv-416668d3c8bb5d09ebb3d5e3dbe715856165898b.tar.xz
stats.lua: page 4 (keys): better alignment of non-ascii keys
Previously we assumed the key-name string occupies strlen(name) cells, now we count codepoints instead. This improves alignment of non-english key names. Still not perfect because we don't know if the key name is single or double width, but wcwidth not available to scripts, notoriously unreliable (depends on locale, correct and updated tables, etc), and also not always available (Windows). Still, better than nothing, and we err by at most one cell - vs up to three before this commit (4 bytes keyname codepoint). In the future we could do the alignment using libass tags, however, this both complicates the ass-output generation, and also not available when we output for the terminal, so for now only count codepoints. Also, if the key name was in a right-to-left language, then previously the name/command were swapped visually. Now we inject a left-to-right marker before the name to ensure direction. This works also when harfbuzz is disabled for libass (--sub-ass-shaper=simple).
-rw-r--r--player/lua/stats.lua18
1 files changed, 16 insertions, 2 deletions
diff --git a/player/lua/stats.lua b/player/lua/stats.lua
index 2c906a6e32..87bff24f0f 100644
--- a/player/lua/stats.lua
+++ b/player/lua/stats.lua
@@ -405,6 +405,19 @@ local function cmd_subject(cmd)
return subw:len() > 1 and subw or "[unknown]"
end
+-- key names are valid UTF-8, ascii7 except maybe the last/only codepoint.
+-- we count codepoints and ignore wcwidth. no need for grapheme clusters.
+-- our error for alignment is at most one cell (if last CP is double-width).
+-- (if k was valid but arbitrary: we'd count all bytes <0x80 or >=0xc0)
+local function keyname_cells(k)
+ local klen = k:len()
+ if klen > 1 and k:byte(klen) >= 0x80 then -- last/only CP is not ascii7
+ repeat klen = klen-1
+ until klen == 1 or k:byte(klen) >= 0xc0 -- last CP begins at klen
+ end
+ return klen
+end
+
local function get_kbinfo_lines(width)
-- active keys: only highest priotity of each key, and not our (stats) keys
local bindings = mp.get_property_native("input-bindings", {})
@@ -437,7 +450,7 @@ local function get_kbinfo_lines(width)
end
local function align_right(key)
- return kspaces:sub(key:len()) .. key
+ return kspaces:sub(keyname_cells(key)) .. key
end
-- sort by: subject, mod(ifier)s count, mods, key-len, lowercase-key, key
@@ -460,8 +473,9 @@ local function get_kbinfo_lines(width)
-- key/subject pre/post formatting for terminal/ass.
-- key/subject alignment uses spaces (with mono font if ass)
-- word-wrapping is disabled for ass, or cut at 79 for the terminal
+ local LTR = string.char(0xE2, 0x80, 0x8E) -- U+200E Left To Right mark
local term = not o.use_ass
- local kpre = term and "" or format("{\\q2\\fn%s}", o.font_mono)
+ local kpre = term and "" or format("{\\q2\\fn%s}%s", o.font_mono, LTR)
local kpost = term and " " or format(" {\\fn%s}", o.font)
local spre = term and kspaces .. " "
or format("{\\q2\\fn%s}%s {\\fn%s}{\\fs%d\\u1}",