From 718ffbdd05f6ede996d2785bc5c36670f42d52e4 Mon Sep 17 00:00:00 2001 From: Zachary Yedidia Date: Wed, 5 May 2021 21:00:14 -0400 Subject: [PATCH] Use xo/terminfo instead of infocmp --- terminfo/dynamic/dynamic.go | 73 +++++++++---------------------------- 1 file changed, 18 insertions(+), 55 deletions(-) diff --git a/terminfo/dynamic/dynamic.go b/terminfo/dynamic/dynamic.go index 047ebded..43b0015e 100644 --- a/terminfo/dynamic/dynamic.go +++ b/terminfo/dynamic/dynamic.go @@ -24,12 +24,11 @@ package dynamic import ( "bytes" "errors" - "os/exec" "regexp" - "strconv" "strings" "github.com/gdamore/tcell/v2/terminfo" + xoterminfo "github.com/xo/terminfo" ) type termcap struct { @@ -117,65 +116,23 @@ func unescape(s string) string { } func (tc *termcap) setupterm(name string) error { - cmd := exec.Command("infocmp", "-1", name) - output := &bytes.Buffer{} - cmd.Stdout = output - - tc.strs = make(map[string]string) - tc.bools = make(map[string]bool) - tc.nums = make(map[string]int) - - if err := cmd.Run(); err != nil { + ti, err := xoterminfo.Load(name) + if err != nil { return err } - // Now parse the output. - // We get comment lines (starting with "#"), followed by - // a header line that looks like "||...|" - // then capabilities, one per line, starting with a tab and ending - // with a comma and newline. - lines := strings.Split(output.String(), "\n") - for len(lines) > 0 && strings.HasPrefix(lines[0], "#") { - lines = lines[1:] - } + tc.name = name + tc.desc = "" + tc.aliases = []string{} + tc.bools = ti.BoolCapsShort() + tc.nums = ti.NumCapsShort() - // Ditch trailing empty last line - if lines[len(lines)-1] == "" { - lines = lines[:len(lines)-1] - } - header := lines[0] - if strings.HasSuffix(header, ",") { - header = header[:len(header)-1] - } - names := strings.Split(header, "|") - tc.name = names[0] - names = names[1:] - if len(names) > 0 { - tc.desc = names[len(names)-1] - names = names[:len(names)-1] + tc.strs = make(map[string]string) + strcaps := ti.StringCapsShort() + for k, v := range strcaps { + tc.strs[k] = string(v) } - tc.aliases = names - for _, val := range lines[1:] { - if (!strings.HasPrefix(val, "\t")) || - (!strings.HasSuffix(val, ",")) { - return (errors.New("malformed infocmp: " + val)) - } - val = val[1:] - val = val[:len(val)-1] - - if k := strings.SplitN(val, "=", 2); len(k) == 2 { - tc.strs[k[0]] = unescape(k[1]) - } else if k := strings.SplitN(val, "#", 2); len(k) == 2 { - u, err := strconv.ParseUint(k[1], 0, 0) - if err != nil { - return (err) - } - tc.nums[k[0]] = int(u) - } else { - tc.bools[val] = true - } - } return nil } @@ -356,6 +313,12 @@ func LoadTerminfo(name string) (*terminfo.Terminfo, string, error) { t.KeyMetaShfEnd = "\x1b[1;10F" } + // If the terminal has all the 'standard' Xterm defines, use ModifiersXTerm to reconstruct + // ALL XTerm sequences dynamically + if t.KeyShfHome == "\x1b[1;2H" && t.KeyShfEnd == "\x1b[1;2F" && t.KeyShfRight == "\x1b[1;2C" && t.KeyShfLeft == "\x1b[1;2D" { + t.Modifiers = terminfo.ModifiersXTerm + } + // And the same thing for rxvt and workalikes (Eterm, aterm, etc.) // It seems that urxvt at least send escaped as ALT prefix for these, // although some places seem to indicate a separate ALT key sesquence.