Reputation: 3661
I am writing an interactive application that accepts user inputs in a loop and prints out responses in the background. The reader part of my code looks like:
scanner := bufio.NewReader(os.Stdin)
for {
fmt.Print(":: ") // prompt for user to enter stuff
in,_:=scanner.ReadString('\n')
}
However, while I am waiting for the user input, I want to print some asynchronous data I got over the network like so:
>> Some text
>> :: Hi I'm the user and I'm
Now some background data arrives:
>> Some text
>> This data was printed while user was inputting
>> :: Hi I'm the user and I'm
And now the user can finish their input:
>> Some text
>> This data was printed while user was inputting
>> :: Hi I'm the user and I'm entering some text
>> ::
I'm thinking that the background routine would need to scan stdin
for text, erase it somehow, print its own data, and restore the original text. I do not know how to scan text that has not been input via the enter key, or how to clear a line. How do I go about it?
Upvotes: 3
Views: 2130
Reputation: 3274
To clear a line you can use \r
to return the cursor to the beginning of line and then replace all the characters on the line with whitespace and then issue another \r
to return to the beginning of line again. For example (add more spaces if needed):
fmt.Printf("\r \r")
Now you can print your background data on top of the data user had inputted.
Then how do you reprint the data user had inputted? You can't read it from terminal itself so you have to save it somewhere while it's being input. One way to do this would be to disable input buffering on your terminal so each character you type immediately gets flushed to stdin where you can read it. For example:
var input []byte
reader := bufio.NewReader(os.Stdin)
// disables input buffering
exec.Command("stty", "-F", "/dev/tty", "cbreak", "min", "1").Run()
// append each character that gets typed to input slice
for {
b, err := reader.ReadByte()
if err != nil {
panic(err)
}
input = append(input, b)
}
So when you need to insert background data, first clear the line, then print your background data and finally print the contents of the input variable on the next line.
Upvotes: 1