diff --git a/frontend/src/main.ts b/frontend/src/main.ts index de0d3d4..1bd6019 100644 --- a/frontend/src/main.ts +++ b/frontend/src/main.ts @@ -1,10 +1,31 @@ import { Terminal } from "xterm"; -const term = new Terminal(); +const term = new Terminal({ + fontFamily: + '"Fira Code", courier-new, courier, monospace, "Powerline Extra Symbols"', +}); + +let line = ""; + +term.onKey(({ key, domEvent }) => { + const printable = !(domEvent.altKey || domEvent.ctrlKey || domEvent.metaKey); + if (domEvent.key === "Enter") { + //@ts-ignore + window.__WRITE_PTY(line); + term.writeln(""); + line = ""; + return; + } + + if (printable) { + term.write(key); + line += key; + } +}); term.open(document.getElementById("terminal")!); //@ts-ignore -window.__WRITE_TERMINAL = (data: string) => { - term.write(data); +window.__WRITE_TERMINAL = (data: { result: string }) => { + term.write(data.result); }; diff --git a/go.mod b/go.mod index 133e4ab..8c2f2a9 100644 --- a/go.mod +++ b/go.mod @@ -3,3 +3,5 @@ module git.cesium.pw/niku/ratatouille go 1.19 require github.com/webview/webview v0.0.0-20230210061304-7b40e46d97e9 + +require github.com/creack/pty v1.1.18 // indirect diff --git a/go.sum b/go.sum index 71b854e..00d9387 100644 --- a/go.sum +++ b/go.sum @@ -1,2 +1,4 @@ +github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= +github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= github.com/webview/webview v0.0.0-20230210061304-7b40e46d97e9 h1:SPyWnfToUom3xNh3dKGkq1ZV7pw+VSWDcfVrUM1nRWs= github.com/webview/webview v0.0.0-20230210061304-7b40e46d97e9/go.mod h1:rpXAuuHgyEJb6kXcXldlkOjU6y4x+YcASKKXJNUhh0Y= diff --git a/main.go b/main.go index aa75dda..0504722 100644 --- a/main.go +++ b/main.go @@ -1,25 +1,56 @@ package main import ( + "encoding/json" + "fmt" "io/ioutil" + "os/exec" "time" + "github.com/creack/pty" "github.com/webview/webview" ) +type PtyOutEvent struct { + Result string `json:"result"` +} + func main() { + c := exec.Command("bash") + p, _ := pty.Start(c) + w := webview.New(true) defer w.Destroy() - w.SetTitle("Basic Example") + + w.SetTitle("Ratatouille") w.SetSize(480, 320, webview.HintNone) b, _ := ioutil.ReadFile("frontend/dist/index.html") w.SetHtml(string(b)) + w.Bind("__WRITE_PTY", func(command string) { + p.WriteString(command + "\n") + }) + go func() { for { - time.Sleep(2 * time.Second) - w.Eval(`window.__WRITE_TERMINAL('PONG!\r\n');`) + buf := make([]byte, 1024) + n, _ := p.Read(buf) + if n == 0 { + continue + } + + result := string(buf) + event := PtyOutEvent{Result: result[:n]} + payload, err := json.Marshal(event) + if err != nil { + fmt.Println("Whoopsie", err) + continue + } + + fn := fmt.Sprintf(`window.__WRITE_TERMINAL(%s);`, string(payload)) + w.Eval(fn) + time.Sleep(200 * time.Millisecond) } }()