Add :term-close
This commit is contained in:
parent
16c3f0a893
commit
dee0f8938b
|
@ -0,0 +1,29 @@
|
|||
package commands
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"git.sr.ht/~sircmpwn/aerc2/lib/ui"
|
||||
"git.sr.ht/~sircmpwn/aerc2/widgets"
|
||||
)
|
||||
|
||||
func init() {
|
||||
Register("term-close", TermClose)
|
||||
}
|
||||
|
||||
func TermClose(aerc *widgets.Aerc, args []string) error {
|
||||
if len(args) != 1 {
|
||||
return errors.New("Usage: term-close")
|
||||
}
|
||||
grid, ok := aerc.SelectedTab().(*ui.Grid)
|
||||
if !ok {
|
||||
return errors.New("Error: not a terminal")
|
||||
}
|
||||
for _, child := range grid.Children() {
|
||||
if term, ok := child.(*widgets.Terminal); ok {
|
||||
term.Close(nil)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return errors.New("Error: not a terminal")
|
||||
}
|
|
@ -2,10 +2,12 @@ package commands
|
|||
|
||||
import (
|
||||
"os/exec"
|
||||
"time"
|
||||
|
||||
"git.sr.ht/~sircmpwn/aerc2/lib/ui"
|
||||
"git.sr.ht/~sircmpwn/aerc2/widgets"
|
||||
|
||||
"github.com/gdamore/tcell"
|
||||
"github.com/riywo/loginshell"
|
||||
)
|
||||
|
||||
|
@ -32,13 +34,20 @@ func Term(aerc *widgets.Aerc, args []string) error {
|
|||
{ui.SIZE_WEIGHT, 1},
|
||||
})
|
||||
grid.AddChild(term).At(0, 1)
|
||||
tab := aerc.NewTab(grid, "Terminal")
|
||||
tab := aerc.NewTab(grid, args[1])
|
||||
term.OnTitle = func(title string) {
|
||||
if title == "" {
|
||||
title = "Terminal"
|
||||
title = args[1]
|
||||
}
|
||||
tab.Name = title
|
||||
tab.Content.Invalidate()
|
||||
}
|
||||
term.OnClose = func(err error) {
|
||||
aerc.RemoveTab(grid)
|
||||
if err != nil {
|
||||
aerc.PushStatus(" "+err.Error(), 10*time.Second).
|
||||
Color(tcell.ColorRed, tcell.ColorWhite)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -62,13 +62,13 @@ func (tabs *Tabs) Remove(content Drawable) {
|
|||
}
|
||||
/* Force the selected index into the existing range */
|
||||
if tabs.Selected >= len(tabs.Tabs) {
|
||||
tabs.Select(len(tabs.Tabs) - 1)
|
||||
tabs.Select(tabs.Selected - 1)
|
||||
}
|
||||
tabs.TabStrip.Invalidate()
|
||||
}
|
||||
|
||||
func (tabs *Tabs) Select(index int) {
|
||||
if tabs.Selected >= len(tabs.Tabs) {
|
||||
if index >= len(tabs.Tabs) {
|
||||
panic("Tried to set tab index to a non-existing element")
|
||||
}
|
||||
|
||||
|
|
|
@ -20,7 +20,11 @@ type Text struct {
|
|||
}
|
||||
|
||||
func NewText(text string) *Text {
|
||||
return &Text{text: text}
|
||||
return &Text{
|
||||
bg: tcell.ColorDefault,
|
||||
fg: tcell.ColorDefault,
|
||||
text: text,
|
||||
}
|
||||
}
|
||||
|
||||
func (t *Text) Text(text string) *Text {
|
||||
|
|
|
@ -139,12 +139,20 @@ func (aerc *Aerc) SelectedAccount() *AccountView {
|
|||
return acct
|
||||
}
|
||||
|
||||
func (aerc *Aerc) SelectedTab() ui.Drawable {
|
||||
return aerc.tabs.Tabs[aerc.tabs.Selected].Content
|
||||
}
|
||||
|
||||
func (aerc *Aerc) NewTab(drawable ui.Drawable, name string) *ui.Tab {
|
||||
tab := aerc.tabs.Add(drawable, name)
|
||||
aerc.tabs.Select(len(aerc.tabs.Tabs) - 1)
|
||||
return tab
|
||||
}
|
||||
|
||||
func (aerc *Aerc) RemoveTab(tab ui.Drawable) {
|
||||
aerc.tabs.Remove(tab)
|
||||
}
|
||||
|
||||
func (aerc *Aerc) NextTab() {
|
||||
next := aerc.tabs.Selected + 1
|
||||
if next >= len(aerc.tabs.Tabs) {
|
||||
|
|
|
@ -20,12 +20,14 @@ type Terminal struct {
|
|||
cursorPos vterm.Pos
|
||||
cursorShown bool
|
||||
damage []vterm.Rect
|
||||
err error
|
||||
focus bool
|
||||
onInvalidate func(d ui.Drawable)
|
||||
pty *os.File
|
||||
start chan interface{}
|
||||
vterm *vterm.VTerm
|
||||
|
||||
OnClose func(err error)
|
||||
OnTitle func(title string)
|
||||
}
|
||||
|
||||
|
@ -41,11 +43,11 @@ func NewTerminal(cmd *exec.Cmd) (*Terminal, error) {
|
|||
for {
|
||||
n, err := term.pty.Read(buf)
|
||||
if err != nil {
|
||||
term.Close()
|
||||
term.Close(err)
|
||||
}
|
||||
n, err = term.vterm.Write(buf[:n])
|
||||
if err != nil {
|
||||
term.Close()
|
||||
term.Close(err)
|
||||
}
|
||||
term.Invalidate()
|
||||
}
|
||||
|
@ -79,14 +81,24 @@ func NewTerminal(cmd *exec.Cmd) (*Terminal, error) {
|
|||
return term, nil
|
||||
}
|
||||
|
||||
func (term *Terminal) Close() {
|
||||
if term.closed {
|
||||
return
|
||||
func (term *Terminal) Close(err error) {
|
||||
term.err = err
|
||||
if term.vterm != nil {
|
||||
term.vterm.Close()
|
||||
term.vterm = nil
|
||||
}
|
||||
if term.pty != nil {
|
||||
term.pty.Close()
|
||||
term.pty = nil
|
||||
}
|
||||
if term.cmd != nil && term.cmd.Process != nil {
|
||||
term.cmd.Process.Kill()
|
||||
term.cmd = nil
|
||||
}
|
||||
if !term.closed && term.OnClose != nil {
|
||||
term.OnClose(err)
|
||||
}
|
||||
term.closed = true
|
||||
term.vterm.Close()
|
||||
term.pty.Close()
|
||||
term.cmd.Process.Kill()
|
||||
}
|
||||
|
||||
func (term *Terminal) OnInvalidate(cb func(d ui.Drawable)) {
|
||||
|
@ -100,6 +112,15 @@ func (term *Terminal) Invalidate() {
|
|||
}
|
||||
|
||||
func (term *Terminal) Draw(ctx *ui.Context) {
|
||||
if term.closed {
|
||||
if term.err != nil {
|
||||
ui.NewText(term.err.Error()).Strategy(ui.TEXT_CENTER).Draw(ctx)
|
||||
} else {
|
||||
ui.NewText("Terminal closed").Strategy(ui.TEXT_CENTER).Draw(ctx)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
winsize := pty.Winsize{
|
||||
Cols: uint16(ctx.Width()),
|
||||
Rows: uint16(ctx.Height()),
|
||||
|
@ -110,16 +131,13 @@ func (term *Terminal) Draw(ctx *ui.Context) {
|
|||
tty, err := pty.StartWithSize(term.cmd, &winsize)
|
||||
term.pty = tty
|
||||
if err != nil {
|
||||
term.Close()
|
||||
term.Close(err)
|
||||
return
|
||||
}
|
||||
term.start <- nil
|
||||
}
|
||||
|
||||
term.ctx = ctx // gross
|
||||
if term.closed {
|
||||
return
|
||||
}
|
||||
|
||||
rows, cols, err := pty.Getsize(term.pty)
|
||||
if err != nil {
|
||||
|
|
Loading…
Reference in New Issue