diff --git a/pkg/commands/oscommands/os.go b/pkg/commands/oscommands/os.go index 1a486162f..5b9b4dd91 100644 --- a/pkg/commands/oscommands/os.go +++ b/pkg/commands/oscommands/os.go @@ -40,6 +40,7 @@ type OSCommand struct { Command func(string, ...string) *exec.Cmd BeforeExecuteCmd func(*exec.Cmd) Getenv func(string) string + onRunCommand func(string) } // NewOSCommand os command runner @@ -54,6 +55,10 @@ func NewOSCommand(log *logrus.Entry, config config.AppConfigurer) *OSCommand { } } +func (c *OSCommand) SetOnRunCommand(f func(string)) { + c.onRunCommand = f +} + // SetCommand sets the command function used by the struct. // To be used for testing only func (c *OSCommand) SetCommand(cmd func(string, ...string) *exec.Cmd) { @@ -70,6 +75,9 @@ type RunCommandOptions struct { func (c *OSCommand) RunCommandWithOutputWithOptions(command string, options RunCommandOptions) (string, error) { c.Log.WithField("command", command).Info("RunCommand") + if c.onRunCommand != nil { + c.onRunCommand(command) + } cmd := c.ExecutableFromString(command) cmd.Env = append(cmd.Env, "GIT_TERMINAL_PROMPT=0") // prevents git from prompting us for input which would freeze the program @@ -95,6 +103,9 @@ func (c *OSCommand) RunCommandWithOutput(formatString string, formatArgs ...inte command = fmt.Sprintf(formatString, formatArgs...) } c.Log.WithField("command", command).Info("RunCommand") + if c.onRunCommand != nil { + c.onRunCommand(command) + } cmd := c.ExecutableFromString(command) output, err := sanitisedCommandOutput(cmd.CombinedOutput()) if err != nil { diff --git a/pkg/gui/arrangement.go b/pkg/gui/arrangement.go index 125e089d2..b2a44f6eb 100644 --- a/pkg/gui/arrangement.go +++ b/pkg/gui/arrangement.go @@ -146,6 +146,8 @@ func (gui *Gui) getWindowDimensions(informationStr string, appStatus string) map mainPanelsDirection = boxlayout.COLUMN } + cmdLogSize := 10 + root := &boxlayout.Box{ Direction: boxlayout.ROW, Children: []*boxlayout.Box{ @@ -159,9 +161,19 @@ func (gui *Gui) getWindowDimensions(informationStr string, appStatus string) map ConditionalChildren: gui.sidePanelChildren, }, { - Direction: mainPanelsDirection, + Direction: boxlayout.ROW, Weight: mainSectionWeight, - Children: gui.mainSectionChildren(), + Children: []*boxlayout.Box{ + { + Direction: mainPanelsDirection, + Children: gui.mainSectionChildren(), + Weight: 1, + }, + { + Window: "cmdLog", + Size: cmdLogSize, + }, + }, }, }, }, diff --git a/pkg/gui/gui.go b/pkg/gui/gui.go index fc85ca9e4..5ba0064db 100644 --- a/pkg/gui/gui.go +++ b/pkg/gui/gui.go @@ -109,6 +109,9 @@ type Gui struct { // we typically want to pause some things that are running like background // file refreshes PauseBackgroundThreads bool + + // Log of the commands that get run, to be displayed to the user. + CmdLog []string } type listPanelState struct { @@ -250,6 +253,7 @@ type Views struct { SearchPrefix *gocui.View Limit *gocui.View Suggestions *gocui.View + CmdLog *gocui.View } type searchingState struct { @@ -459,12 +463,23 @@ func NewGui(log *logrus.Entry, gitCommand *commands.GitCommand, oSCommand *oscom showRecentRepos: showRecentRepos, RepoPathStack: []string{}, RepoStateMap: map[Repo]*guiState{}, + CmdLog: []string{}, } gui.resetState(filterPath, false) gui.watchFilesForChanges() + oSCommand.SetOnRunCommand(func(cmdStr string) { + gui.Log.Warn("HHMM") + gui.CmdLog = append(gui.CmdLog, cmdStr) + if gui.Views.CmdLog != nil { + fmt.Fprintln(gui.Views.CmdLog, cmdStr) + gui.Log.Warn("HHMM") + gui.Log.Warn(cmdStr) + } + }) + return gui, nil } diff --git a/pkg/gui/layout.go b/pkg/gui/layout.go index 10f350707..ae9b8ca31 100644 --- a/pkg/gui/layout.go +++ b/pkg/gui/layout.go @@ -48,6 +48,7 @@ func (gui *Gui) createAllViews() error { {viewPtr: &gui.Views.Suggestions, name: "suggestions"}, {viewPtr: &gui.Views.Confirmation, name: "confirmation"}, {viewPtr: &gui.Views.Limit, name: "limit"}, + {viewPtr: &gui.Views.CmdLog, name: "cmdLog"}, } var err error @@ -134,6 +135,10 @@ func (gui *Gui) createAllViews() error { gui.Views.Information.FgColor = gocui.ColorGreen gui.Views.Information.Frame = false + gui.Views.CmdLog.Title = gui.Tr.CommandLog + gui.Views.CmdLog.FgColor = theme.GocuiDefaultTextColor + gui.Views.CmdLog.Autoscroll = true + if _, err := gui.g.SetCurrentView(gui.defaultSideContext().GetViewName()); err != nil { return err } @@ -235,6 +240,7 @@ func (gui *Gui) layout(g *gocui.Gui) error { {viewName: "search", windowName: "search", frame: false}, {viewName: "appStatus", windowName: "appStatus", frame: false}, {viewName: "information", windowName: "information", frame: false}, + {viewName: "cmdLog", windowName: "cmdLog", frame: true}, } for _, arg := range args { @@ -344,6 +350,7 @@ func (gui *Gui) onInitialViewsCreation() error { gui.Views.CommitFiles, gui.Views.Main, gui.Views.Secondary, + gui.Views.CmdLog, // bottom line gui.Views.Options, diff --git a/pkg/i18n/english.go b/pkg/i18n/english.go index 8abd881c1..7507744b2 100644 --- a/pkg/i18n/english.go +++ b/pkg/i18n/english.go @@ -443,6 +443,7 @@ type TranslationSet struct { ErrCannotEditDirectory string ErrStageDirWithInlineMergeConflicts string ErrRepositoryMovedOrDeleted string + CommandLog string } const englishReleaseNotes = `lazygit 0.27.1-0.27.4 Release notes @@ -1094,5 +1095,6 @@ func englishTranslationSet() TranslationSet { ErrCannotEditDirectory: "Cannot edit directory: you can only edit individual files", ErrStageDirWithInlineMergeConflicts: "Cannot stage/unstage directory containing files with inline merge conflicts. Please fix up the merge conflicts first", ErrRepositoryMovedOrDeleted: "Cannot find repo. It might have been moved or deleted ¯\\_(ツ)_/¯", + CommandLog: "Command Log", } }