mirror of
https://github.com/jesseduffield/lazydocker.git
synced 2026-07-25 08:31:03 +00:00
separate refreshing of container panel from refreshing of main view using a key based on container id and context name
This commit is contained in:
parent
cf8e1f0195
commit
1488bfbcd4
3 changed files with 37 additions and 47 deletions
|
|
@ -44,7 +44,7 @@ func (gui *Gui) handleContainersFocus(g *gocui.Gui, v *gocui.View) error {
|
||||||
newSelectedLine := cy - oy
|
newSelectedLine := cy - oy
|
||||||
|
|
||||||
if newSelectedLine > len(gui.State.Containers)-1 || len(utils.Decolorise(gui.State.Containers[newSelectedLine].Name)) < cx {
|
if newSelectedLine > len(gui.State.Containers)-1 || len(utils.Decolorise(gui.State.Containers[newSelectedLine].Name)) < cx {
|
||||||
return gui.handleContainerSelect(gui.g, v, false)
|
return gui.handleContainerSelect(gui.g, v)
|
||||||
}
|
}
|
||||||
|
|
||||||
gui.State.Panels.Containers.SelectedLine = newSelectedLine
|
gui.State.Panels.Containers.SelectedLine = newSelectedLine
|
||||||
|
|
@ -52,11 +52,11 @@ func (gui *Gui) handleContainersFocus(g *gocui.Gui, v *gocui.View) error {
|
||||||
if prevSelectedLine == newSelectedLine && gui.currentViewName() == v.Name() {
|
if prevSelectedLine == newSelectedLine && gui.currentViewName() == v.Name() {
|
||||||
return gui.handleContainerPress(gui.g, v)
|
return gui.handleContainerPress(gui.g, v)
|
||||||
} else {
|
} else {
|
||||||
return gui.handleContainerSelect(gui.g, v, true)
|
return gui.handleContainerSelect(gui.g, v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gui *Gui) handleContainerSelect(g *gocui.Gui, v *gocui.View, alreadySelected bool) error {
|
func (gui *Gui) handleContainerSelect(g *gocui.Gui, v *gocui.View) error {
|
||||||
if _, err := gui.g.SetCurrentView(v.Name()); err != nil {
|
if _, err := gui.g.SetCurrentView(v.Name()); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -69,14 +69,21 @@ func (gui *Gui) handleContainerSelect(g *gocui.Gui, v *gocui.View, alreadySelect
|
||||||
return gui.renderString(g, "main", gui.Tr.SLocalize("NoChangedContainers"))
|
return gui.renderString(g, "main", gui.Tr.SLocalize("NoChangedContainers"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
key := container.ID + "-" + gui.getContainerContexts()[gui.State.Panels.Containers.ContextIndex]
|
||||||
|
if gui.State.Panels.Main.ObjectKey == key {
|
||||||
|
return nil
|
||||||
|
} else {
|
||||||
|
gui.State.Panels.Main.ObjectKey = key
|
||||||
|
}
|
||||||
|
|
||||||
if err := gui.focusPoint(0, gui.State.Panels.Containers.SelectedLine, len(gui.State.Containers), v); err != nil {
|
if err := gui.focusPoint(0, gui.State.Panels.Containers.SelectedLine, len(gui.State.Containers), v); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
mainView := gui.getMainView()
|
mainView := gui.getMainView()
|
||||||
|
|
||||||
gui.State.MainWriterID++
|
gui.State.Panels.Main.WriterID++
|
||||||
writerID := gui.State.MainWriterID
|
writerID := gui.State.Panels.Main.WriterID
|
||||||
|
|
||||||
mainView.Clear()
|
mainView.Clear()
|
||||||
mainView.SetOrigin(0, 0)
|
mainView.SetOrigin(0, 0)
|
||||||
|
|
@ -150,7 +157,7 @@ func (gui *Gui) renderStats(mainView *gocui.View, container *commands.Container,
|
||||||
gui.createErrorPanel(gui.g, err.Error())
|
gui.createErrorPanel(gui.g, err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
if gui.State.MainWriterID != writerID {
|
if gui.State.Panels.Main.WriterID != writerID {
|
||||||
stream.Body.Close()
|
stream.Body.Close()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -177,7 +184,7 @@ func (gui *Gui) renderLogs(mainView *gocui.View, container *commands.Container,
|
||||||
go func() {
|
go func() {
|
||||||
for {
|
for {
|
||||||
time.Sleep(time.Second / 100)
|
time.Sleep(time.Second / 100)
|
||||||
if gui.State.MainWriterID != writerID {
|
if gui.State.Panels.Main.WriterID != writerID {
|
||||||
cmd.Process.Kill()
|
cmd.Process.Kill()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -188,8 +195,6 @@ func (gui *Gui) renderLogs(mainView *gocui.View, container *commands.Container,
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gui *Gui) refreshContainers() error {
|
func (gui *Gui) refreshContainers() error {
|
||||||
selectedContainer, _ := gui.getSelectedContainer(gui.g)
|
|
||||||
|
|
||||||
containersView := gui.getContainersView()
|
containersView := gui.getContainersView()
|
||||||
if containersView == nil {
|
if containersView == nil {
|
||||||
// if the containersView hasn't been instantiated yet we just return
|
// if the containersView hasn't been instantiated yet we just return
|
||||||
|
|
@ -217,9 +222,7 @@ func (gui *Gui) refreshContainers() error {
|
||||||
fmt.Fprint(containersView, list)
|
fmt.Fprint(containersView, list)
|
||||||
|
|
||||||
if containersView == g.CurrentView() {
|
if containersView == g.CurrentView() {
|
||||||
newSelectedContainer, _ := gui.getSelectedContainer(gui.g)
|
return gui.handleContainerSelect(g, containersView)
|
||||||
alreadySelected := newSelectedContainer.Name == selectedContainer.Name
|
|
||||||
return gui.handleContainerSelect(g, containersView, alreadySelected)
|
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|
@ -246,7 +249,7 @@ func (gui *Gui) handleContainersNextLine(g *gocui.Gui, v *gocui.View) error {
|
||||||
panelState := gui.State.Panels.Containers
|
panelState := gui.State.Panels.Containers
|
||||||
gui.changeSelectedLine(&panelState.SelectedLine, len(gui.State.Containers), false)
|
gui.changeSelectedLine(&panelState.SelectedLine, len(gui.State.Containers), false)
|
||||||
|
|
||||||
return gui.handleContainerSelect(gui.g, v, false)
|
return gui.handleContainerSelect(gui.g, v)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gui *Gui) handleContainersPrevLine(g *gocui.Gui, v *gocui.View) error {
|
func (gui *Gui) handleContainersPrevLine(g *gocui.Gui, v *gocui.View) error {
|
||||||
|
|
@ -257,7 +260,7 @@ func (gui *Gui) handleContainersPrevLine(g *gocui.Gui, v *gocui.View) error {
|
||||||
panelState := gui.State.Panels.Containers
|
panelState := gui.State.Panels.Containers
|
||||||
gui.changeSelectedLine(&panelState.SelectedLine, len(gui.State.Containers), true)
|
gui.changeSelectedLine(&panelState.SelectedLine, len(gui.State.Containers), true)
|
||||||
|
|
||||||
return gui.handleContainerSelect(gui.g, v, false)
|
return gui.handleContainerSelect(gui.g, v)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gui *Gui) handleContainerPress(g *gocui.Gui, v *gocui.View) error {
|
func (gui *Gui) handleContainerPress(g *gocui.Gui, v *gocui.View) error {
|
||||||
|
|
@ -272,7 +275,7 @@ func (gui *Gui) handleContainersPrevContext(g *gocui.Gui, v *gocui.View) error {
|
||||||
gui.State.Panels.Containers.ContextIndex++
|
gui.State.Panels.Containers.ContextIndex++
|
||||||
}
|
}
|
||||||
|
|
||||||
gui.handleContainerSelect(gui.g, v, false)
|
gui.handleContainerSelect(gui.g, v)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
@ -285,7 +288,7 @@ func (gui *Gui) handleContainersNextContext(g *gocui.Gui, v *gocui.View) error {
|
||||||
gui.State.Panels.Containers.ContextIndex--
|
gui.State.Panels.Containers.ContextIndex--
|
||||||
}
|
}
|
||||||
|
|
||||||
gui.handleContainerSelect(gui.g, v, false)
|
gui.handleContainerSelect(gui.g, v)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -82,9 +82,15 @@ type menuPanelState struct {
|
||||||
SelectedLine int
|
SelectedLine int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type mainPanelState struct {
|
||||||
|
ObjectKey string
|
||||||
|
WriterID int
|
||||||
|
}
|
||||||
|
|
||||||
type panelStates struct {
|
type panelStates struct {
|
||||||
Containers *containerPanelState
|
Containers *containerPanelState
|
||||||
Menu *menuPanelState
|
Menu *menuPanelState
|
||||||
|
Main *mainPanelState
|
||||||
}
|
}
|
||||||
|
|
||||||
type guiState struct {
|
type guiState struct {
|
||||||
|
|
@ -95,7 +101,6 @@ type guiState struct {
|
||||||
Updating bool
|
Updating bool
|
||||||
Panels *panelStates
|
Panels *panelStates
|
||||||
SubProcessOutput string
|
SubProcessOutput string
|
||||||
MainWriterID int
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewGui builds a new gui handler
|
// NewGui builds a new gui handler
|
||||||
|
|
@ -108,8 +113,11 @@ func NewGui(log *logrus.Entry, dockerCommand *commands.DockerCommand, oSCommand
|
||||||
Panels: &panelStates{
|
Panels: &panelStates{
|
||||||
Containers: &containerPanelState{SelectedLine: -1, ContextIndex: 0},
|
Containers: &containerPanelState{SelectedLine: -1, ContextIndex: 0},
|
||||||
Menu: &menuPanelState{SelectedLine: 0},
|
Menu: &menuPanelState{SelectedLine: 0},
|
||||||
|
Main: &mainPanelState{
|
||||||
|
WriterID: 0,
|
||||||
|
ObjectKey: "",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
MainWriterID: 0,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gui := &Gui{
|
gui := &Gui{
|
||||||
|
|
@ -200,7 +208,7 @@ func (gui *Gui) onFocusLost(v *gocui.View, newView *gocui.View) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if v.Name() == "containers" {
|
if v.Name() == "containers" {
|
||||||
gui.State.MainWriterID++
|
gui.State.Panels.Main.WriterID++
|
||||||
}
|
}
|
||||||
gui.Log.Info(v.Name() + " focus lost")
|
gui.Log.Info(v.Name() + " focus lost")
|
||||||
return nil
|
return nil
|
||||||
|
|
@ -479,6 +487,7 @@ func (gui *Gui) Run() error {
|
||||||
gui.waitForIntro.Wait()
|
gui.waitForIntro.Wait()
|
||||||
gui.goEvery(time.Millisecond*50, gui.renderAppStatus)
|
gui.goEvery(time.Millisecond*50, gui.renderAppStatus)
|
||||||
gui.goEvery(time.Millisecond*30, gui.reRenderMain)
|
gui.goEvery(time.Millisecond*30, gui.reRenderMain)
|
||||||
|
gui.goEvery(time.Millisecond*500, gui.refreshContainers)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
g.SetManager(gocui.ManagerFunc(gui.layout), gocui.ManagerFunc(gui.getFocusLayout()))
|
g.SetManager(gocui.ManagerFunc(gui.layout), gocui.ManagerFunc(gui.getFocusLayout()))
|
||||||
|
|
@ -530,34 +539,10 @@ func (gui *Gui) RunWithSubprocesses() error {
|
||||||
// adapted from https://blog.kowalczyk.info/article/wOYk/advanced-command-execution-in-go-with-osexec.html
|
// adapted from https://blog.kowalczyk.info/article/wOYk/advanced-command-execution-in-go-with-osexec.html
|
||||||
func (gui *Gui) runCommand(cmd *exec.Cmd) (string, error) {
|
func (gui *Gui) runCommand(cmd *exec.Cmd) (string, error) {
|
||||||
var stdoutBuf bytes.Buffer
|
var stdoutBuf bytes.Buffer
|
||||||
stdoutIn, _ := cmd.StdoutPipe()
|
cmd.Stdout = io.MultiWriter(os.Stdout, &stdoutBuf)
|
||||||
stderrIn, _ := cmd.StderrPipe()
|
cmd.Stderr = io.MultiWriter(os.Stderr, &stdoutBuf)
|
||||||
|
|
||||||
stdout := io.MultiWriter(os.Stdout, &stdoutBuf)
|
if err := cmd.Run(); err != nil {
|
||||||
stderr := io.MultiWriter(os.Stderr, &stdoutBuf)
|
|
||||||
err := cmd.Start()
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
var wg sync.WaitGroup
|
|
||||||
wg.Add(1)
|
|
||||||
|
|
||||||
go func() {
|
|
||||||
if _, err := io.Copy(stdout, stdoutIn); err != nil {
|
|
||||||
gui.Log.Error(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
wg.Done()
|
|
||||||
}()
|
|
||||||
|
|
||||||
if _, err := io.Copy(stderr, stderrIn); err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
wg.Wait()
|
|
||||||
|
|
||||||
if err := cmd.Wait(); err != nil {
|
|
||||||
// not handling the error explicitly because usually we're going to see it
|
// not handling the error explicitly because usually we're going to see it
|
||||||
// in the output anyway
|
// in the output anyway
|
||||||
gui.Log.Error(err)
|
gui.Log.Error(err)
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,7 @@ func (gui *Gui) nextView(g *gocui.Gui, v *gocui.View) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
gui.State.Panels.Main.ObjectKey = ""
|
||||||
return gui.switchFocus(g, v, focusedView)
|
return gui.switchFocus(g, v, focusedView)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -64,6 +65,7 @@ func (gui *Gui) previousView(g *gocui.Gui, v *gocui.View) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
gui.State.Panels.Main.ObjectKey = ""
|
||||||
return gui.switchFocus(g, v, focusedView)
|
return gui.switchFocus(g, v, focusedView)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -74,7 +76,7 @@ func (gui *Gui) newLineFocused(g *gocui.Gui, v *gocui.View) error {
|
||||||
case "status":
|
case "status":
|
||||||
return gui.handleStatusSelect(g, v)
|
return gui.handleStatusSelect(g, v)
|
||||||
case "containers":
|
case "containers":
|
||||||
return gui.handleContainerSelect(g, v, true)
|
return gui.handleContainerSelect(g, v)
|
||||||
case "confirmation":
|
case "confirmation":
|
||||||
return nil
|
return nil
|
||||||
case "main":
|
case "main":
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue