mirror of
https://github.com/jesseduffield/lazygit.git
synced 2025-08-06 11:02:41 +03:00
Move file discard action into files controller
It's better just having all the keybindings in one file especially when you want to share code
This commit is contained in:
@@ -172,7 +172,6 @@ func (gui *Gui) resetHelpersAndControllers() {
|
|||||||
|
|
||||||
branchesController := controllers.NewBranchesController(common)
|
branchesController := controllers.NewBranchesController(common)
|
||||||
gitFlowController := controllers.NewGitFlowController(common)
|
gitFlowController := controllers.NewGitFlowController(common)
|
||||||
filesRemoveController := controllers.NewFilesRemoveController(common)
|
|
||||||
stashController := controllers.NewStashController(common)
|
stashController := controllers.NewStashController(common)
|
||||||
commitFilesController := controllers.NewCommitFilesController(common)
|
commitFilesController := controllers.NewCommitFilesController(common)
|
||||||
patchExplorerControllerFactory := controllers.NewPatchExplorerControllerFactory(common)
|
patchExplorerControllerFactory := controllers.NewPatchExplorerControllerFactory(common)
|
||||||
@@ -297,7 +296,6 @@ func (gui *Gui) resetHelpersAndControllers() {
|
|||||||
|
|
||||||
controllers.AttachControllers(gui.State.Contexts.Files,
|
controllers.AttachControllers(gui.State.Contexts.Files,
|
||||||
filesController,
|
filesController,
|
||||||
filesRemoveController,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
controllers.AttachControllers(gui.State.Contexts.Tags,
|
controllers.AttachControllers(gui.State.Contexts.Tags,
|
||||||
|
@@ -9,6 +9,7 @@ import (
|
|||||||
"github.com/jesseduffield/lazygit/pkg/gui/context"
|
"github.com/jesseduffield/lazygit/pkg/gui/context"
|
||||||
"github.com/jesseduffield/lazygit/pkg/gui/filetree"
|
"github.com/jesseduffield/lazygit/pkg/gui/filetree"
|
||||||
"github.com/jesseduffield/lazygit/pkg/gui/types"
|
"github.com/jesseduffield/lazygit/pkg/gui/types"
|
||||||
|
"github.com/jesseduffield/lazygit/pkg/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
type FilesController struct {
|
type FilesController struct {
|
||||||
@@ -124,6 +125,13 @@ func (self *FilesController) GetKeybindings(opts types.KeybindingsOpts) []*types
|
|||||||
GetDisabledReason: self.require(self.singleItemSelected()),
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||||
Description: self.c.Tr.FileEnter,
|
Description: self.c.Tr.FileEnter,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Key: opts.GetKey(opts.Config.Universal.Remove),
|
||||||
|
Handler: self.withItem(self.remove),
|
||||||
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||||
|
Description: self.c.Tr.ViewDiscardOptions,
|
||||||
|
OpensMenu: true,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Commits.ViewResetOptions),
|
Key: opts.GetKey(opts.Config.Commits.ViewResetOptions),
|
||||||
Handler: self.createResetToUpstreamMenu,
|
Handler: self.createResetToUpstreamMenu,
|
||||||
@@ -963,3 +971,130 @@ func (self *FilesController) fetchAux(task gocui.Task) (err error) {
|
|||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (self *FilesController) remove(node *filetree.FileNode) error {
|
||||||
|
var menuItems []*types.MenuItem
|
||||||
|
if node.File == nil {
|
||||||
|
menuItems = []*types.MenuItem{
|
||||||
|
{
|
||||||
|
Label: self.c.Tr.DiscardAllChanges,
|
||||||
|
OnPress: func() error {
|
||||||
|
self.c.LogAction(self.c.Tr.Actions.DiscardAllChangesInDirectory)
|
||||||
|
if err := self.c.Git().WorkingTree.DiscardAllDirChanges(node); err != nil {
|
||||||
|
return self.c.Error(err)
|
||||||
|
}
|
||||||
|
return self.c.Refresh(types.RefreshOptions{Mode: types.ASYNC, Scope: []types.RefreshableView{types.FILES, types.WORKTREES}})
|
||||||
|
},
|
||||||
|
Key: self.c.KeybindingsOpts().GetKey(self.c.UserConfig.Keybinding.Files.ConfirmDiscard),
|
||||||
|
Tooltip: utils.ResolvePlaceholderString(
|
||||||
|
self.c.Tr.DiscardAllTooltip,
|
||||||
|
map[string]string{
|
||||||
|
"path": node.GetPath(),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
if node.GetHasStagedChanges() && node.GetHasUnstagedChanges() {
|
||||||
|
menuItems = append(menuItems, &types.MenuItem{
|
||||||
|
Label: self.c.Tr.DiscardUnstagedChanges,
|
||||||
|
OnPress: func() error {
|
||||||
|
self.c.LogAction(self.c.Tr.Actions.DiscardUnstagedChangesInDirectory)
|
||||||
|
if err := self.c.Git().WorkingTree.DiscardUnstagedDirChanges(node); err != nil {
|
||||||
|
return self.c.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return self.c.Refresh(types.RefreshOptions{Mode: types.ASYNC, Scope: []types.RefreshableView{types.FILES, types.WORKTREES}})
|
||||||
|
},
|
||||||
|
Key: 'u',
|
||||||
|
Tooltip: utils.ResolvePlaceholderString(
|
||||||
|
self.c.Tr.DiscardUnstagedTooltip,
|
||||||
|
map[string]string{
|
||||||
|
"path": node.GetPath(),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
file := node.File
|
||||||
|
|
||||||
|
submodules := self.c.Model().Submodules
|
||||||
|
if file.IsSubmodule(submodules) {
|
||||||
|
submodule := file.SubmoduleConfig(submodules)
|
||||||
|
|
||||||
|
menuItems = []*types.MenuItem{
|
||||||
|
{
|
||||||
|
Label: self.c.Tr.SubmoduleStashAndReset,
|
||||||
|
OnPress: func() error {
|
||||||
|
return self.ResetSubmodule(submodule)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
menuItems = []*types.MenuItem{
|
||||||
|
{
|
||||||
|
Label: self.c.Tr.DiscardAllChanges,
|
||||||
|
OnPress: func() error {
|
||||||
|
self.c.LogAction(self.c.Tr.Actions.DiscardAllChangesInFile)
|
||||||
|
if err := self.c.Git().WorkingTree.DiscardAllFileChanges(file); err != nil {
|
||||||
|
return self.c.Error(err)
|
||||||
|
}
|
||||||
|
return self.c.Refresh(types.RefreshOptions{Mode: types.ASYNC, Scope: []types.RefreshableView{types.FILES, types.WORKTREES}})
|
||||||
|
},
|
||||||
|
Key: self.c.KeybindingsOpts().GetKey(self.c.UserConfig.Keybinding.Files.ConfirmDiscard),
|
||||||
|
Tooltip: utils.ResolvePlaceholderString(
|
||||||
|
self.c.Tr.DiscardAllTooltip,
|
||||||
|
map[string]string{
|
||||||
|
"path": node.GetPath(),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
if file.HasStagedChanges && file.HasUnstagedChanges {
|
||||||
|
menuItems = append(menuItems, &types.MenuItem{
|
||||||
|
Label: self.c.Tr.DiscardUnstagedChanges,
|
||||||
|
OnPress: func() error {
|
||||||
|
self.c.LogAction(self.c.Tr.Actions.DiscardAllUnstagedChangesInFile)
|
||||||
|
if err := self.c.Git().WorkingTree.DiscardUnstagedFileChanges(file); err != nil {
|
||||||
|
return self.c.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return self.c.Refresh(types.RefreshOptions{Mode: types.ASYNC, Scope: []types.RefreshableView{types.FILES, types.WORKTREES}})
|
||||||
|
},
|
||||||
|
Key: 'u',
|
||||||
|
Tooltip: utils.ResolvePlaceholderString(
|
||||||
|
self.c.Tr.DiscardUnstagedTooltip,
|
||||||
|
map[string]string{
|
||||||
|
"path": node.GetPath(),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return self.c.Menu(types.CreateMenuOptions{Title: node.GetPath(), Items: menuItems})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *FilesController) ResetSubmodule(submodule *models.SubmoduleConfig) error {
|
||||||
|
return self.c.WithWaitingStatus(self.c.Tr.ResettingSubmoduleStatus, func(gocui.Task) error {
|
||||||
|
self.c.LogAction(self.c.Tr.Actions.ResetSubmodule)
|
||||||
|
|
||||||
|
file := self.c.Helpers().WorkingTree.FileForSubmodule(submodule)
|
||||||
|
if file != nil {
|
||||||
|
if err := self.c.Git().WorkingTree.UnStageFile(file.Names(), file.Tracked); err != nil {
|
||||||
|
return self.c.Error(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := self.c.Git().Submodule.Stash(submodule); err != nil {
|
||||||
|
return self.c.Error(err)
|
||||||
|
}
|
||||||
|
if err := self.c.Git().Submodule.Reset(submodule); err != nil {
|
||||||
|
return self.c.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return self.c.Refresh(types.RefreshOptions{Mode: types.ASYNC, Scope: []types.RefreshableView{types.FILES, types.SUBMODULES}})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
@@ -1,175 +0,0 @@
|
|||||||
package controllers
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/jesseduffield/gocui"
|
|
||||||
"github.com/jesseduffield/lazygit/pkg/commands/models"
|
|
||||||
"github.com/jesseduffield/lazygit/pkg/gui/filetree"
|
|
||||||
"github.com/jesseduffield/lazygit/pkg/gui/types"
|
|
||||||
"github.com/jesseduffield/lazygit/pkg/utils"
|
|
||||||
)
|
|
||||||
|
|
||||||
// splitting this action out into its own file because it's self-contained
|
|
||||||
|
|
||||||
type FilesRemoveController struct {
|
|
||||||
baseController
|
|
||||||
*ListControllerTrait[*filetree.FileNode]
|
|
||||||
c *ControllerCommon
|
|
||||||
}
|
|
||||||
|
|
||||||
var _ types.IController = &FilesRemoveController{}
|
|
||||||
|
|
||||||
func NewFilesRemoveController(
|
|
||||||
c *ControllerCommon,
|
|
||||||
) *FilesRemoveController {
|
|
||||||
return &FilesRemoveController{
|
|
||||||
baseController: baseController{},
|
|
||||||
c: c,
|
|
||||||
ListControllerTrait: NewListControllerTrait[*filetree.FileNode](
|
|
||||||
c,
|
|
||||||
c.Contexts().Files,
|
|
||||||
c.Contexts().Files.GetSelected,
|
|
||||||
c.Contexts().Files.GetSelectedItems,
|
|
||||||
),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *FilesRemoveController) GetKeybindings(opts types.KeybindingsOpts) []*types.Binding {
|
|
||||||
bindings := []*types.Binding{
|
|
||||||
{
|
|
||||||
Key: opts.GetKey(opts.Config.Universal.Remove),
|
|
||||||
Handler: self.withItem(self.remove),
|
|
||||||
GetDisabledReason: self.require(self.singleItemSelected()),
|
|
||||||
Description: self.c.Tr.ViewDiscardOptions,
|
|
||||||
OpensMenu: true,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
return bindings
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *FilesRemoveController) remove(node *filetree.FileNode) error {
|
|
||||||
var menuItems []*types.MenuItem
|
|
||||||
if node.File == nil {
|
|
||||||
menuItems = []*types.MenuItem{
|
|
||||||
{
|
|
||||||
Label: self.c.Tr.DiscardAllChanges,
|
|
||||||
OnPress: func() error {
|
|
||||||
self.c.LogAction(self.c.Tr.Actions.DiscardAllChangesInDirectory)
|
|
||||||
if err := self.c.Git().WorkingTree.DiscardAllDirChanges(node); err != nil {
|
|
||||||
return self.c.Error(err)
|
|
||||||
}
|
|
||||||
return self.c.Refresh(types.RefreshOptions{Mode: types.ASYNC, Scope: []types.RefreshableView{types.FILES, types.WORKTREES}})
|
|
||||||
},
|
|
||||||
Key: self.c.KeybindingsOpts().GetKey(self.c.UserConfig.Keybinding.Files.ConfirmDiscard),
|
|
||||||
Tooltip: utils.ResolvePlaceholderString(
|
|
||||||
self.c.Tr.DiscardAllTooltip,
|
|
||||||
map[string]string{
|
|
||||||
"path": node.GetPath(),
|
|
||||||
},
|
|
||||||
),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
if node.GetHasStagedChanges() && node.GetHasUnstagedChanges() {
|
|
||||||
menuItems = append(menuItems, &types.MenuItem{
|
|
||||||
Label: self.c.Tr.DiscardUnstagedChanges,
|
|
||||||
OnPress: func() error {
|
|
||||||
self.c.LogAction(self.c.Tr.Actions.DiscardUnstagedChangesInDirectory)
|
|
||||||
if err := self.c.Git().WorkingTree.DiscardUnstagedDirChanges(node); err != nil {
|
|
||||||
return self.c.Error(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return self.c.Refresh(types.RefreshOptions{Mode: types.ASYNC, Scope: []types.RefreshableView{types.FILES, types.WORKTREES}})
|
|
||||||
},
|
|
||||||
Key: 'u',
|
|
||||||
Tooltip: utils.ResolvePlaceholderString(
|
|
||||||
self.c.Tr.DiscardUnstagedTooltip,
|
|
||||||
map[string]string{
|
|
||||||
"path": node.GetPath(),
|
|
||||||
},
|
|
||||||
),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
file := node.File
|
|
||||||
|
|
||||||
submodules := self.c.Model().Submodules
|
|
||||||
if file.IsSubmodule(submodules) {
|
|
||||||
submodule := file.SubmoduleConfig(submodules)
|
|
||||||
|
|
||||||
menuItems = []*types.MenuItem{
|
|
||||||
{
|
|
||||||
Label: self.c.Tr.SubmoduleStashAndReset,
|
|
||||||
OnPress: func() error {
|
|
||||||
return self.ResetSubmodule(submodule)
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
menuItems = []*types.MenuItem{
|
|
||||||
{
|
|
||||||
Label: self.c.Tr.DiscardAllChanges,
|
|
||||||
OnPress: func() error {
|
|
||||||
self.c.LogAction(self.c.Tr.Actions.DiscardAllChangesInFile)
|
|
||||||
if err := self.c.Git().WorkingTree.DiscardAllFileChanges(file); err != nil {
|
|
||||||
return self.c.Error(err)
|
|
||||||
}
|
|
||||||
return self.c.Refresh(types.RefreshOptions{Mode: types.ASYNC, Scope: []types.RefreshableView{types.FILES, types.WORKTREES}})
|
|
||||||
},
|
|
||||||
Key: self.c.KeybindingsOpts().GetKey(self.c.UserConfig.Keybinding.Files.ConfirmDiscard),
|
|
||||||
Tooltip: utils.ResolvePlaceholderString(
|
|
||||||
self.c.Tr.DiscardAllTooltip,
|
|
||||||
map[string]string{
|
|
||||||
"path": node.GetPath(),
|
|
||||||
},
|
|
||||||
),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
if file.HasStagedChanges && file.HasUnstagedChanges {
|
|
||||||
menuItems = append(menuItems, &types.MenuItem{
|
|
||||||
Label: self.c.Tr.DiscardUnstagedChanges,
|
|
||||||
OnPress: func() error {
|
|
||||||
self.c.LogAction(self.c.Tr.Actions.DiscardAllUnstagedChangesInFile)
|
|
||||||
if err := self.c.Git().WorkingTree.DiscardUnstagedFileChanges(file); err != nil {
|
|
||||||
return self.c.Error(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return self.c.Refresh(types.RefreshOptions{Mode: types.ASYNC, Scope: []types.RefreshableView{types.FILES, types.WORKTREES}})
|
|
||||||
},
|
|
||||||
Key: 'u',
|
|
||||||
Tooltip: utils.ResolvePlaceholderString(
|
|
||||||
self.c.Tr.DiscardUnstagedTooltip,
|
|
||||||
map[string]string{
|
|
||||||
"path": node.GetPath(),
|
|
||||||
},
|
|
||||||
),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return self.c.Menu(types.CreateMenuOptions{Title: node.GetPath(), Items: menuItems})
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *FilesRemoveController) ResetSubmodule(submodule *models.SubmoduleConfig) error {
|
|
||||||
return self.c.WithWaitingStatus(self.c.Tr.ResettingSubmoduleStatus, func(gocui.Task) error {
|
|
||||||
self.c.LogAction(self.c.Tr.Actions.ResetSubmodule)
|
|
||||||
|
|
||||||
file := self.c.Helpers().WorkingTree.FileForSubmodule(submodule)
|
|
||||||
if file != nil {
|
|
||||||
if err := self.c.Git().WorkingTree.UnStageFile(file.Names(), file.Tracked); err != nil {
|
|
||||||
return self.c.Error(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := self.c.Git().Submodule.Stash(submodule); err != nil {
|
|
||||||
return self.c.Error(err)
|
|
||||||
}
|
|
||||||
if err := self.c.Git().Submodule.Reset(submodule); err != nil {
|
|
||||||
return self.c.Error(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return self.c.Refresh(types.RefreshOptions{Mode: types.ASYNC, Scope: []types.RefreshableView{types.FILES, types.SUBMODULES}})
|
|
||||||
})
|
|
||||||
}
|
|
Reference in New Issue
Block a user