diff options
author | Jesse Duffield <jessedduffield@gmail.com> | 2019-11-18 09:38:36 +1100 |
---|---|---|
committer | Jesse Duffield <jessedduffield@gmail.com> | 2019-11-21 22:07:14 +1100 |
commit | 3c1322914518168374be02a78cee968cf1d13730 (patch) | |
tree | d31c1064a1101a6081db025328f39789fc3b74c4 /pkg/gui | |
parent | cea24c2cf98c48e187900041d9e3bbeb93596019 (diff) |
add tags panel
Diffstat (limited to 'pkg/gui')
-rw-r--r-- | pkg/gui/branches_panel.go | 9 | ||||
-rw-r--r-- | pkg/gui/commits_panel.go | 27 | ||||
-rw-r--r-- | pkg/gui/gui.go | 9 | ||||
-rw-r--r-- | pkg/gui/keybindings.go | 39 | ||||
-rw-r--r-- | pkg/gui/list_view.go | 10 | ||||
-rw-r--r-- | pkg/gui/remotes_panel.go | 8 | ||||
-rw-r--r-- | pkg/gui/tags_panel.go | 149 | ||||
-rw-r--r-- | pkg/gui/view_helpers.go | 2 |
8 files changed, 249 insertions, 4 deletions
diff --git a/pkg/gui/branches_panel.go b/pkg/gui/branches_panel.go index 790f24bd4..f78d86ab8 100644 --- a/pkg/gui/branches_panel.go +++ b/pkg/gui/branches_panel.go @@ -80,6 +80,10 @@ func (gui *Gui) refreshBranches(g *gocui.Gui) error { return err } + if err := gui.refreshTags(); err != nil { + return err + } + g.Update(func(g *gocui.Gui) error { builder, err := commands.NewBranchListBuilder(gui.Log, gui.GitCommand) if err != nil { @@ -373,7 +377,7 @@ func (gui *Gui) handleFastForward(g *gocui.Gui, v *gocui.View) error { } func (gui *Gui) onBranchesTabClick(tabIndex int) error { - contexts := []string{"local-branches", "remotes", "tabs"} + contexts := []string{"local-branches", "remotes", "tags"} branchesView := gui.getBranchesView() branchesView.TabIndex = tabIndex @@ -388,6 +392,7 @@ func (gui *Gui) switchBranchesPanelContext(context string) error { "local-branches": 0, "remotes": 1, "remote-branches": 1, + "tags": 2, } branchesView.TabIndex = contextTabIndexMap[context] @@ -399,6 +404,8 @@ func (gui *Gui) switchBranchesPanelContext(context string) error { return gui.renderRemotesWithSelection() case "remote-branches": return gui.renderRemoteBranchesWithSelection() + case "tags": + return gui.renderTagsWithSelection() } return nil diff --git a/pkg/gui/commits_panel.go b/pkg/gui/commits_panel.go index c29935f14..22ea6fe7e 100644 --- a/pkg/gui/commits_panel.go +++ b/pkg/gui/commits_panel.go @@ -584,3 +584,30 @@ func (gui *Gui) handleCreateCommitResetMenu(g *gocui.Gui, v *gocui.View) error { return gui.createMenu(fmt.Sprintf("%s %s", gui.Tr.SLocalize("resetTo"), commit.Sha), options, len(options), handleMenuPress) } + +func (gui *Gui) handleTagCommit(g *gocui.Gui, v *gocui.View) error { + // TODO: bring up menu asking if you want to make a lightweight or annotated tag + // if annotated, switch to a subprocess to create the message + + commit := gui.getSelectedCommit(g) + if commit == nil { + return nil + } + + return gui.handleCreateLightweightTag(commit.Sha) +} + +func (gui *Gui) handleCreateLightweightTag(commitSha string) error { + return gui.createPromptPanel(gui.g, gui.getCommitsView(), gui.Tr.SLocalize("TagNameTitle"), "", func(g *gocui.Gui, v *gocui.View) error { + if err := gui.GitCommand.CreateLightweightTag(v.Buffer(), commitSha); err != nil { + return gui.createErrorPanel(g, err.Error()) + } + if err := gui.refreshCommits(g); err != nil { + return gui.createErrorPanel(g, err.Error()) + } + if err := gui.refreshTags(); err != nil { + return gui.createErrorPanel(g, err.Error()) + } + return gui.handleCommitSelect(g, v) + }) +} diff --git a/pkg/gui/gui.go b/pkg/gui/gui.go index c08c82817..3b6f2fb11 100644 --- a/pkg/gui/gui.go +++ b/pkg/gui/gui.go @@ -120,6 +120,10 @@ type remoteBranchesState struct { SelectedLine int } +type tagsPanelState struct { + SelectedLine int +} + type commitPanelState struct { SelectedLine int SpecificDiffMode bool @@ -148,6 +152,7 @@ type panelStates struct { Branches *branchPanelState Remotes *remotePanelState RemoteBranches *remoteBranchesState + Tags *tagsPanelState Commits *commitPanelState Stash *stashPanelState Menu *menuPanelState @@ -166,6 +171,7 @@ type guiState struct { DiffEntries []*commands.Commit Remotes []*commands.Remote RemoteBranches []*commands.RemoteBranch + Tags []*commands.Tag MenuItemCount int // can't store the actual list because it's of interface{} type PreviousView string Platform commands.Platform @@ -198,6 +204,7 @@ func NewGui(log *logrus.Entry, gitCommand *commands.GitCommand, oSCommand *comma Branches: &branchPanelState{SelectedLine: 0}, Remotes: &remotePanelState{SelectedLine: 0}, RemoteBranches: &remoteBranchesState{SelectedLine: -1}, + Tags: &tagsPanelState{SelectedLine: -1}, Commits: &commitPanelState{SelectedLine: -1}, CommitFiles: &commitFilesPanelState{SelectedLine: -1}, Stash: &stashPanelState{SelectedLine: -1}, @@ -497,7 +504,7 @@ func (gui *Gui) layout(g *gocui.Gui) error { return err } branchesView.Title = gui.Tr.SLocalize("BranchesTitle") - branchesView.Tabs = []string{"Local Branches", "Remotes"} + branchesView.Tabs = []string{"Local Branches", "Remotes", "Tags"} branchesView.FgColor = textColor } diff --git a/pkg/gui/keybindings.go b/pkg/gui/keybindings.go index a64bb2965..2dfdedf61 100644 --- a/pkg/gui/keybindings.go +++ b/pkg/gui/keybindings.go @@ -403,6 +403,38 @@ func (gui *Gui) GetInitialKeybindings() []*Binding { Description: gui.Tr.SLocalize("FastForward"), }, { + ViewName: "branches", + Contexts: []string{"tags"}, + Key: gocui.KeySpace, + Modifier: gocui.ModNone, + Handler: gui.handleCheckoutTag, + Description: gui.Tr.SLocalize("checkout"), + }, + { + ViewName: "branches", + Contexts: []string{"tags"}, + Key: 'd', + Modifier: gocui.ModNone, + Handler: gui.handleDeleteTag, + Description: gui.Tr.SLocalize("deleteTag"), + }, + { + ViewName: "branches", + Contexts: []string{"tags"}, + Key: 'P', + Modifier: gocui.ModNone, + Handler: gui.handlePushTag, + Description: gui.Tr.SLocalize("pushTags"), + }, + { + ViewName: "branches", + Contexts: []string{"tags"}, + Key: 'n', + Modifier: gocui.ModNone, + Handler: gui.handleCreateTag, + Description: gui.Tr.SLocalize("createTag"), + }, + { ViewName: "branches", Key: ']', Modifier: gocui.ModNone, @@ -556,6 +588,13 @@ func (gui *Gui) GetInitialKeybindings() []*Binding { Description: gui.Tr.SLocalize("CommitsDiff"), }, { + ViewName: "commits", + Key: 'T', + Modifier: gocui.ModNone, + Handler: gui.handleTagCommit, + Description: gui.Tr.SLocalize("tagCommit"), + }, + { ViewName: "stash", Key: gocui.KeySpace, Modifier: gocui.ModNone, diff --git a/pkg/gui/list_view.go b/pkg/gui/list_view.go index 3a93bd526..4d72efc43 100644 --- a/pkg/gui/list_view.go +++ b/pkg/gui/list_view.go @@ -117,6 +117,16 @@ func (gui *Gui) getListViews() []*listView { rendersToMainView: true, }, { + viewName: "branches", + context: "tags", + getItemsLength: func() int { return len(gui.State.Tags) }, + getSelectedLineIdxPtr: func() *int { return &gui.State.Panels.Tags.SelectedLine }, + handleFocus: gui.handleTagSelect, + handleItemSelect: gui.handleTagSelect, + gui: gui, + rendersToMainView: true, + }, + { viewName: "commits", getItemsLength: func() int { return len(gui.State.Commits) }, getSelectedLineIdxPtr: func() *int { return &gui.State.Panels.Commits.SelectedLine }, diff --git a/pkg/gui/remotes_panel.go b/pkg/gui/remotes_panel.go index bf9f8e110..90c2c8d59 100644 --- a/pkg/gui/remotes_panel.go +++ b/pkg/gui/remotes_panel.go @@ -35,6 +35,9 @@ func (gui *Gui) handleRemoteSelect(g *gocui.Gui, v *gocui.View) error { gui.getMainView().Title = "Remote" remote := gui.getSelectedRemote() + if remote == nil { + return gui.renderString(g, "main", "No remotes") + } if err := gui.focusPoint(0, gui.State.Panels.Remotes.SelectedLine, len(gui.State.Remotes), v); err != nil { return err } @@ -42,8 +45,6 @@ func (gui *Gui) handleRemoteSelect(g *gocui.Gui, v *gocui.View) error { return gui.renderString(g, "main", fmt.Sprintf("%s\nUrls:\n%s", utils.ColoredString(remote.Name, color.FgGreen), strings.Join(remote.Urls, "\n"))) } -// gui.refreshStatus is called at the end of this because that's when we can -// be sure there is a state.Remotes array to pick the current remote from func (gui *Gui) refreshRemotes() error { prevSelectedRemote := gui.getSelectedRemote() @@ -92,6 +93,9 @@ func (gui *Gui) renderRemotesWithSelection() error { func (gui *Gui) handleRemoteEnter(g *gocui.Gui, v *gocui.View) error { // naive implementation: get the branches and render them to the list, change the context remote := gui.getSelectedRemote() + if remote == nil { + return nil + } gui.State.RemoteBranches = remote.Branches diff --git a/pkg/gui/tags_panel.go b/pkg/gui/tags_panel.go new file mode 100644 index 000000000..e1f9d364a --- /dev/null +++ b/pkg/gui/tags_panel.go @@ -0,0 +1,149 @@ +package gui + +import ( + "fmt" + + "github.com/jesseduffield/gocui" + "github.com/jesseduffield/lazygit/pkg/commands" +) + +// list panel functions + +func (gui *Gui) getSelectedTag() *commands.Tag { + selectedLine := gui.State.Panels.Tags.SelectedLine + if selectedLine == -1 || len(gui.State.Tags) == 0 { + return nil + } + + return gui.State.Tags[selectedLine] +} + +func (gui *Gui) handleTagSelect(g *gocui.Gui, v *gocui.View) error { + if gui.popupPanelFocused() { + return nil + } + + gui.State.SplitMainPanel = false + + if _, err := gui.g.SetCurrentView(v.Name()); err != nil { + return err + } + + gui.getMainView().Title = "Tag" + + tag := gui.getSelectedTag() + if tag == nil { + return gui.renderString(g, "main", "No tags") + } + if err := gui.focusPoint(0, gui.State.Panels.Tags.SelectedLine, len(gui.State.Tags), v); err != nil { + return err + } + + go func() { + show, err := gui.GitCommand.ShowTag(tag.Name) + if err != nil { + show = "" + } + + graph, err := gui.GitCommand.GetBranchGraph(tag.Name) + if err != nil { + graph = "No graph for tag " + tag.Name + } + + _ = gui.renderString(g, "main", fmt.Sprintf("%s\n%s", show, graph)) + }() + + return nil +} + +func (gui *Gui) refreshTags() error { + tags, err := gui.GitCommand.GetTags() + if err != nil { + return gui.createErrorPanel(gui.g, err.Error()) + } + + gui.State.Tags = tags + + if gui.getBranchesView().Context == "tags" { + gui.renderTagsWithSelection() + } + + return nil +} + +func (gui *Gui) renderTagsWithSelection() error { + branchesView := gui.getBranchesView() + + gui.refreshSelectedLine(&gui.State.Panels.Tags.SelectedLine, len(gui.State.Tags)) + if err := gui.renderListPanel(branchesView, gui.State.Tags); err != nil { + return err + } + if err := gui.handleTagSelect(gui.g, branchesView); err != nil { + return err + } + + return nil +} + +func (gui *Gui) handleCheckoutTag(g *gocui.Gui, v *gocui.View) error { + tag := gui.getSelectedTag() + if tag == nil { + return nil + } + if err := gui.handleCheckoutBranch(tag.Name); err != nil { + return err + } + return gui.switchBranchesPanelContext("local-branches") +} + +func (gui *Gui) handleDeleteTag(g *gocui.Gui, v *gocui.View) error { + tag := gui.getSelectedTag() + if tag == nil { + return nil + } + + prompt := gui.Tr.TemplateLocalize( + "DeleteTagPrompt", + Teml{ + "tagName": tag.Name, + }, + ) + + return gui.createConfirmationPanel(gui.g, v, true, gui.Tr.SLocalize("DeleteTagTitle"), prompt, func(g *gocui.Gui, v *gocui.View) error { + if err := gui.GitCommand.DeleteTag(tag.Name); err != nil { + return gui.createErrorPanel(gui.g, err.Error()) + } + return gui.refreshTags() + }, nil) +} + +func (gui *Gui) handlePushTag(g *gocui.Gui, v *gocui.View) error { + tag := gui.getSelectedTag() + if tag == nil { + return nil + } + + title := gui.Tr.TemplateLocalize( + "PushTagTitle", + Teml{ + "tagName": tag.Name, + }, + ) + + return gui.createPromptPanel(gui.g, v, title, "origin", func(g *gocui.Gui, v *gocui.View) error { + if err := gui.GitCommand.PushTag(v.Buffer(), tag.Name); err != nil { + return gui.createErrorPanel(gui.g, err.Error()) + } + return gui.refreshTags() + }) +} + +func (gui *Gui) handleCreateTag(g *gocui.Gui, v *gocui.View) error { + return gui.createPromptPanel(gui.g, v, gui.Tr.SLocalize("CreateTagTitle"), "", func(g *gocui.Gui, v *gocui.View) error { + // leaving commit SHA blank so that we're just creating the tag for the current commit + if err := gui.GitCommand.CreateLightweightTag(v.Buffer(), ""); err != nil { + return gui.createErrorPanel(gui.g, err.Error()) + } + return gui.refreshTags() + }) +} diff --git a/pkg/gui/view_helpers.go b/pkg/gui/view_helpers.go index e671165a3..6112a5422 100644 --- a/pkg/gui/view_helpers.go +++ b/pkg/gui/view_helpers.go @@ -112,6 +112,8 @@ func (gui *Gui) newLineFocused(g *gocui.Gui, v *gocui.View) error { return gui.handleRemoteSelect(g, v) case "remote-branches": return gui.handleRemoteBranchSelect(g, v) + case "tags": + return gui.handleTagSelect(g, v) default: return errors.New("unknown branches panel context: " + branchesView.Context) } |