diff --git a/_example/http-prompt/main.go b/_example/http-prompt/main.go index b372a35..ec28c64 100644 --- a/_example/http-prompt/main.go +++ b/_example/http-prompt/main.go @@ -163,7 +163,22 @@ func completer(in prompt.Document) []prompt.Suggest { return prompt.FilterHasPrefix(suggestions, w, true) } +func setLog() *os.File { + f, err := os.OpenFile("log", os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0666) + if err != nil { + log.Fatalf("error opening file: %v", err) + } + + log.SetFlags(log.LstdFlags | log.Lshortfile) + log.SetOutput(f) + return f +} + func main() { + + f := setLog() + defer f.Close() + var baseURL = "http://localhost:8000/" if len(os.Args) == 2 { baseURL = os.Args[1] diff --git a/go.sum b/go.sum index 3c72526..9d8e2fa 100644 --- a/go.sum +++ b/go.sum @@ -1,41 +1,23 @@ -github.com/mattn/go-colorable v0.0.9 h1:UVL0vNpWh04HeJXV0KLcaT7r06gOH2l4OW6ddYRUIY4= -github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.7 h1:bQGKb3vps/j0E9GfJQ03JyhRuxsvdAanXlT9BTw3mdw= github.com/mattn/go-colorable v0.1.7/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-isatty v0.0.3 h1:ns/ykhmWi7G9O+8a448SecJU3nSMBXJfqQkl0upE1jI= -github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= -github.com/mattn/go-runewidth v0.0.3 h1:a+kO+98RDGEfo6asOGMmpodZq4FNtnGP54yps8BzLR4= -github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.6/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= -github.com/mattn/go-tty v0.0.0-20180219170247-931426f7535a h1:8TGB3DFRNl06DB1Q6zBX+I7FDoCUZY2fmMS9WGUIIpw= -github.com/mattn/go-tty v0.0.0-20180219170247-931426f7535a/go.mod h1:XPvLUNfbS4fJH25nqRHfWLMa1ONC8Amw+mIA639KxkE= github.com/mattn/go-tty v0.0.3 h1:5OfyWorkyO7xP52Mq7tB36ajHDG5OHrmBGIS/DtakQI= github.com/mattn/go-tty v0.0.3/go.mod h1:ihxohKRERHTVzN+aSVRwACLCeqIoZAWpoICkkvrWyR0= -github.com/pkg/term v0.0.0-20180423043932-cda20d4ac917 h1:BinR73QvQveJdQ8uYZK/8MOjLADpZbI2qs/2+5rnhzQ= -github.com/pkg/term v0.0.0-20180423043932-cda20d4ac917/go.mod h1:eCbImbZ95eXtAUIbLAuAVnBnwf83mjf6QIVH8SHYwqQ= -github.com/pkg/term v1.0.0 h1:raTSNJjic7X4n89hhPyLOsgRYczmr3MyezRierWCTa8= -github.com/pkg/term v1.0.0/go.mod h1:6rk0zrj6TXf8MR5fdVFsZMeGM2lxe3tUFLNBRlwX+dk= github.com/pkg/term v1.1.0 h1:xIAAdCMh3QIAy+5FrE8Ad8XoDhEU4ufwbaSozViP9kk= github.com/pkg/term v1.1.0/go.mod h1:E25nymQcrSllhX42Ok8MRm1+hyBdHY0dCeiKZ9jpNGw= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20180620133508-ad87a3a340fa h1:MUO6aP6ViFfqImh/3zU3O6QX3W2hFRzkkuCIQuUCOsM= -golang.org/x/sys v0.0.0-20180620133508-ad87a3a340fa/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200519105757-fe76b779f299 h1:DYfZAGf2WMFjMxbgTjaC+2HC7NkNAQs+6Q8b9WEB/F4= -golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200909081042-eff7692f9009/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200917073148-efd3b9a0ff20 h1:4X356008q5SA3YXu8PiRap39KFmy4Lf6sGlceJKZQsU= -golang.org/x/sys v0.0.0-20200917073148-efd3b9a0ff20/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200918174421-af09f7315aff h1:1CPUrky56AcgSpxz/KfgzQWzfG09u5YOL8MvPYBlrL8= golang.org/x/sys v0.0.0-20200918174421-af09f7315aff/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= diff --git a/input_posix.go b/input_posix.go index f104303..1b981fb 100644 --- a/input_posix.go +++ b/input_posix.go @@ -20,9 +20,9 @@ type PosixParser struct { // Setup should be called before starting input func (t *PosixParser) Setup() error { // Set NonBlocking mode because if syscall.Read block this goroutine, it cannot receive data from stopCh. - if err := syscall.SetNonblock(t.fd, true); err != nil { - return err - } + //if err := syscall.SetNonblock(t.fd, true); err != nil { + // return err + //} if err := term.SetRaw(t.fd); err != nil { return err } diff --git a/prompt.go b/prompt.go index 173cd51..6c3e8ba 100644 --- a/prompt.go +++ b/prompt.go @@ -3,7 +3,6 @@ package prompt import ( "bytes" "os" - "time" "github.com/c-bata/go-prompt/internal/debug" ) @@ -46,7 +45,7 @@ type Exec struct { func (p *Prompt) Run() { p.skipTearDown = false defer debug.Teardown() - debug.Log("start prompt") + debug.Log("Run start prompt") p.setUp() defer p.tearDown() @@ -56,9 +55,8 @@ func (p *Prompt) Run() { p.renderer.Render(p.buf, p.completion) - bufCh := make(chan []byte, 128) - stopReadBufCh := make(chan struct{}) - go p.readBuffer(bufCh, stopReadBufCh) + bufCh := make(chan []byte) + go p.readBuffer(bufCh) exitCh := make(chan int) winSizeCh := make(chan *WinSize) @@ -70,12 +68,9 @@ func (p *Prompt) Run() { case b := <-bufCh: if shouldExit, e := p.feed(b); shouldExit { p.renderer.BreakLine(p.buf) - stopReadBufCh <- struct{}{} stopHandleSignalCh <- struct{}{} return } else if e != nil { - // Stop goroutine to run readBuffer function - stopReadBufCh <- struct{}{} stopHandleSignalCh <- struct{}{} // Unset raw mode @@ -93,7 +88,6 @@ func (p *Prompt) Run() { } // Set raw mode debug.AssertNoError(p.in.Setup()) - go p.readBuffer(bufCh, stopReadBufCh) go p.handleSignals(exitCh, winSizeCh, stopHandleSignalCh) } else { p.completion.Update(*p.buf.Document()) @@ -106,8 +100,6 @@ func (p *Prompt) Run() { p.renderer.BreakLine(p.buf) p.tearDown() os.Exit(code) - default: - time.Sleep(10 * time.Millisecond) } } } @@ -150,6 +142,7 @@ func (p *Prompt) feed(b []byte) (shouldExit bool, exec *Exec) { shouldExit = true return } + case NotDefined: if p.handleASCIICodeBinding(b) { return @@ -232,7 +225,7 @@ func (p *Prompt) handleASCIICodeBinding(b []byte) bool { // Input just returns user input text. func (p *Prompt) Input() string { defer debug.Teardown() - debug.Log("start prompt") + debug.Log("Input start prompt") p.setUp() defer p.tearDown() @@ -241,44 +234,33 @@ func (p *Prompt) Input() string { } p.renderer.Render(p.buf, p.completion) - bufCh := make(chan []byte, 128) - stopReadBufCh := make(chan struct{}) - go p.readBuffer(bufCh, stopReadBufCh) + bufCh := make(chan []byte) + go p.readBuffer(bufCh) for { select { case b := <-bufCh: if shouldExit, e := p.feed(b); shouldExit { p.renderer.BreakLine(p.buf) - stopReadBufCh <- struct{}{} return "" } else if e != nil { - // Stop goroutine to run readBuffer function - stopReadBufCh <- struct{}{} return e.input } else { p.completion.Update(*p.buf.Document()) p.renderer.Render(p.buf, p.completion) } - default: - time.Sleep(10 * time.Millisecond) } } } -func (p *Prompt) readBuffer(bufCh chan []byte, stopCh chan struct{}) { +func (p *Prompt) readBuffer(bufCh chan []byte) { debug.Log("start reading buffer") + + // blocking read from tty, this groutine will not exit until os.Exit() for { - select { - case <-stopCh: - debug.Log("stop reading buffer") - return - default: - if b, err := p.in.Read(); err == nil && !(len(b) == 1 && b[0] == 0) { - bufCh <- b - } + if b, err := p.in.Read(); err == nil && !(len(b) == 1 && b[0] == 0) { + bufCh <- b // blocking send } - time.Sleep(10 * time.Millisecond) } }