mirror of
				https://github.com/jesseduffield/lazygit.git
				synced 2025-10-30 23:57:43 +02:00 
			
		
		
		
	Change direct access to Common.UserConfig to a getter
This will allow us to turn the field into an atomic.Value for safe concurrent access.
This commit is contained in:
		| @@ -71,14 +71,15 @@ func NewCommon(config config.AppConfigurer) (*common.Common, error) { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	return &common.Common{ | ||||
| 		Log:        log, | ||||
| 		Tr:         tr, | ||||
| 		UserConfig: userConfig, | ||||
| 		AppState:   appState, | ||||
| 		Debug:      config.GetDebug(), | ||||
| 		Fs:         afero.NewOsFs(), | ||||
| 	}, nil | ||||
| 	cmn := &common.Common{ | ||||
| 		Log:      log, | ||||
| 		Tr:       tr, | ||||
| 		AppState: appState, | ||||
| 		Debug:    config.GetDebug(), | ||||
| 		Fs:       afero.NewOsFs(), | ||||
| 	} | ||||
| 	cmn.SetUserConfig(userConfig) | ||||
| 	return cmn, nil | ||||
| } | ||||
|  | ||||
| func newLogger(cfg config.AppConfigurer) *logrus.Entry { | ||||
| @@ -195,7 +196,7 @@ func (app *App) setupRepo( | ||||
|  | ||||
| 		var shouldInitRepo bool | ||||
| 		initialBranchArg := "" | ||||
| 		switch app.UserConfig.NotARepository { | ||||
| 		switch app.UserConfig().NotARepository { | ||||
| 		case "prompt": | ||||
| 			// Offer to initialize a new repository in current directory. | ||||
| 			fmt.Print(app.Tr.CreateRepo) | ||||
|   | ||||
| @@ -145,7 +145,7 @@ func (self *BranchCommands) GetGraph(branchName string) (string, error) { | ||||
| } | ||||
|  | ||||
| func (self *BranchCommands) GetGraphCmdObj(branchName string) oscommands.ICmdObj { | ||||
| 	branchLogCmdTemplate := self.UserConfig.Git.BranchLogCmd | ||||
| 	branchLogCmdTemplate := self.UserConfig().Git.BranchLogCmd | ||||
| 	templateValues := map[string]string{ | ||||
| 		"branchName": self.cmd.Quote(branchName), | ||||
| 	} | ||||
| @@ -236,7 +236,7 @@ func (self *BranchCommands) Merge(branchName string, opts MergeOpts) error { | ||||
| 	} | ||||
| 	cmdArgs := NewGitCmd("merge"). | ||||
| 		Arg("--no-edit"). | ||||
| 		Arg(strings.Fields(self.UserConfig.Git.Merging.Args)...). | ||||
| 		Arg(strings.Fields(self.UserConfig().Git.Merging.Args)...). | ||||
| 		ArgIf(opts.FastForwardOnly, "--ff-only"). | ||||
| 		ArgIf(opts.Squash, "--squash", "--ff"). | ||||
| 		Arg(branchName). | ||||
| @@ -248,9 +248,9 @@ func (self *BranchCommands) Merge(branchName string, opts MergeOpts) error { | ||||
| func (self *BranchCommands) AllBranchesLogCmdObj() oscommands.ICmdObj { | ||||
| 	// Only choose between non-empty, non-identical commands | ||||
| 	candidates := lo.Uniq(lo.WithoutEmpty(append([]string{ | ||||
| 		self.UserConfig.Git.AllBranchesLogCmd, | ||||
| 		self.UserConfig().Git.AllBranchesLogCmd, | ||||
| 	}, | ||||
| 		self.UserConfig.Git.AllBranchesLogCmds..., | ||||
| 		self.UserConfig().Git.AllBranchesLogCmds..., | ||||
| 	))) | ||||
|  | ||||
| 	n := len(candidates) | ||||
|   | ||||
| @@ -140,7 +140,7 @@ func (self *BranchLoader) Load(reflogCommits []*models.Commit, | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if loadBehindCounts && self.UserConfig.Gui.ShowDivergenceFromBaseBranch != "none" { | ||||
| 	if loadBehindCounts && self.UserConfig().Gui.ShowDivergenceFromBaseBranch != "none" { | ||||
| 		onWorker(func() error { | ||||
| 			return self.GetBehindBaseBranchValuesForAllBranches(branches, mainBranches, renderFunc) | ||||
| 		}) | ||||
|   | ||||
| @@ -88,7 +88,7 @@ func (self *CommitCommands) ResetToCommit(hash string, strength string, envVars | ||||
| func (self *CommitCommands) CommitCmdObj(summary string, description string) oscommands.ICmdObj { | ||||
| 	messageArgs := self.commitMessageArgs(summary, description) | ||||
|  | ||||
| 	skipHookPrefix := self.UserConfig.Git.SkipHookPrefix | ||||
| 	skipHookPrefix := self.UserConfig().Git.SkipHookPrefix | ||||
|  | ||||
| 	cmdArgs := NewGitCmd("commit"). | ||||
| 		ArgIf(skipHookPrefix != "" && strings.HasPrefix(summary, skipHookPrefix), "--no-verify"). | ||||
| @@ -148,7 +148,7 @@ func (self *CommitCommands) CommitEditorCmdObj() oscommands.ICmdObj { | ||||
| } | ||||
|  | ||||
| func (self *CommitCommands) signoffFlag() string { | ||||
| 	if self.UserConfig.Git.Commit.SignOff { | ||||
| 	if self.UserConfig().Git.Commit.SignOff { | ||||
| 		return "--signoff" | ||||
| 	} else { | ||||
| 		return "" | ||||
| @@ -258,13 +258,13 @@ func (self *CommitCommands) AmendHeadCmdObj() oscommands.ICmdObj { | ||||
| func (self *CommitCommands) ShowCmdObj(hash string, filterPath string) oscommands.ICmdObj { | ||||
| 	contextSize := self.AppState.DiffContextSize | ||||
|  | ||||
| 	extDiffCmd := self.UserConfig.Git.Paging.ExternalDiffCommand | ||||
| 	extDiffCmd := self.UserConfig().Git.Paging.ExternalDiffCommand | ||||
| 	cmdArgs := NewGitCmd("show"). | ||||
| 		Config("diff.noprefix=false"). | ||||
| 		ConfigIf(extDiffCmd != "", "diff.external="+extDiffCmd). | ||||
| 		ArgIfElse(extDiffCmd != "", "--ext-diff", "--no-ext-diff"). | ||||
| 		Arg("--submodule"). | ||||
| 		Arg("--color="+self.UserConfig.Git.Paging.ColorArg). | ||||
| 		Arg("--color="+self.UserConfig().Git.Paging.ColorArg). | ||||
| 		Arg(fmt.Sprintf("--unified=%d", contextSize)). | ||||
| 		Arg("--stat"). | ||||
| 		Arg("--decorate"). | ||||
|   | ||||
| @@ -322,7 +322,7 @@ func TestGetCommits(t *testing.T) { | ||||
| 				}, | ||||
| 			} | ||||
|  | ||||
| 			common.UserConfig.Git.MainBranches = scenario.mainBranches | ||||
| 			common.UserConfig().Git.MainBranches = scenario.mainBranches | ||||
| 			opts := scenario.opts | ||||
| 			opts.MainBranches = NewMainBranches(scenario.mainBranches, cmd) | ||||
| 			commits, err := builder.GetCommits(opts) | ||||
|   | ||||
| @@ -43,7 +43,7 @@ func (self *ConfigCommands) ConfiguredPager() string { | ||||
| } | ||||
|  | ||||
| func (self *ConfigCommands) GetPager(width int) string { | ||||
| 	useConfig := self.UserConfig.Git.Paging.UseConfig | ||||
| 	useConfig := self.UserConfig().Git.Paging.UseConfig | ||||
| 	if useConfig { | ||||
| 		pager := self.ConfiguredPager() | ||||
| 		return strings.Split(pager, "| less")[0] | ||||
| @@ -53,14 +53,14 @@ func (self *ConfigCommands) GetPager(width int) string { | ||||
| 		"columnWidth": strconv.Itoa(width/2 - 6), | ||||
| 	} | ||||
|  | ||||
| 	pagerTemplate := string(self.UserConfig.Git.Paging.Pager) | ||||
| 	pagerTemplate := string(self.UserConfig().Git.Paging.Pager) | ||||
| 	return utils.ResolvePlaceholderString(pagerTemplate, templateValues) | ||||
| } | ||||
|  | ||||
| // UsingGpg tells us whether the user has gpg enabled so that we can know | ||||
| // whether we need to run a subprocess to allow them to enter their password | ||||
| func (self *ConfigCommands) UsingGpg() bool { | ||||
| 	overrideGpg := self.UserConfig.Git.OverrideGpg | ||||
| 	overrideGpg := self.UserConfig().Git.OverrideGpg | ||||
| 	if overrideGpg { | ||||
| 		return false | ||||
| 	} | ||||
|   | ||||
| @@ -58,9 +58,9 @@ func buildGitCommon(deps commonDeps) *GitCommon { | ||||
| 	} | ||||
| 	gitCommon.cmd = cmd | ||||
|  | ||||
| 	gitCommon.Common.UserConfig = deps.userConfig | ||||
| 	if gitCommon.Common.UserConfig == nil { | ||||
| 		gitCommon.Common.UserConfig = config.GetDefaultConfig() | ||||
| 	gitCommon.Common.SetUserConfig(deps.userConfig) | ||||
| 	if gitCommon.Common.UserConfig() == nil { | ||||
| 		gitCommon.Common.SetUserConfig(config.GetDefaultConfig()) | ||||
| 	} | ||||
|  | ||||
| 	gitCommon.version = deps.gitVersion | ||||
|   | ||||
| @@ -17,7 +17,7 @@ func NewDiffCommands(gitCommon *GitCommon) *DiffCommands { | ||||
| } | ||||
|  | ||||
| func (self *DiffCommands) DiffCmdObj(diffArgs []string) oscommands.ICmdObj { | ||||
| 	extDiffCmd := self.UserConfig.Git.Paging.ExternalDiffCommand | ||||
| 	extDiffCmd := self.UserConfig().Git.Paging.ExternalDiffCommand | ||||
| 	useExtDiff := extDiffCmd != "" | ||||
|  | ||||
| 	return self.cmd.New( | ||||
| @@ -26,7 +26,7 @@ func (self *DiffCommands) DiffCmdObj(diffArgs []string) oscommands.ICmdObj { | ||||
| 			ConfigIf(useExtDiff, "diff.external="+extDiffCmd). | ||||
| 			ArgIfElse(useExtDiff, "--ext-diff", "--no-ext-diff"). | ||||
| 			Arg("--submodule"). | ||||
| 			Arg(fmt.Sprintf("--color=%s", self.UserConfig.Git.Paging.ColorArg)). | ||||
| 			Arg(fmt.Sprintf("--color=%s", self.UserConfig().Git.Paging.ColorArg)). | ||||
| 			Arg(diffArgs...). | ||||
| 			Dir(self.repoPaths.worktreePath). | ||||
| 			ToArgv(), | ||||
|   | ||||
| @@ -31,7 +31,7 @@ func (self *FileCommands) Cat(fileName string) (string, error) { | ||||
| } | ||||
|  | ||||
| func (self *FileCommands) GetEditCmdStrLegacy(filename string, lineNumber int) (string, error) { | ||||
| 	editor := self.UserConfig.OS.EditCommand | ||||
| 	editor := self.UserConfig().OS.EditCommand | ||||
|  | ||||
| 	if editor == "" { | ||||
| 		editor = self.config.GetCoreEditor() | ||||
| @@ -60,7 +60,7 @@ func (self *FileCommands) GetEditCmdStrLegacy(filename string, lineNumber int) ( | ||||
| 		"line":     strconv.Itoa(lineNumber), | ||||
| 	} | ||||
|  | ||||
| 	editCmdTemplate := self.UserConfig.OS.EditCommandTemplate | ||||
| 	editCmdTemplate := self.UserConfig().OS.EditCommandTemplate | ||||
| 	if len(editCmdTemplate) == 0 { | ||||
| 		switch editor { | ||||
| 		case "emacs", "nano", "vi", "vim", "nvim": | ||||
| @@ -78,7 +78,7 @@ func (self *FileCommands) GetEditCmdStrLegacy(filename string, lineNumber int) ( | ||||
|  | ||||
| func (self *FileCommands) GetEditCmdStr(filenames []string) (string, bool) { | ||||
| 	// Legacy support for old config; to be removed at some point | ||||
| 	if self.UserConfig.OS.Edit == "" && self.UserConfig.OS.EditCommandTemplate != "" { | ||||
| 	if self.UserConfig().OS.Edit == "" && self.UserConfig().OS.EditCommandTemplate != "" { | ||||
| 		// If multiple files are selected, we'll simply edit just the first one. | ||||
| 		// It's not worth fixing this for the legacy support. | ||||
| 		if cmdStr, err := self.GetEditCmdStrLegacy(filenames[0], 1); err == nil { | ||||
| @@ -86,7 +86,7 @@ func (self *FileCommands) GetEditCmdStr(filenames []string) (string, bool) { | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	template, suspend := config.GetEditTemplate(&self.UserConfig.OS, self.guessDefaultEditor) | ||||
| 	template, suspend := config.GetEditTemplate(&self.UserConfig().OS, self.guessDefaultEditor) | ||||
| 	quotedFilenames := lo.Map(filenames, func(filename string, _ int) string { return self.cmd.Quote(filename) }) | ||||
|  | ||||
| 	templateValues := map[string]string{ | ||||
| @@ -99,13 +99,13 @@ func (self *FileCommands) GetEditCmdStr(filenames []string) (string, bool) { | ||||
|  | ||||
| func (self *FileCommands) GetEditAtLineCmdStr(filename string, lineNumber int) (string, bool) { | ||||
| 	// Legacy support for old config; to be removed at some point | ||||
| 	if self.UserConfig.OS.EditAtLine == "" && self.UserConfig.OS.EditCommandTemplate != "" { | ||||
| 	if self.UserConfig().OS.EditAtLine == "" && self.UserConfig().OS.EditCommandTemplate != "" { | ||||
| 		if cmdStr, err := self.GetEditCmdStrLegacy(filename, lineNumber); err == nil { | ||||
| 			return cmdStr, true | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	template, suspend := config.GetEditAtLineTemplate(&self.UserConfig.OS, self.guessDefaultEditor) | ||||
| 	template, suspend := config.GetEditAtLineTemplate(&self.UserConfig().OS, self.guessDefaultEditor) | ||||
|  | ||||
| 	templateValues := map[string]string{ | ||||
| 		"filename": self.cmd.Quote(filename), | ||||
| @@ -118,13 +118,13 @@ func (self *FileCommands) GetEditAtLineCmdStr(filename string, lineNumber int) ( | ||||
|  | ||||
| func (self *FileCommands) GetEditAtLineAndWaitCmdStr(filename string, lineNumber int) string { | ||||
| 	// Legacy support for old config; to be removed at some point | ||||
| 	if self.UserConfig.OS.EditAtLineAndWait == "" && self.UserConfig.OS.EditCommandTemplate != "" { | ||||
| 	if self.UserConfig().OS.EditAtLineAndWait == "" && self.UserConfig().OS.EditCommandTemplate != "" { | ||||
| 		if cmdStr, err := self.GetEditCmdStrLegacy(filename, lineNumber); err == nil { | ||||
| 			return cmdStr | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	template := config.GetEditAtLineAndWaitTemplate(&self.UserConfig.OS, self.guessDefaultEditor) | ||||
| 	template := config.GetEditAtLineAndWaitTemplate(&self.UserConfig().OS, self.guessDefaultEditor) | ||||
|  | ||||
| 	templateValues := map[string]string{ | ||||
| 		"filename": self.cmd.Quote(filename), | ||||
| @@ -136,7 +136,7 @@ func (self *FileCommands) GetEditAtLineAndWaitCmdStr(filename string, lineNumber | ||||
| } | ||||
|  | ||||
| func (self *FileCommands) GetOpenDirInEditorCmdStr(path string) (string, bool) { | ||||
| 	template, suspend := config.GetOpenDirInEditorTemplate(&self.UserConfig.OS, self.guessDefaultEditor) | ||||
| 	template, suspend := config.GetOpenDirInEditorTemplate(&self.UserConfig().OS, self.guessDefaultEditor) | ||||
|  | ||||
| 	templateValues := map[string]string{ | ||||
| 		"dir": self.cmd.Quote(path), | ||||
|   | ||||
| @@ -84,7 +84,7 @@ func (self *StashCommands) ShowStashEntryCmdObj(index int) oscommands.ICmdObj { | ||||
| 	cmdArgs := NewGitCmd("stash").Arg("show"). | ||||
| 		Arg("-p"). | ||||
| 		Arg("--stat"). | ||||
| 		Arg(fmt.Sprintf("--color=%s", self.UserConfig.Git.Paging.ColorArg)). | ||||
| 		Arg(fmt.Sprintf("--color=%s", self.UserConfig().Git.Paging.ColorArg)). | ||||
| 		Arg(fmt.Sprintf("--unified=%d", self.AppState.DiffContextSize)). | ||||
| 		ArgIf(self.AppState.IgnoreWhitespaceInDiffView, "--ignore-all-space"). | ||||
| 		Arg(fmt.Sprintf("--find-renames=%d%%", self.AppState.RenameSimilarityThreshold)). | ||||
|   | ||||
| @@ -60,7 +60,7 @@ func (self *SyncCommands) fetchCommandBuilder(fetchAll bool) *GitCommandBuilder | ||||
| } | ||||
|  | ||||
| func (self *SyncCommands) FetchCmdObj(task gocui.Task) oscommands.ICmdObj { | ||||
| 	cmdArgs := self.fetchCommandBuilder(self.UserConfig.Git.FetchAll).ToArgv() | ||||
| 	cmdArgs := self.fetchCommandBuilder(self.UserConfig().Git.FetchAll).ToArgv() | ||||
|  | ||||
| 	cmdObj := self.cmd.New(cmdArgs) | ||||
| 	cmdObj.PromptOnCredentialRequest(task) | ||||
| @@ -72,7 +72,7 @@ func (self *SyncCommands) Fetch(task gocui.Task) error { | ||||
| } | ||||
|  | ||||
| func (self *SyncCommands) FetchBackgroundCmdObj() oscommands.ICmdObj { | ||||
| 	cmdArgs := self.fetchCommandBuilder(self.UserConfig.Git.FetchAll).ToArgv() | ||||
| 	cmdArgs := self.fetchCommandBuilder(self.UserConfig().Git.FetchAll).ToArgv() | ||||
|  | ||||
| 	cmdObj := self.cmd.New(cmdArgs) | ||||
| 	cmdObj.DontLog().FailOnCredentialRequest() | ||||
|   | ||||
| @@ -133,7 +133,7 @@ func TestSyncFetch(t *testing.T) { | ||||
| 	for _, s := range scenarios { | ||||
| 		t.Run(s.testName, func(t *testing.T) { | ||||
| 			instance := buildSyncCommands(commonDeps{}) | ||||
| 			instance.UserConfig.Git.FetchAll = s.fetchAllConfig | ||||
| 			instance.UserConfig().Git.FetchAll = s.fetchAllConfig | ||||
| 			task := gocui.NewFakeTask() | ||||
| 			s.test(instance.FetchCmdObj(task)) | ||||
| 		}) | ||||
| @@ -171,7 +171,7 @@ func TestSyncFetchBackground(t *testing.T) { | ||||
| 	for _, s := range scenarios { | ||||
| 		t.Run(s.testName, func(t *testing.T) { | ||||
| 			instance := buildSyncCommands(commonDeps{}) | ||||
| 			instance.UserConfig.Git.FetchAll = s.fetchAllConfig | ||||
| 			instance.UserConfig().Git.FetchAll = s.fetchAllConfig | ||||
| 			s.test(instance.FetchBackgroundCmdObj()) | ||||
| 		}) | ||||
| 	} | ||||
|   | ||||
| @@ -245,7 +245,7 @@ func (self *WorkingTreeCommands) WorktreeFileDiff(file *models.File, plain bool, | ||||
| } | ||||
|  | ||||
| func (self *WorkingTreeCommands) WorktreeFileDiffCmdObj(node models.IFile, plain bool, cached bool) oscommands.ICmdObj { | ||||
| 	colorArg := self.UserConfig.Git.Paging.ColorArg | ||||
| 	colorArg := self.UserConfig().Git.Paging.ColorArg | ||||
| 	if plain { | ||||
| 		colorArg = "never" | ||||
| 	} | ||||
| @@ -253,7 +253,7 @@ func (self *WorkingTreeCommands) WorktreeFileDiffCmdObj(node models.IFile, plain | ||||
| 	contextSize := self.AppState.DiffContextSize | ||||
| 	prevPath := node.GetPreviousPath() | ||||
| 	noIndex := !node.GetIsTracked() && !node.GetHasStagedChanges() && !cached && node.GetIsFile() | ||||
| 	extDiffCmd := self.UserConfig.Git.Paging.ExternalDiffCommand | ||||
| 	extDiffCmd := self.UserConfig().Git.Paging.ExternalDiffCommand | ||||
| 	useExtDiff := extDiffCmd != "" && !plain | ||||
|  | ||||
| 	cmdArgs := NewGitCmd("diff"). | ||||
| @@ -285,12 +285,12 @@ func (self *WorkingTreeCommands) ShowFileDiff(from string, to string, reverse bo | ||||
| func (self *WorkingTreeCommands) ShowFileDiffCmdObj(from string, to string, reverse bool, fileName string, plain bool) oscommands.ICmdObj { | ||||
| 	contextSize := self.AppState.DiffContextSize | ||||
|  | ||||
| 	colorArg := self.UserConfig.Git.Paging.ColorArg | ||||
| 	colorArg := self.UserConfig().Git.Paging.ColorArg | ||||
| 	if plain { | ||||
| 		colorArg = "never" | ||||
| 	} | ||||
|  | ||||
| 	extDiffCmd := self.UserConfig.Git.Paging.ExternalDiffCommand | ||||
| 	extDiffCmd := self.UserConfig().Git.Paging.ExternalDiffCommand | ||||
| 	useExtDiff := extDiffCmd != "" && !plain | ||||
|  | ||||
| 	cmdArgs := NewGitCmd("diff"). | ||||
|   | ||||
| @@ -80,10 +80,10 @@ func FileType(path string) string { | ||||
| } | ||||
|  | ||||
| func (c *OSCommand) OpenFile(filename string) error { | ||||
| 	commandTemplate := c.UserConfig.OS.Open | ||||
| 	commandTemplate := c.UserConfig().OS.Open | ||||
| 	if commandTemplate == "" { | ||||
| 		// Legacy support | ||||
| 		commandTemplate = c.UserConfig.OS.OpenCommand | ||||
| 		commandTemplate = c.UserConfig().OS.OpenCommand | ||||
| 	} | ||||
| 	if commandTemplate == "" { | ||||
| 		commandTemplate = config.GetPlatformDefaultConfig().Open | ||||
| @@ -96,10 +96,10 @@ func (c *OSCommand) OpenFile(filename string) error { | ||||
| } | ||||
|  | ||||
| func (c *OSCommand) OpenLink(link string) error { | ||||
| 	commandTemplate := c.UserConfig.OS.OpenLink | ||||
| 	commandTemplate := c.UserConfig().OS.OpenLink | ||||
| 	if commandTemplate == "" { | ||||
| 		// Legacy support | ||||
| 		commandTemplate = c.UserConfig.OS.OpenLinkCommand | ||||
| 		commandTemplate = c.UserConfig().OS.OpenLinkCommand | ||||
| 	} | ||||
| 	if commandTemplate == "" { | ||||
| 		commandTemplate = config.GetPlatformDefaultConfig().OpenLink | ||||
| @@ -294,8 +294,8 @@ func (c *OSCommand) CopyToClipboard(str string) error { | ||||
| 		}, | ||||
| 	) | ||||
| 	c.LogCommand(msg, false) | ||||
| 	if c.UserConfig.OS.CopyToClipboardCmd != "" { | ||||
| 		cmdStr := utils.ResolvePlaceholderString(c.UserConfig.OS.CopyToClipboardCmd, map[string]string{ | ||||
| 	if c.UserConfig().OS.CopyToClipboardCmd != "" { | ||||
| 		cmdStr := utils.ResolvePlaceholderString(c.UserConfig().OS.CopyToClipboardCmd, map[string]string{ | ||||
| 			"text": c.Cmd.Quote(str), | ||||
| 		}) | ||||
| 		return c.Cmd.NewShell(cmdStr).Run() | ||||
| @@ -307,8 +307,8 @@ func (c *OSCommand) CopyToClipboard(str string) error { | ||||
| func (c *OSCommand) PasteFromClipboard() (string, error) { | ||||
| 	var s string | ||||
| 	var err error | ||||
| 	if c.UserConfig.OS.CopyToClipboardCmd != "" { | ||||
| 		cmdStr := c.UserConfig.OS.ReadFromClipboardCmd | ||||
| 	if c.UserConfig().OS.CopyToClipboardCmd != "" { | ||||
| 		cmdStr := c.UserConfig().OS.ReadFromClipboardCmd | ||||
| 		s, err = c.Cmd.NewShell(cmdStr).RunWithOutput() | ||||
| 	} else { | ||||
| 		s, err = clipboard.ReadAll() | ||||
|   | ||||
| @@ -75,7 +75,7 @@ func TestOSCommandOpenFileDarwin(t *testing.T) { | ||||
| 	for _, s := range scenarios { | ||||
| 		oSCmd := NewDummyOSCommandWithRunner(s.runner) | ||||
| 		oSCmd.Platform.OS = "darwin" | ||||
| 		oSCmd.UserConfig.OS.Open = "open {{filename}}" | ||||
| 		oSCmd.UserConfig().OS.Open = "open {{filename}}" | ||||
|  | ||||
| 		s.test(oSCmd.OpenFile(s.filename)) | ||||
| 	} | ||||
| @@ -135,7 +135,7 @@ func TestOSCommandOpenFileLinux(t *testing.T) { | ||||
| 	for _, s := range scenarios { | ||||
| 		oSCmd := NewDummyOSCommandWithRunner(s.runner) | ||||
| 		oSCmd.Platform.OS = "linux" | ||||
| 		oSCmd.UserConfig.OS.Open = `xdg-open {{filename}} > /dev/null` | ||||
| 		oSCmd.UserConfig().OS.Open = `xdg-open {{filename}} > /dev/null` | ||||
|  | ||||
| 		s.test(oSCmd.OpenFile(s.filename)) | ||||
| 	} | ||||
|   | ||||
| @@ -71,7 +71,7 @@ func TestOSCommandOpenFileWindows(t *testing.T) { | ||||
| 		} | ||||
| 		oSCmd.Platform = platform | ||||
| 		oSCmd.Cmd.platform = platform | ||||
| 		oSCmd.UserConfig.OS.OpenCommand = `start "" {{filename}}` | ||||
| 		oSCmd.UserConfig().OS.OpenCommand = `start "" {{filename}}` | ||||
|  | ||||
| 		s.test(oSCmd.OpenFile(s.filename)) | ||||
| 	} | ||||
|   | ||||
| @@ -11,10 +11,18 @@ import ( | ||||
| type Common struct { | ||||
| 	Log        *logrus.Entry | ||||
| 	Tr         *i18n.TranslationSet | ||||
| 	UserConfig *config.UserConfig | ||||
| 	userConfig *config.UserConfig | ||||
| 	AppState   *config.AppState | ||||
| 	Debug      bool | ||||
| 	// for interacting with the filesystem. We use afero rather than the default | ||||
| 	// `os` package for the sake of mocking the filesystem in tests | ||||
| 	Fs afero.Fs | ||||
| } | ||||
|  | ||||
| func (c *Common) UserConfig() *config.UserConfig { | ||||
| 	return c.userConfig | ||||
| } | ||||
|  | ||||
| func (c *Common) SetUserConfig(userConfig *config.UserConfig) { | ||||
| 	c.userConfig = userConfig | ||||
| } | ||||
|   | ||||
| @@ -25,7 +25,7 @@ func (self *BackgroundRoutineMgr) PauseBackgroundRefreshes(pause bool) { | ||||
| } | ||||
|  | ||||
| func (self *BackgroundRoutineMgr) startBackgroundRoutines() { | ||||
| 	userConfig := self.gui.UserConfig | ||||
| 	userConfig := self.gui.UserConfig() | ||||
|  | ||||
| 	if userConfig.Git.AutoFetch { | ||||
| 		fetchInterval := userConfig.Refresher.FetchInterval | ||||
| @@ -77,7 +77,7 @@ func (self *BackgroundRoutineMgr) startBackgroundFetch() { | ||||
| 	self.gui.waitForIntro.Wait() | ||||
|  | ||||
| 	isNew := self.gui.IsNewRepo | ||||
| 	userConfig := self.gui.UserConfig | ||||
| 	userConfig := self.gui.UserConfig() | ||||
| 	if !isNew { | ||||
| 		time.After(time.Duration(userConfig.Refresher.FetchInterval) * time.Second) | ||||
| 	} | ||||
|   | ||||
| @@ -55,11 +55,11 @@ func (gui *Gui) LogCommand(cmdStr string, commandLine bool) { | ||||
| func (gui *Gui) printCommandLogHeader() { | ||||
| 	introStr := fmt.Sprintf( | ||||
| 		gui.c.Tr.CommandLogHeader, | ||||
| 		keybindings.Label(gui.c.UserConfig.Keybinding.Universal.ExtrasMenu), | ||||
| 		keybindings.Label(gui.c.UserConfig().Keybinding.Universal.ExtrasMenu), | ||||
| 	) | ||||
| 	fmt.Fprintln(gui.Views.Extras, style.FgCyan.Sprint(introStr)) | ||||
|  | ||||
| 	if gui.c.UserConfig.Gui.ShowRandomTip { | ||||
| 	if gui.c.UserConfig().Gui.ShowRandomTip { | ||||
| 		fmt.Fprintf( | ||||
| 			gui.Views.Extras, | ||||
| 			"%s: %s", | ||||
| @@ -70,7 +70,7 @@ func (gui *Gui) printCommandLogHeader() { | ||||
| } | ||||
|  | ||||
| func (gui *Gui) getRandomTip() string { | ||||
| 	config := gui.c.UserConfig.Keybinding | ||||
| 	config := gui.c.UserConfig().Keybinding | ||||
|  | ||||
| 	formattedKey := func(key string) string { | ||||
| 		return keybindings.Label(key) | ||||
|   | ||||
| @@ -32,7 +32,7 @@ func NewBranchesContext(c *ContextCommon) *BranchesContext { | ||||
| 			c.Modes().Diffing.Ref, | ||||
| 			c.Views().Branches.Width(), | ||||
| 			c.Tr, | ||||
| 			c.UserConfig, | ||||
| 			c.UserConfig(), | ||||
| 			c.Model().Worktrees, | ||||
| 		) | ||||
| 	} | ||||
|   | ||||
| @@ -28,7 +28,7 @@ func NewCommitFilesContext(c *ContextCommon) *CommitFilesContext { | ||||
| 	viewModel := filetree.NewCommitFileTreeViewModel( | ||||
| 		func() []*models.CommitFile { return c.Model().CommitFiles }, | ||||
| 		c.Log, | ||||
| 		c.UserConfig.Gui.ShowFileTree, | ||||
| 		c.UserConfig().Gui.ShowFileTree, | ||||
| 	) | ||||
|  | ||||
| 	getDisplayStrings := func(_ int, _ int) [][]string { | ||||
| @@ -36,7 +36,7 @@ func NewCommitFilesContext(c *ContextCommon) *CommitFilesContext { | ||||
| 			return [][]string{{style.FgRed.Sprint("(none)")}} | ||||
| 		} | ||||
|  | ||||
| 		showFileIcons := icons.IsIconEnabled() && c.UserConfig.Gui.ShowFileIcons | ||||
| 		showFileIcons := icons.IsIconEnabled() && c.UserConfig().Gui.ShowFileIcons | ||||
| 		lines := presentation.RenderCommitFileTree(viewModel, c.Git().Patch.PatchBuilder, showFileIcons) | ||||
| 		return lo.Map(lines, func(line string, _ int) []string { | ||||
| 			return []string{line} | ||||
|   | ||||
| @@ -113,15 +113,15 @@ func (self *CommitMessageContext) SetPanelState( | ||||
|  | ||||
| 	self.c.Views().CommitDescription.Subtitle = utils.ResolvePlaceholderString(self.c.Tr.CommitDescriptionSubTitle, | ||||
| 		map[string]string{ | ||||
| 			"togglePanelKeyBinding": keybindings.Label(self.c.UserConfig.Keybinding.Universal.TogglePanel), | ||||
| 			"commitMenuKeybinding":  keybindings.Label(self.c.UserConfig.Keybinding.CommitMessage.CommitMenu), | ||||
| 			"togglePanelKeyBinding": keybindings.Label(self.c.UserConfig().Keybinding.Universal.TogglePanel), | ||||
| 			"commitMenuKeybinding":  keybindings.Label(self.c.UserConfig().Keybinding.CommitMessage.CommitMenu), | ||||
| 		}) | ||||
|  | ||||
| 	self.c.Views().CommitDescription.Visible = true | ||||
| } | ||||
|  | ||||
| func (self *CommitMessageContext) RenderCommitLength() { | ||||
| 	if !self.c.UserConfig.Gui.CommitLength.Show { | ||||
| 	if !self.c.UserConfig().Gui.CommitLength.Show { | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
|   | ||||
| @@ -54,10 +54,10 @@ func NewLocalCommitsContext(c *ContextCommon) *LocalCommitsContext { | ||||
| 			c.Modes().CherryPicking.SelectedHashSet(), | ||||
| 			c.Modes().Diffing.Ref, | ||||
| 			c.Modes().MarkedBaseCommit.GetHash(), | ||||
| 			c.UserConfig.Gui.TimeFormat, | ||||
| 			c.UserConfig.Gui.ShortTimeFormat, | ||||
| 			c.UserConfig().Gui.TimeFormat, | ||||
| 			c.UserConfig().Gui.ShortTimeFormat, | ||||
| 			time.Now(), | ||||
| 			c.UserConfig.Git.ParseEmoji, | ||||
| 			c.UserConfig().Git.ParseEmoji, | ||||
| 			selectedCommitHash, | ||||
| 			startIdx, | ||||
| 			endIdx, | ||||
| @@ -110,7 +110,7 @@ func NewLocalCommitsViewModel(getModel func() []*models.Commit, c *ContextCommon | ||||
| 	self := &LocalCommitsViewModel{ | ||||
| 		ListViewModel:     NewListViewModel(getModel), | ||||
| 		limitCommits:      true, | ||||
| 		showWholeGitGraph: c.UserConfig.Git.Log.ShowWholeGraph, | ||||
| 		showWholeGitGraph: c.UserConfig().Git.Log.ShowWholeGraph, | ||||
| 	} | ||||
|  | ||||
| 	return self | ||||
|   | ||||
| @@ -139,7 +139,7 @@ func (self *MenuViewModel) GetNonModelItems() []*NonModelItem { | ||||
| 	// Don't display section headers when we are filtering, and the filter mode | ||||
| 	// is fuzzy. The reason is that filtering changes the order of the items | ||||
| 	// (they are sorted by best match), so all the sections would be messed up. | ||||
| 	if self.FilteredListViewModel.IsFiltering() && self.c.UserConfig.Gui.UseFuzzySearch() { | ||||
| 	if self.FilteredListViewModel.IsFiltering() && self.c.UserConfig().Gui.UseFuzzySearch() { | ||||
| 		return result | ||||
| 	} | ||||
|  | ||||
|   | ||||
| @@ -33,9 +33,9 @@ func NewReflogCommitsContext(c *ContextCommon) *ReflogCommitsContext { | ||||
| 			c.Modes().CherryPicking.SelectedHashSet(), | ||||
| 			c.Modes().Diffing.Ref, | ||||
| 			time.Now(), | ||||
| 			c.UserConfig.Gui.TimeFormat, | ||||
| 			c.UserConfig.Gui.ShortTimeFormat, | ||||
| 			c.UserConfig.Git.ParseEmoji, | ||||
| 			c.UserConfig().Gui.TimeFormat, | ||||
| 			c.UserConfig().Gui.ShortTimeFormat, | ||||
| 			c.UserConfig().Git.ParseEmoji, | ||||
| 		) | ||||
| 	} | ||||
|  | ||||
|   | ||||
| @@ -26,7 +26,7 @@ func NewRemotesContext(c *ContextCommon) *RemotesContext { | ||||
|  | ||||
| 	getDisplayStrings := func(_ int, _ int) [][]string { | ||||
| 		return presentation.GetRemoteListDisplayStrings( | ||||
| 			viewModel.GetItems(), c.Modes().Diffing.Ref, c.State().GetItemOperation, c.Tr, c.UserConfig) | ||||
| 			viewModel.GetItems(), c.Modes().Diffing.Ref, c.State().GetItemOperation, c.Tr, c.UserConfig()) | ||||
| 	} | ||||
|  | ||||
| 	return &RemotesContext{ | ||||
|   | ||||
| @@ -51,7 +51,7 @@ func (self *SearchTrait) onSelectItemWrapper(innerFunc func(int) error) func(int | ||||
| } | ||||
|  | ||||
| func (self *SearchTrait) RenderSearchStatus(index int, total int) { | ||||
| 	keybindingConfig := self.c.UserConfig.Keybinding | ||||
| 	keybindingConfig := self.c.UserConfig().Keybinding | ||||
|  | ||||
| 	if total == 0 { | ||||
| 		self.c.SetViewContent( | ||||
|   | ||||
| @@ -68,10 +68,10 @@ func NewSubCommitsContext( | ||||
| 			c.Modes().CherryPicking.SelectedHashSet(), | ||||
| 			c.Modes().Diffing.Ref, | ||||
| 			"", | ||||
| 			c.UserConfig.Gui.TimeFormat, | ||||
| 			c.UserConfig.Gui.ShortTimeFormat, | ||||
| 			c.UserConfig().Gui.TimeFormat, | ||||
| 			c.UserConfig().Gui.ShortTimeFormat, | ||||
| 			time.Now(), | ||||
| 			c.UserConfig.Git.ParseEmoji, | ||||
| 			c.UserConfig().Git.ParseEmoji, | ||||
| 			selectedCommitHash, | ||||
| 			startIdx, | ||||
| 			endIdx, | ||||
|   | ||||
| @@ -30,7 +30,7 @@ func NewTagsContext( | ||||
| 		return presentation.GetTagListDisplayStrings( | ||||
| 			viewModel.GetItems(), | ||||
| 			c.State().GetItemOperation, | ||||
| 			c.Modes().Diffing.Ref, c.Tr, c.UserConfig) | ||||
| 			c.Modes().Diffing.Ref, c.Tr, c.UserConfig()) | ||||
| 	} | ||||
|  | ||||
| 	return &TagsContext{ | ||||
|   | ||||
| @@ -25,11 +25,11 @@ func NewWorkingTreeContext(c *ContextCommon) *WorkingTreeContext { | ||||
| 	viewModel := filetree.NewFileTreeViewModel( | ||||
| 		func() []*models.File { return c.Model().Files }, | ||||
| 		c.Log, | ||||
| 		c.UserConfig.Gui.ShowFileTree, | ||||
| 		c.UserConfig().Gui.ShowFileTree, | ||||
| 	) | ||||
|  | ||||
| 	getDisplayStrings := func(_ int, _ int) [][]string { | ||||
| 		showFileIcons := icons.IsIconEnabled() && c.UserConfig.Gui.ShowFileIcons | ||||
| 		showFileIcons := icons.IsIconEnabled() && c.UserConfig().Gui.ShowFileIcons | ||||
| 		lines := presentation.RenderFileTree(viewModel, c.Model().Submodules, showFileIcons) | ||||
| 		return lo.Map(lines, func(line string, _ int) []string { | ||||
| 			return []string{line} | ||||
|   | ||||
| @@ -311,8 +311,8 @@ func (self *BasicCommitsController) canCopyCommits(selectedCommits []*models.Com | ||||
| func (self *BasicCommitsController) handleOldCherryPickKey() error { | ||||
| 	msg := utils.ResolvePlaceholderString(self.c.Tr.OldCherryPickKeyWarning, | ||||
| 		map[string]string{ | ||||
| 			"copy":  keybindings.Label(self.c.UserConfig.Keybinding.Commits.CherryPickCopy), | ||||
| 			"paste": keybindings.Label(self.c.UserConfig.Keybinding.Commits.PasteCommits), | ||||
| 			"copy":  keybindings.Label(self.c.UserConfig().Keybinding.Commits.CherryPickCopy), | ||||
| 			"paste": keybindings.Label(self.c.UserConfig().Keybinding.Commits.PasteCommits), | ||||
| 		}) | ||||
|  | ||||
| 	return errors.New(msg) | ||||
|   | ||||
| @@ -118,8 +118,8 @@ func (self *CommitMessageController) setCommitMessageAtIndex(index int) (bool, e | ||||
| 		} | ||||
| 		return false, errors.New(self.c.Tr.CommitWithoutMessageErr) | ||||
| 	} | ||||
| 	if self.c.UserConfig.Git.Commit.AutoWrapCommitMessage { | ||||
| 		commitMessage = helpers.TryRemoveHardLineBreaks(commitMessage, self.c.UserConfig.Git.Commit.AutoWrapWidth) | ||||
| 	if self.c.UserConfig().Git.Commit.AutoWrapCommitMessage { | ||||
| 		commitMessage = helpers.TryRemoveHardLineBreaks(commitMessage, self.c.UserConfig().Git.Commit.AutoWrapWidth) | ||||
| 	} | ||||
| 	self.c.Helpers().Commits.UpdateCommitPanelView(commitMessage) | ||||
| 	return true, nil | ||||
|   | ||||
| @@ -46,7 +46,7 @@ func (self *ConfirmationController) GetKeybindings(opts types.KeybindingsOpts) [ | ||||
| 						// We assume that whenever things are deletable, they | ||||
| 						// are also editable, so we show both keybindings | ||||
| 						subtitle = fmt.Sprintf(self.c.Tr.SuggestionsSubtitle, | ||||
| 							self.c.UserConfig.Keybinding.Universal.Remove, self.c.UserConfig.Keybinding.Universal.Edit) | ||||
| 							self.c.UserConfig().Keybinding.Universal.Remove, self.c.UserConfig().Keybinding.Universal.Edit) | ||||
| 					} | ||||
| 					self.c.Views().Suggestions.Subtitle = subtitle | ||||
| 					return self.c.Context().Replace(self.c.Contexts().Suggestions) | ||||
|   | ||||
| @@ -258,7 +258,7 @@ func (self *FilesController) GetOnRenderToMain() func() error { | ||||
| 				pair = self.c.MainViewPairs().Staging | ||||
| 			} | ||||
|  | ||||
| 			split := self.c.UserConfig.Gui.SplitDiff == "always" || (node.GetHasUnstagedChanges() && node.GetHasStagedChanges()) | ||||
| 			split := self.c.UserConfig().Gui.SplitDiff == "always" || (node.GetHasUnstagedChanges() && node.GetHasStagedChanges()) | ||||
| 			mainShowsStaged := !split && node.GetHasStagedChanges() | ||||
|  | ||||
| 			cmdObj := self.c.Git().WorkingTree.WorktreeFileDiffCmdObj(node, false, mainShowsStaged) | ||||
| @@ -1083,7 +1083,7 @@ func (self *FilesController) remove(selectedNodes []*filetree.FileNode) error { | ||||
|  | ||||
| 			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), | ||||
| 		Key: self.c.KeybindingsOpts().GetKey(self.c.UserConfig().Keybinding.Files.ConfirmDiscard), | ||||
| 		Tooltip: utils.ResolvePlaceholderString( | ||||
| 			self.c.Tr.DiscardAllTooltip, | ||||
| 			map[string]string{ | ||||
|   | ||||
| @@ -81,16 +81,16 @@ func (self *AppStatusHelper) HasStatus() bool { | ||||
| } | ||||
|  | ||||
| func (self *AppStatusHelper) GetStatusString() string { | ||||
| 	appStatus, _ := self.statusMgr().GetStatusString(self.c.UserConfig) | ||||
| 	appStatus, _ := self.statusMgr().GetStatusString(self.c.UserConfig()) | ||||
| 	return appStatus | ||||
| } | ||||
|  | ||||
| func (self *AppStatusHelper) renderAppStatus() { | ||||
| 	self.c.OnWorker(func(_ gocui.Task) error { | ||||
| 		ticker := time.NewTicker(time.Millisecond * time.Duration(self.c.UserConfig.Gui.Spinner.Rate)) | ||||
| 		ticker := time.NewTicker(time.Millisecond * time.Duration(self.c.UserConfig().Gui.Spinner.Rate)) | ||||
| 		defer ticker.Stop() | ||||
| 		for range ticker.C { | ||||
| 			appStatus, color := self.statusMgr().GetStatusString(self.c.UserConfig) | ||||
| 			appStatus, color := self.statusMgr().GetStatusString(self.c.UserConfig()) | ||||
| 			self.c.Views().AppStatus.FgColor = color | ||||
| 			self.c.OnUIThread(func() error { | ||||
| 				self.c.SetViewContent(self.c.Views().AppStatus, appStatus) | ||||
| @@ -124,7 +124,7 @@ func (self *AppStatusHelper) renderAppStatusSync(stop chan struct{}) { | ||||
| 		for { | ||||
| 			select { | ||||
| 			case <-ticker.C: | ||||
| 				appStatus, color := self.statusMgr().GetStatusString(self.c.UserConfig) | ||||
| 				appStatus, color := self.statusMgr().GetStatusString(self.c.UserConfig()) | ||||
| 				self.c.Views().AppStatus.FgColor = color | ||||
| 				self.c.SetViewContent(self.c.Views().AppStatus, appStatus) | ||||
| 				// Redraw all views of the bottom line: | ||||
|   | ||||
| @@ -173,7 +173,7 @@ func (self *ConfirmationHelper) prepareConfirmationPanel( | ||||
| 		suggestionsView.FgColor = theme.GocuiDefaultTextColor | ||||
| 		suggestionsContext.SetSuggestions(opts.FindSuggestionsFunc("")) | ||||
| 		suggestionsView.Visible = true | ||||
| 		suggestionsView.Title = fmt.Sprintf(self.c.Tr.SuggestionsTitle, self.c.UserConfig.Keybinding.Universal.TogglePanel) | ||||
| 		suggestionsView.Title = fmt.Sprintf(self.c.Tr.SuggestionsTitle, self.c.UserConfig().Keybinding.Universal.TogglePanel) | ||||
| 		suggestionsView.Subtitle = "" | ||||
| 	} | ||||
|  | ||||
|   | ||||
| @@ -46,7 +46,7 @@ func (self *GpgHelper) runAndStream(cmdObj oscommands.ICmdObj, waitingStatus str | ||||
| 		if err := cmdObj.StreamOutput().Run(); err != nil { | ||||
| 			_ = self.c.Refresh(types.RefreshOptions{Mode: types.ASYNC}) | ||||
| 			return fmt.Errorf( | ||||
| 				self.c.Tr.GitCommandFailed, self.c.UserConfig.Keybinding.Universal.ExtrasMenu, | ||||
| 				self.c.Tr.GitCommandFailed, self.c.UserConfig().Keybinding.Universal.ExtrasMenu, | ||||
| 			) | ||||
| 		} | ||||
|  | ||||
|   | ||||
| @@ -46,6 +46,6 @@ func (self *HostHelper) getHostingServiceMgr() (*hosting_service.HostingServiceM | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	configServices := self.c.UserConfig.Services | ||||
| 	configServices := self.c.UserConfig().Services | ||||
| 	return hosting_service.NewHostingServiceMgr(self.c.Log, self.c.Tr, remoteUrl, configServices), nil | ||||
| } | ||||
|   | ||||
| @@ -99,7 +99,7 @@ func (self *InlineStatusHelper) start(opts InlineStatusOpts) { | ||||
| 		self.contextsWithInlineStatus[opts.ContextKey] = info | ||||
|  | ||||
| 		go utils.Safe(func() { | ||||
| 			ticker := time.NewTicker(time.Millisecond * time.Duration(self.c.UserConfig.Gui.Spinner.Rate)) | ||||
| 			ticker := time.NewTicker(time.Millisecond * time.Duration(self.c.UserConfig().Gui.Spinner.Rate)) | ||||
| 			defer ticker.Stop() | ||||
| 		outer: | ||||
| 			for { | ||||
|   | ||||
| @@ -112,7 +112,7 @@ func (self *MergeAndRebaseHelper) genericMergeCommand(command string) error { | ||||
| 	// we should end up with a command like 'git merge --continue' | ||||
|  | ||||
| 	// it's impossible for a rebase to require a commit so we'll use a subprocess only if it's a merge | ||||
| 	needsSubprocess := (status == enums.REBASE_MODE_MERGING && command != REBASE_OPTION_ABORT && self.c.UserConfig.Git.Merging.ManualCommit) || | ||||
| 	needsSubprocess := (status == enums.REBASE_MODE_MERGING && command != REBASE_OPTION_ABORT && self.c.UserConfig().Git.Merging.ManualCommit) || | ||||
| 		// but we'll also use a subprocess if we have exec todos; those are likely to be lengthy build | ||||
| 		// tasks whose output the user will want to see in the terminal | ||||
| 		(status == enums.REBASE_MODE_REBASING && command != REBASE_OPTION_ABORT && self.hasExecTodos()) | ||||
| @@ -435,7 +435,7 @@ func (self *MergeAndRebaseHelper) SquashMergeCommitted(refName, checkedOutBranch | ||||
| 		if err = self.CheckMergeOrRebase(err); err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 		message := utils.ResolvePlaceholderString(self.c.UserConfig.Git.Merging.SquashMergeMessage, map[string]string{ | ||||
| 		message := utils.ResolvePlaceholderString(self.c.UserConfig().Git.Merging.SquashMergeMessage, map[string]string{ | ||||
| 			"selectedRef":   refName, | ||||
| 			"currentBranch": checkedOutBranchName, | ||||
| 		}) | ||||
|   | ||||
| @@ -737,7 +737,7 @@ func (self *RefreshHelper) refreshStatus() { | ||||
|  | ||||
| 	repoName := self.c.Git().RepoPaths.RepoName() | ||||
|  | ||||
| 	status := presentation.FormatStatus(repoName, currentBranch, types.ItemOperationNone, linkedWorktreeName, workingTreeState, self.c.Tr, self.c.UserConfig) | ||||
| 	status := presentation.FormatStatus(repoName, currentBranch, types.ItemOperationNone, linkedWorktreeName, workingTreeState, self.c.Tr, self.c.UserConfig()) | ||||
|  | ||||
| 	self.c.SetViewContent(self.c.Views().Status, status) | ||||
| } | ||||
|   | ||||
| @@ -275,7 +275,7 @@ func (self *RefsHelper) NewBranch(from string, fromFormattedName string, suggest | ||||
| 	) | ||||
|  | ||||
| 	if suggestedBranchName == "" { | ||||
| 		suggestedBranchName = self.c.UserConfig.Git.BranchPrefix | ||||
| 		suggestedBranchName = self.c.UserConfig().Git.BranchPrefix | ||||
| 	} | ||||
|  | ||||
| 	return self.c.Prompt(types.PromptOpts{ | ||||
|   | ||||
| @@ -76,7 +76,7 @@ func (self *SearchHelper) DisplayFilterStatus(context types.IFilterableContext) | ||||
| 	self.searchPrefixView().SetContent(self.c.Tr.FilterPrefix) | ||||
|  | ||||
| 	promptView := self.promptView() | ||||
| 	keybindingConfig := self.c.UserConfig.Keybinding | ||||
| 	keybindingConfig := self.c.UserConfig().Keybinding | ||||
| 	promptView.SetContent(fmt.Sprintf("matches for '%s' ", searchString) + theme.OptionsFgColor.Sprintf(self.c.Tr.ExitTextFilterMode, keybindings.Label(keybindingConfig.Universal.Return))) | ||||
| } | ||||
|  | ||||
| @@ -229,7 +229,7 @@ func (self *SearchHelper) OnPromptContentChanged(searchString string) { | ||||
| 	case types.IFilterableContext: | ||||
| 		context.SetSelection(0) | ||||
| 		_ = context.GetView().SetOriginY(0) | ||||
| 		context.SetFilter(searchString, self.c.UserConfig.Gui.UseFuzzySearch()) | ||||
| 		context.SetFilter(searchString, self.c.UserConfig().Gui.UseFuzzySearch()) | ||||
| 		_ = self.c.PostRefreshUpdate(context) | ||||
| 	case types.ISearchableContext: | ||||
| 		// do nothing | ||||
| @@ -246,7 +246,7 @@ func (self *SearchHelper) ReApplyFilter(context types.Context) { | ||||
| 			filterableContext.SetSelection(0) | ||||
| 			_ = filterableContext.GetView().SetOriginY(0) | ||||
| 		} | ||||
| 		filterableContext.ReApplyFilter(self.c.UserConfig.Gui.UseFuzzySearch()) | ||||
| 		filterableContext.ReApplyFilter(self.c.UserConfig().Gui.UseFuzzySearch()) | ||||
| 	} | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -66,7 +66,7 @@ func matchesToSuggestions(matches []string) []*types.Suggestion { | ||||
| func (self *SuggestionsHelper) GetRemoteSuggestionsFunc() func(string) []*types.Suggestion { | ||||
| 	remoteNames := self.getRemoteNames() | ||||
|  | ||||
| 	return FilterFunc(remoteNames, self.c.UserConfig.Gui.UseFuzzySearch()) | ||||
| 	return FilterFunc(remoteNames, self.c.UserConfig().Gui.UseFuzzySearch()) | ||||
| } | ||||
|  | ||||
| func (self *SuggestionsHelper) getBranchNames() []string { | ||||
| @@ -83,7 +83,7 @@ func (self *SuggestionsHelper) GetBranchNameSuggestionsFunc() func(string) []*ty | ||||
| 		if input == "" { | ||||
| 			matchingBranchNames = branchNames | ||||
| 		} else { | ||||
| 			matchingBranchNames = utils.FilterStrings(input, branchNames, self.c.UserConfig.Gui.UseFuzzySearch()) | ||||
| 			matchingBranchNames = utils.FilterStrings(input, branchNames, self.c.UserConfig().Gui.UseFuzzySearch()) | ||||
| 		} | ||||
|  | ||||
| 		return lo.Map(matchingBranchNames, func(branchName string, _ int) *types.Suggestion { | ||||
| @@ -129,7 +129,7 @@ func (self *SuggestionsHelper) GetFilePathSuggestionsFunc() func(string) []*type | ||||
|  | ||||
| 	return func(input string) []*types.Suggestion { | ||||
| 		matchingNames := []string{} | ||||
| 		if self.c.UserConfig.Gui.UseFuzzySearch() { | ||||
| 		if self.c.UserConfig().Gui.UseFuzzySearch() { | ||||
| 			_ = self.c.Model().FilesTrie.VisitFuzzy(patricia.Prefix(input), true, func(prefix patricia.Prefix, item patricia.Item, skipped int) error { | ||||
| 				matchingNames = append(matchingNames, item.(string)) | ||||
| 				return nil | ||||
| @@ -163,7 +163,7 @@ func (self *SuggestionsHelper) getRemoteBranchNames(separator string) []string { | ||||
| } | ||||
|  | ||||
| func (self *SuggestionsHelper) GetRemoteBranchesSuggestionsFunc(separator string) func(string) []*types.Suggestion { | ||||
| 	return FilterFunc(self.getRemoteBranchNames(separator), self.c.UserConfig.Gui.UseFuzzySearch()) | ||||
| 	return FilterFunc(self.getRemoteBranchNames(separator), self.c.UserConfig().Gui.UseFuzzySearch()) | ||||
| } | ||||
|  | ||||
| func (self *SuggestionsHelper) getTagNames() []string { | ||||
| @@ -175,7 +175,7 @@ func (self *SuggestionsHelper) getTagNames() []string { | ||||
| func (self *SuggestionsHelper) GetTagsSuggestionsFunc() func(string) []*types.Suggestion { | ||||
| 	tagNames := self.getTagNames() | ||||
|  | ||||
| 	return FilterFunc(tagNames, self.c.UserConfig.Gui.UseFuzzySearch()) | ||||
| 	return FilterFunc(tagNames, self.c.UserConfig().Gui.UseFuzzySearch()) | ||||
| } | ||||
|  | ||||
| func (self *SuggestionsHelper) GetRefsSuggestionsFunc() func(string) []*types.Suggestion { | ||||
| @@ -186,7 +186,7 @@ func (self *SuggestionsHelper) GetRefsSuggestionsFunc() func(string) []*types.Su | ||||
|  | ||||
| 	refNames := append(append(append(remoteBranchNames, localBranchNames...), tagNames...), additionalRefNames...) | ||||
|  | ||||
| 	return FilterFunc(refNames, self.c.UserConfig.Gui.UseFuzzySearch()) | ||||
| 	return FilterFunc(refNames, self.c.UserConfig().Gui.UseFuzzySearch()) | ||||
| } | ||||
|  | ||||
| func (self *SuggestionsHelper) GetAuthorsSuggestionsFunc() func(string) []*types.Suggestion { | ||||
| @@ -196,7 +196,7 @@ func (self *SuggestionsHelper) GetAuthorsSuggestionsFunc() func(string) []*types | ||||
|  | ||||
| 	slices.Sort(authors) | ||||
|  | ||||
| 	return FilterFunc(authors, self.c.UserConfig.Gui.UseFuzzySearch()) | ||||
| 	return FilterFunc(authors, self.c.UserConfig().Gui.UseFuzzySearch()) | ||||
| } | ||||
|  | ||||
| func FilterFunc(options []string, useFuzzySearch bool) func(string) []*types.Suggestion { | ||||
|   | ||||
| @@ -48,8 +48,8 @@ func (self *TagsHelper) OpenCreateTagPrompt(ref string, onCreate func()) error { | ||||
| 				self.c.Tr.ForceTagPrompt, | ||||
| 				map[string]string{ | ||||
| 					"tagName":    tagName, | ||||
| 					"cancelKey":  self.c.UserConfig.Keybinding.Universal.Return, | ||||
| 					"confirmKey": self.c.UserConfig.Keybinding.Universal.Confirm, | ||||
| 					"cancelKey":  self.c.UserConfig().Keybinding.Universal.Return, | ||||
| 					"confirmKey": self.c.UserConfig().Keybinding.Universal.Confirm, | ||||
| 				}, | ||||
| 			) | ||||
| 			return self.c.Confirm(types.ConfirmOpts{ | ||||
|   | ||||
| @@ -31,7 +31,7 @@ func (self *UpdateHelper) CheckForUpdateInBackground() { | ||||
| 		if newVersion == "" { | ||||
| 			return nil | ||||
| 		} | ||||
| 		if self.c.UserConfig.Update.Method == "background" { | ||||
| 		if self.c.UserConfig().Update.Method == "background" { | ||||
| 			self.startUpdating(newVersion) | ||||
| 			return nil | ||||
| 		} | ||||
|   | ||||
| @@ -87,7 +87,7 @@ func (self *WindowArrangementHelper) GetWindowDimensions(informationStr string, | ||||
| 	args := WindowArrangementArgs{ | ||||
| 		Width:               width, | ||||
| 		Height:              height, | ||||
| 		UserConfig:          self.c.UserConfig, | ||||
| 		UserConfig:          self.c.UserConfig(), | ||||
| 		CurrentWindow:       self.windowHelper.CurrentWindow(), | ||||
| 		CurrentSideWindow:   self.c.Context().CurrentSide().GetWindowName(), | ||||
| 		CurrentStaticWindow: self.c.Context().CurrentStatic().GetWindowName(), | ||||
|   | ||||
| @@ -136,7 +136,7 @@ func (self *WorkingTreeHelper) HandleCommitEditorPress() error { | ||||
| } | ||||
|  | ||||
| func (self *WorkingTreeHelper) HandleWIPCommitPress() error { | ||||
| 	skipHookPrefix := self.c.UserConfig.Git.SkipHookPrefix | ||||
| 	skipHookPrefix := self.c.UserConfig().Git.SkipHookPrefix | ||||
| 	if skipHookPrefix == "" { | ||||
| 		return errors.New(self.c.Tr.SkipHookPrefixNotConfigured) | ||||
| 	} | ||||
| @@ -209,7 +209,7 @@ func (self *WorkingTreeHelper) syncRefresh() error { | ||||
|  | ||||
| func (self *WorkingTreeHelper) prepareFilesForCommit() error { | ||||
| 	noStagedFiles := !self.AnyStagedFiles() | ||||
| 	if noStagedFiles && self.c.UserConfig.Gui.SkipNoStagedFilesWarning { | ||||
| 	if noStagedFiles && self.c.UserConfig().Gui.SkipNoStagedFilesWarning { | ||||
| 		self.c.LogAction(self.c.Tr.Actions.StageAllFiles) | ||||
| 		err := self.c.Git().WorkingTree.StageAll() | ||||
| 		if err != nil { | ||||
| @@ -223,10 +223,10 @@ func (self *WorkingTreeHelper) prepareFilesForCommit() error { | ||||
| } | ||||
|  | ||||
| func (self *WorkingTreeHelper) commitPrefixConfigForRepo() *config.CommitPrefixConfig { | ||||
| 	cfg, ok := self.c.UserConfig.Git.CommitPrefixes[self.c.Git().RepoPaths.RepoName()] | ||||
| 	cfg, ok := self.c.UserConfig().Git.CommitPrefixes[self.c.Git().RepoPaths.RepoName()] | ||||
| 	if ok { | ||||
| 		return &cfg | ||||
| 	} | ||||
|  | ||||
| 	return self.c.UserConfig.Git.CommitPrefix | ||||
| 	return self.c.UserConfig().Git.CommitPrefix | ||||
| } | ||||
|   | ||||
| @@ -51,7 +51,7 @@ func (self *ListController) HandleScrollRight() error { | ||||
| } | ||||
|  | ||||
| func (self *ListController) HandleScrollUp() error { | ||||
| 	scrollHeight := self.c.UserConfig.Gui.ScrollHeight | ||||
| 	scrollHeight := self.c.UserConfig().Gui.ScrollHeight | ||||
| 	self.context.GetViewTrait().ScrollUp(scrollHeight) | ||||
| 	if self.context.RenderOnlyVisibleLines() { | ||||
| 		return self.context.HandleRender() | ||||
| @@ -61,7 +61,7 @@ func (self *ListController) HandleScrollUp() error { | ||||
| } | ||||
|  | ||||
| func (self *ListController) HandleScrollDown() error { | ||||
| 	scrollHeight := self.c.UserConfig.Gui.ScrollHeight | ||||
| 	scrollHeight := self.c.UserConfig().Gui.ScrollHeight | ||||
| 	self.context.GetViewTrait().ScrollDown(scrollHeight) | ||||
| 	if self.context.RenderOnlyVisibleLines() { | ||||
| 		return self.context.HandleRender() | ||||
| @@ -106,10 +106,10 @@ func (self *ListController) handleLineChangeAux(f func(int), change int) error { | ||||
| 	cursorMoved := before != after | ||||
| 	if cursorMoved { | ||||
| 		if change == -1 { | ||||
| 			checkScrollUp(self.context.GetViewTrait(), self.c.UserConfig, | ||||
| 			checkScrollUp(self.context.GetViewTrait(), self.c.UserConfig(), | ||||
| 				self.context.ModelIndexToViewIndex(before), self.context.ModelIndexToViewIndex(after)) | ||||
| 		} else if change == 1 { | ||||
| 			checkScrollDown(self.context.GetViewTrait(), self.c.UserConfig, | ||||
| 			checkScrollDown(self.context.GetViewTrait(), self.c.UserConfig(), | ||||
| 				self.context.ModelIndexToViewIndex(before), self.context.ModelIndexToViewIndex(after)) | ||||
| 		} | ||||
| 	} | ||||
|   | ||||
| @@ -357,8 +357,8 @@ func (self *LocalCommitsController) reword(commit *models.Commit) error { | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	if self.c.UserConfig.Git.Commit.AutoWrapCommitMessage { | ||||
| 		commitMessage = helpers.TryRemoveHardLineBreaks(commitMessage, self.c.UserConfig.Git.Commit.AutoWrapWidth) | ||||
| 	if self.c.UserConfig().Git.Commit.AutoWrapCommitMessage { | ||||
| 		commitMessage = helpers.TryRemoveHardLineBreaks(commitMessage, self.c.UserConfig().Git.Commit.AutoWrapWidth) | ||||
| 	} | ||||
| 	return self.c.Helpers().Commits.OpenCommitMessagePanel( | ||||
| 		&helpers.OpenCommitMessagePanelOpts{ | ||||
| @@ -438,7 +438,7 @@ func (self *LocalCommitsController) doRewordEditor() error { | ||||
| } | ||||
|  | ||||
| func (self *LocalCommitsController) rewordEditor(commit *models.Commit) error { | ||||
| 	if self.c.UserConfig.Gui.SkipRewordInEditorWarning { | ||||
| 	if self.c.UserConfig().Gui.SkipRewordInEditorWarning { | ||||
| 		return self.doRewordEditor() | ||||
| 	} else { | ||||
| 		return self.c.Confirm(types.ConfirmOpts{ | ||||
| @@ -564,7 +564,7 @@ func (self *LocalCommitsController) findCommitForQuickStartInteractiveRebase() ( | ||||
|  | ||||
| 	if !ok || index == 0 { | ||||
| 		errorMsg := utils.ResolvePlaceholderString(self.c.Tr.CannotQuickStartInteractiveRebase, map[string]string{ | ||||
| 			"editKey": keybindings.Label(self.c.UserConfig.Keybinding.Universal.Edit), | ||||
| 			"editKey": keybindings.Label(self.c.UserConfig().Keybinding.Universal.Edit), | ||||
| 		}) | ||||
|  | ||||
| 		return nil, errors.New(errorMsg) | ||||
| @@ -905,8 +905,8 @@ func (self *LocalCommitsController) createAmendCommit(commit *models.Commit, inc | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	if self.c.UserConfig.Git.Commit.AutoWrapCommitMessage { | ||||
| 		commitMessage = helpers.TryRemoveHardLineBreaks(commitMessage, self.c.UserConfig.Git.Commit.AutoWrapWidth) | ||||
| 	if self.c.UserConfig().Git.Commit.AutoWrapCommitMessage { | ||||
| 		commitMessage = helpers.TryRemoveHardLineBreaks(commitMessage, self.c.UserConfig().Git.Commit.AutoWrapWidth) | ||||
| 	} | ||||
| 	originalSubject, _, _ := strings.Cut(commitMessage, "\n") | ||||
| 	return self.c.Helpers().Commits.OpenCommitMessagePanel( | ||||
|   | ||||
| @@ -173,14 +173,14 @@ func (self *MergeConflictsController) GetOnFocusLost() func(types.OnFocusLostOpt | ||||
|  | ||||
| func (self *MergeConflictsController) HandleScrollUp() error { | ||||
| 	self.context().SetUserScrolling(true) | ||||
| 	self.context().GetViewTrait().ScrollUp(self.c.UserConfig.Gui.ScrollHeight) | ||||
| 	self.context().GetViewTrait().ScrollUp(self.c.UserConfig().Gui.ScrollHeight) | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (self *MergeConflictsController) HandleScrollDown() error { | ||||
| 	self.context().SetUserScrolling(true) | ||||
| 	self.context().GetViewTrait().ScrollDown(self.c.UserConfig.Gui.ScrollHeight) | ||||
| 	self.context().GetViewTrait().ScrollDown(self.c.UserConfig().Gui.ScrollHeight) | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|   | ||||
| @@ -173,7 +173,7 @@ func (self *PatchExplorerController) HandlePrevLine() error { | ||||
| 	after := self.context.GetState().GetSelectedLineIdx() | ||||
|  | ||||
| 	if self.context.GetState().SelectingLine() { | ||||
| 		checkScrollUp(self.context.GetViewTrait(), self.c.UserConfig, before, after) | ||||
| 		checkScrollUp(self.context.GetViewTrait(), self.c.UserConfig(), before, after) | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| @@ -185,7 +185,7 @@ func (self *PatchExplorerController) HandleNextLine() error { | ||||
| 	after := self.context.GetState().GetSelectedLineIdx() | ||||
|  | ||||
| 	if self.context.GetState().SelectingLine() { | ||||
| 		checkScrollDown(self.context.GetViewTrait(), self.c.UserConfig, before, after) | ||||
| 		checkScrollDown(self.context.GetViewTrait(), self.c.UserConfig(), before, after) | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
|   | ||||
| @@ -25,7 +25,7 @@ func (self *QuitActions) quitAux() error { | ||||
| 		return self.confirmQuitDuringUpdate() | ||||
| 	} | ||||
|  | ||||
| 	if self.c.UserConfig.ConfirmOnQuit { | ||||
| 	if self.c.UserConfig().ConfirmOnQuit { | ||||
| 		return self.c.Confirm(types.ConfirmOpts{ | ||||
| 			Title:  "", | ||||
| 			Prompt: self.c.Tr.ConfirmQuit, | ||||
| @@ -88,7 +88,7 @@ func (self *QuitActions) Escape() error { | ||||
| 		return self.c.Helpers().Repos.DispatchSwitchToRepo(repoPathStack.Pop(), context.NO_CONTEXT) | ||||
| 	} | ||||
|  | ||||
| 	if self.c.UserConfig.QuitOnTopLevelReturn { | ||||
| 	if self.c.UserConfig().QuitOnTopLevelReturn { | ||||
| 		return self.Quit() | ||||
| 	} | ||||
|  | ||||
|   | ||||
| @@ -60,7 +60,7 @@ func (self *ShellCommandAction) GetShellCommandsHistorySuggestionsFunc() func(st | ||||
| 	return func(input string) []*types.Suggestion { | ||||
| 		history := self.c.GetAppState().ShellCommandsHistory | ||||
|  | ||||
| 		return helpers.FilterFunc(history, self.c.UserConfig.Gui.UseFuzzySearch())(input) | ||||
| 		return helpers.FilterFunc(history, self.c.UserConfig().Gui.UseFuzzySearch())(input) | ||||
| 	} | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -190,7 +190,7 @@ func (self *StagingController) ToggleStaged() error { | ||||
| func (self *StagingController) DiscardSelection() error { | ||||
| 	reset := func() error { return self.applySelectionAndRefresh(true) } | ||||
|  | ||||
| 	if !self.staged && !self.c.UserConfig.Gui.SkipDiscardChangeWarning { | ||||
| 	if !self.staged && !self.c.UserConfig().Gui.SkipDiscardChangeWarning { | ||||
| 		return self.c.Confirm(types.ConfirmOpts{ | ||||
| 			Title:         self.c.Tr.DiscardChangeTitle, | ||||
| 			Prompt:        self.c.Tr.DiscardChangePrompt, | ||||
|   | ||||
| @@ -114,7 +114,7 @@ func (self *StashController) handleStashApply(stashEntry *models.StashEntry) err | ||||
| 		return nil | ||||
| 	} | ||||
|  | ||||
| 	if self.c.UserConfig.Gui.SkipStashWarning { | ||||
| 	if self.c.UserConfig().Gui.SkipStashWarning { | ||||
| 		return apply() | ||||
| 	} | ||||
|  | ||||
| @@ -138,7 +138,7 @@ func (self *StashController) handleStashPop(stashEntry *models.StashEntry) error | ||||
| 		return nil | ||||
| 	} | ||||
|  | ||||
| 	if self.c.UserConfig.Gui.SkipStashWarning { | ||||
| 	if self.c.UserConfig().Gui.SkipStashWarning { | ||||
| 		return pop() | ||||
| 	} | ||||
|  | ||||
|   | ||||
| @@ -89,7 +89,7 @@ func (self *StatusController) onClickMain(opts gocui.ViewMouseBindingOpts) error | ||||
| } | ||||
|  | ||||
| func (self *StatusController) GetOnRenderToMain() func() error { | ||||
| 	config := self.c.UserConfig.Gui | ||||
| 	config := self.c.UserConfig().Gui | ||||
|  | ||||
| 	switch config.StatusPanelView { | ||||
| 	case "dashboard": | ||||
| @@ -117,7 +117,7 @@ func (self *StatusController) onClick(opts gocui.ViewMouseBindingOpts) error { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	upstreamStatus := utils.Decolorise(presentation.BranchStatus(currentBranch, types.ItemOperationNone, self.c.Tr, time.Now(), self.c.UserConfig)) | ||||
| 	upstreamStatus := utils.Decolorise(presentation.BranchStatus(currentBranch, types.ItemOperationNone, self.c.Tr, time.Now(), self.c.UserConfig())) | ||||
| 	repoName := self.c.Git().RepoPaths.RepoName() | ||||
| 	workingTreeState := self.c.Git().Status.WorkingTreeState() | ||||
| 	switch workingTreeState { | ||||
|   | ||||
| @@ -210,7 +210,7 @@ func (self *SyncController) pushAux(currentBranch *models.Branch, opts pushOpts) | ||||
| 					return errors.New(self.c.Tr.UpdatesRejected) | ||||
| 				} | ||||
|  | ||||
| 				forcePushDisabled := self.c.UserConfig.Git.DisableForcePushing | ||||
| 				forcePushDisabled := self.c.UserConfig().Git.DisableForcePushing | ||||
| 				if forcePushDisabled { | ||||
| 					return errors.New(self.c.Tr.UpdatesRejectedAndForcePushDisabled) | ||||
| 				} | ||||
| @@ -233,7 +233,7 @@ func (self *SyncController) pushAux(currentBranch *models.Branch, opts pushOpts) | ||||
| } | ||||
|  | ||||
| func (self *SyncController) requestToForcePush(currentBranch *models.Branch, opts pushOpts) error { | ||||
| 	forcePushDisabled := self.c.UserConfig.Git.DisableForcePushing | ||||
| 	forcePushDisabled := self.c.UserConfig().Git.DisableForcePushing | ||||
| 	if forcePushDisabled { | ||||
| 		return errors.New(self.c.Tr.ForcePushDisabled) | ||||
| 	} | ||||
| @@ -252,8 +252,8 @@ func (self *SyncController) forcePushPrompt() string { | ||||
| 	return utils.ResolvePlaceholderString( | ||||
| 		self.c.Tr.ForcePushPrompt, | ||||
| 		map[string]string{ | ||||
| 			"cancelKey":  self.c.UserConfig.Keybinding.Universal.Return, | ||||
| 			"confirmKey": self.c.UserConfig.Keybinding.Universal.Confirm, | ||||
| 			"cancelKey":  self.c.UserConfig().Keybinding.Universal.Return, | ||||
| 			"confirmKey": self.c.UserConfig().Keybinding.Universal.Confirm, | ||||
| 		}, | ||||
| 	) | ||||
| } | ||||
|   | ||||
| @@ -65,13 +65,13 @@ func (self *VerticalScrollController) GetMouseKeybindings(opts types.Keybindings | ||||
| } | ||||
|  | ||||
| func (self *VerticalScrollController) HandleScrollUp() error { | ||||
| 	self.context.GetViewTrait().ScrollUp(self.c.UserConfig.Gui.ScrollHeight) | ||||
| 	self.context.GetViewTrait().ScrollUp(self.c.UserConfig().Gui.ScrollHeight) | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (self *VerticalScrollController) HandleScrollDown() error { | ||||
| 	scrollHeight := self.c.UserConfig.Gui.ScrollHeight | ||||
| 	scrollHeight := self.c.UserConfig().Gui.ScrollHeight | ||||
| 	self.context.GetViewTrait().ScrollDown(scrollHeight) | ||||
|  | ||||
| 	if manager, ok := (*self.viewBufferManagerMap)[self.context.GetViewName()]; ok { | ||||
|   | ||||
| @@ -35,7 +35,7 @@ func (self *FilesController) createResetMenu() error { | ||||
| 					return err | ||||
| 				} | ||||
|  | ||||
| 				if self.c.UserConfig.Gui.AnimateExplosion { | ||||
| 				if self.c.UserConfig().Gui.AnimateExplosion { | ||||
| 					self.animateExplosion() | ||||
| 				} | ||||
|  | ||||
|   | ||||
| @@ -13,11 +13,11 @@ import ( | ||||
| const HORIZONTAL_SCROLL_FACTOR = 3 | ||||
|  | ||||
| func (gui *Gui) scrollUpView(view *gocui.View) { | ||||
| 	view.ScrollUp(gui.c.UserConfig.Gui.ScrollHeight) | ||||
| 	view.ScrollUp(gui.c.UserConfig().Gui.ScrollHeight) | ||||
| } | ||||
|  | ||||
| func (gui *Gui) scrollDownView(view *gocui.View) { | ||||
| 	scrollHeight := gui.c.UserConfig.Gui.ScrollHeight | ||||
| 	scrollHeight := gui.c.UserConfig().Gui.ScrollHeight | ||||
| 	view.ScrollDown(scrollHeight) | ||||
|  | ||||
| 	if manager, ok := gui.viewBufferManagerMap[view.Name()]; ok { | ||||
| @@ -123,7 +123,7 @@ func (gui *Gui) handleCopySelectedSideContextItemToClipboard() error { | ||||
|  | ||||
| func (gui *Gui) handleCopySelectedSideContextItemCommitHashToClipboard() error { | ||||
| 	return gui.handleCopySelectedSideContextItemToClipboardWithTruncation( | ||||
| 		gui.UserConfig.Git.TruncateCopiedCommitHashesTo) | ||||
| 		gui.UserConfig().Git.TruncateCopiedCommitHashesTo) | ||||
| } | ||||
|  | ||||
| func (gui *Gui) handleCopySelectedSideContextItemToClipboardWithTruncation(maxWidth int) error { | ||||
|   | ||||
| @@ -379,7 +379,7 @@ func (gui *Gui) resetState(startArgs appTypes.StartArgs) types.Context { | ||||
| 			BisectInfo:            git_commands.NewNullBisectInfo(), | ||||
| 			FilesTrie:             patricia.NewTrie(), | ||||
| 			Authors:               map[string]*models.Author{}, | ||||
| 			MainBranches:          git_commands.NewMainBranches(gui.UserConfig.Git.MainBranches, gui.os.Cmd), | ||||
| 			MainBranches:          git_commands.NewMainBranches(gui.UserConfig().Git.MainBranches, gui.os.Cmd), | ||||
| 		}, | ||||
| 		Modes: &types.Modes{ | ||||
| 			Filtering:        filtering.New(startArgs.FilterPath, ""), | ||||
| @@ -481,7 +481,7 @@ func NewGui( | ||||
| 		// originally we could only hide the command log permanently via the config | ||||
| 		// but now we do it via state. So we need to still support the config for the | ||||
| 		// sake of backwards compatibility. We're making use of short circuiting here | ||||
| 		ShowExtrasWindow: cmn.UserConfig.Gui.ShowCommandLog && !config.GetAppState().HideCommandLog, | ||||
| 		ShowExtrasWindow: cmn.UserConfig().Gui.ShowCommandLog && !config.GetAppState().HideCommandLog, | ||||
| 		Mutexes: types.Mutexes{ | ||||
| 			RefreshingFilesMutex:    &deadlock.Mutex{}, | ||||
| 			RefreshingBranchesMutex: &deadlock.Mutex{}, | ||||
| @@ -538,13 +538,13 @@ func NewGui( | ||||
| 	// TODO: reset these controllers upon changing repos due to state changing | ||||
| 	gui.c = helperCommon | ||||
|  | ||||
| 	authors.SetCustomAuthors(gui.UserConfig.Gui.AuthorColors) | ||||
| 	if gui.UserConfig.Gui.NerdFontsVersion != "" { | ||||
| 		icons.SetNerdFontsVersion(gui.UserConfig.Gui.NerdFontsVersion) | ||||
| 	} else if gui.UserConfig.Gui.ShowIcons { | ||||
| 	authors.SetCustomAuthors(gui.UserConfig().Gui.AuthorColors) | ||||
| 	if gui.UserConfig().Gui.NerdFontsVersion != "" { | ||||
| 		icons.SetNerdFontsVersion(gui.UserConfig().Gui.NerdFontsVersion) | ||||
| 	} else if gui.UserConfig().Gui.ShowIcons { | ||||
| 		icons.SetNerdFontsVersion("2") | ||||
| 	} | ||||
| 	presentation.SetCustomBranches(gui.UserConfig.Gui.BranchColors) | ||||
| 	presentation.SetCustomBranches(gui.UserConfig().Gui.BranchColors) | ||||
|  | ||||
| 	gui.BackgroundRoutineMgr = &BackgroundRoutineMgr{gui: gui} | ||||
| 	gui.stateAccessor = &StateAccessor{gui: gui} | ||||
| @@ -661,13 +661,13 @@ func (gui *Gui) Run(startArgs appTypes.StartArgs) error { | ||||
| 	userConfig := gui.UserConfig | ||||
|  | ||||
| 	gui.g.OnSearchEscape = func() error { gui.helpers.Search.Cancel(); return nil } | ||||
| 	gui.g.SearchEscapeKey = keybindings.GetKey(userConfig.Keybinding.Universal.Return) | ||||
| 	gui.g.NextSearchMatchKey = keybindings.GetKey(userConfig.Keybinding.Universal.NextMatch) | ||||
| 	gui.g.PrevSearchMatchKey = keybindings.GetKey(userConfig.Keybinding.Universal.PrevMatch) | ||||
| 	gui.g.SearchEscapeKey = keybindings.GetKey(userConfig().Keybinding.Universal.Return) | ||||
| 	gui.g.NextSearchMatchKey = keybindings.GetKey(userConfig().Keybinding.Universal.NextMatch) | ||||
| 	gui.g.PrevSearchMatchKey = keybindings.GetKey(userConfig().Keybinding.Universal.PrevMatch) | ||||
|  | ||||
| 	gui.g.ShowListFooter = userConfig.Gui.ShowListFooter | ||||
| 	gui.g.ShowListFooter = userConfig().Gui.ShowListFooter | ||||
|  | ||||
| 	if userConfig.Gui.MouseEvents { | ||||
| 	if userConfig().Gui.MouseEvents { | ||||
| 		gui.g.Mouse = true | ||||
| 	} | ||||
|  | ||||
| @@ -732,7 +732,7 @@ func (gui *Gui) RunAndHandleError(startArgs appTypes.StartArgs) error { | ||||
| } | ||||
|  | ||||
| func (gui *Gui) checkForDeprecatedEditConfigs() { | ||||
| 	osConfig := &gui.UserConfig.OS | ||||
| 	osConfig := &gui.UserConfig().OS | ||||
| 	deprecatedConfigs := []struct { | ||||
| 		config  string | ||||
| 		oldName string | ||||
| @@ -932,7 +932,7 @@ func (gui *Gui) showBreakingChangesMessage() { | ||||
|  | ||||
| // setColorScheme sets the color scheme for the app based on the user config | ||||
| func (gui *Gui) setColorScheme() { | ||||
| 	userConfig := gui.UserConfig | ||||
| 	userConfig := gui.UserConfig() | ||||
| 	theme.UpdateTheme(userConfig.Gui.Theme) | ||||
|  | ||||
| 	gui.g.FgColor = theme.InactiveBorderColor | ||||
|   | ||||
| @@ -60,7 +60,7 @@ func (self *Gui) GetCheatsheetKeybindings() []*types.Binding { | ||||
| } | ||||
|  | ||||
| func (self *Gui) keybindingOpts() types.KeybindingsOpts { | ||||
| 	config := self.c.UserConfig.Keybinding | ||||
| 	config := self.c.UserConfig().Keybinding | ||||
|  | ||||
| 	guards := types.KeybindingGuards{ | ||||
| 		OutsideFilterMode: self.outsideFilterMode, | ||||
|   | ||||
| @@ -260,7 +260,7 @@ func (gui *Gui) onRepoViewReset() error { | ||||
| } | ||||
|  | ||||
| func (gui *Gui) onInitialViewsCreation() error { | ||||
| 	if !gui.c.UserConfig.DisableStartupPopups { | ||||
| 	if !gui.c.UserConfig().DisableStartupPopups { | ||||
| 		storedPopupVersion := gui.c.GetAppState().StartupPopupVersion | ||||
| 		if storedPopupVersion < StartupPopupVersion { | ||||
| 			gui.showIntroPopupMessage() | ||||
|   | ||||
| @@ -324,7 +324,7 @@ func Test_getBranchDisplayStrings(t *testing.T) { | ||||
|  | ||||
| 	for i, s := range scenarios { | ||||
| 		icons.SetNerdFontsVersion(lo.Ternary(s.useIcons, "3", "")) | ||||
| 		c.UserConfig.Gui.ShowDivergenceFromBaseBranch = s.showDivergenceCfg | ||||
| 		c.UserConfig().Gui.ShowDivergenceFromBaseBranch = s.showDivergenceCfg | ||||
|  | ||||
| 		worktrees := []*models.Worktree{} | ||||
| 		if s.checkedOutByWorktree { | ||||
| @@ -332,7 +332,7 @@ func Test_getBranchDisplayStrings(t *testing.T) { | ||||
| 		} | ||||
|  | ||||
| 		t.Run(fmt.Sprintf("getBranchDisplayStrings_%d", i), func(t *testing.T) { | ||||
| 			strings := getBranchDisplayStrings(s.branch, s.itemOperation, s.fullDescription, false, s.viewWidth, c.Tr, c.UserConfig, worktrees, time.Time{}) | ||||
| 			strings := getBranchDisplayStrings(s.branch, s.itemOperation, s.fullDescription, false, s.viewWidth, c.Tr, c.UserConfig(), worktrees, time.Time{}) | ||||
| 			assert.Equal(t, s.expected, strings) | ||||
| 		}) | ||||
| 	} | ||||
|   | ||||
| @@ -173,7 +173,7 @@ func GetCommitListDisplayStrings( | ||||
| 					// Don't show a marker for the current branch | ||||
| 					b.Name != currentBranchName && | ||||
| 					// Don't show a marker for main branches | ||||
| 					!lo.Contains(common.UserConfig.Git.MainBranches, b.Name) && | ||||
| 					!lo.Contains(common.UserConfig().Git.MainBranches, b.Name) && | ||||
| 					// Don't show a marker for the head commit unless the | ||||
| 					// rebase.updateRefs config is on | ||||
| 					(hasRebaseUpdateRefsConfig || b.CommitHash != commits[0].Hash) | ||||
| @@ -370,7 +370,7 @@ func displayCommit( | ||||
|  | ||||
| 	hashString := "" | ||||
| 	hashColor := getHashColor(commit, diffName, cherryPickedCommitHashSet, bisectStatus, bisectInfo) | ||||
| 	hashLength := common.UserConfig.Gui.CommitHashLength | ||||
| 	hashLength := common.UserConfig().Gui.CommitHashLength | ||||
| 	if hashLength >= len(commit.Hash) { | ||||
| 		hashString = hashColor.Sprint(commit.Hash) | ||||
| 	} else if hashLength > 0 { | ||||
| @@ -440,9 +440,9 @@ func displayCommit( | ||||
| 		mark = fmt.Sprintf("%s ", willBeRebased) | ||||
| 	} | ||||
|  | ||||
| 	authorLength := common.UserConfig.Gui.CommitAuthorShortLength | ||||
| 	authorLength := common.UserConfig().Gui.CommitAuthorShortLength | ||||
| 	if fullDescription { | ||||
| 		authorLength = common.UserConfig.Gui.CommitAuthorLongLength | ||||
| 		authorLength = common.UserConfig().Gui.CommitAuthorLongLength | ||||
| 	} | ||||
| 	author := authors.AuthorWithLength(commit.AuthorName, authorLength) | ||||
|  | ||||
|   | ||||
| @@ -26,7 +26,7 @@ func NewClient( | ||||
| 		helpers.MergeAndRebase, | ||||
| 	) | ||||
| 	keybindingCreator := NewKeybindingCreator(c) | ||||
| 	customCommands := c.UserConfig.CustomCommands | ||||
| 	customCommands := c.UserConfig().CustomCommands | ||||
|  | ||||
| 	return &Client{ | ||||
| 		customCommands:    customCommands, | ||||
|   | ||||
| @@ -179,7 +179,7 @@ func (gui *Gui) createAllViews() error { | ||||
|  | ||||
| func (gui *Gui) configureViewProperties() { | ||||
| 	frameRunes := []rune{'─', '│', '┌', '┐', '└', '┘'} | ||||
| 	switch gui.c.UserConfig.Gui.Border { | ||||
| 	switch gui.c.UserConfig().Gui.Border { | ||||
| 	case "double": | ||||
| 		frameRunes = []rune{'═', '║', '╔', '╗', '╚', '╝'} | ||||
| 	case "rounded": | ||||
| @@ -198,15 +198,15 @@ func (gui *Gui) configureViewProperties() { | ||||
| 	} | ||||
|  | ||||
| 	for _, view := range []*gocui.View{gui.Views.Main, gui.Views.Secondary, gui.Views.Staging, gui.Views.StagingSecondary, gui.Views.PatchBuilding, gui.Views.PatchBuildingSecondary, gui.Views.MergeConflicts} { | ||||
| 		view.CanScrollPastBottom = gui.c.UserConfig.Gui.ScrollPastBottom | ||||
| 		view.CanScrollPastBottom = gui.c.UserConfig().Gui.ScrollPastBottom | ||||
| 	} | ||||
|  | ||||
| 	gui.Views.CommitDescription.FgColor = theme.GocuiDefaultTextColor | ||||
| 	gui.Views.CommitDescription.TextArea.AutoWrap = gui.c.UserConfig.Git.Commit.AutoWrapCommitMessage | ||||
| 	gui.Views.CommitDescription.TextArea.AutoWrapWidth = gui.c.UserConfig.Git.Commit.AutoWrapWidth | ||||
| 	gui.Views.CommitDescription.TextArea.AutoWrap = gui.c.UserConfig().Git.Commit.AutoWrapCommitMessage | ||||
| 	gui.Views.CommitDescription.TextArea.AutoWrapWidth = gui.c.UserConfig().Git.Commit.AutoWrapWidth | ||||
|  | ||||
| 	if gui.c.UserConfig.Gui.ShowPanelJumps { | ||||
| 		jumpBindings := gui.c.UserConfig.Keybinding.Universal.JumpToBlock | ||||
| 	if gui.c.UserConfig().Gui.ShowPanelJumps { | ||||
| 		jumpBindings := gui.c.UserConfig().Keybinding.Universal.JumpToBlock | ||||
| 		jumpLabels := lo.Map(jumpBindings, func(binding string, _ int) string { | ||||
| 			return fmt.Sprintf("[%s]", binding) | ||||
| 		}) | ||||
|   | ||||
| @@ -168,7 +168,7 @@ func (u *Updater) skipUpdateCheck() bool { | ||||
| 		return true | ||||
| 	} | ||||
|  | ||||
| 	userConfig := u.UserConfig | ||||
| 	userConfig := u.UserConfig() | ||||
| 	if userConfig.Update.Method == "never" { | ||||
| 		u.Log.Info("Update method is set to never so we won't check for an update") | ||||
| 		return true | ||||
|   | ||||
| @@ -19,23 +19,25 @@ func NewDummyLog() *logrus.Entry { | ||||
|  | ||||
| func NewDummyCommon() *common.Common { | ||||
| 	tr := i18n.EnglishTranslationSet() | ||||
| 	return &common.Common{ | ||||
| 		Log:        NewDummyLog(), | ||||
| 		Tr:         tr, | ||||
| 		UserConfig: config.GetDefaultConfig(), | ||||
| 		Fs:         afero.NewOsFs(), | ||||
| 	cmn := &common.Common{ | ||||
| 		Log: NewDummyLog(), | ||||
| 		Tr:  tr, | ||||
| 		Fs:  afero.NewOsFs(), | ||||
| 	} | ||||
| 	cmn.SetUserConfig(config.GetDefaultConfig()) | ||||
| 	return cmn | ||||
| } | ||||
|  | ||||
| func NewDummyCommonWithUserConfigAndAppState(userConfig *config.UserConfig, appState *config.AppState) *common.Common { | ||||
| 	tr := i18n.EnglishTranslationSet() | ||||
| 	return &common.Common{ | ||||
| 		Log:        NewDummyLog(), | ||||
| 		Tr:         tr, | ||||
| 		UserConfig: userConfig, | ||||
| 		AppState:   appState, | ||||
| 	cmn := &common.Common{ | ||||
| 		Log:      NewDummyLog(), | ||||
| 		Tr:       tr, | ||||
| 		AppState: appState, | ||||
| 		// TODO: remove dependency on actual filesystem in tests and switch to using | ||||
| 		// in-memory for everything | ||||
| 		Fs: afero.NewOsFs(), | ||||
| 	} | ||||
| 	cmn.SetUserConfig(userConfig) | ||||
| 	return cmn | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user