diff --git a/bapps/go_prompt.go b/bapps/go_prompt.go index 93453e5..9245f3f 100644 --- a/bapps/go_prompt.go +++ b/bapps/go_prompt.go @@ -63,6 +63,7 @@ func NewPromptApp(config *configs.Config, opts ...AppOption) BApp { pa.sugguestHistory = !pa.sugguestHistory }, }), + HandleFD, ) pa.prompt = p return pa @@ -128,6 +129,7 @@ func (a *PromptApp) promptExecute(in string) { }() } } else { + os.Stdout = stdout close(pagerSig) } a.currentState, _ = a.currentState.Process(in) diff --git a/bapps/go_prompt_parser.go b/bapps/go_prompt_parser.go new file mode 100644 index 0000000..ef738ad --- /dev/null +++ b/bapps/go_prompt_parser.go @@ -0,0 +1,46 @@ +package bapps + +import ( + "os" + "os/exec" + "reflect" + "unsafe" + + "github.com/c-bata/go-prompt" +) + +// bInputParser wraps prompt.PosixParser to change TearDown behavior. +type bInputParser struct { + *prompt.PosixParser +} + +// TearDown should be called after stopping input +func (t *bInputParser) TearDown() error { + t.PosixParser.TearDown() + rawModeOff := exec.Command("/bin/stty", "-raw", "echo") + rawModeOff.Stdin = os.Stdin + _ = rawModeOff.Run() + rawModeOff.Wait() + return nil +} + +func NewInputParser(parser *prompt.PosixParser) *bInputParser { + p := &bInputParser{ + PosixParser: prompt.NewStandardInputParser(), + } + return p +} + +func HandleFD(p *prompt.Prompt) error { + in, ok := GetUnexportedField(reflect.ValueOf(p).Elem().FieldByName("in")).(*prompt.PosixParser) + if !ok { + // failed to reflect + return nil + } + + return prompt.OptionParser(NewInputParser(in))(p) +} + +func GetUnexportedField(field reflect.Value) interface{} { + return reflect.NewAt(field.Type(), unsafe.Pointer(field.UnsafeAddr())).Elem().Interface() +}