Fix terminal colors; wait until tty size is known
This commit is contained in:
parent
1170893e39
commit
bd71787e3f
1 changed files with 75 additions and 21 deletions
|
@ -1,6 +1,7 @@
|
||||||
package widgets
|
package widgets
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
gocolor "image/color"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
|
|
||||||
|
@ -14,6 +15,7 @@ import (
|
||||||
type Terminal struct {
|
type Terminal struct {
|
||||||
closed bool
|
closed bool
|
||||||
cmd *exec.Cmd
|
cmd *exec.Cmd
|
||||||
|
colors map[tcell.Color]tcell.Color
|
||||||
ctx *ui.Context
|
ctx *ui.Context
|
||||||
cursorPos vterm.Pos
|
cursorPos vterm.Pos
|
||||||
cursorShown bool
|
cursorShown bool
|
||||||
|
@ -21,24 +23,18 @@ type Terminal struct {
|
||||||
focus bool
|
focus bool
|
||||||
onInvalidate func(d ui.Drawable)
|
onInvalidate func(d ui.Drawable)
|
||||||
pty *os.File
|
pty *os.File
|
||||||
|
start chan interface{}
|
||||||
vterm *vterm.VTerm
|
vterm *vterm.VTerm
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewTerminal(cmd *exec.Cmd) (*Terminal, error) {
|
func NewTerminal(cmd *exec.Cmd) (*Terminal, error) {
|
||||||
term := &Terminal{}
|
term := &Terminal{}
|
||||||
term.cmd = cmd
|
term.cmd = cmd
|
||||||
tty, err := pty.Start(cmd)
|
term.vterm = vterm.New(24, 80)
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
term.pty = tty
|
|
||||||
rows, cols, err := pty.Getsize(term.pty)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
term.vterm = vterm.New(rows, cols)
|
|
||||||
term.vterm.SetUTF8(true)
|
term.vterm.SetUTF8(true)
|
||||||
|
term.start = make(chan interface{})
|
||||||
go func() {
|
go func() {
|
||||||
|
<-term.start
|
||||||
buf := make([]byte, 2048)
|
buf := make([]byte, 2048)
|
||||||
for {
|
for {
|
||||||
n, err := term.pty.Read(buf)
|
n, err := term.pty.Read(buf)
|
||||||
|
@ -56,6 +52,27 @@ func NewTerminal(cmd *exec.Cmd) (*Terminal, error) {
|
||||||
screen.OnDamage = term.onDamage
|
screen.OnDamage = term.onDamage
|
||||||
screen.OnMoveCursor = term.onMoveCursor
|
screen.OnMoveCursor = term.onMoveCursor
|
||||||
screen.Reset(true)
|
screen.Reset(true)
|
||||||
|
|
||||||
|
state := term.vterm.ObtainState()
|
||||||
|
term.colors = make(map[tcell.Color]tcell.Color)
|
||||||
|
for i := 0; i < 16; i += 1 {
|
||||||
|
// Set the first 16 colors to predictable near-black RGB values
|
||||||
|
tcolor := tcell.Color(i)
|
||||||
|
var r uint8 = 0
|
||||||
|
var g uint8 = 0
|
||||||
|
var b uint8 = uint8(i + 1)
|
||||||
|
state.SetPaletteColor(i,
|
||||||
|
vterm.NewVTermColorRGB(gocolor.RGBA{r, g, b, 255}))
|
||||||
|
term.colors[tcell.NewRGBColor(int32(r), int32(g), int32(b))] = tcolor
|
||||||
|
}
|
||||||
|
fg, bg := state.GetDefaultColors()
|
||||||
|
r, g, b := bg.GetRGB()
|
||||||
|
term.colors[tcell.NewRGBColor(
|
||||||
|
int32(r), int32(g), int32(b))] = tcell.ColorDefault
|
||||||
|
r, g, b = fg.GetRGB()
|
||||||
|
term.colors[tcell.NewRGBColor(
|
||||||
|
int32(r), int32(g), int32(b))] = tcell.ColorDefault
|
||||||
|
|
||||||
return term, nil
|
return term, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,6 +97,22 @@ func (term *Terminal) Invalidate() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (term *Terminal) Draw(ctx *ui.Context) {
|
func (term *Terminal) Draw(ctx *ui.Context) {
|
||||||
|
winsize := pty.Winsize{
|
||||||
|
Cols: uint16(ctx.Width()),
|
||||||
|
Rows: uint16(ctx.Height()),
|
||||||
|
}
|
||||||
|
|
||||||
|
if term.pty == nil {
|
||||||
|
term.vterm.SetSize(ctx.Height(), ctx.Width())
|
||||||
|
tty, err := pty.StartWithSize(term.cmd, &winsize)
|
||||||
|
term.pty = tty
|
||||||
|
if err != nil {
|
||||||
|
term.Close()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
term.start <- nil
|
||||||
|
}
|
||||||
|
|
||||||
term.ctx = ctx // gross
|
term.ctx = ctx // gross
|
||||||
if term.closed {
|
if term.closed {
|
||||||
return
|
return
|
||||||
|
@ -90,10 +123,6 @@ func (term *Terminal) Draw(ctx *ui.Context) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if ctx.Width() != cols || ctx.Height() != rows {
|
if ctx.Width() != cols || ctx.Height() != rows {
|
||||||
winsize := pty.Winsize{
|
|
||||||
Cols: uint16(ctx.Width()),
|
|
||||||
Rows: uint16(ctx.Height()),
|
|
||||||
}
|
|
||||||
pty.Setsize(term.pty, &winsize)
|
pty.Setsize(term.pty, &winsize)
|
||||||
term.vterm.SetSize(ctx.Height(), ctx.Width())
|
term.vterm.SetSize(ctx.Height(), ctx.Width())
|
||||||
return
|
return
|
||||||
|
@ -125,7 +154,7 @@ func (term *Terminal) Draw(ctx *ui.Context) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
style := styleFromCell(cell)
|
style := term.styleFromCell(cell)
|
||||||
ctx.Printf(x, y, style, "%s", string(cell.Chars()))
|
ctx.Printf(x, y, style, "%s", string(cell.Chars()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -142,14 +171,39 @@ func (term *Terminal) Event(event tcell.Event) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func styleFromCell(cell *vterm.ScreenCell) tcell.Style {
|
func (term *Terminal) styleFromCell(cell *vterm.ScreenCell) tcell.Style {
|
||||||
|
style := tcell.StyleDefault
|
||||||
|
|
||||||
background := cell.Bg()
|
background := cell.Bg()
|
||||||
br, bg, bb := background.GetRGB()
|
r, g, b := background.GetRGB()
|
||||||
|
bg := tcell.NewRGBColor(int32(r), int32(g), int32(b))
|
||||||
foreground := cell.Fg()
|
foreground := cell.Fg()
|
||||||
fr, fg, fb := foreground.GetRGB()
|
r, g, b = foreground.GetRGB()
|
||||||
style := tcell.StyleDefault.
|
fg := tcell.NewRGBColor(int32(r), int32(g), int32(b))
|
||||||
Background(tcell.NewRGBColor(int32(br), int32(bg), int32(bb))).
|
|
||||||
Foreground(tcell.NewRGBColor(int32(fr), int32(fg), int32(fb)))
|
if color, ok := term.colors[bg]; ok {
|
||||||
|
style = style.Background(color)
|
||||||
|
} else {
|
||||||
|
style = style.Background(bg)
|
||||||
|
}
|
||||||
|
if color, ok := term.colors[fg]; ok {
|
||||||
|
style = style.Foreground(color)
|
||||||
|
} else {
|
||||||
|
style = style.Foreground(fg)
|
||||||
|
}
|
||||||
|
|
||||||
|
if cell.Attrs().Bold != 0 {
|
||||||
|
style = style.Bold(true)
|
||||||
|
}
|
||||||
|
if cell.Attrs().Underline != 0 {
|
||||||
|
style = style.Underline(true)
|
||||||
|
}
|
||||||
|
if cell.Attrs().Blink != 0 {
|
||||||
|
style = style.Blink(true)
|
||||||
|
}
|
||||||
|
if cell.Attrs().Reverse != 0 {
|
||||||
|
style = style.Reverse(true)
|
||||||
|
}
|
||||||
return style
|
return style
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue