From c63c8f63ac802edebb453068f0dc072fbb832d5b Mon Sep 17 00:00:00 2001 From: Gokcehan Date: Tue, 3 Apr 2018 22:22:58 +0300 Subject: [PATCH] pipe stdin for 'shell-pipe' commands --- app.go | 47 +++++++++++++++++++++++++++++++++-------------- eval.go | 7 +++++++ ui.go | 15 +++++++++++---- 3 files changed, 51 insertions(+), 18 deletions(-) diff --git a/app.go b/app.go index b732470..9047287 100644 --- a/app.go +++ b/app.go @@ -19,6 +19,7 @@ type app struct { ui *ui nav *nav quitChan chan bool + cmdIn io.WriteCloser cmdHist []cmdItem cmdHistInd int } @@ -191,16 +192,17 @@ func (app *app) runShell(s string, args []string, prefix string) { defer app.ui.resume() defer app.nav.renew(app.ui.wins[0].h) case "%": + stdin, err := cmd.StdinPipe() + if err != nil { + log.Printf("writing stdin: %s", err) + } + app.cmdIn = stdin stdout, err := cmd.StdoutPipe() if err != nil { log.Printf("reading stdout: %s", err) } - stderr, err := cmd.StderrPipe() - if err != nil { - log.Printf("reading stderr: %s", err) - } - out = io.MultiReader(stdout, stderr) - defer app.nav.renew(app.ui.wins[0].h) + out = stdout + cmd.Stderr = cmd.Stdout } var err error @@ -227,14 +229,31 @@ func (app *app) runShell(s string, args []string, prefix string) { switch prefix { case "%": - app.ui.cmdPrefix = "" - scanner := bufio.NewScanner(out) - for scanner.Scan() { - app.ui.msg = scanner.Text() + go func() { + app.ui.msg = "" + app.ui.cmdPrefix = ">" + + reader := bufio.NewReader(out) + var buf []byte + for { + b, err := reader.ReadByte() + if err == io.EOF { + break + } + buf = append(buf, b) + app.ui.msg = string(buf) + app.ui.draw(app.nav) + if b == '\n' { + buf = nil + } + } + + if err := cmd.Wait(); err != nil { + log.Printf("running shell: %s", err) + } + app.nav.renew(app.ui.wins[0].h) + app.ui.cmdPrefix = "" app.ui.draw(app.nav) - } - if err := cmd.Wait(); err != nil { - log.Printf("running shell: %s", err) - } + }() } } diff --git a/eval.go b/eval.go index ac118c5..3cb6612 100644 --- a/eval.go +++ b/eval.go @@ -1,6 +1,7 @@ package main import ( + "io" "log" "os" "strconv" @@ -410,6 +411,9 @@ func (e *callExpr) eval(app *app, args []string) { app.ui.cmdAccLeft = append(app.ui.cmdAccLeft, []rune(e.args[0])...) } case "cmd-escape": + if app.ui.cmdPrefix == ">" { + return + } app.ui.menuBuf = nil app.ui.cmdAccLeft = nil app.ui.cmdAccRight = nil @@ -453,6 +457,9 @@ func (e *callExpr) eval(app *app, args []string) { app.runShell(s, nil, app.ui.cmdPrefix) app.cmdHist = append(app.cmdHist, cmdItem{"%", s}) return + case ">": + io.WriteString(app.cmdIn, s+"\n") + return case "!": log.Printf("shell-wait: %s", s) app.runShell(s, nil, app.ui.cmdPrefix) diff --git a/ui.go b/ui.go index 25a70ce..166f667 100644 --- a/ui.go +++ b/ui.go @@ -611,14 +611,21 @@ func (ui *ui) draw(nav *nav) { ui.wins[woff+i].printDir(nav.dirs[doff+i], nav.marks, nav.saves) } - if ui.cmdPrefix != "" { + switch ui.cmdPrefix { + case "": + ui.drawStatLine(nav) + termbox.HideCursor() + case ">": + ui.msgWin.printLine(0, 0, fg, bg, ui.cmdPrefix) + ui.msgWin.print(len(ui.cmdPrefix), 0, fg, bg, ui.msg) + ui.msgWin.print(len(ui.cmdPrefix)+len(ui.msg), 0, fg, bg, string(ui.cmdAccLeft)) + ui.msgWin.print(len(ui.cmdPrefix)+len(ui.msg)+runeSliceWidth(ui.cmdAccLeft), 0, fg, bg, string(ui.cmdAccRight)) + termbox.SetCursor(ui.msgWin.x+len(ui.cmdPrefix)+len(ui.msg)+runeSliceWidth(ui.cmdAccLeft), ui.msgWin.y) + default: ui.msgWin.printLine(0, 0, fg, bg, ui.cmdPrefix) ui.msgWin.print(len(ui.cmdPrefix), 0, fg, bg, string(ui.cmdAccLeft)) ui.msgWin.print(len(ui.cmdPrefix)+runeSliceWidth(ui.cmdAccLeft), 0, fg, bg, string(ui.cmdAccRight)) termbox.SetCursor(ui.msgWin.x+len(ui.cmdPrefix)+runeSliceWidth(ui.cmdAccLeft), ui.msgWin.y) - } else { - ui.drawStatLine(nav) - termbox.HideCursor() } if gOpts.preview {