diff options
Diffstat (limited to 'pkg')
-rw-r--r-- | pkg/commands/oscommands/exec_live_default.go | 5 | ||||
-rw-r--r-- | pkg/commands/oscommands/os.go | 4 | ||||
-rw-r--r-- | pkg/gui/app_status_manager.go | 8 | ||||
-rw-r--r-- | pkg/gui/branches_panel.go | 8 | ||||
-rw-r--r-- | pkg/gui/commits_panel.go | 16 | ||||
-rw-r--r-- | pkg/gui/confirmation_panel.go | 4 | ||||
-rw-r--r-- | pkg/gui/context.go | 2 | ||||
-rw-r--r-- | pkg/gui/file_watching.go | 5 | ||||
-rw-r--r-- | pkg/gui/files_panel.go | 6 | ||||
-rw-r--r-- | pkg/gui/gui.go | 22 | ||||
-rw-r--r-- | pkg/gui/recording.go | 5 | ||||
-rw-r--r-- | pkg/gui/view_helpers.go | 10 | ||||
-rw-r--r-- | pkg/tasks/tasks.go | 29 | ||||
-rw-r--r-- | pkg/updates/updates.go | 8 | ||||
-rw-r--r-- | pkg/utils/utils.go | 16 |
15 files changed, 84 insertions, 64 deletions
diff --git a/pkg/commands/oscommands/exec_live_default.go b/pkg/commands/oscommands/exec_live_default.go index 2e09e38dd..6f51ecedc 100644 --- a/pkg/commands/oscommands/exec_live_default.go +++ b/pkg/commands/oscommands/exec_live_default.go @@ -9,6 +9,7 @@ import ( "unicode/utf8" "github.com/go-errors/errors" + "github.com/jesseduffield/lazygit/pkg/utils" "github.com/creack/pty" ) @@ -31,14 +32,14 @@ func RunCommandWithOutputLiveWrapper(c *OSCommand, command string, output func(s return err } - go func() { + go utils.Safe(func() { scanner := bufio.NewScanner(ptmx) scanner.Split(scanWordsWithNewLines) for scanner.Scan() { toOutput := strings.Trim(scanner.Text(), " ") _, _ = ptmx.WriteString(output(toOutput)) } - }() + }) err = cmd.Wait() ptmx.Close() diff --git a/pkg/commands/oscommands/os.go b/pkg/commands/oscommands/os.go index 3f5076dae..e16a821de 100644 --- a/pkg/commands/oscommands/os.go +++ b/pkg/commands/oscommands/os.go @@ -411,7 +411,7 @@ func (c *OSCommand) PipeCommands(commandStrings ...string) error { for _, cmd := range cmds { currentCmd := cmd - go func() { + go utils.Safe(func() { stderr, err := currentCmd.StderrPipe() if err != nil { c.Log.Error(err) @@ -432,7 +432,7 @@ func (c *OSCommand) PipeCommands(commandStrings ...string) error { } wg.Done() - }() + }) } wg.Wait() diff --git a/pkg/gui/app_status_manager.go b/pkg/gui/app_status_manager.go index 39f2940e2..a613f5adb 100644 --- a/pkg/gui/app_status_manager.go +++ b/pkg/gui/app_status_manager.go @@ -50,14 +50,14 @@ func (m *statusManager) getStatusString() string { // WithWaitingStatus wraps a function and shows a waiting status while the function is still executing func (gui *Gui) WithWaitingStatus(name string, f func() error) error { - go func() { + go utils.Safe(func() { gui.statusManager.addWaitingStatus(name) defer func() { gui.statusManager.removeStatus(name) }() - go func() { + go utils.Safe(func() { ticker := time.NewTicker(time.Millisecond * 50) defer ticker.Stop() for range ticker.C { @@ -67,14 +67,14 @@ func (gui *Gui) WithWaitingStatus(name string, f func() error) error { } gui.renderString("appStatus", appStatus) } - }() + }) if err := f(); err != nil { gui.g.Update(func(g *gocui.Gui) error { return gui.surfaceError(err) }) } - }() + }) return nil } diff --git a/pkg/gui/branches_panel.go b/pkg/gui/branches_panel.go index c8b63e0d5..bb53cbb4c 100644 --- a/pkg/gui/branches_panel.go +++ b/pkg/gui/branches_panel.go @@ -103,11 +103,11 @@ func (gui *Gui) handleGitFetch(g *gocui.Gui, v *gocui.View) error { if err := gui.createLoaderPanel(v, gui.Tr.FetchWait); err != nil { return err } - go func() { + go utils.Safe(func() { err := gui.fetch(true) gui.handleCredentialsPopup(err) _ = gui.refreshSidePanels(refreshOptions{mode: ASYNC}) - }() + }) return nil } @@ -385,7 +385,7 @@ func (gui *Gui) handleFastForward(g *gocui.Gui, v *gocui.View) error { "to": branch.Name, }, ) - go func() { + go utils.Safe(func() { _ = gui.createLoaderPanel(v, message) if gui.State.Panels.Branches.SelectedLineIdx == 0 { @@ -395,7 +395,7 @@ func (gui *Gui) handleFastForward(g *gocui.Gui, v *gocui.View) error { gui.handleCredentialsPopup(err) _ = gui.refreshSidePanels(refreshOptions{mode: ASYNC, scope: []int{BRANCHES}}) } - }() + }) return nil } diff --git a/pkg/gui/commits_panel.go b/pkg/gui/commits_panel.go index cc969c0c1..b5803a6a0 100644 --- a/pkg/gui/commits_panel.go +++ b/pkg/gui/commits_panel.go @@ -24,11 +24,11 @@ func (gui *Gui) handleCommitSelect() error { state := gui.State.Panels.Commits if state.SelectedLineIdx > 290 && state.LimitCommits { state.LimitCommits = false - go func() { + go utils.Safe(func() { if err := gui.refreshCommitsWithLimit(); err != nil { _ = gui.surfaceError(err) } - }() + }) } gui.escapeLineByLinePanel() @@ -60,11 +60,11 @@ func (gui *Gui) handleCommitSelect() error { func (gui *Gui) refreshReflogCommitsConsideringStartup() { switch gui.State.StartupStage { case INITIAL: - go func() { + go utils.Safe(func() { _ = gui.refreshReflogCommits() gui.refreshBranches() gui.State.StartupStage = COMPLETE - }() + }) case COMPLETE: _ = gui.refreshReflogCommits() @@ -78,14 +78,14 @@ func (gui *Gui) refreshCommits() error { wg := sync.WaitGroup{} wg.Add(2) - go func() { + go utils.Safe(func() { gui.refreshReflogCommitsConsideringStartup() gui.refreshBranches() wg.Done() - }() + }) - go func() { + go utils.Safe(func() { _ = gui.refreshCommitsWithLimit() context, ok := gui.Contexts.CommitFiles.Context.GetParentContext() if ok && context.GetKey() == BRANCH_COMMITS_CONTEXT_KEY { @@ -102,7 +102,7 @@ func (gui *Gui) refreshCommits() error { } } wg.Done() - }() + }) wg.Wait() diff --git a/pkg/gui/confirmation_panel.go b/pkg/gui/confirmation_panel.go index 135ac782f..ee1b1bab7 100644 --- a/pkg/gui/confirmation_panel.go +++ b/pkg/gui/confirmation_panel.go @@ -189,14 +189,14 @@ func (gui *Gui) createPopupPanel(opts createPopupPanelOpts) error { } confirmationView.Editable = opts.editable if opts.editable { - go func() { + go utils.Safe(func() { // TODO: remove this wait (right now if you remove it the EditGotoToEndOfLine method doesn't seem to work) time.Sleep(time.Millisecond) gui.g.Update(func(g *gocui.Gui) error { confirmationView.EditGotoToEndOfLine() return nil }) - }() + }) } gui.renderString("confirmation", opts.prompt) diff --git a/pkg/gui/context.go b/pkg/gui/context.go index 3119065a5..063de50f9 100644 --- a/pkg/gui/context.go +++ b/pkg/gui/context.go @@ -727,7 +727,7 @@ func (gui *Gui) mustContextForContextKey(contextKey string) Context { context, ok := gui.contextForContextKey(contextKey) if !ok { - panic(fmt.Sprintf("context now found for key %s", contextKey)) + panic(fmt.Sprintf("context not found for key %s", contextKey)) } return context diff --git a/pkg/gui/file_watching.go b/pkg/gui/file_watching.go index 09b994a14..41f1ff837 100644 --- a/pkg/gui/file_watching.go +++ b/pkg/gui/file_watching.go @@ -6,6 +6,7 @@ import ( "github.com/fsnotify/fsnotify" "github.com/jesseduffield/lazygit/pkg/commands/models" + "github.com/jesseduffield/lazygit/pkg/utils" "github.com/sirupsen/logrus" ) @@ -120,7 +121,7 @@ func (gui *Gui) watchFilesForChanges() { if gui.fileWatcher.Disabled { return } - go func() { + go utils.Safe(func() { for { select { // watch for events @@ -141,5 +142,5 @@ func (gui *Gui) watchFilesForChanges() { } } } - }() + }) } diff --git a/pkg/gui/files_panel.go b/pkg/gui/files_panel.go index a413beab5..67d1a6eee 100644 --- a/pkg/gui/files_panel.go +++ b/pkg/gui/files_panel.go @@ -511,7 +511,7 @@ func (gui *Gui) pullFiles(opts PullFilesOptions) error { mode := gui.Config.GetUserConfig().Git.Pull.Mode - go gui.pullWithMode(mode, opts) + go utils.Safe(func() { gui.pullWithMode(mode, opts) }) return nil } @@ -551,7 +551,7 @@ func (gui *Gui) pushWithForceFlag(v *gocui.View, force bool, upstream string, ar if err := gui.createLoaderPanel(v, gui.Tr.PushWait); err != nil { return err } - go func() { + go utils.Safe(func() { branchName := gui.getCheckedOutBranch().Name err := gui.GitCommand.Push(branchName, force, upstream, args, gui.promptUserForCredential) if err != nil && !force && strings.Contains(err.Error(), "Updates were rejected") { @@ -571,7 +571,7 @@ func (gui *Gui) pushWithForceFlag(v *gocui.View, force bool, upstream string, ar } gui.handleCredentialsPopup(err) _ = gui.refreshSidePanels(refreshOptions{mode: ASYNC}) - }() + }) return nil } diff --git a/pkg/gui/gui.go b/pkg/gui/gui.go index ce3546c74..9ce5df7c2 100644 --- a/pkg/gui/gui.go +++ b/pkg/gui/gui.go @@ -443,7 +443,7 @@ func (gui *Gui) Run() error { defer g.Close() if recordEvents { - go gui.recordEvents() + go utils.Safe(gui.recordEvents) } if gui.State.Modes.Filtering.Active() { @@ -481,10 +481,10 @@ func (gui *Gui) Run() error { gui.waitForIntro.Add(1) if gui.Config.GetUserConfig().Git.AutoFetch { - go gui.startBackgroundFetch() + go utils.Safe(gui.startBackgroundFetch) } - gui.goEvery(time.Second*10, gui.stopChan, gui.refreshFilesAndSubmodules) + gui.goEvery(time.Millisecond*50, gui.stopChan, gui.refreshFilesAndSubmodules) g.SetManager(gocui.ManagerFunc(gui.layout), gocui.ManagerFunc(gui.getFocusLayout())) @@ -499,7 +499,7 @@ func (gui *Gui) Run() error { // otherwise it handles the error, possibly by quitting the application func (gui *Gui) RunWithSubprocesses() error { gui.StartTime = time.Now() - go gui.replayRecordedEvents() + go utils.Safe(gui.replayRecordedEvents) for { gui.stopChan = make(chan struct{}) @@ -584,18 +584,18 @@ func (gui *Gui) showInitialPopups(tasks []func(chan struct{}) error) { gui.waitForIntro.Add(len(tasks)) done := make(chan struct{}) - go func() { + go utils.Safe(func() { for _, task := range tasks { - go func() { + go utils.Safe(func() { if err := task(done); err != nil { _ = gui.surfaceError(err) } - }() + }) <-done gui.waitForIntro.Done() } - }() + }) } func (gui *Gui) showIntroPopupMessage(done chan struct{}) error { @@ -614,7 +614,7 @@ func (gui *Gui) showIntroPopupMessage(done chan struct{}) error { } func (gui *Gui) goEvery(interval time.Duration, stop chan struct{}, function func() error) { - go func() { + go utils.Safe(func() { ticker := time.NewTicker(interval) defer ticker.Stop() for { @@ -625,7 +625,7 @@ func (gui *Gui) goEvery(interval time.Duration, stop chan struct{}, function fun return } } - }() + }) } func (gui *Gui) startBackgroundFetch() { @@ -641,7 +641,7 @@ func (gui *Gui) startBackgroundFetch() { prompt: gui.Tr.NoAutomaticGitFetchBody, }) } else { - gui.goEvery(time.Second*60, gui.stopChan, func() error { + gui.goEvery(time.Millisecond*50, gui.stopChan, func() error { err := gui.fetch(false) return err }) diff --git a/pkg/gui/recording.go b/pkg/gui/recording.go index 0f8f9a370..936413799 100644 --- a/pkg/gui/recording.go +++ b/pkg/gui/recording.go @@ -9,6 +9,7 @@ import ( "time" "github.com/jesseduffield/gocui" + "github.com/jesseduffield/lazygit/pkg/utils" ) func recordingEvents() bool { @@ -28,10 +29,10 @@ func (gui *Gui) replayRecordedEvents() { return } - go func() { + go utils.Safe(func() { time.Sleep(time.Second * 20) log.Fatal("20 seconds is up, lazygit recording took too long to complete") - }() + }) events, err := gui.loadRecordedEvents() if err != nil { diff --git a/pkg/gui/view_helpers.go b/pkg/gui/view_helpers.go index 06de4179b..64faa5940 100644 --- a/pkg/gui/view_helpers.go +++ b/pkg/gui/view_helpers.go @@ -110,7 +110,7 @@ func (gui *Gui) refreshSidePanels(options refreshOptions) error { wg.Add(1) func() { if options.mode == ASYNC { - go gui.refreshCommits() + go utils.Safe(func() { gui.refreshCommits() }) } else { gui.refreshCommits() } @@ -122,7 +122,7 @@ func (gui *Gui) refreshSidePanels(options refreshOptions) error { wg.Add(1) func() { if options.mode == ASYNC { - go gui.refreshFilesAndSubmodules() + go utils.Safe(func() { gui.refreshFilesAndSubmodules() }) } else { gui.refreshFilesAndSubmodules() } @@ -134,7 +134,7 @@ func (gui *Gui) refreshSidePanels(options refreshOptions) error { wg.Add(1) func() { if options.mode == ASYNC { - go gui.refreshStashEntries() + go utils.Safe(func() { gui.refreshStashEntries() }) } else { gui.refreshStashEntries() } @@ -146,7 +146,7 @@ func (gui *Gui) refreshSidePanels(options refreshOptions) error { wg.Add(1) func() { if options.mode == ASYNC { - go gui.refreshTags() + go utils.Safe(func() { gui.refreshTags() }) } else { gui.refreshTags() } @@ -158,7 +158,7 @@ func (gui *Gui) refreshSidePanels(options refreshOptions) error { wg.Add(1) func() { if options.mode == ASYNC { - go gui.refreshRemotes() + go utils.Safe(func() { gui.refreshRemotes() }) } else { gui.refreshRemotes() } diff --git a/pkg/tasks/tasks.go b/pkg/tasks/tasks.go index f6e3432f2..5854b4f46 100644 --- a/pkg/tasks/tasks.go +++ b/pkg/tasks/tasks.go @@ -10,6 +10,7 @@ import ( "time" "github.com/jesseduffield/lazygit/pkg/commands/oscommands" + "github.com/jesseduffield/lazygit/pkg/utils" "github.com/sirupsen/logrus" ) @@ -41,14 +42,14 @@ func NewViewBufferManager(log *logrus.Entry, writer io.Writer, beforeStart func( } func (m *ViewBufferManager) ReadLines(n int) { - go func() { + go utils.Safe(func() { m.readLines <- n - }() + }) } func (m *ViewBufferManager) NewCmdTask(r io.Reader, cmd *exec.Cmd, prefix string, linesToRead int, onDone func()) func(chan struct{}) error { return func(stop chan struct{}) error { - go func() { + go utils.Safe(func() { <-stop if err := oscommands.Kill(cmd); err != nil { if !strings.Contains(err.Error(), "process already finished") { @@ -58,7 +59,7 @@ func (m *ViewBufferManager) NewCmdTask(r io.Reader, cmd *exec.Cmd, prefix string if onDone != nil { onDone() } - }() + }) loadingMutex := sync.Mutex{} @@ -67,13 +68,13 @@ func (m *ViewBufferManager) NewCmdTask(r io.Reader, cmd *exec.Cmd, prefix string done := make(chan struct{}) - go func() { + go utils.Safe(func() { scanner := bufio.NewScanner(r) scanner.Split(bufio.ScanLines) loaded := false - go func() { + go utils.Safe(func() { ticker := time.NewTicker(time.Millisecond * 100) defer ticker.Stop() select { @@ -88,7 +89,7 @@ func (m *ViewBufferManager) NewCmdTask(r io.Reader, cmd *exec.Cmd, prefix string case <-stop: return } - }() + }) outer: for { @@ -139,7 +140,7 @@ func (m *ViewBufferManager) NewCmdTask(r io.Reader, cmd *exec.Cmd, prefix string } close(done) - }() + }) m.readLines <- linesToRead @@ -157,10 +158,10 @@ func (t *ViewBufferManager) Close() { c := make(chan struct{}) - go func() { + go utils.Safe(func() { t.currentTask.Stop() c <- struct{}{} - }() + }) select { case <-c: @@ -175,7 +176,7 @@ func (t *ViewBufferManager) Close() { // 2) string based, where the manager can also be asked to read more lines func (m *ViewBufferManager) NewTask(f func(stop chan struct{}) error) error { - go func() { + go utils.Safe(func() { m.taskIDMutex.Lock() m.newTaskId++ taskID := m.newTaskId @@ -202,14 +203,14 @@ func (m *ViewBufferManager) NewTask(f func(stop chan struct{}) error) error { f: f, } - go func() { + go utils.Safe(func() { if err := f(stop); err != nil { m.Log.Error(err) // might need an onError callback } close(notifyStopped) - }() - }() + }) + }) return nil } diff --git a/pkg/updates/updates.go b/pkg/updates/updates.go index 163773e58..ba7df37ac 100644 --- a/pkg/updates/updates.go +++ b/pkg/updates/updates.go @@ -145,12 +145,12 @@ func (u *Updater) CheckForNewUpdate(onFinish func(string, error) error, userRequ return } - go func() { + go utils.Safe(func() { newVersion, err := u.checkForNewUpdate() if err = onFinish(newVersion, err); err != nil { u.Log.Error(err) } - }() + }) } func (u *Updater) skipUpdateCheck() bool { @@ -235,12 +235,12 @@ func (u *Updater) getBinaryUrl(newVersion string) (string, error) { // Update downloads the latest binary and replaces the current binary with it func (u *Updater) Update(newVersion string, onFinish func(error) error) { - go func() { + go utils.Safe(func() { err := u.update(newVersion) if err = onFinish(err); err != nil { u.Log.Error(err) } - }() + }) } func (u *Updater) update(newVersion string) error { diff --git a/pkg/utils/utils.go b/pkg/utils/utils.go index c4d1dbe7e..4e179473f 100644 --- a/pkg/utils/utils.go +++ b/pkg/utils/utils.go @@ -14,6 +14,7 @@ import ( "time" "github.com/fatih/color" + "github.com/jesseduffield/termbox-go" ) // SplitLines takes a multiline string and splits it on newlines @@ -360,3 +361,18 @@ func ResolveTemplate(templateStr string, object interface{}) (string, error) { return buf.String(), nil } + +// Safe will close termbox if a panic occurs so that we don't end up in a malformed +// terminal state +func Safe(f func()) { + panicking := true + defer func() { + if panicking { + termbox.Close() + } + }() + + f() + + panicking = false +} |