Skip to content

Commit

Permalink
Use xo/terminfo instead of infocmp
Browse files Browse the repository at this point in the history
  • Loading branch information
zyedidia committed Feb 12, 2024
1 parent 0393f5e commit 718ffbd
Showing 1 changed file with 18 additions and 55 deletions.
73 changes: 18 additions & 55 deletions terminfo/dynamic/dynamic.go
Expand Up @@ -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 {
Expand Down Expand Up @@ -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 "<name>|<alias>|...|<desc>"
// 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
}

Expand Down Expand Up @@ -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.
Expand Down

0 comments on commit 718ffbd

Please sign in to comment.