diff --git a/getter.rb b/getter.rb index 7e75bd00..31b5dbe9 100644 --- a/getter.rb +++ b/getter.rb @@ -26,6 +26,7 @@ NoViewMachingNewLineFocusedSwitchStatement OpenConfig pressEnterToReturn previousContext +ProjectTitle pruneImages PruningStatus remove @@ -40,7 +41,6 @@ RestartingStatus RunningSubprocess scroll ServicesTitle -StatusTitle stop StopContainer StoppingStatus @@ -59,4 +59,4 @@ f.lines.each_with_index do |line, index| puts "#{key}: \"#{value}\"," end end -end \ No newline at end of file +end diff --git a/main.go b/main.go index 9c05b7c8..68dac33e 100644 --- a/main.go +++ b/main.go @@ -46,7 +46,12 @@ func main() { os.Exit(0) } - appConfig, err := config.NewAppConfig("lazydocker", version, commit, date, buildSource, debuggingFlag, composeFiles) + projectDir, err := os.Getwd() + if err != nil { + log.Fatal(err.Error()) + } + + appConfig, err := config.NewAppConfig("lazydocker", version, commit, date, buildSource, debuggingFlag, composeFiles, projectDir) if err != nil { log.Fatal(err.Error()) } diff --git a/pkg/config/app_config.go b/pkg/config/app_config.go index 3976ad98..8c4ca92c 100644 --- a/pkg/config/app_config.go +++ b/pkg/config/app_config.go @@ -362,10 +362,11 @@ type AppConfig struct { BuildSource string `long:"build-source" env:"BUILD_SOURCE" default:""` UserConfig *UserConfig ConfigDir string + ProjectDir string } // NewAppConfig makes a new app config -func NewAppConfig(name, version, commit, date string, buildSource string, debuggingFlag bool, composeFiles []string) (*AppConfig, error) { +func NewAppConfig(name, version, commit, date string, buildSource string, debuggingFlag bool, composeFiles []string, projectDir string) (*AppConfig, error) { configDir, err := findOrCreateConfigDir(name) if err != nil { return nil, err @@ -390,6 +391,7 @@ func NewAppConfig(name, version, commit, date string, buildSource string, debugg BuildSource: buildSource, UserConfig: userConfig, ConfigDir: configDir, + ProjectDir: projectDir, } return appConfig, nil diff --git a/pkg/config/app_config_test.go b/pkg/config/app_config_test.go index bae43e3a..b6764493 100644 --- a/pkg/config/app_config_test.go +++ b/pkg/config/app_config_test.go @@ -6,7 +6,7 @@ import ( func TestDockerComposeCommandNoFiles(t *testing.T) { composeFiles := []string{} - conf, err := NewAppConfig("name", "version", "commit", "date", "buildSource", false, composeFiles) + conf, err := NewAppConfig("name", "version", "commit", "date", "buildSource", false, composeFiles, "projectDir") if err != nil { t.Fatalf("Unexpected error: %s", err) @@ -21,7 +21,7 @@ func TestDockerComposeCommandNoFiles(t *testing.T) { func TestDockerComposeCommandSingleFile(t *testing.T) { composeFiles := []string{"one.yml"} - conf, err := NewAppConfig("name", "version", "commit", "date", "buildSource", false, composeFiles) + conf, err := NewAppConfig("name", "version", "commit", "date", "buildSource", false, composeFiles, "projectDir") if err != nil { t.Fatalf("Unexpected error: %s", err) @@ -36,7 +36,7 @@ func TestDockerComposeCommandSingleFile(t *testing.T) { func TestDockerComposeCommandMultipleFiles(t *testing.T) { composeFiles := []string{"one.yml", "two.yml", "three.yml"} - conf, err := NewAppConfig("name", "version", "commit", "date", "buildSource", false, composeFiles) + conf, err := NewAppConfig("name", "version", "commit", "date", "buildSource", false, composeFiles, "projectDir") if err != nil { t.Fatalf("Unexpected error: %s", err) diff --git a/pkg/gui/gui.go b/pkg/gui/gui.go index a5eb08b1..8ef53626 100644 --- a/pkg/gui/gui.go +++ b/pkg/gui/gui.go @@ -81,7 +81,7 @@ type containerPanelState struct { ContextIndex int // for specifying if you are looking at logs/stats/config/etc } -type statusState struct { +type projectState struct { ContextIndex int // for specifying if you are looking at credits/logs } @@ -112,7 +112,7 @@ type panelStates struct { Main *mainPanelState Images *imagePanelState Volumes *volumePanelState - Status *statusState + Project *projectState } type guiState struct { @@ -142,14 +142,14 @@ func NewGui(log *logrus.Entry, dockerCommand *commands.DockerCommand, oSCommand Main: &mainPanelState{ ObjectKey: "", }, - Status: &statusState{ContextIndex: 0}, + Project: &projectState{ContextIndex: 0}, }, SessionIndex: 0, } - cyclableViews := []string{"status", "containers", "images", "volumes"} + cyclableViews := []string{"project", "containers", "images", "volumes"} if dockerCommand.InDockerComposeProject { - cyclableViews = []string{"status", "services", "containers", "images", "volumes"} + cyclableViews = []string{"project", "services", "containers", "images", "volumes"} } gui := &Gui{ @@ -271,6 +271,7 @@ func (gui *Gui) Run() error { gui.waitForIntro.Wait() gui.goEvery(time.Millisecond*50, gui.renderAppStatus) gui.goEvery(time.Millisecond*30, gui.reRenderMain) + gui.goEvery(time.Millisecond*100, gui.refreshProject) gui.goEvery(time.Millisecond*100, gui.refreshContainersAndServices) gui.goEvery(time.Millisecond*100, gui.refreshVolumes) gui.goEvery(time.Millisecond*1000, gui.DockerCommand.UpdateContainerDetails) diff --git a/pkg/gui/keybindings.go b/pkg/gui/keybindings.go index e3b44f77..c1fe9196 100644 --- a/pkg/gui/keybindings.go +++ b/pkg/gui/keybindings.go @@ -126,51 +126,51 @@ func (gui *Gui) GetInitialKeybindings() []*Binding { Handler: gui.handleCustomCommand, }, { - ViewName: "status", + ViewName: "project", Key: 'e', Modifier: gocui.ModNone, Handler: gui.handleEditConfig, Description: gui.Tr.EditConfig, }, { - ViewName: "status", + ViewName: "project", Key: 'o', Modifier: gocui.ModNone, Handler: gui.handleOpenConfig, Description: gui.Tr.OpenConfig, }, { - ViewName: "status", + ViewName: "project", Key: '[', Modifier: gocui.ModNone, - Handler: gui.handleStatusPrevContext, + Handler: gui.handleProjectPrevContext, Description: gui.Tr.PreviousContext, }, { - ViewName: "status", + ViewName: "project", Key: ']', Modifier: gocui.ModNone, - Handler: gui.handleStatusNextContext, + Handler: gui.handleProjectNextContext, Description: gui.Tr.NextContext, }, { - ViewName: "status", + ViewName: "project", Key: gocui.MouseLeft, Modifier: gocui.ModNone, - Handler: gui.handleStatusClick, + Handler: gui.handleProjectClick, }, { - ViewName: "status", + ViewName: "project", Key: 'm', Modifier: gocui.ModNone, Handler: gui.handleViewAllLogs, Description: gui.Tr.ViewLogs, }, { - ViewName: "status", + ViewName: "project", Key: gocui.MouseLeft, Modifier: gocui.ModNone, - Handler: gui.handleStatusSelect, + Handler: gui.handleProjectSelect, }, { ViewName: "menu", @@ -430,7 +430,7 @@ func (gui *Gui) GetInitialKeybindings() []*Binding { } // TODO: add more views here - for _, viewName := range []string{"status", "services", "containers", "images", "volumes", "menu"} { + for _, viewName := range []string{"project", "services", "containers", "images", "volumes", "menu"} { bindings = append(bindings, []*Binding{ {ViewName: viewName, Key: gocui.KeyArrowLeft, Modifier: gocui.ModNone, Handler: gui.previousView}, {ViewName: viewName, Key: gocui.KeyArrowRight, Modifier: gocui.ModNone, Handler: gui.nextView}, @@ -464,7 +464,7 @@ func (gui *Gui) GetInitialKeybindings() []*Binding { }...) } - for _, viewName := range []string{"status", "services", "containers", "images", "volumes"} { + for _, viewName := range []string{"project", "services", "containers", "images", "volumes"} { bindings = append(bindings, &Binding{ ViewName: viewName, Key: gocui.KeyEnter, diff --git a/pkg/gui/layout.go b/pkg/gui/layout.go index 71fb7e6a..789af0e1 100644 --- a/pkg/gui/layout.go +++ b/pkg/gui/layout.go @@ -72,7 +72,7 @@ func (gui *Gui) layout(g *gocui.Gui) error { g.Highlight = true width, height := g.Size() - information := gui.Config.Version + information := "lazydocker " + gui.Config.Version if gui.g.Mouse { donate := color.New(color.FgMagenta, color.Underline).Sprint(gui.Tr.Donate) information = donate + " " + information @@ -117,7 +117,7 @@ func (gui *Gui) layout(g *gocui.Gui) error { if gui.DockerCommand.InDockerComposeProject { tallPanels++ vHeights = map[string]int{ - "status": 3, + "project": 3, "services": usableSpace/tallPanels + usableSpace%tallPanels, "containers": usableSpace / tallPanels, "images": usableSpace / tallPanels, @@ -126,7 +126,7 @@ func (gui *Gui) layout(g *gocui.Gui) error { } } else { vHeights = map[string]int{ - "status": 3, + "project": 3, "containers": usableSpace/tallPanels + usableSpace%tallPanels, "images": usableSpace / tallPanels, "volumes": usableSpace / tallPanels, @@ -140,7 +140,7 @@ func (gui *Gui) layout(g *gocui.Gui) error { defaultHeight = 1 } vHeights = map[string]int{ - "status": defaultHeight, + "project": defaultHeight, "containers": defaultHeight, "images": defaultHeight, "volumes": defaultHeight, @@ -176,19 +176,19 @@ func (gui *Gui) layout(g *gocui.Gui) error { v.IgnoreCarriageReturns = true } - if v, err := g.SetView("status", 0, 0, leftSideWidth, vHeights["status"]-1, gocui.BOTTOM|gocui.RIGHT); err != nil { + if v, err := g.SetView("project", 0, 0, leftSideWidth, vHeights["project"]-1, gocui.BOTTOM|gocui.RIGHT); err != nil { if err.Error() != "unknown view" { return err } - v.Title = gui.Tr.StatusTitle + v.Title = gui.Tr.ProjectTitle v.FgColor = gocui.ColorDefault } var servicesView *gocui.View - aboveContainersView := "status" + aboveContainersView := "project" if gui.DockerCommand.InDockerComposeProject { aboveContainersView = "services" - servicesView, err = g.SetViewBeneath("services", "status", vHeights["services"]) + servicesView, err = g.SetViewBeneath("services", "project", vHeights["services"]) if err != nil { if err.Error() != "unknown view" { return err diff --git a/pkg/gui/main_panel.go b/pkg/gui/main_panel.go index ca3cb1b1..96ddde80 100644 --- a/pkg/gui/main_panel.go +++ b/pkg/gui/main_panel.go @@ -58,6 +58,9 @@ func (gui *Gui) onMainTabClick(tabIndex int) error { } switch viewName { + case "project": + gui.State.Panels.Project.ContextIndex = tabIndex + return gui.handleProjectSelect(gui.g, gui.getProjectView()) case "services": gui.State.Panels.Services.ContextIndex = tabIndex return gui.handleServiceSelect(gui.g, gui.getServicesView()) @@ -70,9 +73,6 @@ func (gui *Gui) onMainTabClick(tabIndex int) error { case "volumes": gui.State.Panels.Volumes.ContextIndex = tabIndex return gui.handleVolumeSelect(gui.g, gui.getVolumesView()) - case "status": - gui.State.Panels.Status.ContextIndex = tabIndex - return gui.handleStatusSelect(gui.g, gui.getStatusView()) } return nil diff --git a/pkg/gui/status_panel.go b/pkg/gui/project_panel.go similarity index 71% rename from pkg/gui/status_panel.go rename to pkg/gui/project_panel.go index 3e09aae0..76435f6b 100644 --- a/pkg/gui/status_panel.go +++ b/pkg/gui/project_panel.go @@ -3,6 +3,7 @@ package gui import ( "bytes" "fmt" + "path" "strings" "github.com/fatih/color" @@ -13,33 +14,43 @@ import ( "github.com/jesseduffield/yaml" ) -func (gui *Gui) getStatusContexts() []string { +func (gui *Gui) getProjectContexts() []string { if gui.DockerCommand.InDockerComposeProject { - return []string{"logs", "credits", "config"} + return []string{"logs", "config", "credits"} } return []string{"credits"} } -func (gui *Gui) getStatusContextTitles() []string { +func (gui *Gui) getProjectContextTitles() []string { if gui.DockerCommand.InDockerComposeProject { - return []string{gui.Tr.LogsTitle, gui.Tr.CreditsTitle, gui.Tr.DockerComposeConfigTitle} + return []string{gui.Tr.LogsTitle, gui.Tr.DockerComposeConfigTitle, gui.Tr.CreditsTitle} } return []string{gui.Tr.CreditsTitle} } -func (gui *Gui) refreshStatus() error { - v := gui.getStatusView() +func (gui *Gui) refreshProject() error { + v := gui.getProjectView() + + projectName := path.Base(gui.Config.ProjectDir) + if gui.DockerCommand.InDockerComposeProject { + for _, service := range gui.DockerCommand.Services { + if service.Container != nil { + projectName = service.Container.Details.Config.Labels["com.docker.compose.project"] + break + } + } + } gui.g.Update(func(*gocui.Gui) error { v.Clear() - fmt.Fprint(v, "lazydocker") + fmt.Fprint(v, projectName) return nil }) return nil } -func (gui *Gui) handleStatusClick(g *gocui.Gui, v *gocui.View) error { +func (gui *Gui) handleProjectClick(g *gocui.Gui, v *gocui.View) error { if gui.popupPanelFocused() { return nil } @@ -48,15 +59,15 @@ func (gui *Gui) handleStatusClick(g *gocui.Gui, v *gocui.View) error { return err } - return gui.handleStatusSelect(g, v) + return gui.handleProjectSelect(g, v) } -func (gui *Gui) handleStatusSelect(g *gocui.Gui, v *gocui.View) error { +func (gui *Gui) handleProjectSelect(g *gocui.Gui, v *gocui.View) error { if gui.popupPanelFocused() { return nil } - key := gui.getStatusContexts()[gui.State.Panels.Status.ContextIndex] + key := gui.getProjectContexts()[gui.State.Panels.Project.ContextIndex] if !gui.shouldRefresh(key) { return nil } @@ -64,10 +75,10 @@ func (gui *Gui) handleStatusSelect(g *gocui.Gui, v *gocui.View) error { gui.clearMainView() mainView := gui.getMainView() - mainView.Tabs = gui.getStatusContextTitles() - mainView.TabIndex = gui.State.Panels.Status.ContextIndex + mainView.Tabs = gui.getProjectContextTitles() + mainView.TabIndex = gui.State.Panels.Project.ContextIndex - switch gui.getStatusContexts()[gui.State.Panels.Status.ContextIndex] { + switch gui.getProjectContexts()[gui.State.Panels.Project.ContextIndex] { case "credits": if err := gui.renderCredits(); err != nil { return err @@ -176,28 +187,28 @@ func lazydockerTitle() string { ` } -func (gui *Gui) handleStatusNextContext(g *gocui.Gui, v *gocui.View) error { - contexts := gui.getStatusContexts() - if gui.State.Panels.Status.ContextIndex >= len(contexts)-1 { - gui.State.Panels.Status.ContextIndex = 0 +func (gui *Gui) handleProjectNextContext(g *gocui.Gui, v *gocui.View) error { + contexts := gui.getProjectContexts() + if gui.State.Panels.Project.ContextIndex >= len(contexts)-1 { + gui.State.Panels.Project.ContextIndex = 0 } else { - gui.State.Panels.Status.ContextIndex++ + gui.State.Panels.Project.ContextIndex++ } - gui.handleStatusSelect(gui.g, v) + gui.handleProjectSelect(gui.g, v) return nil } -func (gui *Gui) handleStatusPrevContext(g *gocui.Gui, v *gocui.View) error { - contexts := gui.getStatusContexts() - if gui.State.Panels.Status.ContextIndex <= 0 { - gui.State.Panels.Status.ContextIndex = len(contexts) - 1 +func (gui *Gui) handleProjectPrevContext(g *gocui.Gui, v *gocui.View) error { + contexts := gui.getProjectContexts() + if gui.State.Panels.Project.ContextIndex <= 0 { + gui.State.Panels.Project.ContextIndex = len(contexts) - 1 } else { - gui.State.Panels.Status.ContextIndex-- + gui.State.Panels.Project.ContextIndex-- } - gui.handleStatusSelect(gui.g, v) + gui.handleProjectSelect(gui.g, v) return nil } diff --git a/pkg/gui/view_helpers.go b/pkg/gui/view_helpers.go index 51aa2178..d661a9d9 100644 --- a/pkg/gui/view_helpers.go +++ b/pkg/gui/view_helpers.go @@ -15,9 +15,6 @@ func (gui *Gui) refreshSidePanels(g *gocui.Gui) error { if err := gui.refreshImages(); err != nil { return err } - if err := gui.refreshStatus(); err != nil { - return err - } return nil } @@ -85,8 +82,8 @@ func (gui *Gui) newLineFocused(v *gocui.View) error { switch v.Name() { case "menu": return gui.handleMenuSelect(gui.g, v) - case "status": - return gui.handleStatusSelect(gui.g, v) + case "project": + return gui.handleProjectSelect(gui.g, v) case "services": return gui.handleServiceSelect(gui.g, v) case "containers": @@ -236,6 +233,11 @@ func (gui *Gui) renderOptionsMap(optionsMap map[string]string) error { return gui.renderString(gui.g, "options", gui.optionsMapToString(optionsMap)) } +func (gui *Gui) getProjectView() *gocui.View { + v, _ := gui.g.View("project") + return v +} + func (gui *Gui) getServicesView() *gocui.View { v, _ := gui.g.View("services") return v @@ -261,11 +263,6 @@ func (gui *Gui) getMainView() *gocui.View { return v } -func (gui *Gui) getStatusView() *gocui.View { - v, _ := gui.g.View("status") - return v -} - func (gui *Gui) trimmedContent(v *gocui.View) string { return strings.TrimSpace(v.Buffer()) } diff --git a/pkg/i18n/dutch.go b/pkg/i18n/dutch.go index c416413e..1f858d9d 100644 --- a/pkg/i18n/dutch.go +++ b/pkg/i18n/dutch.go @@ -56,7 +56,7 @@ func dutchSet() TranslationSet { GlobalTitle: "Globaal", MainTitle: "Hooft", - StatusTitle: "Staat", + ProjectTitle: "Project", ServicesTitle: "Diensten", ContainersTitle: "Containers", StandaloneContainersTitle: "Alleenstaande Containers", diff --git a/pkg/i18n/english.go b/pkg/i18n/english.go index 5117c791..d8e660fc 100644 --- a/pkg/i18n/english.go +++ b/pkg/i18n/english.go @@ -5,7 +5,7 @@ type TranslationSet struct { AddFavourite string ErrorMessage string NotEnoughSpace string - StatusTitle string + ProjectTitle string MainTitle string GlobalTitle string Navigate string @@ -140,7 +140,7 @@ func englishSet() TranslationSet { GlobalTitle: "Global", MainTitle: "Main", - StatusTitle: "Status", + ProjectTitle: "Project", ServicesTitle: "Services", ContainersTitle: "Containers", StandaloneContainersTitle: "Standalone Containers", diff --git a/pkg/i18n/german.go b/pkg/i18n/german.go index eb9f605d..c8086a8a 100644 --- a/pkg/i18n/german.go +++ b/pkg/i18n/german.go @@ -56,7 +56,7 @@ func germanSet() TranslationSet { GlobalTitle: "Global", MainTitle: "Haupt", - StatusTitle: "Status", + ProjectTitle: "Projekt", ServicesTitle: "Dienste", ContainersTitle: "Container", StandaloneContainersTitle: "Alleinstehende Container", diff --git a/scripts/generate_cheatsheet.go b/scripts/generate_cheatsheet.go index 4062dcca..111f53ad 100644 --- a/scripts/generate_cheatsheet.go +++ b/scripts/generate_cheatsheet.go @@ -26,7 +26,7 @@ type bindingSection struct { func main() { langs := []string{"pl", "nl", "en"} - mConfig, err := config.NewAppConfig("lazydocker", "", "", "", "", true, nil) + mConfig, err := config.NewAppConfig("lazydocker", "", "", "", "", true, nil, "") if err != nil { panic(err) } @@ -76,7 +76,7 @@ func getBindingSections(mApp *app.App) []*bindingSection { titleMap := map[string]string{ "global": mApp.Tr.GlobalTitle, "main": mApp.Tr.MainTitle, - "status": mApp.Tr.StatusTitle, + "project": mApp.Tr.ProjectTitle, "services": mApp.Tr.ServicesTitle, "containers": mApp.Tr.ContainersTitle, "images": mApp.Tr.ImagesTitle,