diff --git a/colorfit.go b/colorfit.go index b7740b8a..f690097f 100644 --- a/colorfit.go +++ b/colorfit.go @@ -15,8 +15,9 @@ package tcell import ( - "github.com/lucasb-eyer/go-colorful" "math" + + "github.com/lucasb-eyer/go-colorful" ) // FindColor attempts to find a given color, or the best match possible for it, diff --git a/terminfo/dynamic/dynamic.go b/terminfo/dynamic/dynamic.go index 0ee6ba0c..5668e5cd 100644 --- a/terminfo/dynamic/dynamic.go +++ b/terminfo/dynamic/dynamic.go @@ -25,10 +25,11 @@ import ( "bytes" "errors" "os" + "os/exec" "regexp" + "strconv" "strings" - xoterminfo "github.com/xo/terminfo" "github.com/zyedidia/tcell/v2/terminfo" ) @@ -117,23 +118,65 @@ func unescape(s string) string { } func (tc *termcap) setupterm(name string) error { - ti, err := xoterminfo.Load(name) - if err != nil { + 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 { return err } - tc.name = name - tc.desc = "" - tc.aliases = []string{} - tc.bools = ti.BoolCapsShort() - tc.nums = ti.NumCapsShort() + // 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.strs = make(map[string]string) - strcaps := ti.StringCapsShort() - for k, v := range strcaps { - tc.strs[k] = string(v) + // 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.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 } diff --git a/tscreen.go b/tscreen.go index a8379545..7e9c410a 100644 --- a/tscreen.go +++ b/tscreen.go @@ -63,9 +63,9 @@ const ( // $COLUMNS environment variables can be set to the actual window size, // otherwise defaults taken from the terminal database are used. func NewTerminfoScreen() (Screen, error) { - ti, e := loadDynamicTerminfo(os.Getenv("TERM")) + ti, e := terminfo.LookupTerminfo(os.Getenv("TERM")) if e != nil { - ti, e = terminfo.LookupTerminfo(os.Getenv("TERM")) + ti, e = loadDynamicTerminfo(os.Getenv("TERM")) if e != nil { return nil, e } @@ -182,9 +182,13 @@ func (t *tScreen) Init() error { if os.Getenv("TCELL_TRUECOLOR") == "disable" { t.truecolor = false } - t.colors = make(map[Color]Color) - t.palette = make([]Color, t.nColors()) - for i := 0; i < t.nColors(); i++ { + nColors := t.nColors() + if nColors > 256 { + nColors = 256 // clip to reasonable limits + } + t.colors = make(map[Color]Color, nColors) + t.palette = make([]Color, nColors) + for i := 0; i < nColors; i++ { t.palette[i] = Color(i) | ColorValid // identity map for our builtin colors t.colors[Color(i)|ColorValid] = Color(i) | ColorValid