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 Jun 24, 2021
1 parent b60a903 commit 1888c8a
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 55 deletions.
1 change: 1 addition & 0 deletions go.mod
Expand Up @@ -6,6 +6,7 @@ require (
github.com/gdamore/encoding v1.0.0
github.com/lucasb-eyer/go-colorful v1.0.3
github.com/mattn/go-runewidth v0.0.10
github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68
golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf
golang.org/x/text v0.3.0
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Expand Up @@ -6,6 +6,8 @@ github.com/mattn/go-runewidth v0.0.10 h1:CoZ3S2P7pvtP45xOtBw+/mDL2z0RKI576gSkzRR
github.com/mattn/go-runewidth v0.0.10/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
github.com/rivo/uniseg v0.1.0 h1:+2KBaVoUmb9XzDsrx/Ct0W/EYOSFf/nWTauy++DprtY=
github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 h1:QldyIu/L63oPpyvQmHgvgickp1Yw510KJOqX7H24mg8=
github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778/go.mod h1:2MuV+tbUrU1zIOPMxZ5EncGwgmMJsa+9ucAQZXxsObs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68 h1:nxC68pudNYkKU6jWhgrqdreuFiOQWj1Fs7T3VrH4Pjw=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf h1:MZ2shdL+ZM/XzY3ZGOnh4Nlpnxz5GSOhOmtHo3iPU6M=
Expand Down
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 @@ -360,6 +317,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 1888c8a

Please sign in to comment.