Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support copy/pasting #7

Open
tj opened this issue Jun 9, 2020 · 2 comments
Open

Support copy/pasting #7

tj opened this issue Jun 9, 2020 · 2 comments

Comments

@tj
Copy link
Owner

tj commented Jun 9, 2020

Not sure how this is typically done

@danneu
Copy link

danneu commented Jun 23, 2020

I don't know either. I'm new to Go but here's some obvious sleuth-work that's certainly no mystery to you.

One place that obviously varies on single keypress vs. pasting is how many bytes you are going to read from term.Read():

https://github.com/tj/go-terminput/blob/691367d1d60da90c822e81c172dd22ddb4280065/terminput.go#L18

Currently, terminput.Read() grabs the first rune c off the paste and returns it, ignoring the rest, so go-tea can never perceive the rest of the characters without changes to go-terminput:

go-tea/tea.go

Line 134 in 791bd3b

msg, err := terminput.Read(p.rw)

It's also worth mentioning that, of course, entering character "k" is going to look the same as pasting a single character "k" to n, err := term.Read(). And that if runelen(buf[:n]) > 1, maybe it's not too naive to assume that it's going to be a sequence of KeyRunes rather than control characters like KeySOH (ctrl-a). Like, can you actually copy control characters like KeySOH to be pasted into a cli app? If the answer is no, then I think the solution following solution might be nice.

So one naive idea is for msg, err := terminput.Read() to return a sum type of ((KeyboardInput | []KeyRune), error) which seems ergonomic to work with from go-tea at the expense of possibly being too naive. Or since sum types don't really work in Go, maybe KeyboardInput just takes on a new field { ..., Runes []KeyRune } (well, []rune or string would prob be more accurate there) that will be have a length on pastes if runelen(buf[:n])>1.

Another less ergonomic idea is to always return a sequence ([]KeyboardInput, error) since n, err := term.Read(); runelen(buf[:n]) may be greater than 1. But this becomes inaccurate if, in practice, only the first element could ever be a non-KeyRune. Or in that case maybe it's not so bad since the user can pop the first key off to check it for ctrl chars and then assume the rest are just printable RuneKey runes. But that may have the user writing logic to handle states that can never actually exist.

Anyways, great lib. I've built a CLI app with go-tea that I can leave open and use to quickly translate/lookup words between languages for personal use and to learn Go. Being able to paste words/sentences into it would be a next layer of polish one day.

Some coming weekend, I'll vendor go-terminput and go-tea into my project and play with it myself to see if any of these assumptions are reliable in practice.

@tj
Copy link
Owner Author

tj commented Jun 24, 2020

Awesome! Yeah definitely let me know if your technique works out, sounds fine to me! KeyboardInput's name is pretty generic so we could probably even just stuff the entire string in there, but it might be nice to return an interface and a second type like you mention, just to switch on.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants