mitranim / gow

Missing watch mode for Go commands. Watch Go files and execute a command like "go run" or "go test"
The Unlicense
747 stars 29 forks source link

Cannot backspace during interactive stdin #33

Open glacials opened 1 year ago

glacials commented 1 year ago

Hi, thanks for all your hard work on gow! It is an amazingly simple tool and it has saved me so many development hours during the time that I've used it.

I have an issue where my program has an interactive flow where it prompts the user for input at certain points, and I'm trying to run this flow using gow when doing manual testing.

Everything works perfectly, except while inputting text I cannot backspace. See video:

https://github.com/mitranim/gow/assets/438911/56bcdbfb-a14f-44f0-82be-bbaa9b79cfdd

I'm on macOS 13.5 and have tried this in iTerm and Terminal.app. As seen in the video it's not just visual, the text ultimately entered has whitespace added onto it instead of characters removed from it. Is this intentional?

Thanks for any help!

EDIT: For convenience, here's the code used in the screen recording:

package main

import (
    "bufio"
    "fmt"
    "os"
)

func main() {
    fmt.Print("Enter some text: ")
    in := bufio.NewReader(os.Stdin)
    line, err := in.ReadString('\n')
    if err != nil {
        panic(fmt.Errorf("cannot read input: %w", err))
    }
    fmt.Println("You inputted:", line)
}
mitranim commented 1 year ago

See the following changes: https://github.com/mitranim/gow/compare/87df6e48eec654d4e4dfa9ae4c9cdb378cb3796b...478cc6665328b5fc69dd83a4a31c9a60f63625c5.

To summarize, there were multiple issues:

Raw mode allows gow to support hotkeys, but it also makes gow responsible for handling ASCII control codes. Currently it handles control codes related to process state, such as various forms of shutdown and restart, but does not handle the ASCII delete code. It also doesn't handle various ANSI escape codes necessary for "proper" text editing such as cursor movement and more.

When the terminal operates in default "cooked mode" (-r=false in gow), the terminal itself handles common editing operations such as deleting characters before sending the resulting line to the sub-process. When using raw mode (default in gow), the program is responsible for interpreting ASCII delete by removing characters from its own text buffer or whatever, which also requires maintaining the cursor position and interpreting ANSI escape codes for cursor movement. When using gow, the choice of cooked vs raw is going to depend on the specific program. In your case, it seems that you want -r=false, which should work now. Let me know if you run into any issues.