1
0
mirror of https://github.com/jesseduffield/lazygit.git synced 2025-07-31 14:24:25 +03:00

add submodules context

This commit is contained in:
Jesse Duffield
2020-09-30 08:27:23 +10:00
parent 3b93b5dde4
commit 7b4a0f20b2
14 changed files with 367 additions and 93 deletions

View File

@ -5,3 +5,15 @@ type SubmoduleConfig struct {
Path string
Url string
}
func (r *SubmoduleConfig) RefName() string {
return r.Name
}
func (r *SubmoduleConfig) ID() string {
return r.RefName()
}
func (r *SubmoduleConfig) Description() string {
return r.RefName()
}

View File

@ -34,6 +34,7 @@ const (
CONFIRMATION_CONTEXT_KEY = "confirmation"
SEARCH_CONTEXT_KEY = "search"
COMMIT_MESSAGE_CONTEXT_KEY = "commitMessage"
SUBMODULES_CONTEXT_KEY = "submodules"
)
var allContextKeys = []string{
@ -57,6 +58,64 @@ var allContextKeys = []string{
CONFIRMATION_CONTEXT_KEY,
SEARCH_CONTEXT_KEY,
COMMIT_MESSAGE_CONTEXT_KEY,
SUBMODULES_CONTEXT_KEY,
}
type SimpleContextNode struct {
Context Context
}
type RemotesContextNode struct {
Context Context
Branches SimpleContextNode
}
type ContextTree struct {
Status SimpleContextNode
Files SimpleContextNode
Submodules SimpleContextNode
Menu SimpleContextNode
Branches SimpleContextNode
Remotes RemotesContextNode
Tags SimpleContextNode
BranchCommits SimpleContextNode
CommitFiles SimpleContextNode
ReflogCommits SimpleContextNode
SubCommits SimpleContextNode
Stash SimpleContextNode
Normal SimpleContextNode
Staging SimpleContextNode
PatchBuilding SimpleContextNode
Merging SimpleContextNode
Credentials SimpleContextNode
Confirmation SimpleContextNode
CommitMessage SimpleContextNode
Search SimpleContextNode
}
func (gui *Gui) allContexts() []Context {
return []Context{
gui.Contexts.Status.Context,
gui.Contexts.Files.Context,
gui.Contexts.Submodules.Context,
gui.Contexts.Branches.Context,
gui.Contexts.Remotes.Context,
gui.Contexts.Remotes.Branches.Context,
gui.Contexts.Tags.Context,
gui.Contexts.BranchCommits.Context,
gui.Contexts.CommitFiles.Context,
gui.Contexts.ReflogCommits.Context,
gui.Contexts.Stash.Context,
gui.Contexts.Menu.Context,
gui.Contexts.Confirmation.Context,
gui.Contexts.Credentials.Context,
gui.Contexts.CommitMessage.Context,
gui.Contexts.Normal.Context,
gui.Contexts.Staging.Context,
gui.Contexts.Merging.Context,
gui.Contexts.PatchBuilding.Context,
gui.Contexts.SubCommits.Context,
}
}
type Context interface {
@ -139,61 +198,6 @@ func (c BasicContext) GetKey() string {
return c.Key
}
type SimpleContextNode struct {
Context Context
}
type RemotesContextNode struct {
Context Context
Branches SimpleContextNode
}
type ContextTree struct {
Status SimpleContextNode
Files SimpleContextNode
Menu SimpleContextNode
Branches SimpleContextNode
Remotes RemotesContextNode
Tags SimpleContextNode
BranchCommits SimpleContextNode
CommitFiles SimpleContextNode
ReflogCommits SimpleContextNode
SubCommits SimpleContextNode
Stash SimpleContextNode
Normal SimpleContextNode
Staging SimpleContextNode
PatchBuilding SimpleContextNode
Merging SimpleContextNode
Credentials SimpleContextNode
Confirmation SimpleContextNode
CommitMessage SimpleContextNode
Search SimpleContextNode
}
func (gui *Gui) allContexts() []Context {
return []Context{
gui.Contexts.Status.Context,
gui.Contexts.Files.Context,
gui.Contexts.Branches.Context,
gui.Contexts.Remotes.Context,
gui.Contexts.Remotes.Branches.Context,
gui.Contexts.Tags.Context,
gui.Contexts.BranchCommits.Context,
gui.Contexts.CommitFiles.Context,
gui.Contexts.ReflogCommits.Context,
gui.Contexts.Stash.Context,
gui.Contexts.Menu.Context,
gui.Contexts.Confirmation.Context,
gui.Contexts.Credentials.Context,
gui.Contexts.CommitMessage.Context,
gui.Contexts.Normal.Context,
gui.Contexts.Staging.Context,
gui.Contexts.Merging.Context,
gui.Contexts.PatchBuilding.Context,
gui.Contexts.SubCommits.Context,
}
}
func (gui *Gui) contextTree() ContextTree {
return ContextTree{
Status: SimpleContextNode{
@ -207,6 +211,9 @@ func (gui *Gui) contextTree() ContextTree {
Files: SimpleContextNode{
Context: gui.filesListContext(),
},
Submodules: SimpleContextNode{
Context: gui.submodulesListContext(),
},
Menu: SimpleContextNode{
Context: gui.menuListContext(),
},
@ -365,6 +372,18 @@ func (gui *Gui) viewTabContextMap() map[string][]tabContext {
},
},
},
"files": {
{
tab: "Files",
contexts: []Context{gui.Contexts.Files.Context},
},
{
tab: "Submodules",
contexts: []Context{
gui.Contexts.Submodules.Context,
},
},
},
}
}

View File

@ -34,7 +34,8 @@ func (gui *Gui) currentDiffTerminals() []string {
switch gui.currentContext().GetKey() {
case "":
return nil
case FILES_CONTEXT_KEY:
case FILES_CONTEXT_KEY, SUBMODULES_CONTEXT_KEY:
// TODO: should we just return nil here?
return []string{""}
case COMMIT_FILES_CONTEXT_KEY:
return []string{gui.State.Panels.CommitFiles.refName}

View File

@ -6,7 +6,7 @@ import (
)
func (gui *Gui) submoduleFromFile(file *models.File) *models.SubmoduleConfig {
for _, config := range gui.State.SubmoduleConfigs {
for _, config := range gui.State.Submodules {
if config.Name == file.Name {
return config
}
@ -23,7 +23,7 @@ func (gui *Gui) handleCreateDiscardMenu(g *gocui.Gui, v *gocui.View) error {
var menuItems []*menuItem
submoduleConfigs := gui.State.SubmoduleConfigs
submoduleConfigs := gui.State.Submodules
if file.IsSubmodule(submoduleConfigs) {
submoduleConfig := file.SubmoduleConfig(submoduleConfigs)

View File

@ -8,7 +8,6 @@ import (
// "strings"
"fmt"
"os"
"regexp"
"strings"
@ -80,7 +79,7 @@ func (gui *Gui) selectFile(alreadySelected bool) error {
return gui.refreshMainViews(refreshOpts)
}
func (gui *Gui) refreshFiles() error {
func (gui *Gui) refreshFilesAndSubmodules() error {
gui.State.RefreshingFilesMutex.Lock()
gui.State.IsRefreshingFiles = true
defer func() {
@ -103,15 +102,25 @@ func (gui *Gui) refreshFiles() error {
}
gui.g.Update(func(g *gocui.Gui) error {
if err := gui.postRefreshUpdate(gui.Contexts.Submodules.Context); err != nil {
gui.Log.Error(err)
}
if gui.getFilesView().Context == FILES_CONTEXT_KEY {
// doing this a little custom (as opposed to using gui.postRefreshUpdate) because we handle selecting the file explicitly below
if err := gui.Contexts.Files.Context.HandleRender(); err != nil {
return err
}
}
if g.CurrentView() == filesView || (g.CurrentView() == gui.getMainView() && g.CurrentView().Context == MAIN_MERGING_CONTEXT_KEY) {
if gui.currentContext().GetKey() == FILES_CONTEXT_KEY || (g.CurrentView() == gui.getMainView() && g.CurrentView().Context == MAIN_MERGING_CONTEXT_KEY) {
newSelectedFile := gui.getSelectedFile()
alreadySelected := selectedFile != nil && newSelectedFile != nil && newSelectedFile.Name == selectedFile.Name
return gui.selectFile(alreadySelected)
if err := gui.selectFile(alreadySelected); err != nil {
return err
}
}
return nil
})
@ -161,15 +170,10 @@ func (gui *Gui) enterFile(forceSecondaryFocused bool, selectedLineIdx int) error
return nil
}
submoduleConfigs := gui.State.SubmoduleConfigs
submoduleConfigs := gui.State.Submodules
if file.IsSubmodule(submoduleConfigs) {
wd, err := os.Getwd()
if err != nil {
return err
}
gui.State.RepoPathStack = append(gui.State.RepoPathStack, wd)
submoduleConfig := file.SubmoduleConfig(submoduleConfigs)
return gui.dispatchSwitchToRepo(submoduleConfig.Path)
return gui.enterSubmodule(submoduleConfig)
}
if file.HasInlineMergeConflicts {
@ -325,7 +329,7 @@ func (gui *Gui) promptToStageAllAndRetry(retry func() error) error {
if err := gui.GitCommand.StageAll(); err != nil {
return gui.surfaceError(err)
}
if err := gui.refreshFiles(); err != nil {
if err := gui.refreshFilesAndSubmodules(); err != nil {
return gui.surfaceError(err)
}
@ -448,7 +452,7 @@ func (gui *Gui) refreshStateSubmoduleConfigs() error {
return err
}
gui.State.SubmoduleConfigs = configs
gui.State.Submodules = configs
return nil
}

View File

@ -209,6 +209,10 @@ type commitFilesPanelState struct {
canRebase bool
}
type submodulePanelState struct {
listPanelState
}
type panelStates struct {
Files *filePanelState
Branches *branchPanelState
@ -223,6 +227,7 @@ type panelStates struct {
LineByLine *lineByLinePanelState
Merging *mergingPanelState
CommitFiles *commitFilesPanelState
Submodules *submodulePanelState
}
type searchingState struct {
@ -274,7 +279,7 @@ type Modes struct {
type guiState struct {
Files []*models.File
SubmoduleConfigs []*models.SubmoduleConfig
Submodules []*models.SubmoduleConfig
Branches []*models.Branch
Commits []*models.Commit
StashEntries []*models.StashEntry
@ -358,6 +363,7 @@ func (gui *Gui) resetState() {
Panels: &panelStates{
// TODO: work out why some of these are -1 and some are 0. Last time I checked there was a good reason but I'm less certain now
Files: &filePanelState{listPanelState{SelectedLineIdx: -1}},
Submodules: &submodulePanelState{listPanelState{SelectedLineIdx: -1}},
Branches: &branchPanelState{listPanelState{SelectedLineIdx: 0}},
Remotes: &remotePanelState{listPanelState{SelectedLineIdx: 0}},
RemoteBranches: &remoteBranchesState{listPanelState{SelectedLineIdx: -1}},
@ -456,7 +462,7 @@ func (gui *Gui) Run() error {
go gui.startBackgroundFetch()
}
gui.goEvery(time.Second*10, gui.stopChan, gui.refreshFiles)
gui.goEvery(time.Second*10, gui.stopChan, gui.refreshFilesAndSubmodules)
g.SetManager(gocui.ManagerFunc(gui.layout), gocui.ManagerFunc(gui.getFocusLayout()))

View File

@ -363,102 +363,119 @@ func (gui *Gui) GetInitialKeybindings() []*Binding {
},
{
ViewName: "files",
Contexts: []string{FILES_CONTEXT_KEY},
Key: gui.getKey("files.commitChanges"),
Handler: gui.wrappedHandler(gui.handleCommitPress),
Description: gui.Tr.SLocalize("CommitChanges"),
},
{
ViewName: "files",
Contexts: []string{FILES_CONTEXT_KEY},
Key: gui.getKey("files.commitChangesWithoutHook"),
Handler: gui.handleWIPCommitPress,
Description: gui.Tr.SLocalize("commitChangesWithoutHook"),
},
{
ViewName: "files",
Contexts: []string{FILES_CONTEXT_KEY},
Key: gui.getKey("files.amendLastCommit"),
Handler: gui.wrappedHandler(gui.handleAmendCommitPress),
Description: gui.Tr.SLocalize("AmendLastCommit"),
},
{
ViewName: "files",
Contexts: []string{FILES_CONTEXT_KEY},
Key: gui.getKey("files.commitChangesWithEditor"),
Handler: gui.wrappedHandler(gui.handleCommitEditorPress),
Description: gui.Tr.SLocalize("CommitChangesWithEditor"),
},
{
ViewName: "files",
Contexts: []string{FILES_CONTEXT_KEY},
Key: gui.getKey("universal.select"),
Handler: gui.wrappedHandler(gui.handleFilePress),
Description: gui.Tr.SLocalize("toggleStaged"),
},
{
ViewName: "files",
Contexts: []string{FILES_CONTEXT_KEY},
Key: gui.getKey("universal.remove"),
Handler: gui.handleCreateDiscardMenu,
Description: gui.Tr.SLocalize("viewDiscardOptions"),
},
{
ViewName: "files",
Contexts: []string{FILES_CONTEXT_KEY},
Key: gui.getKey("universal.edit"),
Handler: gui.handleFileEdit,
Description: gui.Tr.SLocalize("editFile"),
},
{
ViewName: "files",
Contexts: []string{FILES_CONTEXT_KEY},
Key: gui.getKey("universal.openFile"),
Handler: gui.handleFileOpen,
Description: gui.Tr.SLocalize("openFile"),
},
{
ViewName: "files",
Contexts: []string{FILES_CONTEXT_KEY},
Key: gui.getKey("files.ignoreFile"),
Handler: gui.handleIgnoreFile,
Description: gui.Tr.SLocalize("ignoreFile"),
},
{
ViewName: "files",
Contexts: []string{FILES_CONTEXT_KEY},
Key: gui.getKey("files.refreshFiles"),
Handler: gui.handleRefreshFiles,
Description: gui.Tr.SLocalize("refreshFiles"),
},
{
ViewName: "files",
Contexts: []string{FILES_CONTEXT_KEY},
Key: gui.getKey("files.stashAllChanges"),
Handler: gui.handleStashChanges,
Description: gui.Tr.SLocalize("stashAllChanges"),
},
{
ViewName: "files",
Contexts: []string{FILES_CONTEXT_KEY},
Key: gui.getKey("files.viewStashOptions"),
Handler: gui.handleCreateStashMenu,
Description: gui.Tr.SLocalize("viewStashOptions"),
},
{
ViewName: "files",
Contexts: []string{FILES_CONTEXT_KEY},
Key: gui.getKey("files.toggleStagedAll"),
Handler: gui.handleStageAll,
Description: gui.Tr.SLocalize("toggleStagedAll"),
},
{
ViewName: "files",
Contexts: []string{FILES_CONTEXT_KEY},
Key: gui.getKey("files.viewResetOptions"),
Handler: gui.handleCreateResetMenu,
Description: gui.Tr.SLocalize("viewResetOptions"),
},
{
ViewName: "files",
Contexts: []string{FILES_CONTEXT_KEY},
Key: gui.getKey("universal.goInto"),
Handler: gui.handleEnterFile,
Description: gui.Tr.SLocalize("StageLines"),
},
{
ViewName: "files",
Contexts: []string{FILES_CONTEXT_KEY},
Key: gui.getKey("files.fetch"),
Handler: gui.handleGitFetch,
Description: gui.Tr.SLocalize("fetch"),
},
{
ViewName: "files",
Contexts: []string{FILES_CONTEXT_KEY},
Key: gui.getKey("universal.copyToClipboard"),
Handler: gui.wrappedHandler(gui.handleCopySelectedSideContextItemToClipboard),
Description: gui.Tr.SLocalize("copyFileNameToClipboard"),
@ -471,6 +488,7 @@ func (gui *Gui) GetInitialKeybindings() []*Binding {
},
{
ViewName: "files",
Contexts: []string{FILES_CONTEXT_KEY},
Key: gui.getKey("commits.viewResetOptions"),
Handler: gui.handleCreateResetToUpstreamMenu,
Description: gui.Tr.SLocalize("viewResetToUpstreamOptions"),
@ -1542,6 +1560,32 @@ func (gui *Gui) GetInitialKeybindings() []*Binding {
Modifier: gocui.ModNone,
Handler: gui.wrappedHandler(gui.onMenuPress),
},
{
ViewName: "files",
Contexts: []string{SUBMODULES_CONTEXT_KEY},
Key: gui.getKey("universal.goInto"),
Handler: gui.wrappedHandler(gui.handleSubmoduleEnter),
Description: gui.Tr.SLocalize("enterSubmodule"),
},
{
ViewName: "files",
Key: gui.getKey("universal.nextTab"),
Handler: gui.handleNextTab,
Description: gui.Tr.SLocalize("nextTab"),
},
{
ViewName: "files",
Key: gui.getKey("universal.prevTab"),
Handler: gui.handlePrevTab,
Description: gui.Tr.SLocalize("prevTab"),
},
{
ViewName: "files",
Contexts: []string{SUBMODULES_CONTEXT_KEY},
Key: gui.getKey("universal.copyToClipboard"),
Handler: gui.wrappedHandler(gui.handleCopySelectedSideContextItemToClipboard),
Description: gui.Tr.SLocalize("copySubmoduleNameToClipboard"),
},
}
for _, viewName := range []string{"status", "branches", "files", "commits", "commitFiles", "stash", "menu"} {

View File

@ -285,8 +285,10 @@ func (gui *Gui) layout(g *gocui.Gui) error {
listContext *ListContext
}
// TODO: don't we already have the view included in the context object itself? Or might that change in a way we don't want reflected here?
listContextStates := []listContextState{
{view: filesView, listContext: gui.filesListContext()},
{view: filesView, listContext: gui.submodulesListContext()},
{view: branchesView, listContext: gui.branchesListContext()},
{view: branchesView, listContext: gui.remotesListContext()},
{view: branchesView, listContext: gui.remoteBranchesListContext()},

View File

@ -270,7 +270,7 @@ func (gui *Gui) filesListContext() *ListContext {
ResetMainViewOriginOnFocus: false,
Kind: SIDE_CONTEXT,
GetDisplayStrings: func() [][]string {
return presentation.GetFileListDisplayStrings(gui.State.Files, gui.State.Modes.Diffing.Ref, gui.State.SubmoduleConfigs)
return presentation.GetFileListDisplayStrings(gui.State.Files, gui.State.Modes.Diffing.Ref, gui.State.Submodules)
},
SelectedItem: func() (ListItem, bool) {
item := gui.getSelectedFile()
@ -462,6 +462,27 @@ func (gui *Gui) commitFilesListContext() *ListContext {
}
}
func (gui *Gui) submodulesListContext() *ListContext {
return &ListContext{
ViewName: "files",
WindowName: "files",
ContextKey: SUBMODULES_CONTEXT_KEY,
GetItemsLength: func() int { return len(gui.State.Submodules) },
GetPanelState: func() IListPanelState { return gui.State.Panels.Submodules },
OnFocus: gui.handleSubmoduleSelect,
Gui: gui,
ResetMainViewOriginOnFocus: true,
Kind: SIDE_CONTEXT,
GetDisplayStrings: func() [][]string {
return presentation.GetSubmoduleListDisplayStrings(gui.State.Submodules)
},
SelectedItem: func() (ListItem, bool) {
item := gui.getSelectedSubmodule()
return item, item != nil
},
}
}
func (gui *Gui) getListContexts() []*ListContext {
return []*ListContext{
gui.menuListContext(),
@ -475,6 +496,7 @@ func (gui *Gui) getListContexts() []*ListContext {
gui.subCommitsListContext(),
gui.stashListContext(),
gui.commitFilesListContext(),
gui.submodulesListContext(),
}
}

View File

@ -0,0 +1,21 @@
package presentation
import (
"github.com/jesseduffield/lazygit/pkg/commands/models"
"github.com/jesseduffield/lazygit/pkg/theme"
"github.com/jesseduffield/lazygit/pkg/utils"
)
func GetSubmoduleListDisplayStrings(submodules []*models.SubmoduleConfig) [][]string {
lines := make([][]string, len(submodules))
for i := range submodules {
lines[i] = getSubmoduleDisplayStrings(submodules[i])
}
return lines
}
func getSubmoduleDisplayStrings(s *models.SubmoduleConfig) []string {
return []string{utils.ColoredString(s.Name, theme.DefaultTextColor)}
}

135
pkg/gui/submodules_panel.go Normal file
View File

@ -0,0 +1,135 @@
package gui
import (
"fmt"
"os"
"github.com/fatih/color"
"github.com/jesseduffield/lazygit/pkg/commands/models"
"github.com/jesseduffield/lazygit/pkg/utils"
)
func (gui *Gui) getSelectedSubmodule() *models.SubmoduleConfig {
selectedLine := gui.State.Panels.Submodules.SelectedLineIdx
if selectedLine == -1 || len(gui.State.Submodules) == 0 {
return nil
}
return gui.State.Submodules[selectedLine]
}
func (gui *Gui) handleSubmoduleSelect() error {
var task updateTask
submodule := gui.getSelectedSubmodule()
if submodule == nil {
task = gui.createRenderStringTask("No submodules")
} else {
// TODO: we want to display the path, name, url, and a diff. We really need to be able to pipe commands together. We can always pipe commands together and just not do it asynchronously, but what if it's an expensive diff to obtain? I think that makes the most sense now though.
task = gui.createRenderStringTask(
fmt.Sprintf(
"Name: %s\nPath: %s\nUrl: %s\n",
utils.ColoredString(submodule.Name, color.FgGreen),
utils.ColoredString(submodule.Path, color.FgYellow),
utils.ColoredString(submodule.Url, color.FgCyan),
),
)
}
return gui.refreshMainViews(refreshMainOpts{
main: &viewUpdateOpts{
title: "Submodule",
task: task,
},
})
}
func (gui *Gui) handleSubmoduleEnter() error {
submodule := gui.getSelectedSubmodule()
if submodule == nil {
return nil
}
return gui.enterSubmodule(submodule)
}
func (gui *Gui) enterSubmodule(submodule *models.SubmoduleConfig) error {
wd, err := os.Getwd()
if err != nil {
return err
}
gui.State.RepoPathStack = append(gui.State.RepoPathStack, wd)
return gui.dispatchSwitchToRepo(submodule.Path)
}
// func (gui *Gui) handleAddRemote(g *gocui.Gui, v *gocui.View) error {
// return gui.prompt(gui.Tr.SLocalize("newRemoteName"), "", func(remoteName string) error {
// return gui.prompt(gui.Tr.SLocalize("newRemoteUrl"), "", func(remoteUrl string) error {
// if err := gui.GitCommand.AddRemote(remoteName, remoteUrl); err != nil {
// return err
// }
// return gui.refreshSidePanels(refreshOptions{scope: []int{REMOTES}})
// })
// })
// }
// func (gui *Gui) handleRemoveRemote(g *gocui.Gui, v *gocui.View) error {
// remote := gui.getSelectedSubmodule()
// if remote == nil {
// return nil
// }
// return gui.ask(askOpts{
// title: gui.Tr.SLocalize("removeRemote"),
// prompt: gui.Tr.SLocalize("removeRemotePrompt") + " '" + remote.Name + "'?",
// handleConfirm: func() error {
// if err := gui.GitCommand.RemoveRemote(remote.Name); err != nil {
// return err
// }
// return gui.refreshSidePanels(refreshOptions{scope: []int{BRANCHES, REMOTES}})
// },
// })
// }
// func (gui *Gui) handleEditRemote(g *gocui.Gui, v *gocui.View) error {
// remote := gui.getSelectedSubmodule()
// if remote == nil {
// return nil
// }
// editNameMessage := gui.Tr.TemplateLocalize(
// "editRemoteName",
// Teml{
// "remoteName": remote.Name,
// },
// )
// return gui.prompt(editNameMessage, remote.Name, func(updatedRemoteName string) error {
// if updatedRemoteName != remote.Name {
// if err := gui.GitCommand.RenameRemote(remote.Name, updatedRemoteName); err != nil {
// return gui.surfaceError(err)
// }
// }
// editUrlMessage := gui.Tr.TemplateLocalize(
// "editRemoteUrl",
// Teml{
// "remoteName": updatedRemoteName,
// },
// )
// urls := remote.Urls
// url := ""
// if len(urls) > 0 {
// url = urls[0]
// }
// return gui.prompt(editUrlMessage, url, func(updatedRemoteUrl string) error {
// if err := gui.GitCommand.UpdateRemoteUrl(updatedRemoteName, updatedRemoteUrl); err != nil {
// return gui.surfaceError(err)
// }
// return gui.refreshSidePanels(refreshOptions{scope: []int{BRANCHES, REMOTES}})
// })
// })
// }

View File

@ -25,6 +25,7 @@ const (
TAGS
REMOTES
STATUS
SUBMODULES
)
func getScopeNames(scopes []int) []string {
@ -32,6 +33,7 @@ func getScopeNames(scopes []int) []string {
COMMITS: "commits",
BRANCHES: "branches",
FILES: "files",
SUBMODULES: "submodules",
STASH: "stash",
REFLOG: "reflog",
TAGS: "tags",
@ -116,13 +118,13 @@ func (gui *Gui) refreshSidePanels(options refreshOptions) error {
}()
}
if scopeMap[FILES] {
if scopeMap[FILES] || scopeMap[SUBMODULES] {
wg.Add(1)
func() {
if options.mode == ASYNC {
go gui.refreshFiles()
go gui.refreshFilesAndSubmodules()
} else {
gui.refreshFiles()
gui.refreshFilesAndSubmodules()
}
wg.Done()
}()

View File

@ -11,7 +11,7 @@ func (gui *Gui) handleCreateResetMenu(g *gocui.Gui, v *gocui.View) error {
red := color.New(color.FgRed)
nukeStr := "reset --hard HEAD && git clean -fd"
if len(gui.State.SubmoduleConfigs) > 0 {
if len(gui.State.Submodules) > 0 {
nukeStr = fmt.Sprintf("%s (%s)", nukeStr, gui.Tr.SLocalize("andResetSubmodules"))
}

View File

@ -1197,6 +1197,12 @@ func addEnglish(i18nObject *i18n.Bundle) error {
}, &i18n.Message{
ID: "andResetSubmodules",
Other: "and reset submodules",
}, &i18n.Message{
ID: "enterSubmodule",
Other: "enter submodule",
}, &i18n.Message{
ID: "copySubmoduleNameToClipboard",
Other: "copy submodule name to clipboard",
},
)
}