Update dependencies

This commit is contained in:
Tulir Asokan 2018-05-25 22:44:12 +03:00
parent a76ce88a30
commit 7b8229dab1
41 changed files with 1232 additions and 1319 deletions

6
Gopkg.lock generated
View File

@ -23,7 +23,7 @@
branch = "master" branch = "master"
name = "github.com/lucasb-eyer/go-colorful" name = "github.com/lucasb-eyer/go-colorful"
packages = ["."] packages = ["."]
revision = "fa0f842f26263fb2ace6d6118309c8481e029fc1" revision = "8abd3beca3a7f5039809449d6013a0254ac22bb1"
[[projects]] [[projects]]
name = "github.com/mattn/go-runewidth" name = "github.com/mattn/go-runewidth"
@ -88,7 +88,7 @@
"html", "html",
"html/atom" "html/atom"
] ]
revision = "9ef9f5bb98a1fdc41f8cf6c250a4404b4085e389" revision = "dfa909b99c79129e1100513e5cd36307665e5723"
[[projects]] [[projects]]
name = "golang.org/x/text" name = "golang.org/x/text"
@ -133,7 +133,7 @@
".", ".",
"terminfo" "terminfo"
] ]
revision = "e03df2c40d0ab5487a6b3c06a228755cdfec1c46" revision = "9dc7ec911605bc6db5c96f502e6a80494afe4e1b"
[[projects]] [[projects]]
branch = "master" branch = "master"

View File

@ -3,52 +3,53 @@
package colorful package colorful
import ( import (
"math/rand" "math/rand"
) )
// Creates a random dark, "warm" color through a restricted HSV space. // Creates a random dark, "warm" color through a restricted HSV space.
func FastWarmColor() Color { func FastWarmColor() Color {
return Hsv( return Hsv(
rand.Float64() * 360.0, rand.Float64()*360.0,
0.5 + rand.Float64()*0.3, 0.5+rand.Float64()*0.3,
0.3 + rand.Float64()*0.3) 0.3+rand.Float64()*0.3)
} }
// Creates a random dark, "warm" color through restricted HCL space. // Creates a random dark, "warm" color through restricted HCL space.
// This is slower than FastWarmColor but will likely give you colors which have // This is slower than FastWarmColor but will likely give you colors which have
// the same "warmness" if you run it many times. // the same "warmness" if you run it many times.
func WarmColor() (c Color) { func WarmColor() (c Color) {
for c = randomWarm() ; !c.IsValid() ; c = randomWarm() {} for c = randomWarm(); !c.IsValid(); c = randomWarm() {
return }
return
} }
func randomWarm() Color { func randomWarm() Color {
return Hcl( return Hcl(
rand.Float64() * 360.0, rand.Float64()*360.0,
0.1 + rand.Float64()*0.3, 0.1+rand.Float64()*0.3,
0.2 + rand.Float64()*0.3) 0.2+rand.Float64()*0.3)
} }
// Creates a random bright, "pimpy" color through a restricted HSV space. // Creates a random bright, "pimpy" color through a restricted HSV space.
func FastHappyColor() Color { func FastHappyColor() Color {
return Hsv( return Hsv(
rand.Float64() * 360.0, rand.Float64()*360.0,
0.7 + rand.Float64()*0.3, 0.7+rand.Float64()*0.3,
0.6 + rand.Float64()*0.3) 0.6+rand.Float64()*0.3)
} }
// Creates a random bright, "pimpy" color through restricted HCL space. // Creates a random bright, "pimpy" color through restricted HCL space.
// This is slower than FastHappyColor but will likely give you colors which // This is slower than FastHappyColor but will likely give you colors which
// have the same "brightness" if you run it many times. // have the same "brightness" if you run it many times.
func HappyColor() (c Color) { func HappyColor() (c Color) {
for c = randomPimp() ; !c.IsValid() ; c = randomPimp() {} for c = randomPimp(); !c.IsValid(); c = randomPimp() {
return }
return
} }
func randomPimp() Color { func randomPimp() Color {
return Hcl( return Hcl(
rand.Float64() * 360.0, rand.Float64()*360.0,
0.5 + rand.Float64()*0.3, 0.5+rand.Float64()*0.3,
0.5 + rand.Float64()*0.3) 0.5+rand.Float64()*0.3)
} }

File diff suppressed because it is too large Load Diff

View File

@ -1,26 +1,25 @@
package colorful package colorful
import ( import (
"math/rand" "math/rand"
) )
// Uses the HSV color space to generate colors with similar S,V but distributed // Uses the HSV color space to generate colors with similar S,V but distributed
// evenly along their Hue. This is fast but not always pretty. // evenly along their Hue. This is fast but not always pretty.
// If you've got time to spare, use Lab (the non-fast below). // If you've got time to spare, use Lab (the non-fast below).
func FastHappyPalette(colorsCount int) (colors []Color) { func FastHappyPalette(colorsCount int) (colors []Color) {
colors = make([]Color, colorsCount) colors = make([]Color, colorsCount)
for i := 0 ; i < colorsCount ; i++ { for i := 0; i < colorsCount; i++ {
colors[i] = Hsv(float64(i)*(360.0/float64(colorsCount)), 0.8 + rand.Float64()*0.2, 0.65 + rand.Float64()*0.2) colors[i] = Hsv(float64(i)*(360.0/float64(colorsCount)), 0.8+rand.Float64()*0.2, 0.65+rand.Float64()*0.2)
} }
return return
} }
func HappyPalette(colorsCount int) ([]Color, error) { func HappyPalette(colorsCount int) ([]Color, error) {
pimpy := func(l, a, b float64) bool { pimpy := func(l, a, b float64) bool {
_, c, _ := LabToHcl(l, a, b) _, c, _ := LabToHcl(l, a, b)
return 0.3 <= c && 0.4 <= l && l <= 0.8 return 0.3 <= c && 0.4 <= l && l <= 0.8
} }
return SoftPaletteEx(colorsCount, SoftPaletteSettings{pimpy, 50, true}) return SoftPaletteEx(colorsCount, SoftPaletteSettings{pimpy, 50, true})
} }

View File

@ -4,27 +4,27 @@
package colorful package colorful
import ( import (
"fmt" "fmt"
"math" "math"
"math/rand" "math/rand"
) )
// The algorithm works in L*a*b* color space and converts to RGB in the end. // The algorithm works in L*a*b* color space and converts to RGB in the end.
// L* in [0..1], a* and b* in [-1..1] // L* in [0..1], a* and b* in [-1..1]
type lab_t struct { type lab_t struct {
L, A, B float64 L, A, B float64
} }
type SoftPaletteSettings struct { type SoftPaletteSettings struct {
// A function which can be used to restrict the allowed color-space. // A function which can be used to restrict the allowed color-space.
CheckColor func(l, a, b float64) bool CheckColor func(l, a, b float64) bool
// The higher, the better quality but the slower. Usually two figures. // The higher, the better quality but the slower. Usually two figures.
Iterations int Iterations int
// Use up to 160000 or 8000 samples of the L*a*b* space (and thus calls to CheckColor). // Use up to 160000 or 8000 samples of the L*a*b* space (and thus calls to CheckColor).
// Set this to true only if your CheckColor shapes the Lab space weirdly. // Set this to true only if your CheckColor shapes the Lab space weirdly.
ManySamples bool ManySamples bool
} }
// Yeah, windows-stype Foo, FooEx, screw you golang... // Yeah, windows-stype Foo, FooEx, screw you golang...
@ -34,152 +34,152 @@ type SoftPaletteSettings struct {
// specify a CheckColor function. // specify a CheckColor function.
func SoftPaletteEx(colorsCount int, settings SoftPaletteSettings) ([]Color, error) { func SoftPaletteEx(colorsCount int, settings SoftPaletteSettings) ([]Color, error) {
// Checks whether it's a valid RGB and also fulfills the potentially provided constraint. // Checks whether it's a valid RGB and also fulfills the potentially provided constraint.
check := func(col lab_t) bool { check := func(col lab_t) bool {
c := Lab(col.L, col.A, col.B) c := Lab(col.L, col.A, col.B)
return c.IsValid() && (settings.CheckColor == nil || settings.CheckColor(col.L, col.A, col.B)) return c.IsValid() && (settings.CheckColor == nil || settings.CheckColor(col.L, col.A, col.B))
} }
// Sample the color space. These will be the points k-means is run on. // Sample the color space. These will be the points k-means is run on.
dl := 0.05 dl := 0.05
dab := 0.1 dab := 0.1
if settings.ManySamples { if settings.ManySamples {
dl = 0.01 dl = 0.01
dab = 0.05 dab = 0.05
} }
samples := make([]lab_t, 0, int(1.0/dl * 2.0/dab * 2.0/dab)) samples := make([]lab_t, 0, int(1.0/dl*2.0/dab*2.0/dab))
for l := 0.0; l <= 1.0; l += dl { for l := 0.0; l <= 1.0; l += dl {
for a := -1.0; a <= 1.0; a += dab { for a := -1.0; a <= 1.0; a += dab {
for b := -1.0; b <= 1.0; b += dab { for b := -1.0; b <= 1.0; b += dab {
if check(lab_t{l,a,b}) { if check(lab_t{l, a, b}) {
samples = append(samples, lab_t{l, a, b}) samples = append(samples, lab_t{l, a, b})
} }
} }
} }
} }
// That would cause some infinite loops down there... // That would cause some infinite loops down there...
if len(samples) < colorsCount { if len(samples) < colorsCount {
return nil, fmt.Errorf("palettegen: more colors requested (%v) than samples available (%v). Your requested color count may be wrong, you might want to use many samples or your constraint function makes the valid color space too small.", colorsCount, len(samples)) return nil, fmt.Errorf("palettegen: more colors requested (%v) than samples available (%v). Your requested color count may be wrong, you might want to use many samples or your constraint function makes the valid color space too small.", colorsCount, len(samples))
} else if len(samples) == colorsCount { } else if len(samples) == colorsCount {
return labs2cols(samples), nil // Oops? return labs2cols(samples), nil // Oops?
} }
// We take the initial means out of the samples, so they are in fact medoids. // We take the initial means out of the samples, so they are in fact medoids.
// This helps us avoid infinite loops or arbitrary cutoffs with too restrictive constraints. // This helps us avoid infinite loops or arbitrary cutoffs with too restrictive constraints.
means := make([]lab_t, colorsCount) means := make([]lab_t, colorsCount)
for i := 0; i < colorsCount; i++ { for i := 0; i < colorsCount; i++ {
for means[i] = samples[rand.Intn(len(samples))] ; in(means, i, means[i]) ; means[i] = samples[rand.Intn(len(samples))] { for means[i] = samples[rand.Intn(len(samples))]; in(means, i, means[i]); means[i] = samples[rand.Intn(len(samples))] {
} }
} }
clusters := make([]int, len(samples)) clusters := make([]int, len(samples))
samples_used := make([]bool, len(samples)) samples_used := make([]bool, len(samples))
// The actual k-means/medoid iterations // The actual k-means/medoid iterations
for i := 0; i < settings.Iterations; i++ { for i := 0; i < settings.Iterations; i++ {
// Reassing the samples to clusters, i.e. to their closest mean. // Reassing the samples to clusters, i.e. to their closest mean.
// By the way, also check if any sample is used as a medoid and if so, mark that. // By the way, also check if any sample is used as a medoid and if so, mark that.
for isample, sample := range samples { for isample, sample := range samples {
samples_used[isample] = false samples_used[isample] = false
mindist := math.Inf(+1) mindist := math.Inf(+1)
for imean, mean := range means { for imean, mean := range means {
dist := lab_dist(sample, mean) dist := lab_dist(sample, mean)
if dist < mindist { if dist < mindist {
mindist = dist mindist = dist
clusters[isample] = imean clusters[isample] = imean
} }
// Mark samples which are used as a medoid. // Mark samples which are used as a medoid.
if lab_eq(sample, mean) { if lab_eq(sample, mean) {
samples_used[isample] = true samples_used[isample] = true
} }
} }
} }
// Compute new means according to the samples. // Compute new means according to the samples.
for imean := range means { for imean := range means {
// The new mean is the average of all samples belonging to it.. // The new mean is the average of all samples belonging to it..
nsamples := 0 nsamples := 0
newmean := lab_t{0.0, 0.0, 0.0} newmean := lab_t{0.0, 0.0, 0.0}
for isample, sample := range samples { for isample, sample := range samples {
if clusters[isample] == imean { if clusters[isample] == imean {
nsamples++ nsamples++
newmean.L += sample.L newmean.L += sample.L
newmean.A += sample.A newmean.A += sample.A
newmean.B += sample.B newmean.B += sample.B
} }
} }
if nsamples > 0 { if nsamples > 0 {
newmean.L /= float64(nsamples) newmean.L /= float64(nsamples)
newmean.A /= float64(nsamples) newmean.A /= float64(nsamples)
newmean.B /= float64(nsamples) newmean.B /= float64(nsamples)
} else { } else {
// That mean doesn't have any samples? Get a new mean from the sample list! // That mean doesn't have any samples? Get a new mean from the sample list!
var inewmean int var inewmean int
for inewmean = rand.Intn(len(samples_used)); samples_used[inewmean]; inewmean = rand.Intn(len(samples_used)) { for inewmean = rand.Intn(len(samples_used)); samples_used[inewmean]; inewmean = rand.Intn(len(samples_used)) {
} }
newmean = samples[inewmean] newmean = samples[inewmean]
samples_used[inewmean] = true samples_used[inewmean] = true
} }
// But now we still need to check whether the new mean is an allowed color. // But now we still need to check whether the new mean is an allowed color.
if nsamples > 0 && check(newmean) { if nsamples > 0 && check(newmean) {
// It does, life's good (TM) // It does, life's good (TM)
means[imean] = newmean means[imean] = newmean
} else { } else {
// New mean isn't an allowed color or doesn't have any samples! // New mean isn't an allowed color or doesn't have any samples!
// Switch to medoid mode and pick the closest (unused) sample. // Switch to medoid mode and pick the closest (unused) sample.
// This should always find something thanks to len(samples) >= colorsCount // This should always find something thanks to len(samples) >= colorsCount
mindist := math.Inf(+1) mindist := math.Inf(+1)
for isample, sample := range samples { for isample, sample := range samples {
if !samples_used[isample] { if !samples_used[isample] {
dist := lab_dist(sample, newmean) dist := lab_dist(sample, newmean)
if dist < mindist { if dist < mindist {
mindist = dist mindist = dist
newmean = sample newmean = sample
} }
} }
} }
} }
} }
} }
return labs2cols(means), nil return labs2cols(means), nil
} }
// A wrapper which uses common parameters. // A wrapper which uses common parameters.
func SoftPalette(colorsCount int) ([]Color, error) { func SoftPalette(colorsCount int) ([]Color, error) {
return SoftPaletteEx(colorsCount, SoftPaletteSettings{nil, 50, false}) return SoftPaletteEx(colorsCount, SoftPaletteSettings{nil, 50, false})
} }
func in(haystack []lab_t, upto int, needle lab_t) bool { func in(haystack []lab_t, upto int, needle lab_t) bool {
for i := 0 ; i < upto && i < len(haystack) ; i++ { for i := 0; i < upto && i < len(haystack); i++ {
if haystack[i] == needle { if haystack[i] == needle {
return true return true
} }
} }
return false return false
} }
const LAB_DELTA = 1e-6 const LAB_DELTA = 1e-6
func lab_eq(lab1, lab2 lab_t) bool { func lab_eq(lab1, lab2 lab_t) bool {
return math.Abs(lab1.L - lab2.L) < LAB_DELTA && return math.Abs(lab1.L-lab2.L) < LAB_DELTA &&
math.Abs(lab1.A - lab2.A) < LAB_DELTA && math.Abs(lab1.A-lab2.A) < LAB_DELTA &&
math.Abs(lab1.B - lab2.B) < LAB_DELTA math.Abs(lab1.B-lab2.B) < LAB_DELTA
} }
// That's faster than using colorful's DistanceLab since we would have to // That's faster than using colorful's DistanceLab since we would have to
// convert back and forth for that. Here is no conversion. // convert back and forth for that. Here is no conversion.
func lab_dist(lab1, lab2 lab_t) float64 { func lab_dist(lab1, lab2 lab_t) float64 {
return math.Sqrt(sq(lab1.L-lab2.L) + sq(lab1.A-lab2.A) + sq(lab1.B-lab2.B)) return math.Sqrt(sq(lab1.L-lab2.L) + sq(lab1.A-lab2.A) + sq(lab1.B-lab2.B))
} }
func labs2cols(labs []lab_t) (cols []Color) { func labs2cols(labs []lab_t) (cols []Color) {
cols = make([]Color, len(labs)) cols = make([]Color, len(labs))
for k, v := range labs { for k, v := range labs {
cols[k] = Lab(v.L, v.A, v.B) cols[k] = Lab(v.L, v.A, v.B)
} }
return cols return cols
} }

View File

@ -1,26 +1,25 @@
package colorful package colorful
import ( import (
"math/rand" "math/rand"
) )
// Uses the HSV color space to generate colors with similar S,V but distributed // Uses the HSV color space to generate colors with similar S,V but distributed
// evenly along their Hue. This is fast but not always pretty. // evenly along their Hue. This is fast but not always pretty.
// If you've got time to spare, use Lab (the non-fast below). // If you've got time to spare, use Lab (the non-fast below).
func FastWarmPalette(colorsCount int) (colors []Color) { func FastWarmPalette(colorsCount int) (colors []Color) {
colors = make([]Color, colorsCount) colors = make([]Color, colorsCount)
for i := 0 ; i < colorsCount ; i++ { for i := 0; i < colorsCount; i++ {
colors[i] = Hsv(float64(i)*(360.0/float64(colorsCount)), 0.55 + rand.Float64()*0.2, 0.35 + rand.Float64()*0.2) colors[i] = Hsv(float64(i)*(360.0/float64(colorsCount)), 0.55+rand.Float64()*0.2, 0.35+rand.Float64()*0.2)
} }
return return
} }
func WarmPalette(colorsCount int) ([]Color, error) { func WarmPalette(colorsCount int) ([]Color, error) {
warmy := func(l, a, b float64) bool { warmy := func(l, a, b float64) bool {
_, c, _ := LabToHcl(l, a, b) _, c, _ := LabToHcl(l, a, b)
return 0.1 <= c && c <= 0.4 && 0.2 <= l && l <= 0.5 return 0.1 <= c && c <= 0.4 && 0.2 <= l && l <= 0.5
} }
return SoftPaletteEx(colorsCount, SoftPaletteSettings{warmy, 50, true}) return SoftPaletteEx(colorsCount, SoftPaletteSettings{warmy, 50, true})
} }

View File

@ -48,12 +48,13 @@ func (cb *CellBuffer) SetContent(x int, y int,
if x >= 0 && y >= 0 && x < cb.w && y < cb.h { if x >= 0 && y >= 0 && x < cb.w && y < cb.h {
c := &cb.cells[(y*cb.w)+x] c := &cb.cells[(y*cb.w)+x]
c.currComb = append([]rune{}, combc...)
i := 0 i := 0
for i < len(combc) { for i < len(c.currComb) {
r := combc[i] r := c.currComb[i]
if runewidth.RuneWidth(r) != 0 { if runewidth.RuneWidth(r) != 0 {
// not a combining character, yank it // not a combining character, yank it
combc = append(combc[:i-1], combc[i+1:]...) c.currComb = append(c.currComb[:i-1], c.currComb[i+1:]...)
continue continue
} }
i++ i++
@ -63,7 +64,6 @@ func (cb *CellBuffer) SetContent(x int, y int,
c.width = runewidth.RuneWidth(mainc) c.width = runewidth.RuneWidth(mainc)
} }
c.currMain = mainc c.currMain = mainc
c.currComb = combc
c.currStyle = style c.currStyle = style
} }
} }

View File

@ -185,7 +185,7 @@ func (s *cScreen) CharacterSet() string {
} }
func (s *cScreen) EnableMouse() { func (s *cScreen) EnableMouse() {
s.setInMode(modeResizeEn | modeMouseEn) s.setInMode(modeResizeEn | modeMouseEn | modeExtndFlg)
} }
func (s *cScreen) DisableMouse() { func (s *cScreen) DisableMouse() {
@ -570,8 +570,14 @@ func (s *cScreen) getConsoleInput() error {
if krec.ch != 0 { if krec.ch != 0 {
// synthesized key code // synthesized key code
for krec.repeat > 0 { for krec.repeat > 0 {
s.PostEvent(NewEventKey(KeyRune, rune(krec.ch), // convert shift+tab to backtab
mod2mask(krec.mod))) if mod2mask(krec.mod) == ModShift && krec.ch == vkTab {
s.PostEvent(NewEventKey(KeyBacktab, 0,
ModNone))
} else {
s.PostEvent(NewEventKey(KeyRune, rune(krec.ch),
mod2mask(krec.mod)))
}
krec.repeat-- krec.repeat--
} }
return nil return nil
@ -925,6 +931,7 @@ func (s *cScreen) clearScreen(style Style) {
} }
const ( const (
modeExtndFlg uint32 = 0x0080
modeMouseEn uint32 = 0x0010 modeMouseEn uint32 = 0x0010
modeResizeEn uint32 = 0x0008 modeResizeEn uint32 = 0x0008
modeWrapEOL uint32 = 0x0002 modeWrapEOL uint32 = 0x0002

8
vendor/maunium.net/go/tcell/terminfo/README.md generated vendored Normal file
View File

@ -0,0 +1,8 @@
To run the database:
./mkinfo -all
You can also generate a single entry:
./mkinfo -db <term>

View File

@ -1,189 +0,0 @@
#!/bin/bash
# Copyright 2017 The TCell Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use file except in compliance with the License.
# You may obtain a copy of the license at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# When called with no arguments, this shell script builds the Go database,
# which is somewhat minimal for size reasons (it only contains the most
# commonly used entries), and then builds the complete JSON database.
#
# To limit the action to only building one or more terminals, specify them
# on the command line:
#
# ./mkdatabase xterm
#
# The script will also find and update or add any terminal "aliases".
# It does not remove any old entries.
#
# To add to the set of terminals that we compile into the Go database,
# add their names to the models.txt file.
#
# This script is not very efficient, but there isn't really a better way
# without writing code to decode the terminfo binary format directly.
# Its not worth worrying about.
# This script also requires bash, although ksh93 should work as well, because
# we use arrays, which are not specified in POSIX.
export LANG=C
export LC_CTYPE=C
progress()
{
typeset -i num=$1
typeset -i tot=$2
typeset -i x
typeset back
typeset s
if (( tot < 1 ))
then
s=$(printf "[ %d ]" $num)
back="\b\b\b\b\b"
x=$num
while (( x >= 10 ))
do
back="${back}\b"
x=$(( x / 10 ))
done
else
x=$(( num * 100 / tot ))
s=$(printf "<%3d%%>" $x)
back="\b\b\b\b\b\b"
fi
printf "%s${back}" "$s"
}
ord()
{
printf "%02x" "'$1'"
}
goterms=( $(cat models.txt) )
args=( $* )
if (( ${#args[@]} == 0 ))
then
args=( $(toe -a | cut -f1) )
fi
printf "Scanning terminal definitions: "
i=0
aliases=()
models=()
for term in ${args[@]}
do
case "${term}" in
*-truecolor)
line="${term}|24-bit color"
;;
*)
line=$(infocmp $term | head -2 | tail -1)
if [[ -z "$line" ]]
then
echo "Cannot find terminfo for $term"
exit 1
fi
# take off the trailing comma
line=${line%,}
esac
# grab primary name
term=${line%%|*}
all+=( ${term} )
# should this be in our go terminals?
for model in ${goterms[@]}
do
if [[ "${model}" == "${term}" ]]
then
models+=( ${term} )
fi
done
# chop off primary name
line=${line#${term}}
line=${line#|}
# chop off description
line=${line%|*}
while [[ "$line" != "" ]]
do
a=${line%%|*}
aliases+=( ${a}=${term} )
line=${line#$a}
line=${line#|}
done
i=$(( i + 1 ))
progress $i ${#args[@]}
done
echo
# make sure we have mkinfo
printf "Building mkinfo: "
go build mkinfo.go
echo "done."
# Build all the go database files for the "interesting" terminals".
printf "Building Go database: "
i=0
for model in ${models[@]}
do
safe=$(echo $model | tr - _)
file=term_${safe}.go
./mkinfo -go $file $model
go fmt ${file} >/dev/null
i=$(( i + 1 ))
progress $i ${#models[@]}
done
echo
printf "Building JSON database: "
# The JSON files are located for each terminal in a file with the
# terminal name, in the following fashion "database/x/xterm.json
i=0
for model in ${all[@]}
do
letter=$(ord ${model:0:1})
dir=database/${letter}
file=${dir}/${model}.gz
mkdir -p ${dir}
./mkinfo -nofatal -quiet -gzip -json ${file} ${model}
i=$(( i + 1 ))
progress $i ${#all[@]}
done
echo
printf "Building JSON aliases: "
i=0
for model in ${aliases[@]}
do
canon=${model#*=}
model=${model%=*}
letter=$(ord ${model:0:1})
cletter=$(ord ${canon:0:1})
dir=database/${letter}
file=${dir}/${model}
if [[ -f database/${cletter}/${canon}.gz ]]
then
[[ -d ${dir} ]] || mkdir -p ${dir}
# Generally speaking the aliases are better uncompressed
./mkinfo -nofatal -quiet -json ${file} ${model}
fi
i=$(( i + 1 ))
progress $i ${#aliases[@]}
done
echo

View File

@ -1,6 +1,6 @@
// +build ignore // +build ignore
// Copyright 2017 The TCell Authors // Copyright 2018 The TCell Authors
// //
// Licensed under the Apache License, Version 2.0 (the "License"); // Licensed under the Apache License, Version 2.0 (the "License");
// you may not use file except in compliance with the License. // you may not use file except in compliance with the License.
@ -22,6 +22,8 @@
// //
// mkinfo [-init] [-go file.go] [-json file.json] [-quiet] [-nofatal] [<term>...] // mkinfo [-init] [-go file.go] [-json file.json] [-quiet] [-nofatal] [<term>...]
// //
// -all scan terminfo to determine database entries to use
// -db generate database entries (database/*), implied for -all
// -gzip specifies output should be compressed (json only) // -gzip specifies output should be compressed (json only)
// -go specifies Go output into the named file. Use - for stdout. // -go specifies Go output into the named file. Use - for stdout.
// -json specifies JSON output in the named file. Use - for stdout // -json specifies JSON output in the named file. Use - for stdout
@ -31,8 +33,10 @@
package main package main
import ( import (
"bufio"
"bytes" "bytes"
"compress/gzip" "compress/gzip"
"crypto/sha1"
"encoding/json" "encoding/json"
"errors" "errors"
"flag" "flag"
@ -40,6 +44,7 @@ import (
"io" "io"
"os" "os"
"os/exec" "os/exec"
"path"
"regexp" "regexp"
"strconv" "strconv"
"strings" "strings"
@ -74,6 +79,8 @@ const (
ESC ESC
) )
var notaddressable = errors.New("terminal not cursor addressable")
func unescape(s string) string { func unescape(s string) string {
// Various escapes are in \x format. Control codes are // Various escapes are in \x format. Control codes are
// encoded as ^M (carat followed by ASCII equivalent). // encoded as ^M (carat followed by ASCII equivalent).
@ -131,6 +138,25 @@ func unescape(s string) string {
return (buf.String()) return (buf.String())
} }
func getallterms() ([]string, error) {
out := []string{}
cmd := exec.Command("toe", "-a")
output := &bytes.Buffer{}
cmd.Stdout = output
err := cmd.Run()
if err != nil {
return nil, err
}
lines := strings.Split(output.String(), "\n")
for _, l := range lines {
fields := strings.Fields(l)
if len(fields) > 0 {
out = append(out, fields[0])
}
}
return out, nil
}
func (tc *termcap) setupterm(name string) error { func (tc *termcap) setupterm(name string) error {
cmd := exec.Command("infocmp", "-1", name) cmd := exec.Command("infocmp", "-1", name)
output := &bytes.Buffer{} output := &bytes.Buffer{}
@ -183,7 +209,7 @@ func (tc *termcap) setupterm(name string) error {
if k := strings.SplitN(val, "=", 2); len(k) == 2 { if k := strings.SplitN(val, "=", 2); len(k) == 2 {
tc.strs[k[0]] = unescape(k[1]) tc.strs[k[0]] = unescape(k[1])
} else if k := strings.SplitN(val, "#", 2); len(k) == 2 { } else if k := strings.SplitN(val, "#", 2); len(k) == 2 {
if u, err := strconv.ParseUint(k[1], 10, 0); err != nil { if u, err := strconv.ParseUint(k[1], 0, 0); err != nil {
return (err) return (err)
} else { } else {
tc.nums[k[0]] = int(u) tc.nums[k[0]] = int(u)
@ -438,7 +464,7 @@ func getinfo(name string) (*terminfo.Terminfo, string, error) {
t.Colors = 0 t.Colors = 0
} }
if t.SetCursor == "" { if t.SetCursor == "" {
return nil, "", errors.New("terminal not cursor addressable") return nil, "", notaddressable
} }
// For padding, we lookup the pad char. If that isn't present, // For padding, we lookup the pad char. If that isn't present,
@ -684,13 +710,135 @@ func dotGoInfo(w io.Writer, t *terminfo.Terminfo, desc string) {
fmt.Fprintln(w, "}") fmt.Fprintln(w, "}")
} }
var packname = "terminfo"
func dotGoFile(fname string, term *terminfo.Terminfo, desc string, makeDir bool) error {
w := os.Stdout
var e error
if fname != "-" && fname != "" {
if makeDir {
dname := path.Dir(fname)
_ = os.Mkdir(dname, 0777)
}
if w, e = os.Create(fname); e != nil {
return e
}
}
dotGoHeader(w, packname)
dotGoInfo(w, term, desc)
dotGoTrailer(w)
if w != os.Stdout {
w.Close()
}
cmd := exec.Command("go", "fmt", fname)
cmd.Run()
return nil
}
func dotGzFile(fname string, term *terminfo.Terminfo, makeDir bool) error {
var w io.WriteCloser = os.Stdout
var e error
if fname != "-" && fname != "" {
if makeDir {
dname := path.Dir(fname)
_ = os.Mkdir(dname, 0777)
}
if w, e = os.Create(fname); e != nil {
return e
}
}
w = gzip.NewWriter(w)
js, e := json.Marshal(term)
fmt.Fprintln(w, string(js))
if w != os.Stdout {
w.Close()
}
return nil
}
func jsonFile(fname string, term *terminfo.Terminfo, makeDir bool) error {
w := os.Stdout
var e error
if fname != "-" && fname != "" {
if makeDir {
dname := path.Dir(fname)
_ = os.Mkdir(dname, 0777)
}
if w, e = os.Create(fname); e != nil {
return e
}
}
js, e := json.Marshal(term)
fmt.Fprintln(w, string(js))
if w != os.Stdout {
w.Close()
}
return nil
}
func dumpDatabase(terms map[string]*terminfo.Terminfo, descs map[string]string) {
// Load models .text
mfile, e := os.Open("models.txt")
models := make(map[string]bool)
if e != nil {
fmt.Fprintf(os.Stderr, "Failed reading models.txt: %v", e)
}
scanner := bufio.NewScanner(mfile)
for scanner.Scan() {
models[scanner.Text()] = true
}
for name, t := range terms {
// If this is one of our builtin models, generate the GO file
if models[name] {
desc := descs[name]
safename := strings.Replace(name, "-", "_", -1)
goname := fmt.Sprintf("term_%s.go", safename)
e = dotGoFile(goname, t, desc, true)
if e != nil {
fmt.Fprintf(os.Stderr, "Failed creating %s: %v", goname, e)
os.Exit(1)
}
continue
}
hash := fmt.Sprintf("%x", sha1.Sum([]byte(name)))
fname := fmt.Sprintf("%s.gz", hash[0:8])
fname = path.Join("database", hash[0:2], fname)
e = dotGzFile(fname, t, true)
if e != nil {
fmt.Fprintf(os.Stderr, "Failed creating %s: %v", fname, e)
os.Exit(1)
}
for _, a := range t.Aliases {
hash = fmt.Sprintf("%x", sha1.Sum([]byte(a)))
fname = path.Join("database", hash[0:2], hash[0:8])
e = jsonFile(fname, &terminfo.Terminfo{Name: t.Name}, true)
if e != nil {
fmt.Fprintf(os.Stderr, "Failed creating %s: %v", fname, e)
os.Exit(1)
}
}
}
}
func main() { func main() {
gofile := "" gofile := ""
jsonfile := "" jsonfile := ""
packname := "terminfo"
nofatal := false nofatal := false
quiet := false quiet := false
dogzip := false dogzip := false
all := false
db := false
flag.StringVar(&gofile, "go", "", "generate go source in named file") flag.StringVar(&gofile, "go", "", "generate go source in named file")
flag.StringVar(&jsonfile, "json", "", "generate json in named file") flag.StringVar(&jsonfile, "json", "", "generate json in named file")
@ -698,11 +846,21 @@ func main() {
flag.BoolVar(&nofatal, "nofatal", false, "errors are not fatal") flag.BoolVar(&nofatal, "nofatal", false, "errors are not fatal")
flag.BoolVar(&quiet, "quiet", false, "suppress error messages") flag.BoolVar(&quiet, "quiet", false, "suppress error messages")
flag.BoolVar(&dogzip, "gzip", false, "compress json output") flag.BoolVar(&dogzip, "gzip", false, "compress json output")
flag.BoolVar(&all, "all", false, "load all terminals from terminfo")
flag.BoolVar(&db, "db", false, "generate json db file in place")
flag.Parse() flag.Parse()
var e error var e error
js := []byte{}
args := flag.Args() args := flag.Args()
if all {
db = true // implied
allterms, e := getallterms()
if e != nil {
fmt.Fprintf(os.Stderr, "Failed: %v", e)
os.Exit(1)
}
args = append(args, allterms...)
}
if len(args) == 0 { if len(args) == 0 {
args = []string{os.Getenv("TERM")} args = []string{os.Getenv("TERM")}
} }
@ -712,6 +870,9 @@ func main() {
for _, term := range args { for _, term := range args {
if t, desc, e := getinfo(term); e != nil { if t, desc, e := getinfo(term); e != nil {
if all && e == notaddressable {
continue
}
if !quiet { if !quiet {
fmt.Fprintf(os.Stderr, fmt.Fprintf(os.Stderr,
"Failed loading %s: %v\n", term, e) "Failed loading %s: %v\n", term, e)
@ -729,53 +890,33 @@ func main() {
// No data. // No data.
os.Exit(0) os.Exit(0)
} }
if gofile != "" {
w := os.Stdout if db {
if gofile != "-" { dumpDatabase(tdata, descs)
if w, e = os.Create(gofile); e != nil { } else if gofile != "" {
fmt.Fprintf(os.Stderr, "Failed: %v", e)
os.Exit(1)
}
}
dotGoHeader(w, packname)
for term, t := range tdata { for term, t := range tdata {
if t.Name == term { if t.Name == term {
dotGoInfo(w, t, descs[term]) e = dotGoFile(gofile, t, descs[term], false)
if e != nil {
fmt.Fprintf(os.Stderr, "Failed %s: %v", gofile, e)
os.Exit(1)
}
} }
} }
dotGoTrailer(w)
if w != os.Stdout {
w.Close()
}
} else { } else {
o := os.Stdout for _, t := range tdata {
if jsonfile != "-" && jsonfile != "" { if dogzip {
if o, e = os.Create(jsonfile); e != nil { if e = dotGzFile(jsonfile, t, false); e != nil {
fmt.Fprintf(os.Stderr, "Failed: %v", e) fmt.Fprintf(os.Stderr, "Failed %s: %v", gofile, e)
os.Exit(1)
}
} else {
if e = jsonFile(jsonfile, t, false); e != nil {
fmt.Fprintf(os.Stderr, "Failed %s: %v", gofile, e)
os.Exit(1)
}
} }
} }
var w io.WriteCloser
w = o
if dogzip {
w = gzip.NewWriter(o)
}
for _, term := range args {
if t := tdata[term]; t != nil {
js, e = json.Marshal(t)
fmt.Fprintln(w, string(js))
}
// arguably if there is more than one term, this
// should be a javascript array, but that's not how
// we load it. We marshal objects one at a time from
// the file.
}
if e != nil {
fmt.Fprintf(os.Stderr, "Failed: %v", e)
os.Exit(1)
}
w.Close()
if w != o {
o.Close()
}
} }
} }

View File

@ -8,8 +8,6 @@ cygwin
d200 d200
d210 d210
dtterm dtterm
Eterm
Eterm-256color
eterm eterm
gnome gnome
gnome-256color gnome-256color

View File

@ -1,108 +0,0 @@
// Generated automatically. DO NOT HAND-EDIT.
package terminfo
func init() {
// Eterm with xterm-style color support (X Window System)
AddTerminfo(&Terminfo{
Name: "Eterm",
Aliases: []string{"Eterm-color"},
Columns: 80,
Lines: 24,
Colors: 8,
Bell: "\a",
Clear: "\x1b[H\x1b[2J",
EnterCA: "\x1b7\x1b[?47h",
ExitCA: "\x1b[2J\x1b[?47l\x1b8",
ShowCursor: "\x1b[?25h",
HideCursor: "\x1b[?25l",
AttrOff: "\x1b[m\x0f",
Underline: "\x1b[4m",
Bold: "\x1b[1m",
Italic: "\x1b[3m",
Strikethrough: "\x1b[9m",
Blink: "\x1b[5m",
Reverse: "\x1b[7m",
SetFg: "\x1b[3%p1%dm",
SetBg: "\x1b[4%p1%dm",
SetFgBg: "\x1b[3%p1%d;4%p2%dm",
PadChar: "\x00",
AltChars: "``aaffggjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~",
EnterAcs: "\x0e",
ExitAcs: "\x0f",
EnableAcs: "\x1b)0",
Mouse: "\x1b[M",
MouseMode: "%?%p1%{1}%=%t%'h'%Pa%e%'l'%Pa%;\x1b[?1000%ga%c\x1b[?1002%ga%c\x1b[?1003%ga%c\x1b[?1006%ga%c",
SetCursor: "\x1b[%i%p1%d;%p2%dH",
CursorBack1: "\b",
CursorUp1: "\x1b[A",
KeyUp: "\x1b[A",
KeyDown: "\x1b[B",
KeyRight: "\x1b[C",
KeyLeft: "\x1b[D",
KeyInsert: "\x1b[2~",
KeyDelete: "\x1b[3~",
KeyBackspace: "\u007f",
KeyHome: "\x1b[7~",
KeyEnd: "\x1b[8~",
KeyPgUp: "\x1b[5~",
KeyPgDn: "\x1b[6~",
KeyF1: "\x1b[11~",
KeyF2: "\x1b[12~",
KeyF3: "\x1b[13~",
KeyF4: "\x1b[14~",
KeyF5: "\x1b[15~",
KeyF6: "\x1b[17~",
KeyF7: "\x1b[18~",
KeyF8: "\x1b[19~",
KeyF9: "\x1b[20~",
KeyF10: "\x1b[21~",
KeyF11: "\x1b[23~",
KeyF12: "\x1b[24~",
KeyF13: "\x1b[25~",
KeyF14: "\x1b[26~",
KeyF15: "\x1b[28~",
KeyF16: "\x1b[29~",
KeyF17: "\x1b[31~",
KeyF18: "\x1b[32~",
KeyF19: "\x1b[33~",
KeyF20: "\x1b[34~",
KeyF21: "\x1b[23$",
KeyF22: "\x1b[24$",
KeyF23: "\x1b[11^",
KeyF24: "\x1b[12^",
KeyF25: "\x1b[13^",
KeyF26: "\x1b[14^",
KeyF27: "\x1b[15^",
KeyF28: "\x1b[17^",
KeyF29: "\x1b[18^",
KeyF30: "\x1b[19^",
KeyF31: "\x1b[20^",
KeyF32: "\x1b[21^",
KeyF33: "\x1b[23^",
KeyF34: "\x1b[24^",
KeyF35: "\x1b[25^",
KeyF36: "\x1b[26^",
KeyF37: "\x1b[28^",
KeyF38: "\x1b[29^",
KeyF39: "\x1b[31^",
KeyF40: "\x1b[32^",
KeyF41: "\x1b[33^",
KeyF42: "\x1b[34^",
KeyF43: "\x1b[23@",
KeyF44: "\x1b[24@",
KeyHelp: "\x1b[28~",
KeyShfLeft: "\x1b[d",
KeyShfRight: "\x1b[c",
KeyShfUp: "\x1b[a",
KeyShfDown: "\x1b[b",
KeyCtrlLeft: "\x1b[Od",
KeyCtrlRight: "\x1b[Oc",
KeyCtrlUp: "\x1b[Oa",
KeyCtrlDown: "\x1b[Ob",
KeyShfHome: "\x1b[7$",
KeyShfEnd: "\x1b[8$",
KeyCtrlHome: "\x1b[7^",
KeyCtrlEnd: "\x1b[8^",
})
}

View File

@ -1,107 +0,0 @@
// Generated automatically. DO NOT HAND-EDIT.
package terminfo
func init() {
// Eterm with xterm 256-colors
AddTerminfo(&Terminfo{
Name: "Eterm-256color",
Columns: 80,
Lines: 24,
Colors: 256,
Bell: "\a",
Clear: "\x1b[H\x1b[2J",
EnterCA: "\x1b7\x1b[?47h",
ExitCA: "\x1b[2J\x1b[?47l\x1b8",
ShowCursor: "\x1b[?25h",
HideCursor: "\x1b[?25l",
AttrOff: "\x1b[m\x0f",
Underline: "\x1b[4m",
Bold: "\x1b[1m",
Italic: "\x1b[3m",
Strikethrough: "\x1b[9m",
Blink: "\x1b[5m",
Reverse: "\x1b[7m",
SetFg: "\x1b[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m",
SetBg: "\x1b[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e48;5;%p1%d%;m",
SetFgBg: "\x1b[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;;%?%p2%{8}%<%t4%p2%d%e%p2%{16}%<%t10%p2%{8}%-%d%e48;5;%p2%d%;m",
PadChar: "\x00",
AltChars: "``aaffggjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~",
EnterAcs: "\x0e",
ExitAcs: "\x0f",
EnableAcs: "\x1b)0",
Mouse: "\x1b[M",
MouseMode: "%?%p1%{1}%=%t%'h'%Pa%e%'l'%Pa%;\x1b[?1000%ga%c\x1b[?1002%ga%c\x1b[?1003%ga%c\x1b[?1006%ga%c",
SetCursor: "\x1b[%i%p1%d;%p2%dH",
CursorBack1: "\b",
CursorUp1: "\x1b[A",
KeyUp: "\x1b[A",
KeyDown: "\x1b[B",
KeyRight: "\x1b[C",
KeyLeft: "\x1b[D",
KeyInsert: "\x1b[2~",
KeyDelete: "\x1b[3~",
KeyBackspace: "\u007f",
KeyHome: "\x1b[7~",
KeyEnd: "\x1b[8~",
KeyPgUp: "\x1b[5~",
KeyPgDn: "\x1b[6~",
KeyF1: "\x1b[11~",
KeyF2: "\x1b[12~",
KeyF3: "\x1b[13~",
KeyF4: "\x1b[14~",
KeyF5: "\x1b[15~",
KeyF6: "\x1b[17~",
KeyF7: "\x1b[18~",
KeyF8: "\x1b[19~",
KeyF9: "\x1b[20~",
KeyF10: "\x1b[21~",
KeyF11: "\x1b[23~",
KeyF12: "\x1b[24~",
KeyF13: "\x1b[25~",
KeyF14: "\x1b[26~",
KeyF15: "\x1b[28~",
KeyF16: "\x1b[29~",
KeyF17: "\x1b[31~",
KeyF18: "\x1b[32~",
KeyF19: "\x1b[33~",
KeyF20: "\x1b[34~",
KeyF21: "\x1b[23$",
KeyF22: "\x1b[24$",
KeyF23: "\x1b[11^",
KeyF24: "\x1b[12^",
KeyF25: "\x1b[13^",
KeyF26: "\x1b[14^",
KeyF27: "\x1b[15^",
KeyF28: "\x1b[17^",
KeyF29: "\x1b[18^",
KeyF30: "\x1b[19^",
KeyF31: "\x1b[20^",
KeyF32: "\x1b[21^",
KeyF33: "\x1b[23^",
KeyF34: "\x1b[24^",
KeyF35: "\x1b[25^",
KeyF36: "\x1b[26^",
KeyF37: "\x1b[28^",
KeyF38: "\x1b[29^",
KeyF39: "\x1b[31^",
KeyF40: "\x1b[32^",
KeyF41: "\x1b[33^",
KeyF42: "\x1b[34^",
KeyF43: "\x1b[23@",
KeyF44: "\x1b[24@",
KeyHelp: "\x1b[28~",
KeyShfLeft: "\x1b[d",
KeyShfRight: "\x1b[c",
KeyShfUp: "\x1b[a",
KeyShfDown: "\x1b[b",
KeyCtrlLeft: "\x1b[Od",
KeyCtrlRight: "\x1b[Oc",
KeyCtrlUp: "\x1b[Oa",
KeyCtrlDown: "\x1b[Ob",
KeyShfHome: "\x1b[7$",
KeyShfEnd: "\x1b[8$",
KeyCtrlHome: "\x1b[7^",
KeyCtrlEnd: "\x1b[8^",
})
}

View File

@ -22,6 +22,8 @@ func init() {
SetFgBg: "\x1b[3%p1%d;4%p2%dm", SetFgBg: "\x1b[3%p1%d;4%p2%dm",
PadChar: "\x00", PadChar: "\x00",
AltChars: "jjkkllmmnnqqttuuvvwwxx", AltChars: "jjkkllmmnnqqttuuvvwwxx",
EnterAcs: "\x1b(0",
ExitAcs: "\x1b(B",
SetCursor: "\x1b[%i%p1%d;%p2%dH", SetCursor: "\x1b[%i%p1%d;%p2%dH",
CursorBack1: "\b", CursorBack1: "\b",
CursorUp1: "\x1b[A", CursorUp1: "\x1b[A",

View File

@ -43,7 +43,7 @@ func init() {
KeyLeft: "\x1b[D", KeyLeft: "\x1b[D",
KeyInsert: "\x1b[2~", KeyInsert: "\x1b[2~",
KeyDelete: "\x1b[3~", KeyDelete: "\x1b[3~",
KeyBackspace: "\u007f", KeyBackspace: "\xff",
KeyHome: "\x1b[7~", KeyHome: "\x1b[7~",
KeyEnd: "\x1b[8~", KeyEnd: "\x1b[8~",
KeyPgUp: "\x1b[5~", KeyPgUp: "\x1b[5~",

26
vendor/maunium.net/go/tcell/terminfo/term_eterm.go generated vendored Normal file
View File

@ -0,0 +1,26 @@
// Generated automatically. DO NOT HAND-EDIT.
package terminfo
func init() {
// gnu emacs term.el terminal emulation
AddTerminfo(&Terminfo{
Name: "eterm",
Columns: 80,
Lines: 24,
Bell: "\a",
Clear: "\x1b[H\x1b[J",
EnterCA: "\x1b7\x1b[?47h",
ExitCA: "\x1b[2J\x1b[?47l\x1b8",
AttrOff: "\x1b[m",
Underline: "\x1b[4m",
Bold: "\x1b[1m",
Italic: "\x1b[3m",
Strikethrough: "\x1b[9m",
Reverse: "\x1b[7m",
PadChar: "\x00",
SetCursor: "\x1b[%i%p1%d;%p2%dH",
CursorBack1: "\b",
CursorUp1: "\x1b[A",
})
}

View File

@ -43,7 +43,7 @@ func init() {
KeyLeft: "\x1bOD", KeyLeft: "\x1bOD",
KeyInsert: "\x1b[2~", KeyInsert: "\x1b[2~",
KeyDelete: "\x1b[3~", KeyDelete: "\x1b[3~",
KeyBackspace: "\u007f", KeyBackspace: "\xff",
KeyHome: "\x1bOH", KeyHome: "\x1bOH",
KeyEnd: "\x1bOF", KeyEnd: "\x1bOF",
KeyPgUp: "\x1b[5~", KeyPgUp: "\x1b[5~",

View File

@ -32,7 +32,7 @@ func init() {
EnterAcs: "\x0e", EnterAcs: "\x0e",
ExitAcs: "\x0f", ExitAcs: "\x0f",
EnableAcs: "\x1b)0", EnableAcs: "\x1b)0",
Mouse: "\x1b[M", Mouse: "\x1b[<",
MouseMode: "%?%p1%{1}%=%t%'h'%Pa%e%'l'%Pa%;\x1b[?1000%ga%c\x1b[?1002%ga%c\x1b[?1003%ga%c\x1b[?1006%ga%c", MouseMode: "%?%p1%{1}%=%t%'h'%Pa%e%'l'%Pa%;\x1b[?1000%ga%c\x1b[?1002%ga%c\x1b[?1003%ga%c\x1b[?1006%ga%c",
SetCursor: "\x1b[%i%p1%d;%p2%dH", SetCursor: "\x1b[%i%p1%d;%p2%dH",
CursorBack1: "\b", CursorBack1: "\b",
@ -43,7 +43,7 @@ func init() {
KeyLeft: "\x1bOD", KeyLeft: "\x1bOD",
KeyInsert: "\x1b[2~", KeyInsert: "\x1b[2~",
KeyDelete: "\x1b[3~", KeyDelete: "\x1b[3~",
KeyBackspace: "\u007f", KeyBackspace: "\xff",
KeyHome: "\x1bOH", KeyHome: "\x1bOH",
KeyEnd: "\x1bOF", KeyEnd: "\x1bOF",
KeyPgUp: "\x1b[5~", KeyPgUp: "\x1b[5~",

View File

@ -11,7 +11,7 @@ func init() {
Lines: 24, Lines: 24,
Bell: "\a", Bell: "\a",
Clear: "\x1b&a0y0C\x1bJ", Clear: "\x1b&a0y0C\x1bJ",
AttrOff: "\x1b&d@", AttrOff: "\x1b&d@\x0f",
Underline: "\x1b&dD", Underline: "\x1b&dD",
Bold: "\x1b&dB", Bold: "\x1b&dB",
Italic: "\x1b[3m", Italic: "\x1b[3m",

View File

@ -5,110 +5,151 @@ package terminfo
func init() { func init() {
// KDE console window // KDE console window
AddTerminfo(&Terminfo{ AddTerminfo(&Terminfo{
Name: "konsole", Name: "konsole",
Columns: 80, Columns: 80,
Lines: 24, Lines: 24,
Colors: 8, Colors: 8,
Clear: "\x1b[H\x1b[2J", Clear: "\x1b[H\x1b[2J",
EnterCA: "\x1b7\x1b[?47h", EnterCA: "\x1b7\x1b[?47h",
ExitCA: "\x1b[2J\x1b[?47l\x1b8", ExitCA: "\x1b[2J\x1b[?47l\x1b8",
ShowCursor: "\x1b[?25h", ShowCursor: "\x1b[?25h",
HideCursor: "\x1b[?25l", HideCursor: "\x1b[?25l",
AttrOff: "\x1b[0m\x0f", AttrOff: "\x1b[0m\x0f",
Underline: "\x1b[4m", Underline: "\x1b[4m",
Bold: "\x1b[1m", Bold: "\x1b[1m",
Italic: "\x1b[3m", Italic: "\x1b[3m",
Strikethrough: "\x1b[9m", Strikethrough: "\x1b[9m",
Blink: "\x1b[5m", Dim: "\x1b[2m",
Reverse: "\x1b[7m", Blink: "\x1b[5m",
EnterKeypad: "\x1b[?1h\x1b=", Reverse: "\x1b[7m",
ExitKeypad: "\x1b[?1l\x1b>", EnterKeypad: "\x1b[?1h\x1b=",
SetFg: "\x1b[3%p1%dm", ExitKeypad: "\x1b[?1l\x1b>",
SetBg: "\x1b[4%p1%dm", SetFg: "\x1b[3%p1%dm",
SetFgBg: "\x1b[3%p1%d;4%p2%dm", SetBg: "\x1b[4%p1%dm",
AltChars: "``aaffggiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~", SetFgBg: "\x1b[3%p1%d;4%p2%dm",
EnterAcs: "\x0e", AltChars: "``aaffggiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~",
ExitAcs: "\x0f", EnterAcs: "\x0e",
EnableAcs: "\x1b)0", ExitAcs: "\x0f",
Mouse: "\x1b[M", EnableAcs: "\x1b)0",
MouseMode: "%?%p1%{1}%=%t%'h'%Pa%e%'l'%Pa%;\x1b[?1000%ga%c\x1b[?1002%ga%c\x1b[?1003%ga%c\x1b[?1006%ga%c", Mouse: "\x1b[M",
SetCursor: "\x1b[%i%p1%d;%p2%dH", MouseMode: "%?%p1%{1}%=%t%'h'%Pa%e%'l'%Pa%;\x1b[?1000%ga%c\x1b[?1002%ga%c\x1b[?1003%ga%c\x1b[?1006%ga%c",
CursorBack1: "\b", SetCursor: "\x1b[%i%p1%d;%p2%dH",
CursorUp1: "\x1b[A", CursorBack1: "\b",
KeyUp: "\x1bOA", CursorUp1: "\x1b[A",
KeyDown: "\x1bOB", KeyUp: "\x1bOA",
KeyRight: "\x1bOC", KeyDown: "\x1bOB",
KeyLeft: "\x1bOD", KeyRight: "\x1bOC",
KeyInsert: "\x1b[2~", KeyLeft: "\x1bOD",
KeyDelete: "\x1b[3~", KeyInsert: "\x1b[2~",
KeyBackspace: "\u007f", KeyDelete: "\x1b[3~",
KeyHome: "\x1bOH", KeyBackspace: "\xff",
KeyEnd: "\x1bOF", KeyHome: "\x1bOH",
KeyPgUp: "\x1b[5~", KeyEnd: "\x1bOF",
KeyPgDn: "\x1b[6~", KeyPgUp: "\x1b[5~",
KeyF1: "\x1bOP", KeyPgDn: "\x1b[6~",
KeyF2: "\x1bOQ", KeyF1: "\x1bOP",
KeyF3: "\x1bOR", KeyF2: "\x1bOQ",
KeyF4: "\x1bOS", KeyF3: "\x1bOR",
KeyF5: "\x1b[15~", KeyF4: "\x1bOS",
KeyF6: "\x1b[17~", KeyF5: "\x1b[15~",
KeyF7: "\x1b[18~", KeyF6: "\x1b[17~",
KeyF8: "\x1b[19~", KeyF7: "\x1b[18~",
KeyF9: "\x1b[20~", KeyF8: "\x1b[19~",
KeyF10: "\x1b[21~", KeyF9: "\x1b[20~",
KeyF11: "\x1b[23~", KeyF10: "\x1b[21~",
KeyF12: "\x1b[24~", KeyF11: "\x1b[23~",
KeyF13: "\x1bO2P", KeyF12: "\x1b[24~",
KeyF14: "\x1bO2Q", KeyF13: "\x1bO2P",
KeyF15: "\x1bO2R", KeyF14: "\x1bO2Q",
KeyF16: "\x1bO2S", KeyF15: "\x1bO2R",
KeyF17: "\x1b[15;2~", KeyF16: "\x1bO2S",
KeyF18: "\x1b[17;2~", KeyF17: "\x1b[15;2~",
KeyF19: "\x1b[18;2~", KeyF18: "\x1b[17;2~",
KeyF20: "\x1b[19;2~", KeyF19: "\x1b[18;2~",
KeyF21: "\x1b[20;2~", KeyF20: "\x1b[19;2~",
KeyF22: "\x1b[21;2~", KeyF21: "\x1b[20;2~",
KeyF23: "\x1b[23;2~", KeyF22: "\x1b[21;2~",
KeyF24: "\x1b[24;2~", KeyF23: "\x1b[23;2~",
KeyF25: "\x1bO5P", KeyF24: "\x1b[24;2~",
KeyF26: "\x1bO5Q", KeyF25: "\x1bO5P",
KeyF27: "\x1bO5R", KeyF26: "\x1bO5Q",
KeyF28: "\x1bO5S", KeyF27: "\x1bO5R",
KeyF29: "\x1b[15;5~", KeyF28: "\x1bO5S",
KeyF30: "\x1b[17;5~", KeyF29: "\x1b[15;5~",
KeyF31: "\x1b[18;5~", KeyF30: "\x1b[17;5~",
KeyF32: "\x1b[19;5~", KeyF31: "\x1b[18;5~",
KeyF33: "\x1b[20;5~", KeyF32: "\x1b[19;5~",
KeyF34: "\x1b[21;5~", KeyF33: "\x1b[20;5~",
KeyF35: "\x1b[23;5~", KeyF34: "\x1b[21;5~",
KeyF36: "\x1b[24;5~", KeyF35: "\x1b[23;5~",
KeyF37: "\x1bO6P", KeyF36: "\x1b[24;5~",
KeyF38: "\x1bO6Q", KeyF37: "\x1bO6P",
KeyF39: "\x1bO6R", KeyF38: "\x1bO6Q",
KeyF40: "\x1bO6S", KeyF39: "\x1bO6R",
KeyF41: "\x1b[15;6~", KeyF40: "\x1bO6S",
KeyF42: "\x1b[17;6~", KeyF41: "\x1b[15;6~",
KeyF43: "\x1b[18;6~", KeyF42: "\x1b[17;6~",
KeyF44: "\x1b[19;6~", KeyF43: "\x1b[18;6~",
KeyF45: "\x1b[20;6~", KeyF44: "\x1b[19;6~",
KeyF46: "\x1b[21;6~", KeyF45: "\x1b[20;6~",
KeyF47: "\x1b[23;6~", KeyF46: "\x1b[21;6~",
KeyF48: "\x1b[24;6~", KeyF47: "\x1b[23;6~",
KeyF49: "\x1bO3P", KeyF48: "\x1b[24;6~",
KeyF50: "\x1bO3Q", KeyF49: "\x1bO3P",
KeyF51: "\x1bO3R", KeyF50: "\x1bO3Q",
KeyF52: "\x1bO3S", KeyF51: "\x1bO3R",
KeyF53: "\x1b[15;3~", KeyF52: "\x1bO3S",
KeyF54: "\x1b[17;3~", KeyF53: "\x1b[15;3~",
KeyF55: "\x1b[18;3~", KeyF54: "\x1b[17;3~",
KeyF56: "\x1b[19;3~", KeyF55: "\x1b[18;3~",
KeyF57: "\x1b[20;3~", KeyF56: "\x1b[19;3~",
KeyF58: "\x1b[21;3~", KeyF57: "\x1b[20;3~",
KeyF59: "\x1b[23;3~", KeyF58: "\x1b[21;3~",
KeyF60: "\x1b[24;3~", KeyF59: "\x1b[23;3~",
KeyF61: "\x1bO4P", KeyF60: "\x1b[24;3~",
KeyF62: "\x1bO4Q", KeyF61: "\x1bO4P",
KeyF63: "\x1bO4R", KeyF62: "\x1bO4Q",
KeyBacktab: "\x1b[Z", KeyF63: "\x1bO4R",
KeyBacktab: "\x1b[Z",
KeyShfLeft: "\x1b[1;2D",
KeyShfRight: "\x1b[1;2C",
KeyShfUp: "\x1b[1;2A",
KeyShfDown: "\x1b[1;2B",
KeyCtrlLeft: "\x1b[1;5D",
KeyCtrlRight: "\x1b[1;5C",
KeyCtrlUp: "\x1b[1;5A",
KeyCtrlDown: "\x1b[1;5B",
KeyMetaLeft: "\x1b[1;9D",
KeyMetaRight: "\x1b[1;9C",
KeyMetaUp: "\x1b[1;9A",
KeyMetaDown: "\x1b[1;9B",
KeyAltLeft: "\x1b[1;3D",
KeyAltRight: "\x1b[1;3C",
KeyAltUp: "\x1b[1;3A",
KeyAltDown: "\x1b[1;3B",
KeyAltShfLeft: "\x1b[1;4D",
KeyAltShfRight: "\x1b[1;4C",
KeyAltShfUp: "\x1b[1;4A",
KeyAltShfDown: "\x1b[1;4B",
KeyMetaShfLeft: "\x1b[1;10D",
KeyMetaShfRight: "\x1b[1;10C",
KeyMetaShfUp: "\x1b[1;10A",
KeyMetaShfDown: "\x1b[1;10B",
KeyCtrlShfLeft: "\x1b[1;6D",
KeyCtrlShfRight: "\x1b[1;6C",
KeyCtrlShfUp: "\x1b[1;6A",
KeyCtrlShfDown: "\x1b[1;6B",
KeyShfHome: "\x1b[1;2H",
KeyShfEnd: "\x1b[1;2F",
KeyCtrlHome: "\x1b[1;5H",
KeyCtrlEnd: "\x1b[1;5F",
KeyAltHome: "\x1b[1;9H",
KeyAltEnd: "\x1b[1;9F",
KeyCtrlShfHome: "\x1b[1;6H",
KeyCtrlShfEnd: "\x1b[1;6F",
KeyMetaShfHome: "\x1b[1;10H",
KeyMetaShfEnd: "\x1b[1;10F",
KeyAltShfHome: "\x1b[1;4H",
KeyAltShfEnd: "\x1b[1;4F",
}) })
} }

View File

@ -5,110 +5,151 @@ package terminfo
func init() { func init() {
// KDE console window with xterm 256-colors // KDE console window with xterm 256-colors
AddTerminfo(&Terminfo{ AddTerminfo(&Terminfo{
Name: "konsole-256color", Name: "konsole-256color",
Columns: 80, Columns: 80,
Lines: 24, Lines: 24,
Colors: 256, Colors: 256,
Clear: "\x1b[H\x1b[2J", Clear: "\x1b[H\x1b[2J",
EnterCA: "\x1b7\x1b[?47h", EnterCA: "\x1b7\x1b[?47h",
ExitCA: "\x1b[2J\x1b[?47l\x1b8", ExitCA: "\x1b[2J\x1b[?47l\x1b8",
ShowCursor: "\x1b[?25h", ShowCursor: "\x1b[?25h",
HideCursor: "\x1b[?25l", HideCursor: "\x1b[?25l",
AttrOff: "\x1b[0m\x0f", AttrOff: "\x1b[0m\x0f",
Underline: "\x1b[4m", Underline: "\x1b[4m",
Bold: "\x1b[1m", Bold: "\x1b[1m",
Italic: "\x1b[3m", Italic: "\x1b[3m",
Strikethrough: "\x1b[9m", Strikethrough: "\x1b[9m",
Blink: "\x1b[5m", Dim: "\x1b[2m",
Reverse: "\x1b[7m", Blink: "\x1b[5m",
EnterKeypad: "\x1b[?1h\x1b=", Reverse: "\x1b[7m",
ExitKeypad: "\x1b[?1l\x1b>", EnterKeypad: "\x1b[?1h\x1b=",
SetFg: "\x1b[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m", ExitKeypad: "\x1b[?1l\x1b>",
SetBg: "\x1b[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e48;5;%p1%d%;m", SetFg: "\x1b[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m",
SetFgBg: "\x1b[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;;%?%p2%{8}%<%t4%p2%d%e%p2%{16}%<%t10%p2%{8}%-%d%e48;5;%p2%d%;m", SetBg: "\x1b[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e48;5;%p1%d%;m",
AltChars: "``aaffggiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~", SetFgBg: "\x1b[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;;%?%p2%{8}%<%t4%p2%d%e%p2%{16}%<%t10%p2%{8}%-%d%e48;5;%p2%d%;m",
EnterAcs: "\x0e", AltChars: "``aaffggiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~",
ExitAcs: "\x0f", EnterAcs: "\x0e",
EnableAcs: "\x1b)0", ExitAcs: "\x0f",
Mouse: "\x1b[M", EnableAcs: "\x1b)0",
MouseMode: "%?%p1%{1}%=%t%'h'%Pa%e%'l'%Pa%;\x1b[?1000%ga%c\x1b[?1002%ga%c\x1b[?1003%ga%c\x1b[?1006%ga%c", Mouse: "\x1b[M",
SetCursor: "\x1b[%i%p1%d;%p2%dH", MouseMode: "%?%p1%{1}%=%t%'h'%Pa%e%'l'%Pa%;\x1b[?1000%ga%c\x1b[?1002%ga%c\x1b[?1003%ga%c\x1b[?1006%ga%c",
CursorBack1: "\b", SetCursor: "\x1b[%i%p1%d;%p2%dH",
CursorUp1: "\x1b[A", CursorBack1: "\b",
KeyUp: "\x1bOA", CursorUp1: "\x1b[A",
KeyDown: "\x1bOB", KeyUp: "\x1bOA",
KeyRight: "\x1bOC", KeyDown: "\x1bOB",
KeyLeft: "\x1bOD", KeyRight: "\x1bOC",
KeyInsert: "\x1b[2~", KeyLeft: "\x1bOD",
KeyDelete: "\x1b[3~", KeyInsert: "\x1b[2~",
KeyBackspace: "\u007f", KeyDelete: "\x1b[3~",
KeyHome: "\x1bOH", KeyBackspace: "\xff",
KeyEnd: "\x1bOF", KeyHome: "\x1bOH",
KeyPgUp: "\x1b[5~", KeyEnd: "\x1bOF",
KeyPgDn: "\x1b[6~", KeyPgUp: "\x1b[5~",
KeyF1: "\x1bOP", KeyPgDn: "\x1b[6~",
KeyF2: "\x1bOQ", KeyF1: "\x1bOP",
KeyF3: "\x1bOR", KeyF2: "\x1bOQ",
KeyF4: "\x1bOS", KeyF3: "\x1bOR",
KeyF5: "\x1b[15~", KeyF4: "\x1bOS",
KeyF6: "\x1b[17~", KeyF5: "\x1b[15~",
KeyF7: "\x1b[18~", KeyF6: "\x1b[17~",
KeyF8: "\x1b[19~", KeyF7: "\x1b[18~",
KeyF9: "\x1b[20~", KeyF8: "\x1b[19~",
KeyF10: "\x1b[21~", KeyF9: "\x1b[20~",
KeyF11: "\x1b[23~", KeyF10: "\x1b[21~",
KeyF12: "\x1b[24~", KeyF11: "\x1b[23~",
KeyF13: "\x1bO2P", KeyF12: "\x1b[24~",
KeyF14: "\x1bO2Q", KeyF13: "\x1bO2P",
KeyF15: "\x1bO2R", KeyF14: "\x1bO2Q",
KeyF16: "\x1bO2S", KeyF15: "\x1bO2R",
KeyF17: "\x1b[15;2~", KeyF16: "\x1bO2S",
KeyF18: "\x1b[17;2~", KeyF17: "\x1b[15;2~",
KeyF19: "\x1b[18;2~", KeyF18: "\x1b[17;2~",
KeyF20: "\x1b[19;2~", KeyF19: "\x1b[18;2~",
KeyF21: "\x1b[20;2~", KeyF20: "\x1b[19;2~",
KeyF22: "\x1b[21;2~", KeyF21: "\x1b[20;2~",
KeyF23: "\x1b[23;2~", KeyF22: "\x1b[21;2~",
KeyF24: "\x1b[24;2~", KeyF23: "\x1b[23;2~",
KeyF25: "\x1bO5P", KeyF24: "\x1b[24;2~",
KeyF26: "\x1bO5Q", KeyF25: "\x1bO5P",
KeyF27: "\x1bO5R", KeyF26: "\x1bO5Q",
KeyF28: "\x1bO5S", KeyF27: "\x1bO5R",
KeyF29: "\x1b[15;5~", KeyF28: "\x1bO5S",
KeyF30: "\x1b[17;5~", KeyF29: "\x1b[15;5~",
KeyF31: "\x1b[18;5~", KeyF30: "\x1b[17;5~",
KeyF32: "\x1b[19;5~", KeyF31: "\x1b[18;5~",
KeyF33: "\x1b[20;5~", KeyF32: "\x1b[19;5~",
KeyF34: "\x1b[21;5~", KeyF33: "\x1b[20;5~",
KeyF35: "\x1b[23;5~", KeyF34: "\x1b[21;5~",
KeyF36: "\x1b[24;5~", KeyF35: "\x1b[23;5~",
KeyF37: "\x1bO6P", KeyF36: "\x1b[24;5~",
KeyF38: "\x1bO6Q", KeyF37: "\x1bO6P",
KeyF39: "\x1bO6R", KeyF38: "\x1bO6Q",
KeyF40: "\x1bO6S", KeyF39: "\x1bO6R",
KeyF41: "\x1b[15;6~", KeyF40: "\x1bO6S",
KeyF42: "\x1b[17;6~", KeyF41: "\x1b[15;6~",
KeyF43: "\x1b[18;6~", KeyF42: "\x1b[17;6~",
KeyF44: "\x1b[19;6~", KeyF43: "\x1b[18;6~",
KeyF45: "\x1b[20;6~", KeyF44: "\x1b[19;6~",
KeyF46: "\x1b[21;6~", KeyF45: "\x1b[20;6~",
KeyF47: "\x1b[23;6~", KeyF46: "\x1b[21;6~",
KeyF48: "\x1b[24;6~", KeyF47: "\x1b[23;6~",
KeyF49: "\x1bO3P", KeyF48: "\x1b[24;6~",
KeyF50: "\x1bO3Q", KeyF49: "\x1bO3P",
KeyF51: "\x1bO3R", KeyF50: "\x1bO3Q",
KeyF52: "\x1bO3S", KeyF51: "\x1bO3R",
KeyF53: "\x1b[15;3~", KeyF52: "\x1bO3S",
KeyF54: "\x1b[17;3~", KeyF53: "\x1b[15;3~",
KeyF55: "\x1b[18;3~", KeyF54: "\x1b[17;3~",
KeyF56: "\x1b[19;3~", KeyF55: "\x1b[18;3~",
KeyF57: "\x1b[20;3~", KeyF56: "\x1b[19;3~",
KeyF58: "\x1b[21;3~", KeyF57: "\x1b[20;3~",
KeyF59: "\x1b[23;3~", KeyF58: "\x1b[21;3~",
KeyF60: "\x1b[24;3~", KeyF59: "\x1b[23;3~",
KeyF61: "\x1bO4P", KeyF60: "\x1b[24;3~",
KeyF62: "\x1bO4Q", KeyF61: "\x1bO4P",
KeyF63: "\x1bO4R", KeyF62: "\x1bO4Q",
KeyBacktab: "\x1b[Z", KeyF63: "\x1bO4R",
KeyBacktab: "\x1b[Z",
KeyShfLeft: "\x1b[1;2D",
KeyShfRight: "\x1b[1;2C",
KeyShfUp: "\x1b[1;2A",
KeyShfDown: "\x1b[1;2B",
KeyCtrlLeft: "\x1b[1;5D",
KeyCtrlRight: "\x1b[1;5C",
KeyCtrlUp: "\x1b[1;5A",
KeyCtrlDown: "\x1b[1;5B",
KeyMetaLeft: "\x1b[1;9D",
KeyMetaRight: "\x1b[1;9C",
KeyMetaUp: "\x1b[1;9A",
KeyMetaDown: "\x1b[1;9B",
KeyAltLeft: "\x1b[1;3D",
KeyAltRight: "\x1b[1;3C",
KeyAltUp: "\x1b[1;3A",
KeyAltDown: "\x1b[1;3B",
KeyAltShfLeft: "\x1b[1;4D",
KeyAltShfRight: "\x1b[1;4C",
KeyAltShfUp: "\x1b[1;4A",
KeyAltShfDown: "\x1b[1;4B",
KeyMetaShfLeft: "\x1b[1;10D",
KeyMetaShfRight: "\x1b[1;10C",
KeyMetaShfUp: "\x1b[1;10A",
KeyMetaShfDown: "\x1b[1;10B",
KeyCtrlShfLeft: "\x1b[1;6D",
KeyCtrlShfRight: "\x1b[1;6C",
KeyCtrlShfUp: "\x1b[1;6A",
KeyCtrlShfDown: "\x1b[1;6B",
KeyShfHome: "\x1b[1;2H",
KeyShfEnd: "\x1b[1;2F",
KeyCtrlHome: "\x1b[1;5H",
KeyCtrlEnd: "\x1b[1;5F",
KeyAltHome: "\x1b[1;9H",
KeyAltEnd: "\x1b[1;9F",
KeyCtrlShfHome: "\x1b[1;6H",
KeyCtrlShfEnd: "\x1b[1;6F",
KeyMetaShfHome: "\x1b[1;10H",
KeyMetaShfEnd: "\x1b[1;10F",
KeyAltShfHome: "\x1b[1;4H",
KeyAltShfEnd: "\x1b[1;4F",
}) })
} }

View File

@ -39,7 +39,7 @@ func init() {
KeyLeft: "\x1bOD", KeyLeft: "\x1bOD",
KeyInsert: "\x1b[2~", KeyInsert: "\x1b[2~",
KeyDelete: "\x1b[3~", KeyDelete: "\x1b[3~",
KeyBackspace: "\b", KeyBackspace: "\xff",
KeyPgUp: "\x1b[5~", KeyPgUp: "\x1b[5~",
KeyPgDn: "\x1b[6~", KeyPgDn: "\x1b[6~",
KeyF1: "\x1b[11~", KeyF1: "\x1b[11~",

View File

@ -26,7 +26,7 @@ func init() {
AltChars: "++,,--..00__``aaffgghhiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}c~~", AltChars: "++,,--..00__``aaffgghhiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}c~~",
EnterAcs: "\x0e", EnterAcs: "\x0e",
ExitAcs: "\x0f", ExitAcs: "\x0f",
EnableAcs: "\x1b(B\x1b)0", EnableAcs: "\x1b)0",
Mouse: "\x1b[M", Mouse: "\x1b[M",
MouseMode: "%?%p1%{1}%=%t%'h'%Pa%e%'l'%Pa%;\x1b[?1000%ga%c\x1b[?1002%ga%c\x1b[?1003%ga%c\x1b[?1006%ga%c", MouseMode: "%?%p1%{1}%=%t%'h'%Pa%e%'l'%Pa%;\x1b[?1000%ga%c\x1b[?1002%ga%c\x1b[?1003%ga%c\x1b[?1006%ga%c",
SetCursor: "\x1b[%i%p1%d;%p2%dH", SetCursor: "\x1b[%i%p1%d;%p2%dH",
@ -38,7 +38,7 @@ func init() {
KeyLeft: "\x1b[D", KeyLeft: "\x1b[D",
KeyInsert: "\x1b[2~", KeyInsert: "\x1b[2~",
KeyDelete: "\x1b[3~", KeyDelete: "\x1b[3~",
KeyBackspace: "\u007f", KeyBackspace: "\xff",
KeyHome: "\x1b[1~", KeyHome: "\x1b[1~",
KeyEnd: "\x1b[4~", KeyEnd: "\x1b[4~",
KeyPgUp: "\x1b[5~", KeyPgUp: "\x1b[5~",

View File

@ -43,7 +43,7 @@ func init() {
KeyLeft: "\x1b[D", KeyLeft: "\x1b[D",
KeyInsert: "\x1b[2~", KeyInsert: "\x1b[2~",
KeyDelete: "\x1b[3~", KeyDelete: "\x1b[3~",
KeyBackspace: "\u007f", KeyBackspace: "\xff",
KeyHome: "\x1b[7~", KeyHome: "\x1b[7~",
KeyEnd: "\x1b[8~", KeyEnd: "\x1b[8~",
KeyPgUp: "\x1b[5~", KeyPgUp: "\x1b[5~",

View File

@ -43,7 +43,7 @@ func init() {
KeyLeft: "\x1b[D", KeyLeft: "\x1b[D",
KeyInsert: "\x1b[2~", KeyInsert: "\x1b[2~",
KeyDelete: "\x1b[3~", KeyDelete: "\x1b[3~",
KeyBackspace: "\u007f", KeyBackspace: "\xff",
KeyHome: "\x1b[7~", KeyHome: "\x1b[7~",
KeyEnd: "\x1b[8~", KeyEnd: "\x1b[8~",
KeyPgUp: "\x1b[5~", KeyPgUp: "\x1b[5~",

View File

@ -41,7 +41,7 @@ func init() {
KeyLeft: "\x1b[D", KeyLeft: "\x1b[D",
KeyInsert: "\x1b[2~", KeyInsert: "\x1b[2~",
KeyDelete: "\x1b[3~", KeyDelete: "\x1b[3~",
KeyBackspace: "\u007f", KeyBackspace: "\xff",
KeyHome: "\x1b[7~", KeyHome: "\x1b[7~",
KeyEnd: "\x1b[8~", KeyEnd: "\x1b[8~",
KeyPgUp: "\x1b[5~", KeyPgUp: "\x1b[5~",

View File

@ -41,7 +41,7 @@ func init() {
KeyLeft: "\x1b[D", KeyLeft: "\x1b[D",
KeyInsert: "\x1b[2~", KeyInsert: "\x1b[2~",
KeyDelete: "\x1b[3~", KeyDelete: "\x1b[3~",
KeyBackspace: "\u007f", KeyBackspace: "\xff",
KeyHome: "\x1b[7~", KeyHome: "\x1b[7~",
KeyEnd: "\x1b[8~", KeyEnd: "\x1b[8~",
KeyPgUp: "\x1b[5~", KeyPgUp: "\x1b[5~",

View File

@ -44,7 +44,7 @@ func init() {
KeyLeft: "\x1bOD", KeyLeft: "\x1bOD",
KeyInsert: "\x1b[2~", KeyInsert: "\x1b[2~",
KeyDelete: "\x1b[3~", KeyDelete: "\x1b[3~",
KeyBackspace: "\u007f", KeyBackspace: "\xff",
KeyHome: "\x1b[1~", KeyHome: "\x1b[1~",
KeyEnd: "\x1b[4~", KeyEnd: "\x1b[4~",
KeyPgUp: "\x1b[5~", KeyPgUp: "\x1b[5~",

View File

@ -44,7 +44,7 @@ func init() {
KeyLeft: "\x1bOD", KeyLeft: "\x1bOD",
KeyInsert: "\x1b[2~", KeyInsert: "\x1b[2~",
KeyDelete: "\x1b[3~", KeyDelete: "\x1b[3~",
KeyBackspace: "\u007f", KeyBackspace: "\xff",
KeyHome: "\x1b[1~", KeyHome: "\x1b[1~",
KeyEnd: "\x1b[4~", KeyEnd: "\x1b[4~",
KeyPgUp: "\x1b[5~", KeyPgUp: "\x1b[5~",

View File

@ -3,7 +3,7 @@
package terminfo package terminfo
func init() { func init() {
// simpleterm 0.4.1 // simpleterm
AddTerminfo(&Terminfo{ AddTerminfo(&Terminfo{
Name: "st", Name: "st",
Aliases: []string{"stterm"}, Aliases: []string{"stterm"},
@ -21,6 +21,7 @@ func init() {
Bold: "\x1b[1m", Bold: "\x1b[1m",
Italic: "\x1b[3m", Italic: "\x1b[3m",
Strikethrough: "\x1b[9m", Strikethrough: "\x1b[9m",
Dim: "\x1b[2m",
Blink: "\x1b[5m", Blink: "\x1b[5m",
Reverse: "\x1b[7m", Reverse: "\x1b[7m",
EnterKeypad: "\x1b[?1h\x1b=", EnterKeypad: "\x1b[?1h\x1b=",
@ -28,8 +29,7 @@ func init() {
SetFg: "\x1b[3%p1%dm", SetFg: "\x1b[3%p1%dm",
SetBg: "\x1b[4%p1%dm", SetBg: "\x1b[4%p1%dm",
SetFgBg: "\x1b[3%p1%d;4%p2%dm", SetFgBg: "\x1b[3%p1%d;4%p2%dm",
PadChar: "\x00", AltChars: "+C,D-A.B0E``aaffgghFiGjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~",
AltChars: "``aaffggiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~",
EnterAcs: "\x1b(0", EnterAcs: "\x1b(0",
ExitAcs: "\x1b(B", ExitAcs: "\x1b(B",
EnableAcs: "\x1b)0", EnableAcs: "\x1b)0",
@ -44,7 +44,7 @@ func init() {
KeyLeft: "\x1bOD", KeyLeft: "\x1bOD",
KeyInsert: "\x1b[2~", KeyInsert: "\x1b[2~",
KeyDelete: "\x1b[3~", KeyDelete: "\x1b[3~",
KeyBackspace: "\u007f", KeyBackspace: "\xff",
KeyHome: "\x1b[1~", KeyHome: "\x1b[1~",
KeyEnd: "\x1b[4~", KeyEnd: "\x1b[4~",
KeyPgUp: "\x1b[5~", KeyPgUp: "\x1b[5~",
@ -113,7 +113,6 @@ func init() {
KeyF62: "\x1b[1;4Q", KeyF62: "\x1b[1;4Q",
KeyF63: "\x1b[1;4R", KeyF63: "\x1b[1;4R",
KeyClear: "\x1b[3;5~", KeyClear: "\x1b[3;5~",
KeyBacktab: "\x1b[Z",
KeyShfLeft: "\x1b[1;2D", KeyShfLeft: "\x1b[1;2D",
KeyShfRight: "\x1b[1;2C", KeyShfRight: "\x1b[1;2C",
KeyShfUp: "\x1b[1;2A", KeyShfUp: "\x1b[1;2A",

View File

@ -21,6 +21,7 @@ func init() {
Bold: "\x1b[1m", Bold: "\x1b[1m",
Italic: "\x1b[3m", Italic: "\x1b[3m",
Strikethrough: "\x1b[9m", Strikethrough: "\x1b[9m",
Dim: "\x1b[2m",
Blink: "\x1b[5m", Blink: "\x1b[5m",
Reverse: "\x1b[7m", Reverse: "\x1b[7m",
EnterKeypad: "\x1b[?1h\x1b=", EnterKeypad: "\x1b[?1h\x1b=",
@ -28,8 +29,7 @@ func init() {
SetFg: "\x1b[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m", SetFg: "\x1b[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m",
SetBg: "\x1b[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e48;5;%p1%d%;m", SetBg: "\x1b[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e48;5;%p1%d%;m",
SetFgBg: "\x1b[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;;%?%p2%{8}%<%t4%p2%d%e%p2%{16}%<%t10%p2%{8}%-%d%e48;5;%p2%d%;m", SetFgBg: "\x1b[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;;%?%p2%{8}%<%t4%p2%d%e%p2%{16}%<%t10%p2%{8}%-%d%e48;5;%p2%d%;m",
PadChar: "\x00", AltChars: "+C,D-A.B0E``aaffgghFiGjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~",
AltChars: "``aaffggiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~",
EnterAcs: "\x1b(0", EnterAcs: "\x1b(0",
ExitAcs: "\x1b(B", ExitAcs: "\x1b(B",
EnableAcs: "\x1b)0", EnableAcs: "\x1b)0",
@ -44,7 +44,7 @@ func init() {
KeyLeft: "\x1bOD", KeyLeft: "\x1bOD",
KeyInsert: "\x1b[2~", KeyInsert: "\x1b[2~",
KeyDelete: "\x1b[3~", KeyDelete: "\x1b[3~",
KeyBackspace: "\u007f", KeyBackspace: "\xff",
KeyHome: "\x1b[1~", KeyHome: "\x1b[1~",
KeyEnd: "\x1b[4~", KeyEnd: "\x1b[4~",
KeyPgUp: "\x1b[5~", KeyPgUp: "\x1b[5~",
@ -113,7 +113,6 @@ func init() {
KeyF62: "\x1b[1;4Q", KeyF62: "\x1b[1;4Q",
KeyF63: "\x1b[1;4R", KeyF63: "\x1b[1;4R",
KeyClear: "\x1b[3;5~", KeyClear: "\x1b[3;5~",
KeyBacktab: "\x1b[Z",
KeyShfLeft: "\x1b[1;2D", KeyShfLeft: "\x1b[1;2D",
KeyShfRight: "\x1b[1;2C", KeyShfRight: "\x1b[1;2C",
KeyShfUp: "\x1b[1;2A", KeyShfUp: "\x1b[1;2A",

View File

@ -24,7 +24,7 @@ func init() {
KeyRight: "\x1b[C", KeyRight: "\x1b[C",
KeyLeft: "\x1b[D", KeyLeft: "\x1b[D",
KeyInsert: "\x1b[247z", KeyInsert: "\x1b[247z",
KeyDelete: "\u007f", KeyDelete: "\xff",
KeyBackspace: "\b", KeyBackspace: "\b",
KeyHome: "\x1b[214z", KeyHome: "\x1b[214z",
KeyEnd: "\x1b[220z", KeyEnd: "\x1b[220z",

View File

@ -28,7 +28,7 @@ func init() {
KeyRight: "\x1b[C", KeyRight: "\x1b[C",
KeyLeft: "\x1b[D", KeyLeft: "\x1b[D",
KeyInsert: "\x1b[247z", KeyInsert: "\x1b[247z",
KeyDelete: "\u007f", KeyDelete: "\xff",
KeyBackspace: "\b", KeyBackspace: "\b",
KeyHome: "\x1b[214z", KeyHome: "\x1b[214z",
KeyEnd: "\x1b[220z", KeyEnd: "\x1b[220z",

View File

@ -35,7 +35,7 @@ func init() {
KeyLeft: "\x1bOD", KeyLeft: "\x1bOD",
KeyInsert: "\x1b[2~", KeyInsert: "\x1b[2~",
KeyDelete: "\x1b[3~", KeyDelete: "\x1b[3~",
KeyBackspace: "\u007f", KeyBackspace: "\xff",
KeyHome: "\x1b[1~", KeyHome: "\x1b[1~",
KeyPgUp: "\x1b[5~", KeyPgUp: "\x1b[5~",
KeyPgDn: "\x1b[6~", KeyPgDn: "\x1b[6~",

View File

@ -42,7 +42,7 @@ func init() {
KeyLeft: "\x1bOD", KeyLeft: "\x1bOD",
KeyInsert: "\x1b[2~", KeyInsert: "\x1b[2~",
KeyDelete: "\x1b[3~", KeyDelete: "\x1b[3~",
KeyBackspace: "\u007f", KeyBackspace: "\xff",
KeyHome: "\x1bOH", KeyHome: "\x1bOH",
KeyEnd: "\x1bOF", KeyEnd: "\x1bOF",
KeyPgUp: "\x1b[5~", KeyPgUp: "\x1b[5~",

View File

@ -28,6 +28,6 @@ func init() {
KeyDown: "\x1bOB", KeyDown: "\x1bOB",
KeyRight: "\x1bOC", KeyRight: "\x1bOC",
KeyLeft: "\x1bOD", KeyLeft: "\x1bOD",
KeyBackspace: "\u007f", KeyBackspace: "\xff",
}) })
} }

View File

@ -12,8 +12,8 @@ func init() {
Colors: 8, Colors: 8,
Bell: "\a", Bell: "\a",
Clear: "\x1b[H\x1b[2J", Clear: "\x1b[H\x1b[2J",
EnterCA: "\x1b[?1049h", EnterCA: "\x1b[?1049h\x1b[22;0;0t",
ExitCA: "\x1b[?1049l", ExitCA: "\x1b[?1049l\x1b[23;0;0t",
ShowCursor: "\x1b[?12l\x1b[?25h", ShowCursor: "\x1b[?12l\x1b[?25h",
HideCursor: "\x1b[?25l", HideCursor: "\x1b[?25l",
AttrOff: "\x1b(B\x1b[m", AttrOff: "\x1b(B\x1b[m",
@ -43,7 +43,7 @@ func init() {
KeyLeft: "\x1bOD", KeyLeft: "\x1bOD",
KeyInsert: "\x1b[2~", KeyInsert: "\x1b[2~",
KeyDelete: "\x1b[3~", KeyDelete: "\x1b[3~",
KeyBackspace: "\u007f", KeyBackspace: "\xff",
KeyHome: "\x1bOH", KeyHome: "\x1bOH",
KeyEnd: "\x1bOF", KeyEnd: "\x1bOF",
KeyPgUp: "\x1b[5~", KeyPgUp: "\x1b[5~",

View File

@ -11,8 +11,8 @@ func init() {
Colors: 256, Colors: 256,
Bell: "\a", Bell: "\a",
Clear: "\x1b[H\x1b[2J", Clear: "\x1b[H\x1b[2J",
EnterCA: "\x1b[?1049h", EnterCA: "\x1b[?1049h\x1b[22;0;0t",
ExitCA: "\x1b[?1049l", ExitCA: "\x1b[?1049l\x1b[23;0;0t",
ShowCursor: "\x1b[?12l\x1b[?25h", ShowCursor: "\x1b[?12l\x1b[?25h",
HideCursor: "\x1b[?25l", HideCursor: "\x1b[?25l",
AttrOff: "\x1b(B\x1b[m", AttrOff: "\x1b(B\x1b[m",
@ -42,7 +42,7 @@ func init() {
KeyLeft: "\x1bOD", KeyLeft: "\x1bOD",
KeyInsert: "\x1b[2~", KeyInsert: "\x1b[2~",
KeyDelete: "\x1b[3~", KeyDelete: "\x1b[3~",
KeyBackspace: "\u007f", KeyBackspace: "\xff",
KeyHome: "\x1bOH", KeyHome: "\x1bOH",
KeyEnd: "\x1bOF", KeyEnd: "\x1bOF",
KeyPgUp: "\x1b[5~", KeyPgUp: "\x1b[5~",

View File

@ -1,4 +1,4 @@
// Copyright 2017 The TCell Authors // Copyright 2018 The TCell Authors
// //
// Licensed under the Apache License, Version 2.0 (the "License"); // Licensed under the Apache License, Version 2.0 (the "License");
// you may not use file except in compliance with the License. // you may not use file except in compliance with the License.
@ -17,12 +17,14 @@ package terminfo
import ( import (
"bytes" "bytes"
"compress/gzip" "compress/gzip"
"crypto/sha1"
"encoding/json" "encoding/json"
"errors" "errors"
"fmt" "fmt"
"io" "io"
"os" "os"
"path" "path"
"path/filepath"
"strconv" "strconv"
"strings" "strings"
"sync" "sync"
@ -757,8 +759,16 @@ func loadFromFile(fname string, term string) (*Terminfo, error) {
// LookupTerminfo attempts to find a definition for the named $TERM. // LookupTerminfo attempts to find a definition for the named $TERM.
// It first looks in the builtin database, which should cover just about // It first looks in the builtin database, which should cover just about
// everyone. If it can't find one there, then it will attempt to read // everyone. If it can't find one there, then it will attempt to read
// one from the JSON file located in either $TCELLDB, $HOME/.tcelldb // one from the JSON file located in either $TCELLDB, $HOME/.tcelldb,
// or in this package's source directory as database.json). // or as a database file.
//
// The database files are named by taking terminal name, hashing it through
// sha1, and then a subdirectory of the form database/hash[0:2]/hash[0:8]
// (with an optional .gz extension).
//
// For other local database files, we will look for the database file using
// the terminal name, so database/term[0:2]/term[0:8], again with optional
// .gz extension.
func LookupTerminfo(name string) (*Terminfo, error) { func LookupTerminfo(name string) (*Terminfo, error) {
if name == "" { if name == "" {
// else on windows: index out of bounds // else on windows: index out of bounds
@ -776,38 +786,65 @@ func LookupTerminfo(name string) (*Terminfo, error) {
letter := fmt.Sprintf("%02x", name[0]) letter := fmt.Sprintf("%02x", name[0])
gzfile := path.Join(letter, name+".gz") gzfile := path.Join(letter, name+".gz")
jsfile := path.Join(letter, name) jsfile := path.Join(letter, name)
hash := fmt.Sprintf("%x", sha1.Sum([]byte(name)))
gzhfile := path.Join(hash[0:2], hash[0:8]+".gz")
jshfile := path.Join(hash[0:2], hash[0:8])
// Build up the search path. Old versions of tcell used a // Build up the search path. Old versions of tcell used a
// single database file, whereas the new ones locate them // single database file, whereas the new ones locate them
// in JSON (optionally compressed) files. // in JSON (optionally compressed) files.
// //
// The search path looks like: // The search path for "xterm" (SHA1 sig e2e28a8e...) looks
// like this:
// //
// $TCELLDB/x/xterm.gz // $TCELLDB/78/xterm.gz
// $TCELLDB/x/xterm // $TCELLDB/78/xterm
// $TCELLDB // $TCELLDB
// $HOME/.tcelldb/x/xterm.gz // $HOME/.tcelldb/e2/e2e28a8e.gz
// $HOME/.tcelldb/x/xterm // $HOME/.tcelldb/e2/e2e28a8e
// $HOME/.tcelldb/78/xterm.gz
// $HOME/.tcelldb/78/xterm
// $HOME/.tcelldb // $HOME/.tcelldb
// $GOPATH/terminfo/database/x/xterm.gz // $GOPATH/terminfo/database/e2/e2e28a8e.gz
// $GOPATH/terminfo/database/x/xterm // $GOPATH/terminfo/database/e2/e2e28a8e
// $GOPATH/terminfo/database/78/xterm.gz
// $GOPATH/terminfo/database/78/xterm
// //
// Note that the legacy name lookups (78/xterm etc.) are
// provided for compatibility. We do not actually deliver
// any files with this style of naming, to avoid collisions
// on case insensitive filesystems. (*cough* mac *cough*).
// If $GOPATH set, honor it, else assume $HOME/go just like
// modern golang does.
gopath := os.Getenv("GOPATH")
if gopath == "" {
gopath = path.Join(os.Getenv("HOME"), "go")
}
if pth := os.Getenv("TCELLDB"); pth != "" { if pth := os.Getenv("TCELLDB"); pth != "" {
files = append(files, path.Join(pth, gzfile)) files = append(files,
files = append(files, path.Join(pth, jsfile)) path.Join(pth, gzfile),
files = append(files, pth) path.Join(pth, jsfile),
pth)
} }
if pth := os.Getenv("HOME"); pth != "" { if pth := os.Getenv("HOME"); pth != "" {
pth = path.Join(pth, ".tcelldb") pth = path.Join(pth, ".tcelldb")
files = append(files, path.Join(pth, gzfile)) files = append(files,
files = append(files, path.Join(pth, jsfile)) path.Join(pth, gzhfile),
files = append(files, pth) path.Join(pth, jshfile),
path.Join(pth, gzfile),
path.Join(pth, jsfile),
pth)
} }
for _, pth := range strings.Split(os.Getenv("GOPATH"), string(os.PathListSeparator)) { for _, pth := range filepath.SplitList(gopath) {
pth = path.Join(pth, "src", "github.com", "gdamore", "tcell", "terminfo", "database") pth = path.Join(pth, "src", "github.com",
files = append(files, path.Join(pth, gzfile)) "gdamore", "tcell", "terminfo", "database")
files = append(files, path.Join(pth, jsfile)) files = append(files,
path.Join(pth, gzhfile),
path.Join(pth, jshfile),
path.Join(pth, gzfile),
path.Join(pth, jsfile))
} }
for _, fname := range files { for _, fname := range files {

View File

@ -444,8 +444,8 @@ func (t *tScreen) ResetTitle() {
func (t *tScreen) Fini() { func (t *tScreen) Fini() {
t.Lock() t.Lock()
defer t.Unlock() defer t.Unlock()
ti := t.ti ti := t.ti
t.cells.Resize(0, 0) t.cells.Resize(0, 0)
t.TPuts(ti.ShowCursor) t.TPuts(ti.ShowCursor)
t.TPuts(ti.AttrOff) t.TPuts(ti.AttrOff)
@ -467,7 +467,7 @@ func (t *tScreen) Fini() {
default: default:
close(t.quit) close(t.quit)
} }
t.termioFini() t.termioFini()
} }