diff options
author | Jesse Duffield <jessedduffield@gmail.com> | 2020-08-18 22:02:35 +1000 |
---|---|---|
committer | Jesse Duffield <jessedduffield@gmail.com> | 2020-08-23 14:29:18 +1000 |
commit | f5b22d94d939b0fc1aff433686e891e0a7507950 (patch) | |
tree | 9812c4c7f3855d7e3fe973dacf5533ef04463c3d /pkg | |
parent | 3c87ff4eff46449d5e697e954b3bdf01d2c76f19 (diff) |
WIP
Diffstat (limited to 'pkg')
-rw-r--r-- | pkg/gui/branches_panel.go | 22 | ||||
-rw-r--r-- | pkg/gui/commit_files_panel.go | 18 | ||||
-rw-r--r-- | pkg/gui/commits_panel.go | 38 | ||||
-rw-r--r-- | pkg/gui/diffing.go | 23 | ||||
-rw-r--r-- | pkg/gui/files_panel.go | 46 | ||||
-rw-r--r-- | pkg/gui/main_panels.go | 111 | ||||
-rw-r--r-- | pkg/gui/merge_panel.go | 15 | ||||
-rw-r--r-- | pkg/gui/patch_building_panel.go | 18 | ||||
-rw-r--r-- | pkg/gui/reflog_panel.go | 18 | ||||
-rw-r--r-- | pkg/gui/remote_branches_panel.go | 30 | ||||
-rw-r--r-- | pkg/gui/remotes_panel.go | 21 | ||||
-rw-r--r-- | pkg/gui/stash_panel.go | 8 | ||||
-rw-r--r-- | pkg/gui/status_panel.go | 11 | ||||
-rw-r--r-- | pkg/gui/tags_panel.go | 30 |
14 files changed, 258 insertions, 151 deletions
diff --git a/pkg/gui/branches_panel.go b/pkg/gui/branches_panel.go index b856b4007..926c589f0 100644 --- a/pkg/gui/branches_panel.go +++ b/pkg/gui/branches_panel.go @@ -34,28 +34,24 @@ func (gui *Gui) handleBranchSelect() error { return gui.renderDiff() } - refreshOpts := refreshMainOpts{ - main: &viewUpdateOpts{ - title: "Log", - task: { - kind: RENDER_STRING, - str: gui.Tr.SLocalize("NoBranchesThisRepo"), - }, - }, - } - + var task updateTask branch := gui.getSelectedBranch() if branch == nil { - refreshOpts.main.task = func() error { return gui.newStringTask("main", gui.Tr.SLocalize("NoBranchesThisRepo")) } + task = gui.createRenderStringTask(gui.Tr.SLocalize("NoBranchesThisRepo")) } else { cmd := gui.OSCommand.ExecutableFromString( gui.GitCommand.GetBranchGraphCmdStr(branch.Name), ) - refreshOpts.main.task = func() error { return gui.newPtyTask("main", cmd) } + task = gui.createRunPtyTask(cmd) } - return gui.refreshMain(refreshOpts) + return gui.refreshMain(refreshMainOpts{ + main: &viewUpdateOpts{ + title: "Log", + task: task, + }, + }) } // gui.refreshStatus is called at the end of this because that's when we can diff --git a/pkg/gui/commit_files_panel.go b/pkg/gui/commit_files_panel.go index 57757445d..6d2981456 100644 --- a/pkg/gui/commit_files_panel.go +++ b/pkg/gui/commit_files_panel.go @@ -21,29 +21,29 @@ func (gui *Gui) handleCommitFileSelect() error { return nil } - gui.getMainView().Title = "Patch" if gui.currentViewName() == "commitFiles" { gui.handleEscapeLineByLinePanel() } commitFile := gui.getSelectedCommitFile() if commitFile == nil { + // TODO: consider making it so that we can also render strings to our own view through some common interface, or just render this to the main view for consistency gui.renderString("commitFiles", gui.Tr.SLocalize("NoCommiteFiles")) return nil } - if err := gui.refreshSecondaryPatchPanel(); err != nil { - return err - } - cmd := gui.OSCommand.ExecutableFromString( gui.GitCommand.ShowCommitFileCmdStr(commitFile.Sha, commitFile.Name, false), ) - if err := gui.newPtyTask("main", cmd); err != nil { - gui.Log.Error(err) - } + task := gui.createRunPtyTask(cmd) - return nil + return gui.refreshMain(refreshMainOpts{ + main: &viewUpdateOpts{ + title: "Patch", + task: task, + }, + secondary: gui.secondaryPatchPanelUpdateOpts(), + }) } func (gui *Gui) handleSwitchToCommitsPanel(g *gocui.Gui, v *gocui.View) error { diff --git a/pkg/gui/commits_panel.go b/pkg/gui/commits_panel.go index ed27a8495..7f2df104b 100644 --- a/pkg/gui/commits_panel.go +++ b/pkg/gui/commits_panel.go @@ -26,9 +26,8 @@ func (gui *Gui) handleCommitSelect() error { return nil } - // this probably belongs in an 'onFocus' function than a 'commit selected' function - if err := gui.refreshSecondaryPatchPanel(); err != nil { - return err + if gui.inDiffMode() { + return gui.renderDiff() } state := gui.State.Panels.Commits @@ -41,27 +40,26 @@ func (gui *Gui) handleCommitSelect() error { }() } - gui.getMainView().Title = "Patch" - gui.getSecondaryView().Title = "Custom Patch" gui.handleEscapeLineByLinePanel() + var task updateTask commit := gui.getSelectedCommit() if commit == nil { - return gui.newStringTask("main", gui.Tr.SLocalize("NoCommitsThisBranch")) - } - - if gui.inDiffMode() { - return gui.renderDiff() - } - - cmd := gui.OSCommand.ExecutableFromString( - gui.GitCommand.ShowCmdStr(commit.Sha, gui.State.FilterPath), - ) - if err := gui.newPtyTask("main", cmd); err != nil { - gui.Log.Error(err) - } - - return nil + task = gui.createRenderStringTask(gui.Tr.SLocalize("NoCommitsThisBranch")) + } else { + cmd := gui.OSCommand.ExecutableFromString( + gui.GitCommand.ShowCmdStr(commit.Sha, gui.State.FilterPath), + ) + task = gui.createRunPtyTask(cmd) + } + + return gui.refreshMain(refreshMainOpts{ + main: &viewUpdateOpts{ + title: "Patch", + task: task, + }, + secondary: gui.secondaryPatchPanelUpdateOpts(), + }) } // during startup, the bottleneck is fetching the reflog entries. We need these diff --git a/pkg/gui/diffing.go b/pkg/gui/diffing.go index 4e88f2e8b..789552659 100644 --- a/pkg/gui/diffing.go +++ b/pkg/gui/diffing.go @@ -18,20 +18,21 @@ func (gui *Gui) exitDiffMode() error { } func (gui *Gui) renderDiff() error { + filterArg := "" + + if gui.inFilterMode() { + filterArg = fmt.Sprintf(" -- %s", gui.State.FilterPath) + } + + cmd := gui.OSCommand.ExecutableFromString( + fmt.Sprintf("git diff --color %s %s", gui.diffStr(), filterArg), + ) + task := gui.createRunPtyTask(cmd) + return gui.refreshMain(refreshMainOpts{ main: &viewUpdateOpts{ title: "Diff", - task: func() error { - filterArg := "" - if gui.inFilterMode() { - filterArg = fmt.Sprintf(" -- %s", gui.State.FilterPath) - } - - cmd := gui.OSCommand.ExecutableFromString( - fmt.Sprintf("git diff --color %s %s", gui.diffStr(), filterArg), - ) - return gui.newPtyTask("main", cmd) - }, + task: task, }, }) } diff --git a/pkg/gui/files_panel.go b/pkg/gui/files_panel.go index 45eee06e4..b9f69c161 100644 --- a/pkg/gui/files_panel.go +++ b/pkg/gui/files_panel.go @@ -37,12 +37,16 @@ func (gui *Gui) selectFile(alreadySelected bool) error { file := gui.getSelectedFile() if file == nil { - gui.splitMainPanel(false) - gui.getMainView().Title = "" - return gui.newStringTask("main", gui.Tr.SLocalize("NoChangedFiles")) + return gui.refreshMain(refreshMainOpts{ + main: &viewUpdateOpts{ + title: "", + task: gui.createRenderStringTask(gui.Tr.SLocalize("NoChangedFiles")), + }, + }) } if !alreadySelected { + // TODO: pull into update task interface if err := gui.resetOrigin(gui.getMainView()); err != nil { return err } @@ -52,36 +56,30 @@ func (gui *Gui) selectFile(alreadySelected bool) error { } if file.HasInlineMergeConflicts { - gui.getMainView().Title = gui.Tr.SLocalize("MergeConflictsTitle") - gui.splitMainPanel(false) return gui.refreshMergePanel() } + cmdStr := gui.GitCommand.DiffCmdStr(file, false, !file.HasUnstagedChanges && file.HasStagedChanges) + cmd := gui.OSCommand.ExecutableFromString(cmdStr) + + refreshOpts := refreshMainOpts{main: &viewUpdateOpts{ + title: gui.Tr.SLocalize("UnstagedChanges"), + task: gui.createRunPtyTask(cmd), + }} + if file.HasStagedChanges && file.HasUnstagedChanges { - gui.splitMainPanel(true) - gui.getMainView().Title = gui.Tr.SLocalize("UnstagedChanges") - gui.getSecondaryView().Title = gui.Tr.SLocalize("StagedChanges") cmdStr := gui.GitCommand.DiffCmdStr(file, false, true) cmd := gui.OSCommand.ExecutableFromString(cmdStr) - if err := gui.newPtyTask("secondary", cmd); err != nil { - return err - } - } else { - gui.splitMainPanel(false) - if file.HasUnstagedChanges { - gui.getMainView().Title = gui.Tr.SLocalize("UnstagedChanges") - } else { - gui.getMainView().Title = gui.Tr.SLocalize("StagedChanges") - } - } - cmdStr := gui.GitCommand.DiffCmdStr(file, false, !file.HasUnstagedChanges && file.HasStagedChanges) - cmd := gui.OSCommand.ExecutableFromString(cmdStr) - if err := gui.newPtyTask("main", cmd); err != nil { - return err + refreshOpts.secondary = &viewUpdateOpts{ + title: gui.Tr.SLocalize("StagedChanges"), + task: gui.createRunPtyTask(cmd), + } + } else if !file.HasUnstagedChanges { + refreshOpts.main.title = gui.Tr.SLocalize("StagedChanges") } - return nil + return gui.refreshMain(refreshOpts) } func (gui *Gui) refreshFiles() error { diff --git a/pkg/gui/main_panels.go b/pkg/gui/main_panels.go index af6718c60..87072406a 100644 --- a/pkg/gui/main_panels.go +++ b/pkg/gui/main_panels.go @@ -4,7 +4,14 @@ import "os/exec" type viewUpdateOpts struct { title string - task func() error + + // awkwardly calling this noWrap because of how hard Go makes it to have + // a boolean option that defaults to true + noWrap bool + + highlight bool + + task updateTask } type refreshMainOpts struct { @@ -15,19 +22,100 @@ type refreshMainOpts struct { // constants for updateTask's kind field const ( RENDER_STRING = iota + RENDER_STRING_WITHOUT_SCROLL RUN_FUNCTION RUN_COMMAND + RUN_PTY ) -type updateTask struct { - kind int - str string - f func(chan struct{}) error - cmd *exec.Cmd +type updateTask interface { + GetKind() int +} + +type renderStringTask struct { + str string +} + +func (t *renderStringTask) GetKind() int { + return RENDER_STRING +} + +func (gui *Gui) createRenderStringTask(str string) *renderStringTask { + return &renderStringTask{str: str} +} + +type renderStringWithoutScrollTask struct { + str string +} + +func (t *renderStringWithoutScrollTask) GetKind() int { + return RENDER_STRING_WITHOUT_SCROLL +} + +func (gui *Gui) createRenderStringWithoutScrollTask(str string) *renderStringWithoutScrollTask { + return &renderStringWithoutScrollTask{str: str} +} + +type runCommandTask struct { + cmd *exec.Cmd +} + +func (t *runCommandTask) GetKind() int { + return RUN_COMMAND +} + +func (gui *Gui) createRunCommandTask(cmd *exec.Cmd) *runCommandTask { + return &runCommandTask{cmd: cmd} +} + +type runPtyTask struct { + cmd *exec.Cmd +} + +func (t *runPtyTask) GetKind() int { + return RUN_PTY +} + +func (gui *Gui) createRunPtyTask(cmd *exec.Cmd) *runPtyTask { + return &runPtyTask{cmd: cmd} +} + +type runFunctionTask struct { + f func(chan struct{}) error +} + +func (t *runFunctionTask) GetKind() int { + return RUN_FUNCTION +} + +func (gui *Gui) createRunFunctionTask(f func(chan struct{}) error) *runFunctionTask { + return &runFunctionTask{f: f} } -func (gui *Gui) createRenderStringTask(str string) { +func (gui *Gui) runTaskForView(viewName string, task updateTask) error { + switch task.GetKind() { + case RENDER_STRING: + specificTask := task.(*renderStringTask) + return gui.newStringTask(viewName, specificTask.str) + + case RENDER_STRING_WITHOUT_SCROLL: + specificTask := task.(*renderStringWithoutScrollTask) + return gui.newStringTaskWithoutScroll(viewName, specificTask.str) + + case RUN_FUNCTION: + specificTask := task.(*runFunctionTask) + return gui.newTask(viewName, specificTask.f) + case RUN_COMMAND: + specificTask := task.(*runCommandTask) + return gui.newCmdTask(viewName, specificTask.cmd) + + case RUN_PTY: + specificTask := task.(*runPtyTask) + return gui.newPtyTask(viewName, specificTask.cmd) + } + + return nil } func (gui *Gui) refreshMain(opts refreshMainOpts) error { @@ -36,7 +124,10 @@ func (gui *Gui) refreshMain(opts refreshMainOpts) error { if opts.main != nil { mainView.Title = opts.main.title - if err := opts.main.task(); err != nil { + mainView.Wrap = !opts.main.noWrap + mainView.Highlight = opts.main.highlight // TODO: see what the default should be + + if err := gui.runTaskForView("main", opts.main.task); err != nil { gui.Log.Error(err) return nil } @@ -46,7 +137,9 @@ func (gui *Gui) refreshMain(opts refreshMainOpts) error { if opts.secondary != nil { secondaryView.Title = opts.secondary.title - if err := opts.secondary.task(); err != nil { + secondaryView.Wrap = !opts.secondary.noWrap + mainView.Highlight = opts.main.highlight // TODO: see what the default should be + if err := gui.runTaskForView("secondary", opts.secondary.task); err != nil { gui.Log.Error(err) return nil } diff --git a/pkg/gui/merge_panel.go b/pkg/gui/merge_panel.go index 1097c3d62..56e2535ba 100644 --- a/pkg/gui/merge_panel.go +++ b/pkg/gui/merge_panel.go @@ -238,14 +238,13 @@ func (gui *Gui) refreshMergePanel() error { return err } - mainView := gui.getMainView() - mainView.Wrap = false - - if err := gui.newStringTaskWithoutScroll("main", content); err != nil { - return err - } - - return nil + return gui.refreshMain(refreshMainOpts{ + main: &viewUpdateOpts{ + title: gui.Tr.SLocalize("MergeConflictsTitle"), + task: gui.createRenderStringWithoutScrollTask(content), + noWrap: true, + }, + }) } func (gui *Gui) catSelectedFile(g *gocui.Gui) (string, error) { diff --git a/pkg/gui/patch_building_panel.go b/pkg/gui/patch_building_panel.go index 67caba0ae..a2b872f36 100644 --- a/pkg/gui/patch_building_panel.go +++ b/pkg/gui/patch_building_panel.go @@ -80,13 +80,14 @@ func (gui *Gui) handleEscapePatchBuildingPanel() error { if gui.GitCommand.PatchManager.IsEmpty() { gui.GitCommand.PatchManager.Reset() - gui.splitMainPanel(false) } return gui.switchContext(gui.Contexts.BranchCommits.Files.Context) } func (gui *Gui) refreshSecondaryPatchPanel() error { + // TODO: swap out for secondaryPatchPanelUpdateOpts + if gui.GitCommand.PatchManager.CommitSelected() { gui.splitMainPanel(true) secondaryView := gui.getSecondaryView() @@ -103,3 +104,18 @@ func (gui *Gui) refreshSecondaryPatchPanel() error { return nil } + +func (gui *Gui) secondaryPatchPanelUpdateOpts() *viewUpdateOpts { + if gui.GitCommand.PatchManager.CommitSelected() { + patch := gui.GitCommand.PatchManager.RenderAggregatedPatchColored(false) + + return &viewUpdateOpts{ + title: "Custom Patch", + noWrap: true, + highlight: true, + task: gui.createRenderStringWithoutScrollTask(patch), + } + } + + return nil +} diff --git a/pkg/gui/reflog_panel.go b/pkg/gui/reflog_panel.go index c1cc118de..1fc7abbd0 100644 --- a/pkg/gui/reflog_panel.go +++ b/pkg/gui/reflog_panel.go @@ -23,24 +23,24 @@ func (gui *Gui) handleReflogCommitSelect() error { return gui.renderDiff() } - refreshOpts := refreshMainOpts{ - main: &viewUpdateOpts{ - title: "Reflog Entry", - }, - } - commit := gui.getSelectedReflogCommit() + var task updateTask if commit == nil { - refreshOpts.main.task = func() error { return gui.newStringTask("main", "No reflog history") } + task = gui.createRenderStringTask("No reflog history") } else { cmd := gui.OSCommand.ExecutableFromString( gui.GitCommand.ShowCmdStr(commit.Sha, gui.State.FilterPath), ) - refreshOpts.main.task = func() error { return gui.newPtyTask("main", cmd) } + task = gui.createRunPtyTask(cmd) } - return gui.refreshMain(refreshOpts) + return gui.refreshMain(refreshMainOpts{ + main: &viewUpdateOpts{ + title: "Reflog Entry", + task: task, + }, + }) } // the reflogs panel is the only panel where we cache data, in that we only diff --git a/pkg/gui/remote_branches_panel.go b/pkg/gui/remote_branches_panel.go index 29531c33f..01f801de1 100644 --- a/pkg/gui/remote_branches_panel.go +++ b/pkg/gui/remote_branches_panel.go @@ -24,27 +24,27 @@ func (gui *Gui) handleRemoteBranchSelect() error { return nil } - gui.splitMainPanel(false) - - gui.getMainView().Title = "Remote Branch" - - remoteBranch := gui.getSelectedRemoteBranch() - if remoteBranch == nil { - return gui.newStringTask("main", "No branches for this remote") - } - if gui.inDiffMode() { return gui.renderDiff() } - cmd := gui.OSCommand.ExecutableFromString( - gui.GitCommand.GetBranchGraphCmdStr(remoteBranch.FullName()), - ) - if err := gui.newCmdTask("main", cmd); err != nil { - gui.Log.Error(err) + var task updateTask + remoteBranch := gui.getSelectedRemoteBranch() + if remoteBranch == nil { + task = gui.createRenderStringTask("No branches for this remote") + } else { + cmd := gui.OSCommand.ExecutableFromString( + gui.GitCommand.GetBranchGraphCmdStr(remoteBranch.FullName()), + ) + task = gui.createRunCommandTask(cmd) } - return nil + return gui.refreshMain(refreshMainOpts{ + main: &viewUpdateOpts{ + title: "Remote Branch", + task: task, + }, + }) } func (gui *Gui) handleRemoteBranchesEscape(g *gocui.Gui, v *gocui.View) error { diff --git a/pkg/gui/remotes_panel.go b/pkg/gui/remotes_panel.go index 8692cdd6b..68f868a1b 100644 --- a/pkg/gui/remotes_panel.go +++ b/pkg/gui/remotes_panel.go @@ -27,19 +27,24 @@ func (gui *Gui) handleRemoteSelect() error { return nil } - gui.splitMainPanel(false) - - gui.getMainView().Title = "Remote" + if gui.inDiffMode() { + return gui.renderDiff() + } + var task updateTask remote := gui.getSelectedRemote() if remote == nil { - return gui.newStringTask("main", "No remotes") - } - if gui.inDiffMode() { - return gui.renderDiff() + task = gui.createRenderStringTask("No remotes") + } else { + task = gui.createRenderStringTask(fmt.Sprintf("%s\nUrls:\n%s", utils.ColoredString(remote.Name, color.FgGreen), strings.Join(remote.Urls, "\n"))) } - return gui.newStringTask("main", fmt.Sprintf("%s\nUrls:\n%s", utils.ColoredString(remote.Name, color.FgGreen), strings.Join(remote.Urls, "\n"))) + return gui.refreshMain(refreshMainOpts{ + main: &viewUpdateOpts{ + title: "Remote", + task: task, + }, + }) } func (gui *Gui) refreshRemotes() error { diff --git a/pkg/gui/stash_panel.go b/pkg/gui/stash_panel.go index ec2c4ba8e..04a82e463 100644 --- a/pkg/gui/stash_panel.go +++ b/pkg/gui/stash_panel.go @@ -22,6 +22,10 @@ func (gui *Gui) handleStashEntrySelect() error { return nil } + if gui.inDiffMode() { + return gui.renderDiff() + } + gui.splitMainPanel(false) gui.getMainView().Title = "Stash" @@ -31,10 +35,6 @@ func (gui *Gui) handleStashEntrySelect() error { return gui.newStringTask("main", gui.Tr.SLocalize("NoStashEntries")) } - if gui.inDiffMode() { - return gui.renderDiff() - } - cmd := gui.OSCommand.ExecutableFromString( gui.GitCommand.ShowStashEntryCmdStr(stashEntry.Index), ) diff --git a/pkg/gui/status_panel.go b/pkg/gui/status_panel.go index e01d8d41b..0a33b84ff 100644 --- a/pkg/gui/status_panel.go +++ b/pkg/gui/status_panel.go @@ -93,10 +93,6 @@ func (gui *Gui) handleStatusSelect() error { return nil } - gui.splitMainPanel(false) - - gui.getMainView().Title = "" - if gui.inDiffMode() { return gui.renderDiff() } @@ -114,7 +110,12 @@ func (gui *Gui) handleStatusSelect() error { magenta.Sprint("Become a sponsor (github is matching all donations for 12 months): https://github.com/sponsors/jesseduffield"), // caffeine ain't free }, "\n\n") - return gui.newStringTask("main", dashboardString) + return gui.refreshMain(refreshMainOpts{ + main: &viewUpdateOpts{ + title: "", + task: gui.createRenderStringTask(dashboardString), + }, + }) } func (gui *Gui) handleOpenConfig(g *gocui.Gui, v *gocui.View) error { diff --git a/pkg/gui/tags_panel.go b/pkg/gui/tags_panel.go index cd50e34eb..ce696a06c 100644 --- a/pkg/gui/tags_panel.go +++ b/pkg/gui/tags_panel.go @@ -22,27 +22,27 @@ func (gui *Gui) handleTagSelect() error { return nil } - gui.splitMainPanel(false) - - gui.getMainView().Title = "Tag" - - tag := gui.getSelectedTag() - if tag == nil { - return gui.newStringTask("main", "No tags") - } - if gui.inDiffMode() { return gui.renderDiff() } - cmd := gui.OSCommand.ExecutableFromString( - gui.GitCommand.GetBranchGraphCmdStr(tag.Name), - ) - if err := gui.newCmdTask("main", cmd); err != nil { - gui.Log.Error(err) + var task updateTask + tag := gui.getSelectedTag() + if tag == nil { + task = gui.createRenderStringTask("No tags") + } else { + cmd := gui.OSCommand.ExecutableFromString( + gui.GitCommand.GetBranchGraphCmdStr(tag.Name), + ) + task = gui.createRunCommandTask(cmd) } - return nil + return gui.refreshMain(refreshMainOpts{ + main: &viewUpdateOpts{ + title: "Tag", + task: task, + }, + }) } func (gui *Gui) refreshTags() error { |