diff --git a/cmd/micro/command.go b/cmd/micro/command.go index 7fcf41d6..8600d7a1 100644 --- a/cmd/micro/command.go +++ b/cmd/micro/command.go @@ -1,11 +1,98 @@ package main import ( + "bytes" "os" + "os/exec" "regexp" "strings" + + "github.com/gdamore/tcell" ) +// HandleShellCommand runs the shell command and outputs to DisplayBlock +func HandleShellCommand(input string, view *View) { + inputCmd := strings.Split(input, " ")[0] + args := strings.Split(input, " ")[1:] + + // Execute Command + cmd := exec.Command(inputCmd, args...) + outputBytes := &bytes.Buffer{} + + cmd.Stdout = outputBytes // send output to buffer + cmd.Start() + cmd.Wait() // wait for command to finish + outstring := outputBytes.String() + totalLines := strings.Split(outstring, "\n") + + if len(totalLines) < 3 { + messenger.Message(outstring) + return + } + + if outstring != "" { + // Display nonblank output + DisplayBlock(outstring) + } +} + +// DisplayBlock displays txt +// It blocks the main loop +func DisplayBlock(text string) { + topline := 0 + _, height := screen.Size() + screen.HideCursor() + totalLines := strings.Split(text, "\n") + for { + screen.Clear() + + lineEnd := topline + height + if lineEnd > len(totalLines) { + lineEnd = len(totalLines) + } + lines := totalLines[topline:lineEnd] + for y, line := range lines { + for x, ch := range line { + st := defStyle + screen.SetContent(x, y, ch, nil, st) + } + } + + screen.Show() + + event := screen.PollEvent() + switch e := event.(type) { + case *tcell.EventResize: + _, height = e.Size() + case *tcell.EventKey: + switch e.Key() { + case tcell.KeyPgUp: + if topline > height { + topline = topline - height + } else { + topline = 0 + } + case tcell.KeyPgDn: + if topline < len(totalLines)-height { + topline = topline + height + } + case tcell.KeyUp: + if topline > 0 { + topline-- + } + case tcell.KeyDown: + if topline < len(totalLines)-height { + topline++ + } + case tcell.KeyCtrlQ, tcell.KeyCtrlW, tcell.KeyEscape, tcell.KeyCtrlC: + return + default: + return + } + } + } +} + // HandleCommand handles input from the user func HandleCommand(input string, view *View) { inputCmd := strings.Split(input, " ")[0] diff --git a/cmd/micro/messenger.go b/cmd/micro/messenger.go index bb30ba2f..ff164c3b 100644 --- a/cmd/micro/messenger.go +++ b/cmd/micro/messenger.go @@ -3,9 +3,10 @@ package main import ( "bufio" "fmt" - "github.com/gdamore/tcell" "os" "strconv" + + "github.com/gdamore/tcell" ) // TermMessage sends a message to the user in the terminal. This usually occurs before diff --git a/cmd/micro/micro.go b/cmd/micro/micro.go index 6dbdb76a..962d8959 100644 --- a/cmd/micro/micro.go +++ b/cmd/micro/micro.go @@ -2,13 +2,14 @@ package main import ( "fmt" + "io/ioutil" + "os" + "github.com/gdamore/tcell" "github.com/gdamore/tcell/encoding" "github.com/go-errors/errors" "github.com/mattn/go-isatty" "github.com/mitchellh/go-homedir" - "io/ioutil" - "os" ) const ( @@ -200,6 +201,11 @@ func main() { if !canceled { HandleCommand(input, view) } + case tcell.KeyCtrlB: + input, canceled := messenger.Prompt("$ ") + if !canceled { + HandleShellCommand(input, view) + } case tcell.KeyCtrlG: DisplayHelp() // Make sure to resize the view if the user resized the terminal while looking at the help text