mirror of
https://github.com/jesseduffield/lazydocker.git
synced 2026-02-20 01:00:22 +08:00
88 lines
2.1 KiB
Go
88 lines
2.1 KiB
Go
package gui
|
|
|
|
import (
|
|
"fmt"
|
|
"io/ioutil"
|
|
"os"
|
|
"os/signal"
|
|
"strings"
|
|
|
|
"github.com/fatih/color"
|
|
"github.com/jesseduffield/gocui"
|
|
"github.com/jesseduffield/lazydocker/pkg/utils"
|
|
)
|
|
|
|
// RunWithSubprocesses loops, instantiating a new gocui.Gui with each iteration
|
|
// if the error returned from a run is a ErrSubProcess, it runs the subprocess
|
|
// otherwise it handles the error, possibly by quitting the application
|
|
func (gui *Gui) RunWithSubprocesses() error {
|
|
for {
|
|
if err := gui.Run(); err != nil {
|
|
if err == gocui.ErrQuit {
|
|
break
|
|
} else if err == gui.Errors.ErrSubProcess {
|
|
// preparing the state for when we return
|
|
gui.pushPreviousView(gui.currentViewName())
|
|
// giving goEvery goroutines time to finish
|
|
gui.State.SessionIndex++
|
|
|
|
if err := gui.runCommand(); err != nil {
|
|
return err
|
|
}
|
|
|
|
// pop here so we don't stack up view names
|
|
gui.popPreviousView()
|
|
// ensuring we render e.g. the logs of the currently selected item upon return
|
|
gui.State.Panels.Main.ObjectKey = ""
|
|
} else {
|
|
return err
|
|
}
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (gui *Gui) runCommand() error {
|
|
gui.SubProcess.Stdout = os.Stdout
|
|
gui.SubProcess.Stderr = os.Stdout
|
|
gui.SubProcess.Stdin = os.Stdin
|
|
|
|
c := make(chan os.Signal, 1)
|
|
|
|
go func() {
|
|
signal.Notify(c, os.Interrupt)
|
|
<-c
|
|
signal.Stop(c)
|
|
|
|
if err := gui.OSCommand.Kill(gui.SubProcess); err != nil {
|
|
gui.Log.Error(err)
|
|
}
|
|
}()
|
|
|
|
fmt.Fprintf(os.Stdout, "\n%s\n\n", utils.ColoredString("+ "+strings.Join(gui.SubProcess.Args, " "), color.FgBlue))
|
|
|
|
if err := gui.SubProcess.Run(); err != nil {
|
|
// not handling the error explicitly because usually we're going to see it
|
|
// in the output anyway
|
|
gui.Log.Error(err)
|
|
}
|
|
|
|
gui.SubProcess.Stdin = nil
|
|
gui.SubProcess.Stdout = ioutil.Discard
|
|
gui.SubProcess.Stderr = ioutil.Discard
|
|
gui.SubProcess = nil
|
|
|
|
signal.Stop(c)
|
|
|
|
if !gui.Config.UserConfig.Gui.ReturnImmediately {
|
|
fmt.Fprintf(os.Stdout, "\n\n%s", utils.ColoredString(gui.Tr.PressEnterToReturn, color.FgGreen))
|
|
|
|
// wait for enter press
|
|
if _, err := fmt.Scanln(); err != nil {
|
|
gui.Log.Error(err)
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|