c-bata / go-prompt

Building powerful interactive prompts in Go, inspired by python-prompt-toolkit.
https://godoc.org/github.com/c-bata/go-prompt
MIT License
5.27k stars 346 forks source link

[Bug] After exiting the program, ctrl+c is invalid #233

Open lpxxn opened 3 years ago

lpxxn commented 3 years ago

Bug reports

Mac os bigsur go version go1.16.2 darwin/amd64 go-prompt v0.2.6 iTerm2 code : main.go

package main

import (
    "fmt"
    "github.com/c-bata/go-prompt"
)
func completer(d prompt.Document) []prompt.Suggest {
    s := []prompt.Suggest{
        {Text: "users", Description: "Store the username and age"},
        {Text: "articles", Description: "Store the article text posted by user"},
    }
    return prompt.FilterHasPrefix(s, d.GetWordBeforeCursor(), true)
}
func main() {
    fmt.Println("Please select table.")
    t := prompt.Input("👻 > ", completer)
    fmt.Println("You selected " + t)
}

in iterm2 run go run main.go after exit the program,and than run go run main2.go ctrl+c not work can not exit program main2.go

package main
import "time"
func main() {
    time.Sleep(100*time.Second)
}

open a new iterm2 tab run go run main2.go than ctrl+c can exit the program

securisec commented 3 years ago

I am having the same issue. Using the example from the readme, if i press ctrl+c before running the built binary, everything works as expected. but after running the binary, ctrl+c no longer works in that terminal tab. Osx, latest go-prompt, zsh, kitty.

In linux, ctrl+c works, but arrow keys no longer shows history.

f00stx commented 3 years ago

Same issue - VSCode running a remote shell on Linux (VSCode itself is running in Big Sur, M1 flavour).

Tested on a Linux shell (without using VSCode), same result.

This happens whether the program crashes or exits gracefully.

UPDATE: running "reset" seems to fix the issue for me.

Neofish22 commented 3 years ago

I saw similar behaviour but also that I could not type commands, like #228 . The solution given by @nodauf there works for me.

If one's terminal is stuck in this state, type stty sane<ENTER> (similar to what the comment above does). This should work even if you can't see the text, though if you've tried inputting anything else there might be stuff there to clear (backspace or enter).

securisec commented 3 years ago

It appears it may be a better call do downgrade based on https://github.com/c-bata/go-prompt/issues/228#issuecomment-818132118 for now.

None of us has mentioned windows here yet, but there might be issues there also, and executing stty does not seem like a very maintainable solution for now.

seyoatda commented 3 years ago

It appears it may be a better call do downgrade based on #228 (comment) for now.

None of us has mentioned windows here yet, but there might be issues there also, and executing stty does not seem like a very maintainable solution for now.

same issue here, use stty to solve this problem, it also works fine in windows powershell as I test. However, this issue is not happenning in windows terminals😂😂😂

XANi commented 3 years ago

Can confirm, downgrading to 0.2.5 fixes it

Is there a reason to capture ctrl+c by default at all ? Doing that by default will just cause problems if apps panic or something and term doesn't get reset to the normal settings

securisec commented 3 years ago

Can confirm, downgrading to 0.2.5 fixes it

Can confirm this also.

Ultimation commented 3 years ago

I'm also finding that after running the binary, enter isn't being detected on applications, but is on the shell.

For example, ssh-add won't accept my passphrase until I hit control Z for end of file, whereas before the binary I can just hit enter.

go version go1.16.2 linux/amd64 go-prompt v0.2.6

WangYihang commented 2 years ago

Another solution is to save terminal state and restore terminal state before exiting.

go-prompt/_example/simple-echo/main.go

package main

import (
    "fmt"
    "os"

    prompt "github.com/c-bata/go-prompt"
    "golang.org/x/term"
)

var termState *term.State

func saveTermState() {
    oldState, err := term.GetState(int(os.Stdin.Fd()))
    if err != nil {
        return
    }
    termState = oldState
}

func restoreTermState() {
    if termState != nil {
        term.Restore(int(os.Stdin.Fd()), termState)
    }
}

func completer(in prompt.Document) []prompt.Suggest {
    s := []prompt.Suggest{
        {Text: "users", Description: "Store the username and age"},
        {Text: "articles", Description: "Store the article text posted by user"},
        {Text: "comments", Description: "Store the text commented to articles"},
        {Text: "groups", Description: "Combine users with specific rules"},
    }
    return prompt.FilterHasPrefix(s, in.GetWordBeforeCursor(), true)
}

func main() {
    saveTermState()
    in := prompt.Input(">>> ", completer,
        prompt.OptionTitle("sql-prompt"),
        prompt.OptionHistory([]string{"SELECT * FROM users;"}),
        prompt.OptionPrefixTextColor(prompt.Yellow),
        prompt.OptionPreviewSuggestionTextColor(prompt.Blue),
        prompt.OptionSelectedSuggestionBGColor(prompt.LightGray),
        prompt.OptionSuggestionBGColor(prompt.DarkGray))
    fmt.Println("Your input: " + in)
    restoreTermState()
}

It works on go-prompt (v0.2.6) :

❯ uname -a
Linux polaris 5.4.0-88-generic #99-Ubuntu SMP Thu Sep 23 17:29:00 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux

❯ cat /etc/issue
Ubuntu 20.04.3 LTS \n \l

❯ go version
go version go1.17.1 linux/amd64
XANi commented 2 years ago

@WangYihang not really as your program can panic.

It shouldn't really block Ctrl+c by default in the first place, if handing ctrl+c is really needed in default cli (of which I doubt, it should be an opt-in option) it should do that via intercepting SIGINT

WangYihang commented 2 years ago

@XANi Yes, you are right, what I have pasted is just a dirty solution. It seems we should wait for @c-bata to leave a suggestion.

wHangsHuGe commented 2 years ago

Another solution is to save terminal state and restore terminal state before exiting.

go-prompt/_example/simple-echo/main.go

package main

import (
  "fmt"
  "os"

  prompt "github.com/c-bata/go-prompt"
  "golang.org/x/term"
)

var termState *term.State

func saveTermState() {
  oldState, err := term.GetState(int(os.Stdin.Fd()))
  if err != nil {
      return
  }
  termState = oldState
}

func restoreTermState() {
  if termState != nil {
      term.Restore(int(os.Stdin.Fd()), termState)
  }
}

func completer(in prompt.Document) []prompt.Suggest {
  s := []prompt.Suggest{
      {Text: "users", Description: "Store the username and age"},
      {Text: "articles", Description: "Store the article text posted by user"},
      {Text: "comments", Description: "Store the text commented to articles"},
      {Text: "groups", Description: "Combine users with specific rules"},
  }
  return prompt.FilterHasPrefix(s, in.GetWordBeforeCursor(), true)
}

func main() {
  saveTermState()
  in := prompt.Input(">>> ", completer,
      prompt.OptionTitle("sql-prompt"),
      prompt.OptionHistory([]string{"SELECT * FROM users;"}),
      prompt.OptionPrefixTextColor(prompt.Yellow),
      prompt.OptionPreviewSuggestionTextColor(prompt.Blue),
      prompt.OptionSelectedSuggestionBGColor(prompt.LightGray),
      prompt.OptionSuggestionBGColor(prompt.DarkGray))
  fmt.Println("Your input: " + in)
  restoreTermState()
}

It works on go-prompt (v0.2.6) :

❯ uname -a
Linux polaris 5.4.0-88-generic #99-Ubuntu SMP Thu Sep 23 17:29:00 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux

❯ cat /etc/issue
Ubuntu 20.04.3 LTS \n \l

❯ go version
go version go1.17.1 linux/amd64

Thank you very much, this problem has been bothering me for a long time, it can run very well on Arch, but can't on Ubuntu. Your solution is very nice to Ubuntu! Thanks again.

obloquy commented 2 years ago

This will be fixed by https://github.com/c-bata/go-prompt/pull/239

MohammadBnei commented 9 months ago

I still have this exact issue on MacOs, it's not fixable with the aforementioned functions