diff options
| author | raven <citrons@mondecitronne.com> | 2026-02-20 13:42:12 -0600 |
|---|---|---|
| committer | raven <citrons@mondecitronne.com> | 2026-02-20 13:46:59 -0600 |
| commit | 5b6196ebe67cf954bae8212c1a33b869da723e11 (patch) | |
| tree | dce33c06621847c3862e64bda914b1e8a450317d /tui/termfo/cmd | |
| parent | 05c068749740f9430d1fda7698c433697eef1652 (diff) | |
support builtin terminfo
copy termfo into the repository and modify it to embed an xterm terminfo to as
a fallback
Diffstat (limited to 'tui/termfo/cmd')
| -rw-r--r-- | tui/termfo/cmd/termfo/build.go | 168 | ||||
| -rw-r--r-- | tui/termfo/cmd/termfo/findcap.go | 150 | ||||
| -rw-r--r-- | tui/termfo/cmd/termfo/internal/term/term.go | 80 | ||||
| -rw-r--r-- | tui/termfo/cmd/termfo/keyscan.go | 120 | ||||
| -rw-r--r-- | tui/termfo/cmd/termfo/lscap.go | 27 | ||||
| -rw-r--r-- | tui/termfo/cmd/termfo/lsterm.go | 55 | ||||
| -rw-r--r-- | tui/termfo/cmd/termfo/main.go | 119 | ||||
| -rw-r--r-- | tui/termfo/cmd/termfo/mkhist.go | 235 | ||||
| -rw-r--r-- | tui/termfo/cmd/termfo/oldterm.go | 328 | ||||
| -rw-r--r-- | tui/termfo/cmd/termfo/show.go | 107 |
10 files changed, 1389 insertions, 0 deletions
diff --git a/tui/termfo/cmd/termfo/build.go b/tui/termfo/cmd/termfo/build.go new file mode 100644 index 0000000..c7e1223 --- /dev/null +++ b/tui/termfo/cmd/termfo/build.go @@ -0,0 +1,168 @@ +//go:build ignore + +package main + +import ( + "fmt" + "os" + "strings" +) + +// This is a little bit of an educated guess. I'm not sure what defaults these +// use. +var commonTerms = []string{ + "alacritty", + "ansi", "pcansi", + "cygwin", + "eterm", "eterm-color", + "gnome", "gnome-256color", "vte", "vte-2018", "vte-256color", "vte-direct", + "vscode", "vscode-direct", + "konsole", "konsole-256color", + "kterm", + "linux", + "rxvt", "rxvt-256color", "rxvt-88color", "rxvt-unicode", "rxvt-unicode-256color", + "screen", "screen-256color", + "st", "st-256color", + "termite", + "tmux", "tmux-256color", + "vt100", "vt102", "vt220", "vt320", "vt400", "vt420", + "xfce", + "xterm", "xterm-88color", "xterm-256color", + "xterm-kitty", +} + +// TODO: make output more stable; lots of map usage here. +// TODO: we can avoid a lot of duplication. +// +// TODO: change to: +// +// func init() { +// termfo.Loaders = append(termfo.Loaders, func(t string) *termfo.Terminfo { +// switch t { +// case "foo": +// extMap := "" +// return &termfo.Terminfo{} +// +// case "bar": +// // ... +// } +// }) +// } +func build(pkg string, terms ...string) { + for i, t := range terms { + if t == "%common" { + terms = append(append(terms[:i], terms[i+1:]...), commonTerms...) + break + } + } + noDup := make(map[string]struct{}) + for _, t := range terms { + noDup[t] = struct{}{} + } + + b := new(strings.Builder) + b.Grow(10_000) + b.WriteString("// Code generated by termfo; DO NOT EDIT.\n\n/* Command to generate:\n\n") + fmt.Fprintf(b, " termfo %s \\\n ", pkg) + b.WriteString(strings.Join(os.Args[3:], " \\\n ")) + fmt.Fprintf(b, "\n*/\n\npackage %s\n\nimport \"citrons.xyz/talk/tui/termfo\"\n\n", pkg) + + // Extended caps are created first; we want them to be the same pointer + // in Bools and Extended. + fmt.Fprintf(b, "func init() {\n\textMap := map[string][]*terminfo.Cap{\n") + extMap := make(map[string]map[string]int) + for t := range noDup { + ti, err := termfo.New(t) + if err != nil { + fatalf("could not load terminfo for %q; make sure it's present on "+ + "your system (you may need to install an additional package", t) + } + + extMap[t] = make(map[string]int) + fmt.Fprintf(b, "\t\t%#v: {\n", t) + for i, e := range ti.Extended { + fmt.Fprintf(b, "\t\t\t%#v,\n", e) + extMap[t][e.Short] = i + i++ + } + fmt.Fprintf(b, "\t\t},\n") + } + + fmt.Fprintf(b, "\t}\n\n\ttermfo.Builtins(map[string]*termfo.Terminfo{\n") + for t := range noDup { + ti, err := termfo.New(t) + if err != nil { + fatalf("could not load terminfo for %q; make sure it's present on "+ + "your system (you may need to install an additional package", t) + } + + ext := "" + for _, e := range ti.Extended { + ext += fmt.Sprintf("\t\t\t\textMap[%#v][%d],\n", t, extMap[t][e.Short]) + } + bools := "" + for c := range ti.Bools { + if e, ok := extMap[t][c.Short]; ok { + bools += fmt.Sprintf("\t\t\t\textMap[%#v][%d]: struct{}{},\n", t, e) + continue + } + for i, b := range termfo.CapBools { + if c.Short == b.Short { + bools += fmt.Sprintf("\t\t\t\ttermfo.CapBools[%d]: struct{}{},\n", i) + break + } + } + } + nums := "" + for c, v := range ti.Numbers { + if e, ok := extMap[t][c.Short]; ok { + nums += fmt.Sprintf("\t\t\t\textMap[%#v][%d]: %d,\n", t, e, v) + continue + } + for i, b := range termfo.CapNums { + if c.Short == b.Short { + nums += fmt.Sprintf("\t\t\t\ttermfo.CapNums[%d]: %d,\n", i, v) + break + } + } + } + strs := "" + for c, v := range ti.Strings { + if e, ok := extMap[t][c.Short]; ok { + strs += fmt.Sprintf("\t\t\t\textMap[%#v][%d]: %#v,\n", t, e, v) + continue + } + for i, b := range termfo.CapStrs { + if c.Short == b.Short { + strs += fmt.Sprintf("\t\t\t\ttermfo.CapStrs[%d]: %#v,\n", i, v) + break + } + } + } + + fmt.Fprintf(b, "\t\t%#v: &termfo.Terminfo{", ti.Name) + fmt.Fprintf(b, ` + Name: %#[1]v, + Desc: %#[2]v, + Aliases: %#[3]v, + IntSize: %[4]d, + Bools: map[*termfo.Cap]struct{}{ +%[5]s + }, + Numbers: map[*termfo.Cap]int32{ +%[6]s + }, + Strings: map[*termfo.Cap]string{ +%[7]s + }, + Extended: []*termfo.Cap{ +%[8]s + }, + },`, ti.Name, ti.Desc, ti.Aliases, ti.IntSize, bools, nums, strs, ext) + b.WriteRune('\n') + } + + fmt.Fprintf(b, "\t})\n}\n") + + fmt.Println(b) +} diff --git a/tui/termfo/cmd/termfo/findcap.go b/tui/termfo/cmd/termfo/findcap.go new file mode 100644 index 0000000..7664c25 --- /dev/null +++ b/tui/termfo/cmd/termfo/findcap.go @@ -0,0 +1,150 @@ +package main + +import ( + "fmt" + "sort" + "strings" + + "citrons.xyz/talk/tui/termfo" + "citrons.xyz/talk/tui/termfo/caps" +) + +func historical(term string) bool { + _, ok := oldterm[term] + return ok +} + +func termWithCap(name string, inclHist, expand, notSupported bool) { + c := findCap(name) + if c == nil { + fatalf("no cap: %q", name) + } + + list := make(map[string][]string) + for _, a := range allInfos("") { + if !inclHist && historical(a) { + continue + } + ti, err := termfo.New(a) + if err != nil { + fatalf(a, "\t", err) + continue + } + + if v, ok := findCapInTi(ti, c); ok { + list[v] = append(list[v], a) + } else if notSupported { + list["[not-supported]"] = append(list["[not-supported]"], a) + } + } + type termWithCap struct { + cap string + terms []string + } + order := make([]termWithCap, 0, len(list)) + pad := 0 + for k, v := range list { + k = fmt.Sprintf("%q", k) + vv := v + if !expand { + vv = dedup(v) + } + order = append(order, termWithCap{cap: k, terms: vv}) + if len(k) > pad { + pad = len(k) + } + } + if pad > 60 { // Some have ridiculously long escapes + pad = 60 + } + sort.SliceStable(order, func(i, j int) bool { return len(order[i].terms) > len(order[j].terms) }) + + w := 100 + pad += 4 + padf := fmt.Sprintf("%%-%ds", pad) + + fmt.Printf("Capability %q / %q: %s\n\n", c.Short, c.Long, c.Desc) + for _, o := range order { + p := o.terms[0] + l := pad + for _, vv := range o.terms[1:] { + if l > w { + p += "\n" + strings.Repeat(" ", pad+7) + vv + l = pad + len(vv) + 0 + } else { + p += " " + vv + l += len(vv) + 2 + } + } + fmt.Printf(padf+" → %3d %s\n", o.cap, len(o.terms), p) + if len(o.terms) > 10 { + fmt.Println() + } + } +} + +func findCap(name string) *caps.Cap { + for _, c := range caps.TableBools { + if c.Short == name || c.Long == name { + return c + } + } + for _, c := range caps.TableNums { + if c.Short == name || c.Long == name { + return c + } + } + for _, c := range caps.TableStrs { + if c.Short == name || c.Long == name { + return c + } + } + return nil +} + +func findCapInTi(ti *termfo.Terminfo, c *caps.Cap) (string, bool) { + if v, ok := ti.Strings[c]; ok { + return v, ok + } + if v2, ok := ti.Numbers[c]; ok { + return fmt.Sprintf("%v", v2), ok + } + if _, ok := ti.Bools[c]; ok { + return fmt.Sprintf("%v", ok), ok + } + return "", false +} + +// List xterm, xterm-256color, xterm-mono, etc. as xterm*; no need to list them +// all one-by-one here. +func dedup(list []string) []string { + dup := make(map[string][]string) + for _, l := range list { + i := strings.IndexAny(l, "-+") + if i > -1 { + dup[l[:i]] = append(dup[l[:i]], l) + } else { + dup[l] = append(dup[l], l) + } + } + + type o struct { + t string + l int + } + order := make([]o, 0, len(dup)) + for k, v := range dup { + order = append(order, o{k, len(v)}) + } + sort.Slice(order, func(i, j int) bool { return order[i].l > order[j].l }) + + ret := make([]string, 0, len(dup)) + for _, v := range order { + if v.l == 1 { + ret = append(ret, v.t) + } else { + ret = append(ret, fmt.Sprintf("%s* (%d)", v.t, v.l)) + } + } + return ret +} diff --git a/tui/termfo/cmd/termfo/internal/term/term.go b/tui/termfo/cmd/termfo/internal/term/term.go new file mode 100644 index 0000000..be46580 --- /dev/null +++ b/tui/termfo/cmd/termfo/internal/term/term.go @@ -0,0 +1,80 @@ +package term + +import ( + "fmt" + "syscall" + "unsafe" +) + +// Some terminal ioctl stuff; we do it here with the stdlib syscall package +// because I'd like to avoid depending on x/term and x/sys, as x/sys is quite +// large (~8.5M). This is used only for the "keyscan" demo, and not any critical +// functionality. +// +// The syscall package hasn't been maintained for quite a while, but this basic +// stuff should (hopefully) work on most systems. If not: well, not a big deal +// really. Maybe we can add a build flag to prefer x/term(?) + +type termios struct { + Iflag uint32 + Oflag uint32 + Cflag uint32 + Lflag uint32 + Line uint8 + Cc [19]uint8 + Ispeed uint32 + Ospeed uint32 +} + +func getTermios() (termios, error) { + var t termios + _, _, err := syscall.Syscall(syscall.SYS_IOCTL, 1, syscall.TCGETS, uintptr(unsafe.Pointer(&t))) + if err > 0 { + return t, fmt.Errorf("%s", err) + } + return t, nil +} + +func MakeRaw() (func(), error) { + termios, err := getTermios() + if err != nil { + return nil, err + } + + old := termios + termios.Iflag &^= syscall.IGNBRK | syscall.BRKINT | syscall.PARMRK | syscall.ISTRIP | + syscall.INLCR | syscall.IGNCR | syscall.ICRNL | syscall.IXON + termios.Lflag &^= syscall.ECHO | syscall.ECHONL | syscall.ICANON | syscall.ISIG | syscall.IEXTEN + termios.Oflag &^= syscall.OPOST + termios.Cflag &^= syscall.CSIZE | syscall.PARENB + termios.Cflag |= syscall.CS8 + termios.Cc[syscall.VMIN] = 1 + termios.Cc[syscall.VTIME] = 0 + + _, _, errno := syscall.Syscall(syscall.SYS_IOCTL, 1, syscall.TCSETS, uintptr(unsafe.Pointer(&termios))) + if errno > 0 { + return nil, fmt.Errorf("%s", errno) + } + + return func() { + syscall.Syscall(syscall.SYS_IOCTL, 1, syscall.TCSETS, uintptr(unsafe.Pointer(&old))) + }, nil +} + +func IsTerminal() bool { + _, err := getTermios() + return err == nil +} + +func Size() (int, int) { + var size struct { + Height, Width uint16 + Xpixel, Ypixel uint16 + } + _, _, err := syscall.Syscall(syscall.SYS_IOCTL, 0, syscall.TIOCGWINSZ, uintptr(unsafe.Pointer(&size))) + if err > 0 || size.Width <= 0 || size.Height <= 0 { + return -1, -1 + } + return int(size.Width), int(size.Height) + +} diff --git a/tui/termfo/cmd/termfo/keyscan.go b/tui/termfo/cmd/termfo/keyscan.go new file mode 100644 index 0000000..c79a991 --- /dev/null +++ b/tui/termfo/cmd/termfo/keyscan.go @@ -0,0 +1,120 @@ +package main + +import ( + "fmt" + "os" + "sort" + "strings" + "unicode" + + "citrons.xyz/talk/tui/termfo" + "citrons.xyz/talk/tui/termfo/caps" + "citrons.xyz/talk/tui/termfo/cmd/termfo/internal/term" + "citrons.xyz/talk/tui/termfo/keys" +) + +func keyscan() { + ti, err := termfo.New("") + if err != nil { + fatalf("%s", err) + } + + restore, err := term.MakeRaw() + if err != nil { + fatalf("%s", err) + } + defer restore() + + fmt.Printf("Loaded terminfo for %q\r\n", ti.Name) + fmt.Print("<C-k> to list key sequences we know about; <C-t> to print terminfo; <C-c> to quit\r\n\n") + + fmt.Printf("%-48s │ %-20s\r\n", "Received", "Sent on channel") + fmt.Printf("%s┼%s\r\n", strings.Repeat("─", 49), strings.Repeat("─", 50)) + + ch := ti.FindKeys(os.Stdin) + for e := <-ch; ; e = <-ch { + if e.Err != nil { + fatalf("keyscan error: %s", e.Err) + } + + showKey(e) + + switch e.Key { + case 'c' | keys.Ctrl: + return + case 't' | keys.Ctrl: + more(ti, ch, fmtTerminfo(ti)) + case 'k' | keys.Ctrl: + more(ti, ch, listKeys(ti)) + } + } +} + +// A very simple pager. +func more(ti *termfo.Terminfo, ch <-chan termfo.Event, s string) { + if height <= 0 { + fmt.Print(strings.ReplaceAll(s, "\n", "\r\n")) + return + } + + lines := strings.Split(s, "\n") + for i, l := range lines { + fmt.Print(l, "\r\n") + if i > 0 && (i+1)%(height-1) == 0 { + fmt.Printf("%s--- Displaying %d-%d of %d. Press any key to show more or <C-C> to abort%s\r", + ti.Strings[caps.EnterStandoutMode], + i-height+3, i+3, len(lines), + ti.Strings[caps.ExitStandoutMode]) + if kk := <-ch; kk.Key == 'c'|keys.Ctrl { + fmt.Print("\r", ti.Strings[caps.ClrEol]) + return + } + } + } +} + +func showKey(e termfo.Event) { + fmt.Printf("Pressed %-40s │ → Key %-12s 0x%02x", + fmt.Sprintf("%-10s 0x% 2x", prSeq(string(e.Seq)), e.Seq), e.Key, rune(e.Key)) + if e.Key.Shift() { + fmt.Print("|Shift") + } + if e.Key.Ctrl() { + fmt.Print("|Ctrl") + } + if e.Key.Alt() { + fmt.Print("|Alt") + } + if kk := e.Key.WithoutMods(); kk < unicode.MaxRune { + fmt.Printf(" U+%04X", rune(kk)) + } + fmt.Print("\r\n") +} + +func listKeys(ti *termfo.Terminfo) string { + all := make([]string, 0, len(ti.Keys)) + for seq, k2 := range ti.Keys { + all = append(all, fmt.Sprintf(" %-22s → %-20s", prSeq(seq), k2)) + } + sort.Strings(all) + + b := new(strings.Builder) + fmt.Fprintf(b, "%d keys; note that not all of these may be supported by your terminal (especially multiple modifiers)\r\n", len(all)) + + w := width - 10 + p := 0 + for _, s := range all { + b.WriteString(s) + p += len(s) + if p > w { + b.WriteString("\r\n") + p = 0 + } + } + b.WriteString("\r\n") + return b.String() +} + +func prSeq(s string) string { + return strings.ReplaceAll(fmt.Sprintf("%q", s), `\x1b`, `\E`) +} diff --git a/tui/termfo/cmd/termfo/lscap.go b/tui/termfo/cmd/termfo/lscap.go new file mode 100644 index 0000000..55ba0c1 --- /dev/null +++ b/tui/termfo/cmd/termfo/lscap.go @@ -0,0 +1,27 @@ +package main + +import ( + "fmt" + "path/filepath" + "sort" + + "citrons.xyz/talk/tui/termfo/caps" +) + +func lsCap(match string) { + all := append(append(caps.TableBools, caps.TableNums...), caps.TableStrs...) + sort.Slice(all, func(i, j int) bool { return all[i].Long < all[j].Long }) + + for _, c := range all { + if match != "" { + m1, _ := filepath.Match(match, c.Short) + m2, _ := filepath.Match(match, c.Long) + if !m1 && !m2 { + continue + } + } + + fmt.Printf("%-30s %-12s %s", c.Long, c.Short, c.Desc) + fmt.Println() + } +} diff --git a/tui/termfo/cmd/termfo/lsterm.go b/tui/termfo/cmd/termfo/lsterm.go new file mode 100644 index 0000000..da7ea5f --- /dev/null +++ b/tui/termfo/cmd/termfo/lsterm.go @@ -0,0 +1,55 @@ +package main + +import ( + "fmt" + "os" + "path/filepath" + "strings" + + "citrons.xyz/talk/tui/termfo" +) + +func lsTerm(match string) { + fmt.Printf("%-20s │ %-42s │ %s\n", "Name", "Data", "Aliases") + fmt.Printf("%s┼%s┼%s\n", + strings.Repeat("─", 21), + strings.Repeat("─", 44), + strings.Repeat("─", 30)) + + for _, a := range allInfos(match) { + if m, _ := filepath.Match(match, a); match != "" && !m { + continue + } + ti, err := termfo.New(a) + if err != nil { + fatalf("error reading %q: %s", a, err) + } + + //fmt.Printf("%-20s %-40s │ %s\n", ti.Name, strings.Join(ti.Aliases, ", "), ti.Desc) + fmt.Printf("%-20s │ bool: %2d num: %2d str: %3d key: %3d ext: %2d │ %s", + ti.Name, len(ti.Bools), len(ti.Numbers), len(ti.Strings), len(ti.Keys), len(ti.Extended), + strings.Join(ti.Aliases, ", ")) + + fmt.Println() + } +} + +func allInfos(match string) []string { + if _, err := os.Open("/usr/share/terminfo"); os.IsNotExist(err) { + fatalf("/usr/share/terminfo doesn't exist") + } + + all, err := filepath.Glob("/usr/share/terminfo/*/*") + if err != nil { + fatalf("reading \"/usr/share/terminfo\" %s", err) + } + + all2 := make([]string, 0, len(all)) + for _, a := range all { + a = filepath.Base(a) + if !strings.ContainsRune(a, '.') { + all2 = append(all2, a) + } + } + return all2 +} diff --git a/tui/termfo/cmd/termfo/main.go b/tui/termfo/cmd/termfo/main.go new file mode 100644 index 0000000..e8ae805 --- /dev/null +++ b/tui/termfo/cmd/termfo/main.go @@ -0,0 +1,119 @@ +// Program termfo prints information about the terminfo database. +package main + +import ( + "fmt" + "os" + "strings" + + "citrons.xyz/talk/tui/termfo/cmd/termfo/internal/term" +) + +const usage = `Usage: termfo [cmd] + +Display information about terminfo files. + +Commands: + ls-term [glob] List terminals/terminfos. + ls-cap [glob] List capabilities. + show [term] [term...] Show terminfo for term; defaults to TERM if none + given. Use "all" to list all terminfo files. + keyscan Scan for keys. + find-cap [cap cap..] Show all terminals with these capabilities. + + Flags: + -o, -old + Also show (very) old terminals. + -e, -expand + Show every terminfo name, rather than + grouping by prefix. + -n, -not, -not-supported + Also show terminals that don't support + this cap at all. +` + +// build [pkg] [terms..] Generate a Go file for package [pkg] with terminals to compile in. +// Use '%common' for a list of common terminals in use today. + +func fatalf(f string, a ...any) { + fmt.Fprintf(os.Stderr, f+"\n", a...) + os.Exit(1) +} + +var ( + width, height = term.Size() + isTerm = term.IsTerminal() +) + +func main() { + if len(os.Args) == 1 { + fmt.Print(usage) + os.Exit(0) + } + + switch os.Args[1] { + default: + fatalf("unknown command: %q", os.Args[1]) + case "help", "-h", "-help", "--help": + fmt.Print(usage) + os.Exit(0) + case "ls-term": + m := "" + if len(os.Args) > 2 { + m = os.Args[2] + } + lsTerm(m) + case "ls-cap": + m := "" + if len(os.Args) > 2 { + m = os.Args[2] + } + lsCap(m) + case "show": + if len(os.Args) > 2 && os.Args[2] == "all" { + show(allInfos("*")...) + } else if len(os.Args) > 2 { + show(os.Args[2:]...) + } else { + show(os.Getenv("TERM")) + } + case "find-cap": + if len(os.Args) <= 2 { + fatalf("need a cap name") + } + var ( + hist, expand, notSup bool + capName string + ) + for _, a := range os.Args[2:] { + if len(a) > 0 && a[0] == '-' { + switch strings.TrimLeft(a, "-") { + case "o", "old": + hist = true + case "e", "expand": + expand = true + case "n", "not", "not-supported": + notSup = true + default: + fatalf("unknown flag: %q", a) + } + continue + } + if capName != "" { + fatalf("can only show one capability") + } + capName = a + } + termWithCap(capName, hist, expand, notSup) + //case "build": + // if len(os.Args) <= 2 { + // fatalf("need a package name to use") + // } + // if len(os.Args) <= 3 { + // fatalf("need at least one terminal name") + // } + // build(os.Args[2], os.Args[3:]...) + case "keyscan": + keyscan() + } +} diff --git a/tui/termfo/cmd/termfo/mkhist.go b/tui/termfo/cmd/termfo/mkhist.go new file mode 100644 index 0000000..9270dd0 --- /dev/null +++ b/tui/termfo/cmd/termfo/mkhist.go @@ -0,0 +1,235 @@ +//go:build ignore + +package main + +import ( + "cmp" + "fmt" + "os" + "slices" + "strings" +) + +func main() { + f, err := os.ReadFile(os.Args[1]) + if err != nil { + panic(err) + } + + // ######## APPLE → #### Terminal.app → ... + var ( + terms = make(map[string]map[string][]string) + sect, subsect string + ) + for _, l := range strings.Split(string(f), "\n") { + if strings.HasPrefix(l, "########") { + sect = strings.TrimLeft(l, "# ") + terms[sect] = make(map[string][]string) + continue + } + if strings.HasPrefix(l, "####") && !strings.Contains(l, "TERMINFO FILE CAN BE SPLIT HERE") { + subsect = strings.TrimLeft(l, "# ") + terms[sect][subsect] = []string{} + continue + } + if !strings.HasPrefix(l, "\t") && strings.HasSuffix(l, ",") && strings.Contains(l, "|") { + t := strings.Split(l, "|") + terms[sect][subsect] = append(terms[sect][subsect], t[:len(t)-1]...) + } + } + + // for k, v := range terms { + // fmt.Println(k) + // for k2, v2 := range v { + // fmt.Println(" ", k2) + // fmt.Println(" ", v2) + // } + // } + // return + + fmt.Println("package main\n\nvar oldterm = map[string]int{") + dopr := func(k string, list []string) { + fmt.Printf("\t// %s\n\t", k) + for _, v := range list { + fmt.Printf("%q: 1,", v) + } + fmt.Println() + } + only := func(list []string, incl ...string) []string { + n := make([]string, 0, 16) + for _, v := range list { + for _, i := range incl { + if strings.HasPrefix(v, i) { + n = append(n, v) + continue + } + } + } + return n + } + for _, k := range ordered(terms) { + v := terms[k] + switch k { + // Pretty much all old hardware terminals. + case "OLDER TERMINAL TYPES", "OTHER OBSOLETE TYPES", "LCD DISPLAYS", "OBSOLETE VDT TYPES", + "COMMON TERMINAL TYPES": // Common hardware terminals in 1990 + fmt.Printf("\t// %s\n", k) + for _, k2 := range ordered(v) { + dopr(k2, v[k2]) + } + + // All of these are very old and/or for outdated versions. + case "Non-Unix Consoles", "NON-ANSI TERMINAL EMULATIONS", "OBSOLETE UNIX CONSOLES", + "COMMERCIAL WORKSTATION CONSOLES", "OBSOLETE PERSONAL-MICRO CONSOLES AND EMULATIONS": + fmt.Printf("\t// %s\n", k) + for _, k2 := range ordered(v) { + dopr(k2, v[k2]) + } + case "APPLE": + for _, k2 := range ordered(v) { + fmt.Printf("\t// %s\n", k) + switch k2 { + case "Terminal.app": + dopr(k2, only(v[k2], "nsterm-build", "nsterm+", "nsterm-7", "nsterm-old")) + // xnuppc* and darwin* is old PowerPC system console. + case "iTerm, iTerm2": + dopr(k2, only(v[k2], "xnuppc", "darwin")) + } + } + case "UNIX VIRTUAL TERMINALS, VIRTUAL CONSOLES, AND TELNET CLIENTS": + fmt.Printf("\t// %s\n", k) + for _, k2 := range ordered(v) { + switch k2 { + // Old Palm pilot, telnet + case "NCSA Telnet", "Pilot Pro Palm-Top": + dopr(k2, v[k2]) + case "Screen": + dopr(k2, only(v[k2], "screen2", "screen3", "screen4", "screen5")) // Old versions + } + } + dopr("CB UNIX, early 80s", []string{"cbunix", "vremote", "pty"}) + case "X TERMINAL EMULATORS": + fmt.Printf("\t// %s\n", k) + for _, k2 := range ordered(v) { + switch k2 { + // "Multi Gnome Terminal", hasn't been updated in 20 years + case "Other GNOME": + dopr(k2, only(v[k2], "mgt")) + // Old pre-VTE gnome-terminal, and specific gnome-terminal/VTE versions + case "GNOME (VTE)": + dopr(k2, only(v[k2], "gnome", + "vte-2007", "vte-2008", "vte-2012", "vte-2014", "vte-2017", "vte-2018")) + case "SIMPLETERM": + dopr(k2, only(v[k2], "st-0.", "old-st", "simpleterm")) // Old versions + case "TERMINOLOGY": + dopr(k2, only(v[k2], "terminology-0", "terminology-1")) // Old versions + case "MLTERM": + dopr(k2, only(v[k2], "mlterm3", "mlterm2")) // Old versions + case "KDE": + dopr(k2, only(v[k2], + // Old konsole name (<2001). + "kvt", + // Old seemingly obselete konsole variants. + "konsole-xf")) + case "XTERM": + // Old versions + dopr(k2, only(v[k2], "x10term", "xterm-r5", "xterm-r6", "xterm-old", "xterm-xf86", "xterm-xfree86", + "xterm-24", "vs100", "xterms", "xterm-new")) + case "XTERM Features": + dopr(k2, only(v[k2], "xterm-8bit", "xterm-vt52", "xterm1", "xterm-nic", "xterm-hp")) + case "Other XTERM": + dopr(k2, only(v[k2], + // Old xterm fork from before xterm supported ECMA-64 colors + "color_xterm", "cx", + // Weird terminal with weird overrides. + "xterm-pcolor", + // xterm as distributes with late 90s Solaris. + "xtermc", "xtermm", "xterm-sun", "xterms-sun", + )) + case + // Old Xfree86 term, or something. + "EMU", + // MGR is old Bell Labs thingy + // https://en.wikipedia.org/wiki/ManaGeR + // https://hack.org/mc/mgr/ + "MGR", + // Seems to be some old (non-ANSI) emulator? Can't find much about it. + "MTERM", + // Seems to be (very) old version of "Rocket® Terminal Emulator" + // https://www.rocketsoftware.com/products/rocket-terminal-emulator/rocket-terminal-emulation + "MVTERM", + // Old versions of https://github.com/TragicWarrior/vwm + "VWM", + // RXVT hasn't been updated in >20 years; no one ships it + // any more (e.g. on Debian it links to rxvt-unicode). + "RXVT", + // Not updated for ages; not packaged by Debian. + "MRXVT", + // Old emulator from 90s with support for Kanji + // https://ja.wikipedia.org/wiki/Kterm + "KTERM", + // HP-UX hpterm terminal emulator; I'm not really sure if + // this is still in use on modern HP-UX systems. Even if it + // is: it's pretty obscure. + "HPTERM": + dopr(k2, v[k2]) + } + } + case "ANSI, UNIX CONSOLE, AND SPECIAL TYPES": + fmt.Printf("\t// %s\n", k) + for _, k2 := range ordered(v) { + switch k2 { + // Only include vt220; no one really targets vt100, or vt400, or + // whatnot. + case "DEC VT100 and compatibles": + dopr(k2, only(v[k2], "vt100", "vt102", "vt125", "vt13", "vt200", + "vt220-old", "vt220-8", "vt220d", "vt3", "vt4", "vt5", "dec-")) + // Old NetBSD system consoles + case "NetBSD consoles": + dopr(k2, only(v[k2], "pcvt", "arm100", "x68k", "ofcons", "rcons", "mgterm", "netbsd6")) + case "ANSI.SYS/ISO 6429/ECMA-48 Capabilities": + dopr(k2, only(v[k2], + "ibcs2", // iBCS is some failed Intel standard + )) + case "ANSI/ECMA-48 terminals and terminal emulators": + dopr(k2, only(v[k2], + "ansi77", // 1977 ANSI + )) + case + "Specials", + "DEC VT52", + "VT100 emulations", + "SCO consoles", "SGI consoles", "386BSD and BSD/OS Consoles", // Old Unix + "Atari ST terminals", // Atari ST (1985) + "Mach", // No one uses this. + "BeOS", // Don't think this is used? + "DOS ANSI.SYS variants", // Old DOS; not used I think. + "QNX": // QNX 4 (1990); probably not used on modern QNX. + dopr(k2, v[k2]) + } + } + case "DOS/WINDOWS": + fmt.Printf("\t// %s\n", k) + for _, k2 := range ordered(v) { + switch k2 { + case "Command prompt": + dopr(k2, only(v[k2], "vt100+", "ms-vt100", "ms-vt-", "vtnt", "vt-utf")) // WinNT 4 + case "PuTTY": + dopr(k2, only(v[k2], "vt100-putty", "putty-vt100", "putty+fnkeys+vt100", "putty+fnkeys+vt400")) + } + } + // CRT is very old outdated version of SecureCRT + dopr("CRT is very old outdated version of SecureCRT", []string{"crt", "crt-vt220"}) + } + } + fmt.Println("}") +} + +func ordered[M ~map[K]V, K cmp.Ordered, V any](m M) []K { + r := make([]K, 0, len(m)) + for k := range m { + r = append(r, k) + } + slices.Sort(r) + return r +} diff --git a/tui/termfo/cmd/termfo/oldterm.go b/tui/termfo/cmd/termfo/oldterm.go new file mode 100644 index 0000000..8a42fd7 --- /dev/null +++ b/tui/termfo/cmd/termfo/oldterm.go @@ -0,0 +1,328 @@ +package main + +var oldterm = map[string]int{ + // ANSI, UNIX CONSOLE, AND SPECIAL TYPES + // 386BSD and BSD/OS Consoles + "origpc3": 1,"origibmpc3": 1,"oldpc3": 1,"oldibmpc3": 1,"bsdos-pc": 1,"bsdos-pc-nobold": 1,"bsdos-pc-m": 1,"bsdos-pc-mono": 1,"pc3": 1,"ibmpc3": 1,"pc3-bold": 1,"bsdos-sparc": 1,"bsdos-ppc": 1, + // ANSI.SYS/ISO 6429/ECMA-48 Capabilities + "ibcs2": 1, + // ANSI/ECMA-48 terminals and terminal emulators + "ansi77": 1, + // Atari ST terminals + "tw52": 1,"tw52-color": 1,"tw52-m": 1,"tt52": 1,"st52-color": 1,"at-color": 1,"atari-color": 1,"atari_st-color": 1,"st52": 1,"st52-m": 1,"at": 1,"at-m": 1,"atari": 1,"atari-m": 1,"atari_st": 1,"atarist-m": 1,"tw100": 1,"stv52": 1,"stv52pc": 1,"atari-old": 1,"uniterm": 1,"uniterm49": 1,"st52-old": 1, + // BeOS + "beterm": 1, + // DEC VT100 and compatibles + "vt100+keypad": 1,"vt100+pfkeys": 1,"vt100+fnkeys": 1,"vt100+enq": 1,"vt102+enq": 1,"vt100": 1,"vt100-am": 1,"vt100+4bsd": 1,"vt100nam": 1,"vt100-nam": 1,"vt100-vb": 1,"vt100-w": 1,"vt100-w-am": 1,"vt100-w-nam": 1,"vt100-nam-w": 1,"vt100-nav": 1,"vt100-nav-w": 1,"vt100-w-nav": 1,"vt100-s": 1,"vt100-s-top": 1,"vt100-top-s": 1,"vt100-s-bot": 1,"vt100-bot-s": 1,"vt102": 1,"vt102-w": 1,"vt102-nsgr": 1,"vt125": 1,"vt131": 1,"vt132": 1,"vt220-old": 1,"vt200-old": 1,"vt200": 1,"vt200-w": 1,"vt220-8bit": 1,"vt220-8": 1,"vt200-8bit": 1,"vt200-8": 1,"vt220d": 1,"vt200-js": 1,"vt320nam": 1,"vt320": 1,"vt300": 1,"vt320-nam": 1,"vt300-nam": 1,"vt320-w": 1,"vt300-w": 1,"vt320-w-nam": 1,"vt300-w-nam": 1,"vt340": 1,"dec-vt340": 1,"vt330": 1,"dec-vt330": 1,"vt420+lrmm": 1,"vt400": 1,"vt400-24": 1,"dec-vt400": 1,"vt420": 1,"vt420pc": 1,"vt420pcdos": 1,"vt420f": 1,"vt510": 1,"vt510pc": 1,"vt510pcdos": 1,"vt520": 1,"vt525": 1,"vt520ansi": 1, + // DEC VT52 + "vt52": 1,"vt52-basic": 1,"vt52+arrows": 1, + // DOS ANSI.SYS variants + "ansi.sys-old": 1,"ansi.sys": 1,"ansi.sysk": 1,"ansisysk": 1,"nansi.sys": 1,"nansisys": 1,"nansi.sysk": 1,"nansisysk": 1, + // Mach + "mach": 1,"mach-bold": 1,"mach-color": 1,"mach-gnu": 1,"mach-gnu-color": 1,"hurd": 1, + // NetBSD consoles + "pcvtXX": 1,"pcvt25": 1,"pcvt28": 1,"pcvt35": 1,"pcvt40": 1,"pcvt43": 1,"pcvt50": 1,"pcvt25w": 1,"pcvt28w": 1,"pcvt35w": 1,"pcvt40w": 1,"pcvt43w": 1,"pcvt50w": 1,"pcvt25-color": 1,"arm100": 1,"arm100-am": 1,"arm100-w": 1,"arm100-wam": 1,"x68k": 1,"x68k-ite": 1,"ofcons": 1,"netbsd6": 1,"rcons": 1,"rcons-color": 1,"mgterm": 1, + // QNX + "qnx": 1,"qnx4": 1,"qnxt": 1,"qnxt4": 1,"qnxm": 1,"qnxw": 1,"qnxtmono": 1,"qnxt2": 1,"qansi-g": 1,"qansi": 1,"qansi-t": 1,"qansi-m": 1,"qansi-w": 1, + // SCO consoles + "scoansi-old": 1,"scoansi-new": 1,"scoansi": 1, + // SGI consoles + "iris-ansi": 1,"iris-ansi-net": 1,"iris-ansi-ap": 1,"iris-color": 1,"xwsh": 1, + // Specials + "dumb": 1,"unknown": 1,"lpr": 1,"printer": 1,"glasstty": 1,"vanilla": 1,"9term": 1, + // VT100 emulations + "dec-vt100": 1,"dec-vt220": 1,"z340": 1,"z340-nam": 1,"tt": 1,"tkterm": 1, + // APPLE + // Terminal.app + "nsterm+7": 1,"nsterm+acs": 1,"nsterm+mac": 1,"nsterm+s": 1,"nsterm+c": 1,"nsterm+c41": 1,"nsterm-7-m": 1,"nsterm-7-m-s": 1,"nsterm-7": 1,"nsterm-7-c": 1,"nsterm-7-s": 1,"nsterm-7-c-s": 1,"nsterm-old": 1,"nsterm-build309": 1,"nsterm-build326": 1,"nsterm-build343": 1,"nsterm-build361": 1,"nsterm-build400": 1,"nsterm-build440": 1, + // APPLE + // iTerm, iTerm2 + "xnuppc+basic": 1,"xnuppc+c": 1,"xnuppc+b": 1,"xnuppc+f": 1,"xnuppc+f2": 1,"xnuppc+80x25": 1,"xnuppc+80x30": 1,"xnuppc+90x30": 1,"xnuppc+100x37": 1,"xnuppc+112x37": 1,"xnuppc+128x40": 1,"xnuppc+128x48": 1,"xnuppc+144x48": 1,"xnuppc+160x64": 1,"xnuppc+200x64": 1,"xnuppc+200x75": 1,"xnuppc+256x96": 1,"xnuppc-m": 1,"darwin-m": 1,"xnuppc": 1,"darwin": 1,"xnuppc-m-b": 1,"darwin-m-b": 1,"xnuppc-b": 1,"darwin-b": 1,"xnuppc-m-f": 1,"darwin-m-f": 1,"xnuppc-f": 1,"darwin-f": 1,"xnuppc-m-f2": 1,"darwin-m-f2": 1,"xnuppc-f2": 1,"darwin-f2": 1,"xnuppc-80x25-m": 1,"darwin-80x25-m": 1,"xnuppc-80x25": 1,"darwin-80x25": 1,"xnuppc-80x30-m": 1,"darwin-80x30-m": 1,"xnuppc-80x30": 1,"darwin-80x30": 1,"xnuppc-90x30-m": 1,"darwin-90x30-m": 1,"xnuppc-90x30": 1,"darwin-90x30": 1,"xnuppc-100x37-m": 1,"darwin-100x37-m": 1,"xnuppc-100x37": 1,"darwin-100x37": 1,"xnuppc-112x37-m": 1,"darwin-112x37-m": 1,"xnuppc-112x37": 1,"darwin-112x37": 1,"xnuppc-128x40-m": 1,"darwin-128x40-m": 1,"xnuppc-128x40": 1,"darwin-128x40": 1,"xnuppc-128x48-m": 1,"darwin-128x48-m": 1,"xnuppc-128x48": 1,"darwin-128x48": 1,"xnuppc-144x48-m": 1,"darwin-144x48-m": 1,"xnuppc-144x48": 1,"darwin-144x48": 1,"xnuppc-160x64-m": 1,"darwin-160x64-m": 1,"xnuppc-160x64": 1,"darwin-160x64": 1,"xnuppc-200x64-m": 1,"darwin-200x64-m": 1,"xnuppc-200x64": 1,"darwin-200x64": 1,"xnuppc-200x75-m": 1,"darwin-200x75-m": 1,"xnuppc-200x75": 1,"darwin-200x75": 1,"xnuppc-256x96-m": 1,"darwin-256x96-m": 1,"xnuppc-256x96": 1,"darwin-256x96": 1, + // COMMERCIAL WORKSTATION CONSOLES + // Alpha consoles + "pccons": 1,"pcconsole": 1, + // Common Desktop Environment + "dtterm": 1, + // Iris consoles + "wsiris": 1,"iris40": 1, + // NeWS consoles + "psterm": 1,"psterm-basic": 1,"psterm-96x48": 1,"psterm-90x28": 1,"psterm-80x24": 1,"psterm-fast": 1, + // NeXT consoles + "next": 1,"nextshell": 1, + // Sony NEWS workstations + "news-unk": 1,"news-29": 1,"news-29-euc": 1,"news-29-sjis": 1,"news-33": 1,"news-33-euc": 1,"news-33-sjis": 1,"news-42": 1,"news-42-euc": 1,"news-42-sjis": 1,"news-old-unk": 1,"nwp512": 1,"news": 1,"nwp514": 1,"news40": 1,"vt100-bm": 1,"nwp512-o": 1,"nwp514-o": 1,"news-o": 1,"news40-o": 1,"vt100-bm-o": 1,"nwp512-a": 1,"nwp514-a": 1,"news-a": 1,"news42": 1,"news40-a": 1,"nwp513": 1,"nwp518": 1,"nwe501": 1,"newscbm": 1,"news31": 1,"nwp513-o": 1,"nwp518-o": 1,"nwe501-o": 1,"nwp251-o": 1,"newscbm-o": 1,"news31-o": 1,"nwp513-a": 1,"nwp518-a": 1,"nwe501-a": 1,"nwp251-a": 1,"newscbm-a": 1,"news31-a": 1,"newscbm33": 1,"news33": 1,"news28": 1,"news29": 1,"news28-a": 1,"nwp511": 1,"nwp-511": 1,"nwp517": 1,"nwp-517": 1,"nwp517-w": 1,"nwp-517-w": 1, + // Sun consoles + "oldsun": 1,"sun-il": 1,"sun-cgsix": 1,"sun-ss5": 1,"sun": 1,"sun1": 1,"sun2": 1,"sun+sl": 1,"sun-s": 1,"sun-e-s": 1,"sun-s-e": 1,"sun-48": 1,"sun-34": 1,"sun-24": 1,"sun-17": 1,"sun-12": 1,"sun-1": 1,"sun-e": 1,"sun-nic": 1,"sune": 1,"sun-c": 1,"sun-cmd": 1,"sun-type4": 1,"sun-color": 1, + // COMMON TERMINAL TYPES + // Altos + "altos2": 1,"alt2": 1,"altos-2": 1,"altos3": 1,"altos5": 1,"alt3": 1,"alt5": 1,"altos-3": 1,"altos-5": 1,"altos4": 1,"alt4": 1,"altos-4": 1,"altos7": 1,"alt7": 1,"altos7pc": 1,"alt7pc": 1, + // Hewlett-Packard (hp) + "hpgeneric": 1,"hp": 1,"hp110": 1,"hp+pfk+cr": 1,"hp+pfk-cr": 1,"hp+pfk+arrows": 1,"hp+arrows": 1,"hp262x": 1,"hp2621-ba": 1,"hp2621": 1,"hp2621a": 1,"hp2621A": 1,"2621": 1,"2621a": 1,"2621A": 1,"hp2621-wl": 1,"2621-wl": 1,"hp2621-fl": 1,"hp2621p": 1,"hp2621p-a": 1,"hp2621-k45": 1,"hp2621k45": 1,"k45": 1,"hp2621-48": 1,"hp2621-nl": 1,"hp2621-nt": 1,"hp2624": 1,"hp2624a": 1,"hp2624b": 1,"hp2624b-4p": 1,"hp2626": 1,"hp2626a": 1,"hp2626p": 1,"hp2626-s": 1,"hp2626-ns": 1,"hp2626-12": 1,"hp2626-12x40": 1,"hp2626-x40": 1,"hp2626-12-s": 1,"hp2627a-rev": 1,"hp2627a": 1,"hp2627c": 1,"hp2640a": 1,"hp2640b": 1,"hp2644a": 1,"hp2641a": 1,"hp2645a": 1,"hp2647a": 1,"hp2645": 1,"hp45": 1,"hp2648": 1,"hp2648a": 1,"hp150": 1,"hp2382a": 1,"hp2382": 1,"hp2621-a": 1,"hp2621a-a": 1,"newhpkeyboard": 1,"newhp": 1,"memhp": 1,"scrhp": 1,"hp+labels": 1,"hp+printer": 1,"hp2621b": 1,"hp2621b-p": 1,"hp2621b-kx": 1,"hp2621b-kx-p": 1,"hp2622": 1,"hp2622a": 1,"hp2623": 1,"hp2623a": 1,"hp2624b-p": 1,"hp2624b-4p-p": 1,"hp2624-10p": 1,"hp2624a-10p": 1,"hp2624b-10p": 1,"hp2624b-10p-p": 1,"hp+color": 1,"hp2397a": 1,"hp2397": 1,"hpansi": 1,"hp700": 1,"hp2392": 1,"hpsub": 1,"hpex": 1,"hp2": 1,"hpex2": 1,"hp236": 1,"hp300h": 1,"hp9837": 1,"hp98720": 1,"hp98721": 1,"hp9845": 1,"hp98550": 1,"hp98550a": 1,"hp98550-color": 1,"hp98550a-color": 1,"hp700-wy": 1,"hp70092": 1,"hp70092a": 1,"hp70092A": 1,"bobcat": 1,"sbobcat": 1,"gator-t": 1,"gator": 1,"gator-52": 1,"gator-52t": 1, + // Honeywell-Bull + "dku7003-dumb": 1,"dku7003": 1, + // Kermit terminal emulations + "kermit": 1,"kermit-am": 1,"pckermit": 1,"pckermit12": 1,"pckermit120": 1,"msk227": 1,"mskermit227": 1,"msk227am": 1,"mskermit227am": 1,"msk22714": 1,"mskermit22714": 1,"vt320-k3": 1,"vt320-k311": 1, + // Lear-Siegler (LSI adm) + "adm1a": 1,"adm1": 1,"adm2": 1,"adm3": 1,"adm3a": 1,"adm3a+": 1,"adm5": 1,"adm+sgr": 1,"adm11": 1,"adm12": 1,"adm20": 1,"adm21": 1,"adm22": 1,"adm31": 1,"adm31-old": 1,"o31": 1,"adm36": 1,"adm42": 1,"adm42-ns": 1,"adm1178": 1,"1178": 1, + // Prime + "pt100": 1,"pt200": 1,"wren": 1,"fenix": 1,"pt100w": 1,"pt200w": 1,"wrenw": 1,"fenixw": 1,"pt250": 1,"pt250w": 1, + // Qume (qvt) + "qvt101": 1,"qvt108": 1,"qvt101+": 1,"qvt101p": 1,"qvt102": 1,"qvt103": 1,"qvt103-w": 1,"qvt119+": 1,"qvt119p": 1,"qvt119": 1,"qvt119+-25": 1,"qvt119p-25": 1,"qvt119+-w": 1,"qvt119p-w": 1,"qvt119-w": 1,"qvt119+-25-w": 1,"qvt119p-25-w": 1,"qvt119-25-w": 1,"qvt203": 1,"qvt203+": 1,"qvt203-w": 1,"qvt203-w-am": 1,"qvt203-25": 1,"qvt203-25-w": 1, + // TeleVideo (tvi) + "tvi803": 1,"tvi910": 1,"tvi910+": 1,"tvi912": 1,"tvi914": 1,"tvi920": 1,"tvi912cc": 1,"tvi912b-unk": 1,"tvi912c-unk": 1,"tvi912b+printer": 1,"tvi912b+dim": 1,"tvi912b+mc": 1,"tvi912b+2p": 1,"tvi912b+vb": 1,"tvi920b+fn": 1,"tvi912b-2p-unk": 1,"tvi912c-2p-unk": 1,"tvi912b-unk-2p": 1,"tvi912c-unk-2p": 1,"tvi912b-vb-unk": 1,"tvi912c-vb-unk": 1,"tvi912b-unk-vb": 1,"tvi912c-unk-vb": 1,"tvi912b-p": 1,"tvi912c-p": 1,"tvi912b-2p-p": 1,"tvi912c-2p-p": 1,"tvi912b-p-2p": 1,"tvi912c-p-2p": 1,"tvi912b-vb-p": 1,"tvi912c-vb-p": 1,"tvi912b-p-vb": 1,"tvi912c-p-vb": 1,"tvi912b-2p": 1,"tvi912c-2p": 1,"tvi912b-2p-mc": 1,"tvi912c-2p-mc": 1,"tvi912b-mc-2p": 1,"tvi912c-mc-2p": 1,"tvi912b-vb": 1,"tvi912c-vb": 1,"tvi912b-vb-mc": 1,"tvi912c-vb-mc": 1,"tvi912b-mc-vb": 1,"tvi912c-mc-vb": 1,"tvi912b": 1,"tvi912c": 1,"tvi912b-mc": 1,"tvi912c-mc": 1,"tvi920b-unk": 1,"tvi920c-unk": 1,"tvi920b-2p-unk": 1,"tvi920c-2p-unk": 1,"tvi920b-unk-2p": 1,"tvi920c-unk-2p": 1,"tvi920b-vb-unk": 1,"tvi920c-vb-unk": 1,"tvi920b-unk-vb": 1,"tvi920c-unk-vb": 1,"tvi920b-p": 1,"tvi920c-p": 1,"tvi920b-2p-p": 1,"tvi920c-2p-p": 1,"tvi920b-p-2p": 1,"tvi920c-p-2p": 1,"tvi920b-vb-p": 1,"tvi920c-vb-p": 1,"tvi920b-p-vb": 1,"tvi920c-p-vb": 1,"tvi920b-2p": 1,"tvi920c-2p": 1,"tvi920b-2p-mc": 1,"tvi920c-2p-mc": 1,"tvi920b-mc-2p": 1,"tvi920c-mc-2p": 1,"tvi920b-vb": 1,"tvi920c-vb": 1,"tvi920b-vb-mc": 1,"tvi920c-vb-mc": 1,"tvi920b-mc-vb": 1,"tvi920c-mc-vb": 1,"tvi920b": 1,"tvi920c": 1,"tvi920b-mc": 1,"tvi920c-mc": 1,"tvi921": 1,"tvi92B": 1,"tvi92D": 1,"tvi924": 1,"tvi925": 1,"tvi925-hi": 1,"tvi950": 1,"tvi950-2p": 1,"tvi950-4p": 1,"tvi950-rv": 1,"tvi950-rv-2p": 1,"tvi950-rv-4p": 1,"tvi955": 1,"tvi955-w": 1,"955-w": 1,"tvi955-hb": 1,"955-hb": 1,"tvi970": 1,"tvi970-vb": 1,"tvi970-2p": 1,"tvipt": 1,"tvi9065": 1, + // Visual (vi) + "vi50": 1,"vi50adm": 1,"vi55": 1,"vi200": 1,"vi200-f": 1,"vi200-rv": 1,"vi300": 1,"vi300-old": 1,"vi500": 1,"vi550": 1,"vi603": 1,"visual603": 1, + // Wyse (wy) + "wy30": 1,"wyse30": 1,"wy30-mc": 1,"wyse30-mc": 1,"wy30-vb": 1,"wyse30-vb": 1,"wy50": 1,"wyse50": 1,"wyse+sl": 1,"wy50-mc": 1,"wyse50-mc": 1,"wy50-vb": 1,"wyse50-vb": 1,"wy50-w": 1,"wyse50-w": 1,"wy50-wvb": 1,"wyse50-wvb": 1,"wy350": 1,"wyse350": 1,"wy350-vb": 1,"wyse350-vb": 1,"wy350-w": 1,"wyse350-w": 1,"wy350-wvb": 1,"wyse350-wvb": 1,"wy100": 1,"wy120": 1,"wyse120": 1,"wy150": 1,"wyse150": 1,"wy120-w": 1,"wyse120-w": 1,"wy150-w": 1,"wyse150-w": 1,"wy120-25": 1,"wyse120-25": 1,"wy150-25": 1,"wyse150-25": 1,"wy120-25-w": 1,"wyse120-25-w": 1,"wy150-25-w": 1,"wyse150-25-w": 1,"wy120-vb": 1,"wyse120-vb": 1,"wy150-vb": 1,"wyse150-vb": 1,"wy120-w-vb": 1,"wy120-wvb": 1,"wyse120-wvb": 1,"wy150-w-vb": 1,"wyse150-w-vb": 1,"wy60": 1,"wyse60": 1,"wy60-w": 1,"wyse60-w": 1,"wy60-25": 1,"wyse60-25": 1,"wy60-25-w": 1,"wyse60-25-w": 1,"wy60-42": 1,"wyse60-42": 1,"wy60-42-w": 1,"wyse60-42-w": 1,"wy60-43": 1,"wyse60-43": 1,"wy60-43-w": 1,"wyse60-43-w": 1,"wy60-vb": 1,"wyse60-vb": 1,"wy60-w-vb": 1,"wy60-wvb": 1,"wyse60-wvb": 1,"wy99gt": 1,"wyse99gt": 1,"wy99gt-w": 1,"wyse99gt-w": 1,"wy99gt-25": 1,"wyse99gt-25": 1,"wy99gt-25-w": 1,"wyse99gt-25-w": 1,"wy99gt-vb": 1,"wyse99gt-vb": 1,"wy99gt-w-vb": 1,"wy99gt-wvb": 1,"wyse99gt-wvb": 1,"wy99-ansi": 1,"wy99a-ansi": 1,"wy99f": 1,"wy99fgt": 1,"wy-99fgt": 1,"wy99fa": 1,"wy99fgta": 1,"wy-99fgta": 1,"wy160": 1,"wyse160": 1,"wy160-w": 1,"wyse160-w": 1,"wy160-25": 1,"wyse160-25": 1,"wy160-25-w": 1,"wyse160-25-w": 1,"wy160-42": 1,"wyse160-42": 1,"wy160-42-w": 1,"wyse160-42-w": 1,"wy160-43": 1,"wyse160-43": 1,"wy160-43-w": 1,"wyse160-43-w": 1,"wy160-vb": 1,"wyse160-vb": 1,"wy160-w-vb": 1,"wy160-wvb": 1,"wyse160-wvb": 1,"wy75": 1,"wyse75": 1,"wy75-mc": 1,"wyse75-mc": 1,"wy75-vb": 1,"wyse75-vb": 1,"wy75-w": 1,"wyse75-w": 1,"wy75-wvb": 1,"wyse75-wvb": 1,"wy85": 1,"wyse85": 1,"wy85-vb": 1,"wyse85-vb": 1,"wy85-w": 1,"wyse85-w": 1,"wy85-wvb": 1,"wyse85-wvb": 1,"wy85-8bit": 1,"wyse85-8bit": 1,"wy185": 1,"wyse185": 1,"wy185-24": 1,"wyse185-24": 1,"wy185-vb": 1,"wyse185-vb": 1,"wy185-w": 1,"wyse185-w": 1,"wy185-wvb": 1,"wyse185-wvb": 1,"wy325": 1,"wyse325": 1,"wy325-vb": 1,"wyse325-vb": 1,"wy325-w": 1,"wyse325-w": 1,"wy325w-24": 1,"wy325-25": 1,"wyse325-25": 1,"wy325-80": 1,"wyse-325": 1,"wy325-25w": 1,"wyse325-25w": 1,"wy325-w-vb": 1,"wy325-wvb": 1,"wyse325-wvb": 1,"wy325-42": 1,"wyse325-42": 1,"wy325-42w": 1,"wyse325-42w": 1,"wy325-42w-vb": 1,"wy325-42wvb": 1,"wy325-43": 1,"wyse325-43": 1,"wy325-43w": 1,"wyse325-43w": 1,"wy325-43w-vb": 1,"wy325-43wvb": 1,"wy370-nk": 1,"wy370": 1,"wyse370": 1,"wy370-101k": 1,"wy370-105k": 1,"wy370-EPC": 1,"wy370-vb": 1,"wy370-w": 1,"wy370-wvb": 1,"wy370-rv": 1,"wy99gt-tek": 1,"wy160-tek": 1,"wy370-tek": 1,"wy520": 1,"wyse520": 1,"wy520-24": 1,"wyse520-24": 1,"wy520-vb": 1,"wyse520-vb": 1,"wy520-w": 1,"wyse520-w": 1,"wy520-wvb": 1,"wyse520-wvb": 1,"wy520-epc": 1,"wyse520-epc": 1,"wy520-epc-24": 1,"wyse520-pc-24": 1,"wy520-epc-vb": 1,"wyse520-pc-vb": 1,"wy520-epc-w": 1,"wyse520-epc-w": 1,"wy520-epc-wvb": 1,"wyse520-p-wvb": 1,"wy520-36": 1,"wyse520-36": 1,"wy520-48": 1,"wyse520-48": 1,"wy520-36w": 1,"wyse520-36w": 1,"wy520-48w": 1,"wyse520-48w": 1,"wy520-36pc": 1,"wyse520-36pc": 1,"wy520-48pc": 1,"wyse520-48pc": 1,"wy520-36wpc": 1,"wyse520-36wpc": 1,"wy520-48wpc": 1,"wyse520-48wpc": 1,"wyse-vp": 1,"wy75ap": 1,"wyse75ap": 1,"wy-75ap": 1,"wyse-75ap": 1,"wy100q": 1, + // DOS/WINDOWS + // Command prompt + "ms-vt100": 1,"ms-vt100-color": 1,"vtnt": 1,"ms-vt100+": 1,"vt100+": 1,"ms-vt-utf8": 1,"vt-utf8": 1,"ms-vt100-16color": 1, + // PuTTY + "vt100-putty": 1,"putty-vt100": 1,"putty+fnkeys+vt400": 1,"putty+fnkeys+vt100": 1, + // CRT is very old outdated version of SecureCRT + "crt": 1,"crt-vt220": 1, + // LCD DISPLAYS + // Matrix Orbital + "MtxOrb": 1,"MtxOrb204": 1,"MtxOrb162": 1, + // NON-ANSI TERMINAL EMULATIONS + // Avatar + "avatar0": 1,"avatar0+": 1,"avatar": 1,"avatar1": 1, + // RBcomm + "rbcomm": 1,"rbcomm-nam": 1,"rbcomm-w": 1, + // Non-Unix Consoles + // Cygwin + "cygwinB19": 1,"cygwin": 1,"cygwinDBG": 1, + // DJGPP + "djgpp": 1,"djgpp203": 1,"djgpp204": 1, + // EMX termcap.dat compatibility modes + "emx-base": 1,"ansi-emx": 1,"ansi-color-2-emx": 1,"ansi-color-3-emx": 1,"mono-emx": 1, + // Microsoft (miscellaneous) + "ansi-nt": 1,"psx_ansi": 1,"pcmw": 1,"interix": 1,"opennt": 1,"opennt-25": 1,"ntconsole": 1,"ntconsole-25": 1,"opennt-35": 1,"ntconsole-35": 1,"opennt-50": 1,"ntconsole-50": 1,"opennt-60": 1,"ntconsole-60": 1,"opennt-100": 1,"ntconsole-100": 1,"opennt-w": 1,"opennt-25-w": 1,"ntconsole-w": 1,"ntconsole-25-w": 1,"opennt-35-w": 1,"ntconsole-35-w": 1,"opennt-50-w": 1,"ntconsole-50-w": 1,"opennt-60-w": 1,"ntconsole-60-w": 1,"opennt-w-vt": 1,"opennt-25-w-vt": 1,"ntconsole-w-vt": 1,"ntconsole-25-w-vt": 1,"interix-nti": 1,"opennt-nti": 1,"opennt-25-nti": 1,"ntconsole-25-nti": 1,"opennt-35-nti": 1,"ntconsole-35-nti": 1,"opennt-50-nti": 1,"ntconsole-50-nti": 1,"opennt-60-nti": 1,"ntconsole-60-nti": 1,"opennt-100-nti": 1,"ntconsole-100-nti": 1, + // U/Win + "uwin": 1, + // OBSOLETE PERSONAL-MICRO CONSOLES AND EMULATIONS + // Apple II + "appleIIgs": 1,"appleIIe": 1,"appleIIc": 1,"apple2e": 1,"apple2e-p": 1,"apple-ae": 1,"appleII": 1,"apple-80": 1,"apple-soroc": 1,"apple-videx": 1,"apple-uterm-vb": 1,"apple-uterm": 1,"apple80p": 1,"apple-videx2": 1,"apple-videx3": 1,"vapple": 1,"aepro": 1,"apple-vm80": 1,"ap-vm80": 1, + // Apple Lisa & Macintosh + "lisa": 1,"liswb": 1,"lisaterm": 1,"lisaterm-w": 1,"mac": 1,"macintosh": 1,"mac-w": 1,"macterminal-w": 1, + // Commodore Business Machines + "amiga": 1,"amiga-h": 1,"amiga-8bit": 1,"amiga-vnc": 1,"morphos": 1,"commodore": 1,"b-128": 1, + // Console types for obsolete UNIX clones + "minix": 1,"minix-3.0": 1,"minix-1.7": 1,"minix-old": 1,"minix-1.5": 1,"minix-old-am": 1,"pc-minix": 1,"pc-coherent": 1,"pcz19": 1,"coherent": 1,"pc-venix": 1,"venix": 1, + // IBM PC and clones + "pcplot": 1,"kaypro": 1,"kaypro2": 1,"ibm-pc": 1,"ibm5051": 1,"5051": 1,"ibmpc": 1,"wy60-PC": 1,"wyse60-PC": 1, + // Miscellaneous microcomputer consoles + "mai": 1,"basic4": 1,"basis": 1,"luna": 1,"luna68k": 1,"megatek": 1,"xerox820": 1,"x820": 1, + // North Star + "northstar": 1, + // Osborne + "osborne-w": 1,"osborne1-w": 1,"osborne": 1,"osborne1": 1,"osexec": 1, + // Radio Shack/Tandy + "coco3": 1,"os9LII": 1,"trs2": 1,"trsII": 1,"trs80II": 1,"trs16": 1, + // Videotex and teletext + "m2-nam": 1,"minitel": 1,"minitel-2": 1,"minitel-2-nam": 1,"minitel1": 1,"minitel1b": 1,"minitel1b-80": 1,"minitel1-nb": 1,"minitel1b-nb": 1,"minitel2-80": 1,"minitel12-80": 1,"screen.minitel1": 1,"screen.minitel1b": 1,"screen.minitel1b-80": 1,"screen.minitel2-80": 1,"screen.minitel12-80": 1,"screen.minitel1-nb": 1,"screen.minitel1b-nb": 1,"linux-m1": 1,"linux-m1b": 1,"linux-m2": 1,"linux-s": 1,"screen.linux-m1": 1,"screen.linux-m1b": 1,"screen.linux-m2": 1,"putty-m1": 1,"putty-m1b": 1,"putty-m2": 1,"putty+screen": 1,"putty-screen": 1,"screen.putty-m1": 1,"screen.putty-m1b": 1,"screen.putty-m2": 1,"viewdata": 1,"viewdata-o": 1,"viewdata-rv": 1, + // OBSOLETE UNIX CONSOLES + // AT&T consoles + "att6386": 1,"at386": 1,"386at": 1,"pc6300plus": 1,"att7300": 1,"unixpc": 1,"pc7300": 1,"3b1": 1,"s4": 1, + // Apollo consoles + "apollo": 1,"apollo+vt132": 1,"apollo_15P": 1,"apollo_19L": 1,"apollo_color": 1, + // Convergent Technology + "aws": 1,"awsc": 1, + // DEC consoles + "qdss": 1,"qdcons": 1, + // Fortune Systems consoles + "fos": 1,"fortune": 1, + // Masscomp consoles + "masscomp": 1,"masscomp1": 1,"masscomp2": 1, + // OSF Unix + "pmcons": 1,"pmconsole": 1, + // Other consoles + "pcix": 1,"ibmpcx": 1,"xenix": 1,"ibmx": 1, + // OBSOLETE VDT TYPES + // Amtek Business Machines + "abm80": 1, + // Bell Labs blit terminals + "blit": 1,"jerq": 1,"cbblit": 1,"fixterm": 1,"oblit": 1,"ojerq": 1, + // Bolt, Beranek & Newman (bbn) + "bitgraph": 1,"bg2.0nv": 1,"bg3.10nv": 1,"bg2.0rv": 1,"bg3.10rv": 1,"bg2.0": 1,"bg3.10": 1,"bg1.25rv": 1,"bg1.25nv": 1,"bg1.25": 1, + // Bull (bq, dku, vip) + "tws-generic": 1,"dku7102": 1,"tws2102-sna": 1,"dku7102-sna": 1,"tws2103": 1,"xdku": 1,"tws2103-sna": 1,"dku7103-sna": 1,"dku7102-old": 1,"dku7202": 1,"bq300": 1,"bq300-rv": 1,"bq300-w": 1,"bq300-w-rv": 1,"bq300-8": 1,"bq300-8rv": 1,"bq300-8w": 1,"bq300-w-8rv": 1,"bq300-pc": 1,"bq300-pc-rv": 1,"bq300-pc-w": 1,"bq300-pc-w-rv": 1,"bq300-8-pc": 1,"Q306-8-pc": 1,"bq300-8-pc-rv": 1,"bq300-8-pc-w": 1,"bq300-8-pc-w-rv": 1,"vip": 1,"vip-w": 1,"vip7800-w": 1,"Q310-vip-w": 1,"Q310-vip-w-am": 1,"vip-H": 1,"vip7800-H": 1,"Q310-vip-H": 1,"Q310-vip-H-am": 1,"vip-Hw": 1,"vip7800-Hw": 1,"Q310-vip-Hw": 1, + // Chromatics + "cg7900": 1,"chromatics": 1, + // Computer Automation + "ca22851": 1, + // Cybernex + "cyb83": 1,"xl83": 1,"cyb110": 1,"mdl110": 1, + // DEC terminals (Obsolete types: DECwriter and VT40/42/50) + "vt52+keypad": 1,"gt40": 1,"gt42": 1,"vt50": 1,"vt50h": 1,"vt61": 1,"vt-61": 1,"vt61.5": 1,"gigi": 1,"vk100": 1,"pro350": 1,"decpro": 1,"dw1": 1,"dw2": 1,"decwriter": 1,"dw": 1,"dw3": 1,"la120": 1,"dw4": 1,"ln03": 1,"ln03-w": 1, + // Datapoint + "dp3360": 1,"datapoint": 1,"dp8242": 1, + // Delta Data (dd) + "delta": 1,"dd5000": 1, + // Digital Data Research (ddr) + "ddr": 1,"rebus3180": 1,"ddr3180": 1, + // Evans & Sutherland + "ps300": 1, + // General Electric (ge) + "terminet1200": 1,"terminet300": 1,"tn1200": 1,"tn300": 1,"terminet": 1, + // Heathkit/Zenith + "h19-a": 1,"h19a": 1,"heath-ansi": 1,"heathkit-a": 1,"h19-bs": 1,"h19-us": 1,"h19us": 1,"h19-smul": 1,"h19": 1,"heath": 1,"h19-b": 1,"heathkit": 1,"heath-19": 1,"z19": 1,"zenith": 1,"h19-u": 1,"h19-g": 1,"h19g": 1,"alto-h19": 1,"altoh19": 1,"altoheath": 1,"alto-heath": 1,"z29": 1,"zenith29": 1,"z29b": 1,"z29a": 1,"z29a-kc-bc": 1,"h29a-kc-bc": 1,"z29a-kc-uc": 1,"h29a-kc-uc": 1,"z29a-nkc-bc": 1,"h29a-nkc-bc": 1,"z29a-nkc-uc": 1,"h29a-nkc-uc": 1,"z39-a": 1,"z39a": 1,"zenith39-a": 1,"zenith39-ansi": 1,"z100": 1,"h100": 1,"z110": 1,"z-100": 1,"h-100": 1,"z100bw": 1,"h100bw": 1,"z110bw": 1,"z-100bw": 1,"h-100bw": 1,"p19": 1,"ztx": 1,"ztx11": 1,"zt-1": 1,"htx11": 1,"ztx-1-a": 1, + // IMS International (ims) + "ims950-b": 1,"ims950": 1,"ims950-rv": 1,"ims-ansi": 1,"ultima2": 1,"ultimaII": 1, + // Intertec Data Systems + "superbrain": 1,"intertube": 1,"intertec": 1,"intertube2": 1, + // Ithaca Intersystems + "graphos": 1,"graphos-30": 1, + // Modgraph + "modgraph": 1,"mod24": 1,"modgraph2": 1,"modgraph48": 1,"mod": 1, + // Morrow Designs + "mt70": 1,"mt-70": 1, + // Motorola + "ex155": 1, + // Omron + "omron": 1, + // RCA + "rca": 1, + // Ramtek + "rt6221": 1,"rt6221-w": 1, + // Selanar + "hirez100": 1,"hirez100-w": 1, + // Signetics + "vsc": 1, + // Soroc + "soroc120": 1,"iq120": 1,"soroc": 1,"soroc140": 1,"iq140": 1, + // Southwest Technical Products + "swtp": 1,"ct82": 1, + // Synertek + "synertek": 1,"ktm": 1,"synertek380": 1, + // Tab Office Products + "tab132": 1,"tab": 1,"tab132-15": 1,"tab132-w": 1,"tab132-rv": 1,"tab132-w-rv": 1, + // Teleray + "t3700": 1,"t3800": 1,"t1061": 1,"teleray": 1,"t1061f": 1,"t10": 1,"t16": 1, + // Texas Instruments (ti) + "ti700": 1,"ti733": 1,"ti735": 1,"ti745": 1,"ti800": 1,"ti703": 1,"ti707": 1,"ti703-w": 1,"ti707-w": 1,"ti916": 1,"ti916-220-7": 1,"ti916-8": 1,"ti916-220-8": 1,"ti916-132": 1,"ti916-8-132": 1,"ti924": 1,"ti924-8": 1,"ti924w": 1,"ti924-8w": 1,"ti931": 1,"ti926": 1,"ti926-8": 1,"ti_ansi": 1,"ti928": 1,"ti928-8": 1, + // Zentec (zen) + "zen30": 1,"z30": 1,"zen50": 1,"z50": 1,"cci": 1,"cci1": 1,"z8001": 1,"zen8001": 1, + // OLDER TERMINAL TYPES + // AT&T (att, tty) + "att2300": 1,"sv80": 1,"att2350": 1,"att5410v1": 1,"att4410v1": 1,"tty5410v1": 1,"att4410v1-w": 1,"att5410v1-w": 1,"tty5410v1-w": 1,"att4410": 1,"att5410": 1,"tty5410": 1,"att5410-w": 1,"att4410-w": 1,"4410-w": 1,"tty5410-w": 1,"5410-w": 1,"v5410": 1,"att4415": 1,"tty5420": 1,"att5420": 1,"att4415-w": 1,"tty5420-w": 1,"att5420-w": 1,"att4415-rv": 1,"tty5420-rv": 1,"att5420-rv": 1,"att4415-w-rv": 1,"tty5420-w-rv": 1,"att5420-w-rv": 1,"att4415+nl": 1,"tty5420+nl": 1,"att5420+nl": 1,"att4415-nl": 1,"tty5420-nl": 1,"att5420-nl": 1,"att4415-rv-nl": 1,"tty5420-rv-nl": 1,"att5420-rv-nl": 1,"att4415-w-nl": 1,"tty5420-w-nl": 1,"att5420-w-nl": 1,"att4415-w-rv-n": 1,"tty5420-w-rv-n": 1,"att5420-w-rv-n": 1,"att5420_2": 1,"att5420_2-w": 1,"att4418": 1,"att5418": 1,"att4418-w": 1,"att5418-w": 1,"att4420": 1,"tty4420": 1,"att4424": 1,"tty4424": 1,"att4424-1": 1,"tty4424-1": 1,"att4424m": 1,"tty4424m": 1,"att5425": 1,"tty5425": 1,"att4425": 1,"att5425-nl": 1,"tty5425-nl": 1,"att4425-nl": 1,"att5425-w": 1,"att4425-w": 1,"tty5425-w": 1,"att4426": 1,"tty4426": 1,"att510a": 1,"bct510a": 1,"att510d": 1,"bct510d": 1,"att500": 1,"att513": 1,"att5310": 1,"att5320": 1,"att5620-1": 1,"tty5620-1": 1,"dmd1": 1,"att5620": 1,"dmd": 1,"tty5620": 1,"ttydmd": 1,"5620": 1,"att5620-24": 1,"tty5620-24": 1,"dmd-24": 1,"att5620-34": 1,"tty5620-34": 1,"dmd-34": 1,"att5620-s": 1,"tty5620-s": 1,"layer": 1,"vitty": 1,"att605": 1,"att605-pc": 1,"att605-w": 1,"att610": 1,"att610-w": 1,"att610-103k": 1,"att610-103k-w": 1,"att615": 1,"att615-w": 1,"att615-103k": 1,"att615-103k-w": 1,"att620": 1,"att620-w": 1,"att620-103k": 1,"att620-103k-w": 1,"att630": 1,"att630-24": 1,"5630-24": 1,"5630DMD-24": 1,"630MTG-24": 1,"att700": 1,"att730": 1,"att730-41": 1,"730MTG-41": 1,"att730-24": 1,"730MTG-24": 1,"att730r": 1,"730MTGr": 1,"att730r-41": 1,"730MTG-41r": 1,"att730r-24": 1,"730MTGr-24": 1,"att505": 1,"pt505": 1,"att5430": 1,"gs5430": 1,"att505-24": 1,"pt505-24": 1,"gs5430-24": 1,"att505-22": 1,"pt505-22": 1,"gs5430-22": 1, + // Ampex (Dialogue) + "ampex80": 1,"a80": 1,"d80": 1,"dialogue": 1,"dialogue80": 1,"ampex175": 1,"ampex175-b": 1,"ampex210": 1,"a210": 1,"ampex219": 1,"ampex-219": 1,"amp219": 1,"ampex219w": 1,"ampex-219w": 1,"amp219w": 1,"ampex232": 1,"ampex-232": 1,"ampex232w": 1, + // Ann Arbor (aa) + "annarbor4080": 1,"aa4080": 1,"aas1901": 1,"aaa+unk": 1,"aaa-unk": 1,"aaa+rv": 1,"aaa+dec": 1,"aaa-18": 1,"aaa-18-rv": 1,"aaa-20": 1,"aaa-22": 1,"aaa-24": 1,"aaa-24-rv": 1,"aaa-26": 1,"aaa-28": 1,"aaa-30-s": 1,"aaa-s": 1,"aaa-30-s-rv": 1,"aaa-s-rv": 1,"aaa-s-ctxt": 1,"aaa-30-s-ctxt": 1,"aaa-s-rv-ctxt": 1,"aaa-30-s-rv-ct": 1,"aaa": 1,"aaa-30": 1,"ambas": 1,"ambassador": 1,"aaa-30-rv": 1,"aaa-rv": 1,"aaa-30-ctxt": 1,"aaa-ctxt": 1,"aaa-30-rv-ctxt": 1,"aaa-rv-ctxt": 1,"aaa-36": 1,"aaa-36-rv": 1,"aaa-40": 1,"aaa-40-rv": 1,"aaa-48": 1,"aaa-48-rv": 1,"aaa-60-s": 1,"aaa-60-s-rv": 1,"aaa-60-dec-rv": 1,"aaa-60": 1,"aaa-60-rv": 1,"aaa-db": 1,"guru": 1,"guru-33": 1,"guru+unk": 1,"guru+rv": 1,"guru-rv": 1,"guru-33-rv": 1,"guru+s": 1,"guru-nctxt": 1,"guru-s": 1,"guru-33-s": 1,"guru-24": 1,"guru-44": 1,"guru-44-s": 1,"guru-76": 1,"guru-76-s": 1,"guru-76-lp": 1,"guru-lp": 1,"guru-76-w": 1,"guru-76-w-s": 1,"guru-76-wm": 1,"aaa-rv-unk": 1, + // Applied Digital Data Systems (adds) + "regent": 1,"regent100": 1,"regent20": 1,"regent25": 1,"regent40": 1,"regent40+": 1,"regent60": 1,"regent200": 1,"adds200": 1,"viewpoint": 1,"addsviewpoint": 1,"screwpoint": 1,"vp3a+": 1,"viewpoint3a+": 1,"vp60": 1,"viewpoint60": 1,"addsvp60": 1,"vp90": 1,"viewpoint90": 1,"adds980": 1,"a980": 1, + // Beehive Medical Electronics + "beehive": 1,"bee": 1,"beehive3": 1,"bh3m": 1,"beehiveIIIm": 1,"beehive4": 1,"bh4": 1,"microb": 1,"microbee": 1,"ha8675": 1,"ha8686": 1, + // C. Itoh Electronics + "cit80": 1,"cit-80": 1,"cit101": 1,"citc": 1,"cit101e": 1,"cit101e-rv": 1,"cit101e-n": 1,"cit101e-132": 1,"cit101e-n132": 1,"cit500": 1,"citoh": 1,"ci8510": 1,"8510": 1,"citoh-pica": 1,"citoh-elite": 1,"citoh-comp": 1,"citoh-prop": 1,"citoh-ps": 1,"ips": 1,"citoh-6lpi": 1,"citoh-8lpi": 1, + // Contel Business Systems. + "contel300": 1,"contel320": 1,"c300": 1,"contel301": 1,"contel321": 1,"c301": 1,"c321": 1, + // Control Data (cdc) + "cdc456": 1,"cdc721": 1,"cdc721ll": 1,"cdc752": 1,"cdc756": 1,"cdc721-esc": 1, + // Data General (dg) + "dgkeys+8b": 1,"dgkeys+7b": 1,"dgkeys+11": 1,"dgkeys+15": 1,"dgunix+fixed": 1,"dg+fixed": 1,"dg+color8": 1,"dg+color": 1,"dgmode+color8": 1,"dgmode+color": 1,"dgunix+ccc": 1,"dg+ccc": 1,"dg-generic": 1,"dg200": 1,"dg210": 1,"dg-ansi": 1,"dg211": 1,"dg450": 1,"dg6134": 1,"dg460-ansi": 1,"dg6053-old": 1,"dg100": 1,"dg6053": 1,"6053": 1,"6053-dg": 1,"dg605x": 1,"605x": 1,"605x-dg": 1,"d2": 1,"d2-dg": 1,"d200": 1,"d200-dg": 1,"d210": 1,"d214": 1,"d210-dg": 1,"d214-dg": 1,"d211": 1,"d215": 1,"d211-7b": 1,"d215-7b": 1,"d211-dg": 1,"d215-dg": 1,"d216-dg": 1,"d216e-dg": 1,"d216+dg": 1,"d216e+dg": 1,"d217-dg": 1,"d216-unix": 1,"d216e-unix": 1,"d216+": 1,"d216e+": 1,"d216-unix-25": 1,"d216+25": 1,"d217-unix": 1,"d217-unix-25": 1,"d220": 1,"d220-7b": 1,"d220-dg": 1,"d230c": 1,"d230": 1,"d230c-dg": 1,"d230-dg": 1,"d400": 1,"d400-dg": 1,"d450": 1,"d450-dg": 1,"d410": 1,"d411": 1,"d460": 1,"d461": 1,"d410-7b": 1,"d411-7b": 1,"d460-7b": 1,"d461-7b": 1,"d410-dg": 1,"d460-dg": 1,"d411-dg": 1,"d461-dg": 1,"d410-w": 1,"d411-w": 1,"d460-w": 1,"d461-w": 1,"d410-7b-w": 1,"d411-7b-w": 1,"d460-7b-w": 1,"d461-7b-w": 1,"d412-dg": 1,"d462-dg": 1,"d462e-dg": 1,"d412+dg": 1,"d462+dg": 1,"d413-dg": 1,"d463-dg": 1,"d412-unix": 1,"d462-unix": 1,"d412+": 1,"d462+": 1,"d412-unix-w": 1,"d462-unix-w": 1,"d412+w": 1,"d462+w": 1,"d412-unix-25": 1,"d462-unix-25": 1,"d412+25": 1,"d462+25": 1,"d412-unix-s": 1,"d462-unix-s": 1,"d412+s": 1,"d462+s": 1,"d412-unix-sr": 1,"d462-unix-sr": 1,"d412+sr": 1,"d462+sr": 1,"d413-unix": 1,"d463-unix": 1,"d413-unix-w": 1,"d463-unix-w": 1,"d413-unix-25": 1,"d463-unix-25": 1,"d413-unix-s": 1,"d463-unix-s": 1,"d413-unix-sr": 1,"d463-unix-sr": 1,"d414-unix": 1,"d464-unix": 1,"d414-unix-w": 1,"d464-unix-w": 1,"d414-unix-25": 1,"d464-unix-25": 1,"d414-unix-s": 1,"d464-unix-s": 1,"d414-unix-sr": 1,"d464-unix-sr": 1,"d430c-dg": 1,"d430-dg": 1,"d430c-dg-ccc": 1,"d430-dg-ccc": 1,"d430c-unix": 1,"d430-unix": 1,"d430c-unix-w": 1,"d430-unix-w": 1,"d430c-unix-25": 1,"d430-unix-25": 1,"d430c-unix-s": 1,"d430-unix-s": 1,"d430c-unix-sr": 1,"d430-unix-sr": 1,"d430c-unix-ccc": 1,"d430-unix-ccc": 1,"d430c-unix-w-ccc": 1,"d430-unix-w-ccc": 1,"d430c-unix-25-ccc": 1,"d430-unix-25-ccc": 1,"d430c-unix-s-ccc": 1,"d430-unix-s-ccc": 1,"d430c-unix-sr-ccc": 1,"d430-unix-sr-ccc": 1,"d470c": 1,"d470": 1,"d470c-7b": 1,"d470-7b": 1,"d470c-dg": 1,"d470-dg": 1,"d555": 1,"d555-7b": 1,"d555-w": 1,"d555-7b-w": 1,"d555-dg": 1,"d577": 1,"d577-7b": 1,"d577-w": 1,"d577-7b-w": 1,"d577-dg": 1,"d578-dg": 1,"d578": 1,"d578-7b": 1, + // Datamedia (dm) + "cs10": 1,"colorscan": 1,"cs10-w": 1,"dm1520": 1,"dm1521": 1,"dm2500": 1,"datamedia2500": 1,"dmchat": 1,"dm3025": 1,"dm3045": 1,"dm80": 1,"dmdt80": 1,"dt80": 1,"dm80w": 1,"dmdt80w": 1,"dt80w": 1,"dt80-sas": 1,"excel62": 1,"excel64": 1,"excel62-w": 1,"excel64-w": 1,"excel62-rv": 1,"excel64-rv": 1, + // Falco + "falco": 1,"ts1": 1,"ts-1": 1,"falco-p": 1,"ts1p": 1,"ts-1p": 1,"ts100": 1,"ts100-sp": 1,"ts100-ctxt": 1, + // Florida Computer Graphics + "beacon": 1, + // Fluke + "f1720": 1,"f1720a": 1, + // Getronics + "visa50": 1, + // GraphOn (go) + "go140": 1,"go140w": 1,"go225": 1,"go-225": 1, + // Harris (Beehive) + "sb1": 1,"sbi": 1,"superbee": 1,"superbee-xsb": 1,"superbeeic": 1,"sb2": 1,"sb3": 1, + // Hazeltine + "hz1000": 1,"hz1420": 1,"hz1500": 1,"hz1510": 1,"hz1520": 1,"hz1520-noesc": 1,"hz1552": 1,"hz1552-rv": 1,"hz2000": 1,"esprit": 1,"esprit-am": 1,"hmod1": 1,"hazel": 1,"exec80": 1,"h80": 1,"he80": 1, + // Human Designed Systems (Concept) + "c108": 1,"concept108": 1,"c108-8p": 1,"concept108-8p": 1,"c108-4p": 1,"concept108-4p": 1,"c108-rv": 1,"c108-rv-8p": 1,"c108-rv-4p": 1,"concept108rv4p": 1,"c108-w": 1,"c108-w-8p": 1,"concept108-w-8": 1,"concept108-w8p": 1,"c100": 1,"concept100": 1,"concept": 1,"c104": 1,"c100-4p": 1,"c100-rv": 1,"c100-rv-4p": 1,"concept100-rv": 1,"oc100": 1,"oconcept": 1,"c100-1p": 1,"hds200": 1,"avt-ns": 1,"avt-rv-ns": 1,"avt-w-ns": 1,"avt-w-rv-ns": 1,"avt+s": 1,"avt": 1,"avt-s": 1,"concept-avt": 1,"avt-rv": 1,"avt-rv-s": 1,"avt-w": 1,"avt-w-s": 1,"avt-w-rv": 1,"avt-w-rv-s": 1, + // IBM + "ibm327x": 1,"ibm3101": 1,"i3101": 1,"ibm3151": 1,"ibm3161": 1,"ibm3163": 1,"wy60-316X": 1,"wyse60-316X": 1,"ibm3161-C": 1,"ibm3162": 1,"ibm3164": 1,"i3164": 1,"ibm5151": 1,"wy60-AT": 1,"wyse60-AT": 1,"ibmaed": 1,"ibm-apl": 1,"apl": 1,"ibmmono": 1,"ibmega": 1,"ibm+color": 1,"ibm+16color": 1,"ibm5154": 1,"ibmega-c": 1,"ibm5154-c": 1,"ibmvga-c": 1,"ibmvga": 1,"rtpc": 1,"ibmapa16": 1,"ibm6155": 1,"ibmapa8c": 1,"ibmapa8": 1,"ibmapa8c-c": 1,"ibm6154-c": 1,"ibm6154": 1,"ibm6153": 1,"ibm6153-90": 1,"ibm6153-40": 1,"ibm8512": 1,"ibm8513": 1,"hft-c": 1,"hft-c-old": 1,"hft-old": 1,"ibm-system1": 1,"system1": 1,"lft": 1,"lft-pc850": 1,"LFT-PC850": 1,"ibm5081": 1,"hft": 1,"ibm5081-c": 1,"ibmmpel-c": 1,"ibm8503": 1,"ibm8507": 1,"ibm8604": 1,"ibm8514": 1,"ibm8514-c": 1,"aixterm": 1,"aixterm+sl": 1,"aixterm-m": 1,"aixterm-m-old": 1,"jaixterm": 1,"jaixterm-m": 1,"aixterm-16color": 1, + // Infoton/General Terminal Corp. + "i100": 1,"gt100": 1,"gt100a": 1,"i400": 1,"addrinfo": 1,"infoton2": 1,"infoton": 1,"icl6404": 1,"kds7372": 1,"icl6402": 1,"kds6402": 1,"icl6404-w": 1,"kds7372-w": 1, + // Interactive Systems Corp + "intext": 1,"intext2": 1,"intextii": 1, + // Kimtron (abm, kt) + "abm85": 1,"abm85h": 1,"abm85e": 1,"abm85h-old": 1,"oabm85h": 1,"o85h": 1,"kt7": 1,"kt7ix": 1, + // Liberty Electronics (Freedom) + "f100": 1,"freedom": 1,"freedom100": 1,"f100-rv": 1,"freedom-rv": 1,"f110": 1,"freedom110": 1,"f110-14": 1,"f110-w": 1,"f110-14w": 1,"f200": 1,"freedom200": 1,"f200-w": 1,"f200vi": 1,"f200vi-w": 1, + // Microdata/MDIS + "prism2": 1,"prism4": 1,"p4": 1,"P4": 1,"prism5": 1,"p5": 1,"P5": 1,"prism7": 1,"p7": 1,"P7": 1,"prism8": 1,"p8": 1,"P8": 1,"prism8-w": 1,"p8-w": 1,"P8-W": 1,"prism9": 1,"p9": 1,"P9": 1,"prism9-w": 1,"p9-w": 1,"P9-W": 1,"prism9-8": 1,"p9-8": 1,"P9-8": 1,"prism9-8-w": 1,"p9-8-w": 1,"P9-8-W": 1,"prism12": 1,"p12": 1,"P12": 1,"prism12-w": 1,"p12-w": 1,"P12-W": 1,"prism12-m": 1,"p12-m": 1,"P12-M": 1,"prism12-m-w": 1,"p12-m-w": 1,"P12-M-W": 1,"prism14": 1,"p14": 1,"P14": 1,"prism14-w": 1,"p14-w": 1,"P14-W": 1,"prism14-m": 1,"p14-m": 1,"P14-M": 1,"prism14-m-w": 1,"p14-m-w": 1,"P14-M-W": 1,"p8gl": 1,"prism8gl": 1, + // Microterm (act, mime) + "act4": 1,"microterm": 1,"act5": 1,"microterm5": 1,"mime-fb": 1,"mime-hb": 1,"mime": 1,"mime1": 1,"mime2": 1,"mimei": 1,"mimeii": 1,"mime2a-s": 1,"mime2a": 1,"mime2a-v": 1,"mime3a": 1,"mime3ax": 1,"mime-3ax": 1,"mime314": 1,"mm314": 1,"mm340": 1,"mime340": 1,"mt4520-rv": 1,"ergo4000": 1, + // NCR + "ncr260intan": 1,"ncr260intwan": 1,"ncr260intpp": 1,"ncr260intwpp": 1,"ncr260vppp": 1,"ncr260vp+sl": 1,"ncr260vpwpp": 1,"ncr260vt100an": 1,"ncr260vt+sl": 1,"ncr260vt100wan": 1,"ncr260vt100pp": 1,"ncr260vt100wpp": 1,"ncr260vt200an": 1,"ncr260vt200wan": 1,"ncr260vt200pp": 1,"ncr260vt200wpp": 1,"ncr260vt300an": 1,"ncr260vt300wan": 1,"ncr260vt300pp": 1,"ncr260vt300wpp": 1,"NCR260VT300WPP": 1,"ncr260wy325pp": 1,"ncr260wy325wpp": 1,"ncr260wy350pp": 1,"ncr260wy350wpp": 1,"ncr260wy50+pp": 1,"ncr260wy50+wpp": 1,"ncr260wy60pp": 1,"ncr260wy60wpp": 1,"ncr160vppp": 1,"ncr160vpwpp": 1,"ncr160vt100an": 1,"ncr160vt100pp": 1,"ncr160vt100wan": 1,"ncr160vt100wpp": 1,"ncr160vt200an": 1,"ncr160vt200pp": 1,"ncr160vt200wan": 1,"ncr160vt200wpp": 1,"ncr160vt300an": 1,"ncr160vt300pp": 1,"ncr160vt300wan": 1,"ncr160vt300wpp": 1,"ncr160wy50+pp": 1,"ncr160wy50+wpp": 1,"ncr160wy60pp": 1,"ncr160wy60wpp": 1,"ncrvt100an": 1,"ncrvt100pp": 1,"ncrvt100wan": 1,"NCRVT100WPP": 1,"ncrvt100wpp": 1,"ncr7900i": 1,"ncr7900": 1,"n7900": 1,"ncr7900iv": 1,"ncr7901": 1,"ndr9500": 1,"nd9500": 1,"ndr9500-nl": 1,"ndr9500-25": 1,"ndr9500-25-nl": 1,"ndr9500-mc": 1,"ndr9500-25-mc": 1,"ndr9500-mc-nl": 1,"ndr9500-25-mc-nl": 1, + // Perkin-Elmer (Owl) + "bantam": 1,"pe550": 1,"pe6100": 1,"fox": 1,"pe1100": 1,"owl": 1,"pe1200": 1,"pe1251": 1,"pe6300": 1,"pe6312": 1,"pe7000m": 1,"pe7000c": 1, + // Sperry Univac + "uts30": 1, + // Tandem + "tandem6510": 1,"tandem653": 1,"t653x": 1, + // Tandy/Radio Shack + "dmterm": 1,"dt100": 1,"dt-100": 1,"dt100w": 1,"dt-100w": 1,"dt110": 1,"pt210": 1, + // Tektronix (tek) + "tek": 1,"tek4012": 1,"tek4013": 1,"tek4014": 1,"tek4015": 1,"tek4014-sm": 1,"tek4015-sm": 1,"tek4023": 1,"tek4024": 1,"tek4025": 1,"tek4027": 1,"tek4025-17": 1,"tek4025-17-ws": 1,"tek4025-ex": 1,"tek4027-ex": 1,"tek4025a": 1,"tek4025-cr": 1,"tek4025ex": 1,"4025ex": 1,"4027ex": 1,"tek4105": 1,"tek4105-30": 1,"tek4105a": 1,"tek4106brl": 1,"tek4107brl": 1,"tek4109brl": 1,"tek4107": 1,"tek4109": 1,"tek4207-s": 1,"otek4112": 1,"o4112-nd": 1,"otek4113": 1,"otek4114": 1,"tek4112": 1,"tek4114": 1,"tek4112-nd": 1,"tek4112-5": 1,"tek4113": 1,"tek4113-34": 1,"tek4113-nd": 1,"otek4115": 1,"tek4115": 1,"tek4125": 1,"tek4207": 1,"tek4404": 1,"ct8500": 1,"tek4205": 1, + // Teletype (tty) + "tty33": 1,"tty35": 1,"tty37": 1,"tty40": 1,"ds40": 1,"ds40-2": 1,"dataspeed40": 1,"tty43": 1, + // Tymshare + "scanset": 1,"sc410": 1,"sc415": 1, + // Volker-Craig (vc) + "vc303": 1,"vc103": 1,"vc203": 1,"vc303a": 1,"vc403a": 1,"vc404": 1,"vc404-s": 1,"vc414": 1,"vc414h": 1,"vc415": 1, + // OTHER OBSOLETE TYPES + // Daisy wheel printers + "diablo1620": 1,"diablo1720": 1,"diablo450": 1,"ipsi": 1,"diablo1620-m8": 1,"diablo1640-m8": 1,"diablo1640": 1,"diablo1730": 1,"diablo1740": 1,"diablo630": 1,"x1700": 1,"diablo": 1,"xerox": 1,"diablo1640-lm": 1,"diablo-lm": 1,"xerox-lm": 1,"diablo1740-lm": 1,"630-lm": 1,"1730-lm": 1,"x1700-lm": 1,"dtc382": 1,"dtc300s": 1,"gsi": 1,"aj830": 1,"aj832": 1,"aj": 1,"aj510": 1,"nec5520": 1,"nec": 1,"spinwriter": 1,"qume5": 1,"qume": 1,"xerox1720": 1,"x1720": 1,"x1750": 1, + // Miscellaneous obsolete terminals, manufacturers unknown + "cad68-3": 1,"cgc3": 1,"cad68-2": 1,"cgc2": 1,"cops10": 1,"cops": 1,"cops-10": 1,"d132": 1,"datagraphix": 1,"d800": 1,"digilog": 1,"dwk": 1,"dwk-vt": 1,"env230": 1,"envision230": 1,"ep48": 1,"ep4080": 1,"ep40": 1,"ep4000": 1,"ifmr": 1,"opus3n1+": 1,"teletec": 1,"v3220": 1, + // Obsolete non-ANSI software emulations + "ctrm": 1,"gs6300": 1,"emots": 1,"h19k": 1,"h19kermit": 1,"versaterm": 1,"xtalk": 1,"simterm": 1, + // UNIX VIRTUAL TERMINALS, VIRTUAL CONSOLES, AND TELNET CLIENTS + // NCSA Telnet + "ncsa-m": 1,"ncsa-vt220-8": 1,"ncsa": 1,"ncsa-ns": 1,"ncsa-m-ns": 1,"ncsa-vt220": 1, + // Pilot Pro Palm-Top + "pilot": 1,"tgtelnet": 1,"elks-glasstty": 1,"elks-vt52": 1,"elks-ansi": 1,"elks": 1,"sibo": 1, + // Screen + "screen2": 1,"screen3": 1,"screen4": 1,"screen5": 1, + // CB UNIX, early 80s + "cbunix": 1,"vremote": 1,"pty": 1, + // X TERMINAL EMULATORS + // EMU + "emu": 1,"emu-220": 1, + // GNOME (VTE) + "gnome-rh62": 1,"gnome-rh72": 1,"gnome-rh80": 1,"gnome-rh90": 1,"gnome-fc5": 1,"vte-2007": 1,"gnome-2007": 1,"vte-2008": 1,"gnome-2008": 1,"vte-2012": 1,"gnome-2012": 1,"gnome+pcfkeys": 1,"gnome": 1,"gnome-256color": 1,"vte-2014": 1,"vte-2017": 1,"vte-2018": 1, + // HPTERM + "hpterm": 1,"X-hpterm": 1,"hpterm-color": 1,"hpterm-color2": 1,"X-hpterm-color2": 1, + // KDE + "kvt": 1,"konsole-xf3x": 1,"konsole-xf4x": 1, + // KTERM + "kterm": 1,"kterm-color": 1,"kterm-co": 1, + // MGR + "mgr": 1,"mgr-sun": 1,"mgr-linux": 1, + // MLTERM + "mlterm3": 1,"mlterm2": 1, + // MRXVT + "mrxvt": 1,"mrxvt-256color": 1, + // MTERM + "mterm-ansi": 1,"mterm": 1,"mouse-sun": 1,"decansi": 1, + // MVTERM + "mvterm": 1,"vv100": 1, + // Other GNOME + "mgt": 1, + // Other XTERM + "xtermm": 1,"xtermc": 1,"xterm-pcolor": 1,"color_xterm": 1,"cx": 1,"cx100": 1,"xterm-sun": 1,"xterms-sun": 1, + // RXVT + "rxvt-basic": 1,"rxvt+pcfkeys": 1,"rxvt": 1,"rxvt-color": 1,"rxvt-256color": 1,"rxvt-88color": 1,"rxvt-xpm": 1,"rxvt-cygwin": 1,"rxvt-cygwin-native": 1,"rxvt-16color": 1, + // SIMPLETERM + "st-0.8": 1,"st-0.7": 1,"st-0.6": 1,"simpleterm": 1,"old-st": 1, + // TERMINOLOGY + "terminology-0.6.1": 1,"terminology-1.0.0": 1,"terminology-1.8.1": 1, + // VWM + "vwmterm": 1, + // XTERM + "x10term": 1,"vs100-x10": 1,"x10term+sl": 1,"xterm-r5": 1,"xterm-r6": 1,"xterm-old": 1,"xterm-xf86-v32": 1,"xterm-xf86-v33": 1,"xterm-xf86-v333": 1,"xterm-xf86-v40": 1,"xterm-xf86-v43": 1,"xterm-xf86-v44": 1,"xterm-xfree86": 1,"xterm-new": 1, + // XTERM Features + "xterm-8bit": 1,"xterm-hp": 1,"xterm-vt52": 1,"xterm-nic": 1,"xterm1": 1, +} diff --git a/tui/termfo/cmd/termfo/show.go b/tui/termfo/cmd/termfo/show.go new file mode 100644 index 0000000..c0eef59 --- /dev/null +++ b/tui/termfo/cmd/termfo/show.go @@ -0,0 +1,107 @@ +package main + +import ( + "fmt" + "sort" + "strings" + + "citrons.xyz/talk/tui/termfo" + "citrons.xyz/talk/tui/termfo/caps" +) + +func show(terms ...string) { + for _, t := range terms { + ti, err := termfo.New(t) + if err != nil { + fatalf("%s", err) + } + fmt.Println(fmtTerminfo(ti)) + } +} + +func fmtTerminfo(ti *termfo.Terminfo) string { + all := append(append(append(caps.TableBools, caps.TableNums...), caps.TableStrs...), ti.Extended...) + sort.Slice(all, func(i, j int) bool { return all[i].Long < all[j].Long }) + + // Highlight escape codes and such; makes it easier to read. + hi := func(s string) string { return s } + if isTerm { + hi = func(s string) string { + r := make([]byte, 0, len(s)) + resetAfter := 0 + for i, c := range []byte(s) { + if c == '\\' { + r = append(r, "\x1b[34m"...) + resetAfter = 1 + if len(s) > i+1 && s[i+1] == 'x' { + resetAfter = 3 + } + } + + r = append(r, c) + if resetAfter > -1 { + resetAfter-- + if resetAfter == -1 { + r = append(r, "\x1b[0m"...) + } + } + } + return string(r) + } + } + + b := new(strings.Builder) + b.Grow(16384) + fmt.Fprintf(b, "Loaded from %s\n", ti.Location) + a := "" + if len(ti.Aliases) > 0 { + a = " (aliases: " + strings.Join(ti.Aliases, ", ") + ")" + } + fmt.Fprintf(b, "%s%s – %s\n\n", ti.Name, a, ti.Desc) + + fmt.Fprintf(b, "%-8s │ %-26s │ %-26s │ Description\n", "Short", "Long", "Value") + fmt.Fprintf(b, "%s┼%s┼%s┼%s\n", + strings.Repeat("─", 9), + strings.Repeat("─", 28), + strings.Repeat("─", 28), + strings.Repeat("─", 22), + ) + for _, k := range all { + var val string + if _, ok := ti.Bools[k]; ok { + val = "True" + } else if v, ok := ti.Numbers[k]; ok { + val = fmt.Sprintf("#%d", v) + } else if v, ok := ti.Strings[k]; ok { + val = strings.ReplaceAll(fmt.Sprintf("%#v", v), `\x1b`, `\E`) + val = val[1 : len(val)-1] + } + + if val != "" { + var overflow string + if isTerm && len(val) > 26 { + overflow = val[26:] + val = val[:26] + } + + // TODO: if it overflows at %\np then the "p" isn't highlighted + // (this is also why that reset is in there). + reset := "" + if isTerm { + reset = "\x1b[0m" + } + fmt.Fprintf(b, "%-8s │ %-26s │ %s%s │ %s\n", k.Short, k.Long, hi(fmt.Sprintf("%-26s", val)), reset, k.Desc) + for p, overflow := first(overflow, 26); p != ""; p, overflow = first(overflow, 26) { + fmt.Fprintf(b, "%-37s │ %s │\n", " ", hi(fmt.Sprintf("%-26s", p))) + } + } + } + return b.String() +} + +func first(s string, n int) (string, string) { + if len(s) > n { + return s[:n], s[n:] + } + return s, "" +} |
