gdamore/tcell

[question] Replaying stdin capture to draw result

fe-ax opened this issue · 4 comments

fe-ax commented

I'm breaking my head over finding a way to simulate a terminal when replaying a stdin capture. I aim to sanitize the stdin input when a user types on the screen.

The following byte array contains aaa

bytes := []byte{0x61, 0x61, 0x61}

The following byte array contains aaa, but it's typed like this: ab[backspace]aa

[]byte{0x61, 0x62, 0x8, 0x1b, 0x5b, 0x4b, 0x61, 0x61}

Replacing the set 0x8, 0x1b, 0x5b, 0x4b and its previous byte would solve only a small part of the problem.

I have the following code: (link to playground)

package main

import (
	"fmt"
	"unicode/utf8"

	"github.com/gdamore/tcell/v2"
)

func main() {
	bytes := []byte{0x61, 0x62, 0x8, 0x1b, 0x5b, 0x4b, 0x61, 0x61}

	screen := tcell.NewSimulationScreen("UTF-8")
	err := screen.Init()
	if err != nil {
		panic(err)
	}
	screen.SetSize(15,1)

	var i int = 0
	for len(bytes) > 0 {
		r, size := utf8.DecodeRune(bytes)
		screen.SetContent(i, 0, r, nil, tcell.StyleDefault)
		bytes = bytes[size:]
		i++
	}
	screen.Show()

	contents, _, _ := screen.GetContents()
	for _, c := range contents {
		aRune, _ := utf8.DecodeRune(c.Bytes)
		fmt.Printf("%s", string(aRune))
	}
	fmt.Println()
}

When reading bytes to screen.SetContent(), I understand that the iterator is moving the cursor to the right, but I'm not sure what my next step should be. How would I simulate the key presses?

Thanks, I hope to be pointed in the right direction.

@fe-ax Craft each key event and then do screen.PostEvent. Your application which is using the test screen will then see these events the same as if the user typed them.

@rockorager @fe-ax

Simplest way to go about this is to just write to the os.Stdin file descriptor. However, depending on your app, you would need a goroutine to do this so the standard events can be interpreted coming into stdin.

However, the most efficient way would be to just dump the stdin data into a file, and pass it into stdin via a pipe.

cat output | go run ./...
or
go run ./outputter/main.go | go run ./reader/main.go

I don't see a request for Tcell in this discussion?

CLosing, as nothing actionable for me here.