diff options
author | Avi Halachmi (:avih) <avihpit@yahoo.com> | 2021-07-30 09:23:56 +0300 |
---|---|---|
committer | avih <avih@users.noreply.github.com> | 2021-07-31 11:00:07 +0300 |
commit | 416668d3c8bb5d09ebb3d5e3dbe715856165898b (patch) | |
tree | e34b2d282ceba458f7ed10b69851b6b2e8a89f76 /player/lua | |
parent | 6857600c47f069aeb68232a745bc8f81d45c9967 (diff) | |
download | mpv-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).
Diffstat (limited to 'player/lua')
-rw-r--r-- | player/lua/stats.lua | 18 |
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}", |