From 928ff67928f5f6772dcfe9d92ee595d4b1f8fb63 Mon Sep 17 00:00:00 2001 From: Sasha Koshka Date: Sat, 8 Apr 2023 22:28:05 -0400 Subject: [PATCH] Why is this error??????? --- cmd/piss/main.go | 16 +++++++ elements/terminal.go | 102 +++++++++++++++++++++++++++++++++++++------ go.mod | 1 + go.sum | 4 +- 4 files changed, 108 insertions(+), 15 deletions(-) diff --git a/cmd/piss/main.go b/cmd/piss/main.go index 9c50ffe..5436fdc 100644 --- a/cmd/piss/main.go +++ b/cmd/piss/main.go @@ -1,6 +1,8 @@ package main +import "os/exec" import "git.tebibyte.media/sashakoshka/tomo" +import "git.tebibyte.media/sashakoshka/tomo/popups" // import "git.tebibyte.media/sashakoshka/tomo/elements" import pissElements "git.tebibyte.media/sashakoshka/piss/elements" import _ "git.tebibyte.media/sashakoshka/tomo/backends/all" @@ -18,4 +20,18 @@ func run () { window.Adopt(terminal) window.OnClose(tomo.Stop) window.Show() + + shell := "ls" + + command := exec.Command(shell) + err := terminal.Start(command) + if err != nil { + popups.NewDialog ( + popups.DialogKindError, + window, + "Couldn't start shell", + "Could not start " + command.String() + ":\n" + + err.Error(), + ).OnClose(tomo.Stop) + } } diff --git a/elements/terminal.go b/elements/terminal.go index 2f4f617..bfd83ad 100644 --- a/elements/terminal.go +++ b/elements/terminal.go @@ -1,35 +1,111 @@ package elements +import "io" +import "os" import "image" +import "os/exec" +import "github.com/creack/pty" import "git.tebibyte.media/sashakoshka/tomo" import "git.tebibyte.media/sashakoshka/piss/ansi" type Terminal struct { *Grid - decoder ansi.Decoder + + stdin io.WriteCloser + stdout io.ReadCloser + stderr io.ReadCloser + pty *os.File + bufferSize int + + decoder ansi.Decoder + cursor image.Point + foreground tomo.Color + background tomo.Color } func NewTerminal () (element *Terminal) { - element = &Terminal { Grid: NewGrid() } + element = &Terminal { + Grid: NewGrid(), + foreground: tomo.ColorForeground, + background: tomo.ColorBackground, + bufferSize: 256, + } element.Grid.OnResize(element.handleResize) + + element.decoder.OnText = element.handleText return } -func (element *Terminal) Write (buffer []byte) (wrote int, err error) { +func (element *Terminal) Start (command *exec.Cmd) (err error) { + winsize := element.winsize() + worked := false + + defer func () { if !worked { element.Close() } } () + + element.stdin, err = command.StdinPipe() + if err != nil { return } + element.stdout, err = command.StdoutPipe() + if err != nil { return } + element.stderr, err = command.StderrPipe() + if err != nil { return } + + element.pty, err = pty.StartWithSize(command, &winsize) + if err != nil { return } + + worked = true + go element.run() + return +} + +func (element *Terminal) Close () { + if element.pty != nil { element.pty.Close() } + if element.stdin != nil { element.stdin.Close() } + if element.stdout != nil { element.stdout.Close() } + if element.stderr != nil { element.stderr.Close() } +} + +func (element *Terminal) run () { + buffer := make([]byte, element.bufferSize) + for { + amount, err := element.stdout.Read(buffer) + if err != nil { break } + + got := buffer[:amount] + for len(got) > 0 { + wrote, err := element.writeFromProcess(got) + got = got[wrote:] + if err != nil { break } + } + } +} + +func (element *Terminal) handleText (text string) { + for _, char := range text { + element.Set(element.cursor, Cell { + Rune: char, + Foreground: element.foreground, + Background: element.background, + }) + } +} + +func (element *Terminal) writeFromProcess (buffer []byte) (wrote int, err error) { wrote, err = element.decoder.Write(buffer) element.Push() return } func (element *Terminal) handleResize () { - element.Set(image.Pt(0, 0), Cell { - Rune: 'X', - Background: tomo.ColorRed, - Foreground: tomo.ColorBrightWhite, - }) - element.Set(image.Pt(15, 10), Cell { - Rune: 'Y', - Background: tomo.ColorBrightYellow, - Foreground: tomo.ColorBlack, - }) + +} + +func (element *Terminal) winsize () pty.Winsize { + columns, rows := element.Size() + bounds := element.Bounds() + return pty.Winsize { + Rows: uint16(rows), + Cols: uint16(columns), + X: uint16(bounds.Dx()), + Y: uint16(bounds.Dy()), + } } diff --git a/go.mod b/go.mod index 05f0459..484ea50 100644 --- a/go.mod +++ b/go.mod @@ -4,6 +4,7 @@ go 1.20 require ( git.tebibyte.media/sashakoshka/tomo v0.0.0-20230408034005-dc077a02abe8 + github.com/creack/pty v1.1.18 golang.org/x/image v0.7.0 ) diff --git a/go.sum b/go.sum index 5510ef1..93b45fb 100644 --- a/go.sum +++ b/go.sum @@ -1,11 +1,11 @@ -git.tebibyte.media/sashakoshka/tomo v0.0.0-20230408030342-43a664009c03 h1:muzaW520ATZPL8Nq/ROBqbxZbBkPLTEPS2lcrKmuv2Q= -git.tebibyte.media/sashakoshka/tomo v0.0.0-20230408030342-43a664009c03/go.mod h1:A0HUbWbA5NgaPVN2ASSn2Y0DxWfaxSV2c0OCSDkYh4c= git.tebibyte.media/sashakoshka/tomo v0.0.0-20230408034005-dc077a02abe8 h1:H4VTKYHpZTM+HyCtfIhw1QDcvY6iJvLUyinPJnalCNU= git.tebibyte.media/sashakoshka/tomo v0.0.0-20230408034005-dc077a02abe8/go.mod h1:A0HUbWbA5NgaPVN2ASSn2Y0DxWfaxSV2c0OCSDkYh4c= github.com/BurntSushi/freetype-go v0.0.0-20160129220410-b763ddbfe298 h1:1qlsVAQJXZHsaM8b6OLVo6muQUQd4CwkH/D3fnnbHXA= github.com/BurntSushi/freetype-go v0.0.0-20160129220410-b763ddbfe298/go.mod h1:D+QujdIlUNfa0igpNMk6UIvlb6C252URs4yupRUV4lQ= github.com/BurntSushi/graphics-go v0.0.0-20160129215708-b43f31a4a966 h1:lTG4HQym5oPKjL7nGs+csTgiDna685ZXjxijkne828g= github.com/BurntSushi/graphics-go v0.0.0-20160129215708-b43f31a4a966/go.mod h1:Mid70uvE93zn9wgF92A/r5ixgnvX8Lh68fxp9KQBaI0= +github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= +github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= github.com/jezek/xgb v1.1.0 h1:wnpxJzP1+rkbGclEkmwpVFQWpuE2PUGNUzP8SbfFobk= github.com/jezek/xgb v1.1.0/go.mod h1:nrhwO0FX/enq75I7Y7G8iN1ubpSGZEiA3v9e9GyRFlk= github.com/jezek/xgbutil v0.0.0-20230403164920-e2f86723ca07 h1:Fr2Oaa4N2oo30/PGecdDkkrth26nD2/yfQFAoddzXmU=