mirror of
				https://github.com/jesseduffield/lazygit.git
				synced 2025-10-30 23:57:43 +02: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) | ||||
| 	gitFlowController := controllers.NewGitFlowController(common) | ||||
| 	filesRemoveController := controllers.NewFilesRemoveController(common) | ||||
| 	stashController := controllers.NewStashController(common) | ||||
| 	commitFilesController := controllers.NewCommitFilesController(common) | ||||
| 	patchExplorerControllerFactory := controllers.NewPatchExplorerControllerFactory(common) | ||||
| @@ -297,7 +296,6 @@ func (gui *Gui) resetHelpersAndControllers() { | ||||
|  | ||||
| 	controllers.AttachControllers(gui.State.Contexts.Files, | ||||
| 		filesController, | ||||
| 		filesRemoveController, | ||||
| 	) | ||||
|  | ||||
| 	controllers.AttachControllers(gui.State.Contexts.Tags, | ||||
|   | ||||
| @@ -9,6 +9,7 @@ import ( | ||||
| 	"github.com/jesseduffield/lazygit/pkg/gui/context" | ||||
| 	"github.com/jesseduffield/lazygit/pkg/gui/filetree" | ||||
| 	"github.com/jesseduffield/lazygit/pkg/gui/types" | ||||
| 	"github.com/jesseduffield/lazygit/pkg/utils" | ||||
| ) | ||||
|  | ||||
| type FilesController struct { | ||||
| @@ -124,6 +125,13 @@ func (self *FilesController) GetKeybindings(opts types.KeybindingsOpts) []*types | ||||
| 			GetDisabledReason: self.require(self.singleItemSelected()), | ||||
| 			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), | ||||
| 			Handler:     self.createResetToUpstreamMenu, | ||||
| @@ -963,3 +971,130 @@ func (self *FilesController) fetchAux(task gocui.Task) (err error) { | ||||
|  | ||||
| 	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