mirror of
				https://github.com/jesseduffield/lazygit.git
				synced 2025-10-30 23:57:43 +02:00 
			
		
		
		
	allow submodule init and show submodule diff with a prefix
This commit is contained in:
		| @@ -164,6 +164,8 @@ Default path for the config file: | ||||
|       toggleDragSelect-alt: 'V' | ||||
|       toggleSelectHunk: 'a' | ||||
|       pickBothHunks: 'b' | ||||
|     submodules: | ||||
|       init: 'i' | ||||
| ``` | ||||
|  | ||||
| ## Platform Defaults | ||||
|   | ||||
| @@ -35,7 +35,7 @@ func (c *GitCommand) UnstageAll() error { | ||||
|  | ||||
| // UnStageFile unstages a file | ||||
| func (c *GitCommand) UnStageFile(fileName string, tracked bool) error { | ||||
| 	command := "git rm --cached %s" | ||||
| 	command := "git rm --cached --force %s" | ||||
| 	if tracked { | ||||
| 		command = "git reset HEAD %s" | ||||
| 	} | ||||
|   | ||||
| @@ -123,5 +123,8 @@ func (c *GitCommand) SubmoduleUpdateUrl(name string, path string, newUrl string) | ||||
| 	} | ||||
|  | ||||
| 	return c.OSCommand.RunCommand("git submodule sync %s", path) | ||||
|  | ||||
| } | ||||
|  | ||||
| func (c *GitCommand) SubmoduleInit(path string) error { | ||||
| 	return c.OSCommand.RunCommand("git submodule init %s", path) | ||||
| } | ||||
|   | ||||
| @@ -393,6 +393,8 @@ keybinding: | ||||
|     toggleDragSelect-alt: 'V' | ||||
|     toggleSelectHunk: 'a' | ||||
|     pickBothHunks: 'b' | ||||
|   submodules: | ||||
|     init: 'i' | ||||
| `) | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -446,17 +446,6 @@ func (gui *Gui) refreshStateFiles() error { | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (gui *Gui) refreshStateSubmoduleConfigs() error { | ||||
| 	configs, err := gui.GitCommand.GetSubmoduleConfigs() | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	gui.State.Submodules = configs | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (gui *Gui) handlePullFiles(g *gocui.Gui, v *gocui.View) error { | ||||
| 	if gui.popupPanelFocused() { | ||||
| 		return nil | ||||
|   | ||||
| @@ -1560,13 +1560,6 @@ 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"), | ||||
| @@ -1586,19 +1579,26 @@ func (gui *Gui) GetInitialKeybindings() []*Binding { | ||||
| 			Handler:     gui.wrappedHandler(gui.handleCopySelectedSideContextItemToClipboard), | ||||
| 			Description: gui.Tr.SLocalize("copySubmoduleNameToClipboard"), | ||||
| 		}, | ||||
| 		{ | ||||
| 			ViewName:    "files", | ||||
| 			Contexts:    []string{SUBMODULES_CONTEXT_KEY}, | ||||
| 			Key:         gui.getKey("universal.goInto"), | ||||
| 			Handler:     gui.forSubmodule(gui.handleSubmoduleEnter), | ||||
| 			Description: gui.Tr.SLocalize("enterSubmodule"), | ||||
| 		}, | ||||
| 		{ | ||||
| 			ViewName: "files", | ||||
| 			Contexts: []string{SUBMODULES_CONTEXT_KEY}, | ||||
| 			Key:      gui.getKey("universal.remove"), | ||||
|  | ||||
| 			Handler:     gui.wrappedHandler(gui.handleRemoveSubmodule), | ||||
| 			Handler:     gui.forSubmodule(gui.handleRemoveSubmodule), | ||||
| 			Description: gui.Tr.SLocalize("removeSubmodule"), | ||||
| 		}, | ||||
| 		{ | ||||
| 			ViewName:    "files", | ||||
| 			Contexts:    []string{SUBMODULES_CONTEXT_KEY}, | ||||
| 			Key:         gui.getKey("u"), | ||||
| 			Handler:     gui.wrappedHandler(gui.handleResetSubmodule), | ||||
| 			Handler:     gui.forSubmodule(gui.handleResetSubmodule), | ||||
| 			Description: gui.Tr.SLocalize("submoduleStashAndReset"), | ||||
| 		}, | ||||
| 		{ | ||||
| @@ -1612,9 +1612,16 @@ func (gui *Gui) GetInitialKeybindings() []*Binding { | ||||
| 			ViewName:    "files", | ||||
| 			Contexts:    []string{SUBMODULES_CONTEXT_KEY}, | ||||
| 			Key:         gui.getKey("universal.edit"), | ||||
| 			Handler:     gui.wrappedHandler(gui.handleEditSubmoduleUrl), | ||||
| 			Handler:     gui.forSubmodule(gui.handleEditSubmoduleUrl), | ||||
| 			Description: gui.Tr.SLocalize("editSubmoduleUrl"), | ||||
| 		}, | ||||
| 		{ | ||||
| 			ViewName:    "files", | ||||
| 			Contexts:    []string{SUBMODULES_CONTEXT_KEY}, | ||||
| 			Key:         gui.getKey("submodules.init"), | ||||
| 			Handler:     gui.forSubmodule(gui.handleSubmoduleInit), | ||||
| 			Description: gui.Tr.SLocalize("initSubmodule"), | ||||
| 		}, | ||||
| 	} | ||||
|  | ||||
| 	for _, viewName := range []string{"status", "branches", "files", "commits", "commitFiles", "stash", "menu"} { | ||||
|   | ||||
| @@ -62,7 +62,8 @@ func (gui *Gui) createRenderStringWithoutScrollTask(str string) *renderStringWit | ||||
| } | ||||
|  | ||||
| type runCommandTask struct { | ||||
| 	cmd *exec.Cmd | ||||
| 	cmd    *exec.Cmd | ||||
| 	prefix string | ||||
| } | ||||
|  | ||||
| func (t *runCommandTask) GetKind() int { | ||||
| @@ -73,8 +74,13 @@ func (gui *Gui) createRunCommandTask(cmd *exec.Cmd) *runCommandTask { | ||||
| 	return &runCommandTask{cmd: cmd} | ||||
| } | ||||
|  | ||||
| func (gui *Gui) createRunCommandTaskWithPrefix(cmd *exec.Cmd, prefix string) *runCommandTask { | ||||
| 	return &runCommandTask{cmd: cmd, prefix: prefix} | ||||
| } | ||||
|  | ||||
| type runPtyTask struct { | ||||
| 	cmd *exec.Cmd | ||||
| 	cmd    *exec.Cmd | ||||
| 	prefix string | ||||
| } | ||||
|  | ||||
| func (t *runPtyTask) GetKind() int { | ||||
| @@ -85,6 +91,10 @@ func (gui *Gui) createRunPtyTask(cmd *exec.Cmd) *runPtyTask { | ||||
| 	return &runPtyTask{cmd: cmd} | ||||
| } | ||||
|  | ||||
| func (gui *Gui) createRunPtyTaskWithPrefix(cmd *exec.Cmd, prefix string) *runPtyTask { | ||||
| 	return &runPtyTask{cmd: cmd, prefix: prefix} | ||||
| } | ||||
|  | ||||
| type runFunctionTask struct { | ||||
| 	f func(chan struct{}) error | ||||
| } | ||||
| @@ -113,11 +123,11 @@ func (gui *Gui) runTaskForView(viewName string, task updateTask) error { | ||||
|  | ||||
| 	case RUN_COMMAND: | ||||
| 		specificTask := task.(*runCommandTask) | ||||
| 		return gui.newCmdTask(viewName, specificTask.cmd) | ||||
| 		return gui.newCmdTask(viewName, specificTask.cmd, specificTask.prefix) | ||||
|  | ||||
| 	case RUN_PTY: | ||||
| 		specificTask := task.(*runPtyTask) | ||||
| 		return gui.newPtyTask(viewName, specificTask.cmd) | ||||
| 		return gui.newPtyTask(viewName, specificTask.cmd, specificTask.prefix) | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
|   | ||||
| @@ -30,13 +30,13 @@ func (gui *Gui) onResize() error { | ||||
| // which is just an io.Reader. the pty package lets us wrap a command in a | ||||
| // pseudo-terminal meaning we'll get the behaviour we want from the underlying | ||||
| // command. | ||||
| func (gui *Gui) newPtyTask(viewName string, cmd *exec.Cmd) error { | ||||
| func (gui *Gui) newPtyTask(viewName string, cmd *exec.Cmd, prefix string) error { | ||||
| 	width, _ := gui.getMainView().Size() | ||||
| 	pager := gui.GitCommand.GetPager(width) | ||||
|  | ||||
| 	if pager == "" { | ||||
| 		// if we're not using a custom pager we don't need to use a pty | ||||
| 		return gui.newCmdTask(viewName, cmd) | ||||
| 		return gui.newCmdTask(viewName, cmd, prefix) | ||||
| 	} | ||||
|  | ||||
| 	cmd.Env = append(cmd.Env, "GIT_PAGER="+pager) | ||||
| @@ -66,7 +66,7 @@ func (gui *Gui) newPtyTask(viewName string, cmd *exec.Cmd) error { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	if err := manager.NewTask(manager.NewCmdTask(ptmx, cmd, height+oy+10, onClose)); err != nil { | ||||
| 	if err := manager.NewTask(manager.NewCmdTask(ptmx, cmd, prefix, height+oy+10, onClose)); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
|   | ||||
| @@ -7,6 +7,7 @@ import ( | ||||
| 	"strings" | ||||
|  | ||||
| 	"github.com/fatih/color" | ||||
| 	"github.com/jesseduffield/gocui" | ||||
| 	"github.com/jesseduffield/lazygit/pkg/commands/models" | ||||
| 	"github.com/jesseduffield/lazygit/pkg/utils" | ||||
| ) | ||||
| @@ -26,16 +27,21 @@ func (gui *Gui) handleSubmoduleSelect() error { | ||||
| 	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), | ||||
| 			), | ||||
| 		prefix := fmt.Sprintf( | ||||
| 			"Name: %s\nPath: %s\nUrl:  %s\n\n", | ||||
| 			utils.ColoredString(submodule.Name, color.FgGreen), | ||||
| 			utils.ColoredString(submodule.Path, color.FgYellow), | ||||
| 			utils.ColoredString(submodule.Url, color.FgCyan), | ||||
| 		) | ||||
|  | ||||
| 		file := gui.fileForSubmodule(submodule) | ||||
| 		if file == nil { | ||||
| 			task = gui.createRenderStringTask(prefix) | ||||
| 		} else { | ||||
| 			cmdStr := gui.GitCommand.WorktreeFileDiffCmdStr(file, false, !file.HasUnstagedChanges && file.HasStagedChanges) | ||||
| 			cmd := gui.OSCommand.ExecutableFromString(cmdStr) | ||||
| 			task = gui.createRunCommandTaskWithPrefix(cmd, prefix) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return gui.refreshMainViews(refreshMainOpts{ | ||||
| @@ -46,12 +52,18 @@ func (gui *Gui) handleSubmoduleSelect() error { | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| func (gui *Gui) handleSubmoduleEnter() error { | ||||
| 	submodule := gui.getSelectedSubmodule() | ||||
| 	if submodule == nil { | ||||
| 		return nil | ||||
| func (gui *Gui) refreshStateSubmoduleConfigs() error { | ||||
| 	configs, err := gui.GitCommand.GetSubmoduleConfigs() | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	gui.State.Submodules = configs | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (gui *Gui) handleSubmoduleEnter(submodule *models.SubmoduleConfig) error { | ||||
| 	return gui.enterSubmodule(submodule) | ||||
| } | ||||
|  | ||||
| @@ -65,12 +77,7 @@ func (gui *Gui) enterSubmodule(submodule *models.SubmoduleConfig) error { | ||||
| 	return gui.dispatchSwitchToRepo(submodule.Path) | ||||
| } | ||||
|  | ||||
| func (gui *Gui) handleRemoveSubmodule() error { | ||||
| 	submodule := gui.getSelectedSubmodule() | ||||
| 	if submodule == nil { | ||||
| 		return nil | ||||
| 	} | ||||
|  | ||||
| func (gui *Gui) handleRemoveSubmodule(submodule *models.SubmoduleConfig) error { | ||||
| 	return gui.ask(askOpts{ | ||||
| 		title:  gui.Tr.SLocalize("RemoveSubmodule"), | ||||
| 		prompt: gui.Tr.SLocalizef("RemoveSubmodulePrompt", submodule.Name), | ||||
| @@ -84,13 +91,8 @@ func (gui *Gui) handleRemoveSubmodule() error { | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| func (gui *Gui) handleResetSubmodule() error { | ||||
| func (gui *Gui) handleResetSubmodule(submodule *models.SubmoduleConfig) error { | ||||
| 	return gui.WithWaitingStatus(gui.Tr.SLocalize("resettingSubmoduleStatus"), func() error { | ||||
| 		submodule := gui.getSelectedSubmodule() | ||||
| 		if submodule == nil { | ||||
| 			return nil | ||||
| 		} | ||||
|  | ||||
| 		return gui.resetSubmodule(submodule) | ||||
| 	}) | ||||
| } | ||||
| @@ -140,12 +142,7 @@ func (gui *Gui) handleAddSubmodule() error { | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| func (gui *Gui) handleEditSubmoduleUrl() error { | ||||
| 	submodule := gui.getSelectedSubmodule() | ||||
| 	if submodule == nil { | ||||
| 		return nil | ||||
| 	} | ||||
|  | ||||
| func (gui *Gui) handleEditSubmoduleUrl(submodule *models.SubmoduleConfig) error { | ||||
| 	return gui.prompt(gui.Tr.SLocalizef("updateSubmoduleUrl", submodule.Name), submodule.Url, func(newUrl string) error { | ||||
| 		return gui.WithWaitingStatus(gui.Tr.SLocalize("updatingSubmoduleUrlStatus"), func() error { | ||||
| 			err := gui.GitCommand.SubmoduleUpdateUrl(submodule.Name, submodule.Path, newUrl) | ||||
| @@ -156,44 +153,24 @@ func (gui *Gui) handleEditSubmoduleUrl() error { | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| // func (gui *Gui) handleEditsubmodule(g *gocui.Gui, v *gocui.View) error { | ||||
| // 	submodule := gui.getSelectedSubmodule() | ||||
| // 	if submodule == nil { | ||||
| // 		return nil | ||||
| // 	} | ||||
| func (gui *Gui) handleSubmoduleInit(submodule *models.SubmoduleConfig) error { | ||||
| 	return gui.WithWaitingStatus(gui.Tr.SLocalize("initializingSubmoduleStatus"), func() error { | ||||
| 		err := gui.GitCommand.SubmoduleInit(submodule.Path) | ||||
| 		gui.handleCredentialsPopup(err) | ||||
|  | ||||
| // 	editNameMessage := gui.Tr.TemplateLocalize( | ||||
| // 		"editsubmoduleName", | ||||
| // 		Teml{ | ||||
| // 			"submoduleName": submodule.Name, | ||||
| // 		}, | ||||
| // 	) | ||||
| 		return gui.refreshSidePanels(refreshOptions{scope: []int{SUBMODULES}}) | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| // 	return gui.prompt(editNameMessage, submodule.Name, func(updatedsubmoduleName string) error { | ||||
| // 		if updatedsubmoduleName != submodule.Name { | ||||
| // 			if err := gui.GitCommand.Renamesubmodule(submodule.Name, updatedsubmoduleName); err != nil { | ||||
| // 				return gui.surfaceError(err) | ||||
| // 			} | ||||
| // 		} | ||||
| func (gui *Gui) forSubmodule(callback func(*models.SubmoduleConfig) error) func(g *gocui.Gui, v *gocui.View) error { | ||||
| 	return gui.wrappedHandler( | ||||
| 		func() error { | ||||
| 			submodule := gui.getSelectedSubmodule() | ||||
| 			if submodule == nil { | ||||
| 				return nil | ||||
| 			} | ||||
|  | ||||
| // 		editUrlMessage := gui.Tr.TemplateLocalize( | ||||
| // 			"editsubmoduleUrl", | ||||
| // 			Teml{ | ||||
| // 				"submoduleName": updatedsubmoduleName, | ||||
| // 			}, | ||||
| // 		) | ||||
|  | ||||
| // 		urls := submodule.Urls | ||||
| // 		url := "" | ||||
| // 		if len(urls) > 0 { | ||||
| // 			url = urls[0] | ||||
| // 		} | ||||
|  | ||||
| // 		return gui.prompt(editUrlMessage, url, func(updatedsubmoduleUrl string) error { | ||||
| // 			if err := gui.GitCommand.UpdatesubmoduleUrl(updatedsubmoduleName, updatedsubmoduleUrl); err != nil { | ||||
| // 				return gui.surfaceError(err) | ||||
| // 			} | ||||
| // 			return gui.refreshSidePanels(refreshOptions{scope: []int{BRANCHES, submoduleS}}) | ||||
| // 		}) | ||||
| // 	}) | ||||
| // } | ||||
| 			return callback(submodule) | ||||
| 		}, | ||||
| 	) | ||||
| } | ||||
|   | ||||
| @@ -8,7 +8,7 @@ import ( | ||||
| 	"github.com/jesseduffield/lazygit/pkg/tasks" | ||||
| ) | ||||
|  | ||||
| func (gui *Gui) newCmdTask(viewName string, cmd *exec.Cmd) error { | ||||
| func (gui *Gui) newCmdTask(viewName string, cmd *exec.Cmd, prefix string) error { | ||||
| 	gui.Log.WithField( | ||||
| 		"command", | ||||
| 		strings.Join(cmd.Args, " "), | ||||
| @@ -34,7 +34,7 @@ func (gui *Gui) newCmdTask(viewName string, cmd *exec.Cmd) error { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	if err := manager.NewTask(manager.NewCmdTask(r, cmd, height+oy+10, nil)); err != nil { | ||||
| 	if err := manager.NewTask(manager.NewCmdTask(r, cmd, prefix, height+oy+10, nil)); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
|   | ||||
| @@ -1239,6 +1239,12 @@ func addEnglish(i18nObject *i18n.Bundle) error { | ||||
| 		}, &i18n.Message{ | ||||
| 			ID:    "editSubmoduleUrl", | ||||
| 			Other: "update submodule URL", | ||||
| 		}, &i18n.Message{ | ||||
| 			ID:    "initializingSubmoduleStatus", | ||||
| 			Other: "initializing submodule", | ||||
| 		}, &i18n.Message{ | ||||
| 			ID:    "initSubmodule", | ||||
| 			Other: "initialize submodule", | ||||
| 		}, | ||||
| 	) | ||||
| } | ||||
|   | ||||
| @@ -46,7 +46,7 @@ func (m *ViewBufferManager) ReadLines(n int) { | ||||
| 	}() | ||||
| } | ||||
|  | ||||
| func (m *ViewBufferManager) NewCmdTask(r io.Reader, cmd *exec.Cmd, linesToRead int, onDone func()) func(chan struct{}) error { | ||||
| func (m *ViewBufferManager) NewCmdTask(r io.Reader, cmd *exec.Cmd, prefix string, linesToRead int, onDone func()) func(chan struct{}) error { | ||||
| 	return func(stop chan struct{}) error { | ||||
| 		go func() { | ||||
| 			<-stop | ||||
| @@ -99,6 +99,9 @@ func (m *ViewBufferManager) NewCmdTask(r io.Reader, cmd *exec.Cmd, linesToRead i | ||||
| 						loadingMutex.Lock() | ||||
| 						if !loaded { | ||||
| 							m.beforeStart() | ||||
| 							if prefix != "" { | ||||
| 								_, _ = m.writer.Write([]byte(prefix)) | ||||
| 							} | ||||
| 							loaded = true | ||||
| 						} | ||||
| 						loadingMutex.Unlock() | ||||
|   | ||||
		Reference in New Issue
	
	Block a user