From 5414ad92a0fbef718cd5069eeee23bc5168b4bf8 Mon Sep 17 00:00:00 2001 From: William Parsons-Heins Date: Sat, 16 Nov 2024 16:34:23 +0000 Subject: [PATCH 1/3] add confirmation when adding new repos to recent repos --- pkg/gui/recent_repos_panel.go | 38 ++++++++++++++++++++++++++++------- 1 file changed, 31 insertions(+), 7 deletions(-) diff --git a/pkg/gui/recent_repos_panel.go b/pkg/gui/recent_repos_panel.go index 0f2f2c7049c..52664cdb73d 100644 --- a/pkg/gui/recent_repos_panel.go +++ b/pkg/gui/recent_repos_panel.go @@ -3,6 +3,8 @@ package gui import ( "os" "path/filepath" + + "github.com/jesseduffield/lazygit/pkg/gui/types" ) // updateRecentRepoList registers the fact that we opened lazygit in this repo, @@ -16,17 +18,39 @@ func (gui *Gui) updateRecentRepoList() error { return nil } - recentRepos := gui.c.GetAppState().RecentRepos + originalRepos := gui.c.GetAppState().RecentRepos currentRepo, err := os.Getwd() if err != nil { return err } - known, recentRepos := newRecentReposList(recentRepos, currentRepo) - gui.IsNewRepo = known - // TODO: migrate this file to use forward slashes on all OSes for consistency - // (windows uses backslashes at the moment) - gui.c.GetAppState().RecentRepos = recentRepos - return gui.c.SaveAppState() + + isNew, updatedRepos := newRecentReposList(originalRepos, currentRepo) + + setRecentRepos := func(repos []string) error { + // TODO: migrate this file to use forward slashes on all OSes for consistency + // (windows uses backslashes at the moment) + gui.c.GetAppState().RecentRepos = repos + + return gui.c.SaveAppState() + } + + if !isNew { + return setRecentRepos(originalRepos) + } + + // TODO: i18n + gui.c.Confirm(types.ConfirmOpts{ + Title: "Add to recent repos", + Prompt: "Do you want to add this to the recent repos list?", + HandleClose: func() error { + return setRecentRepos(originalRepos) + }, + HandleConfirm: func() error { + return setRecentRepos(updatedRepos) + }, + }) + + return nil } // newRecentReposList returns a new repo list with a new entry but only when it doesn't exist yet From 49dee6faa389dc05b7ab1362385a720bd9021397 Mon Sep 17 00:00:00 2001 From: William Parsons-Heins Date: Mon, 18 Nov 2024 17:35:36 +0000 Subject: [PATCH 2/3] provide recent repo policy selection --- pkg/config/app_config.go | 10 ++++++ pkg/gui/recent_repos_panel.go | 64 +++++++++++++++++++++++++++++------ 2 files changed, 63 insertions(+), 11 deletions(-) diff --git a/pkg/config/app_config.go b/pkg/config/app_config.go index d6862086792..62e250c2b10 100644 --- a/pkg/config/app_config.go +++ b/pkg/config/app_config.go @@ -63,6 +63,14 @@ type ConfigFile struct { exists bool } +type RecentReposPolicy int + +const ( + RecentReposPolicyPerRepoConfirmation RecentReposPolicy = iota + RecentReposPolicyAcceptAll + RecentReposPolicyRejectAll +) + // NewAppConfig makes a new app config func NewAppConfig( name string, @@ -448,6 +456,7 @@ func (c *AppConfig) SaveGlobalUserConfig() { type AppState struct { LastUpdateCheck int64 RecentRepos []string + RecentReposPolicy RecentReposPolicy StartupPopupVersion int LastVersion string // this is the last version the user was using, for the purpose of showing release notes @@ -476,6 +485,7 @@ func getDefaultAppState() *AppState { return &AppState{ LastUpdateCheck: 0, RecentRepos: []string{}, + RecentReposPolicy: RecentReposPolicyPerRepoConfirmation, StartupPopupVersion: 0, LastVersion: "", DiffContextSize: 3, diff --git a/pkg/gui/recent_repos_panel.go b/pkg/gui/recent_repos_panel.go index 52664cdb73d..e6e47210dec 100644 --- a/pkg/gui/recent_repos_panel.go +++ b/pkg/gui/recent_repos_panel.go @@ -4,6 +4,7 @@ import ( "os" "path/filepath" + "github.com/jesseduffield/lazygit/pkg/config" "github.com/jesseduffield/lazygit/pkg/gui/types" ) @@ -34,23 +35,64 @@ func (gui *Gui) updateRecentRepoList() error { return gui.c.SaveAppState() } + denyRepo := func() error { return setRecentRepos(originalRepos) } + acceptRepo := func() error { return setRecentRepos(updatedRepos) } + if !isNew { - return setRecentRepos(originalRepos) + return acceptRepo() + } + + menuSection := types.MenuSection{ + Title: "Policy", + Column: 0, + } + + getRadioState := func(policy config.RecentReposPolicy) bool { + return gui.c.GetAppState().RecentReposPolicy == policy + } + + // TODO: how can we make our radio selection without exiting the menu? + // I want to select one then press confirm + setRecentReposPolicy := func(policy config.RecentReposPolicy) error { + gui.c.GetAppState().RecentReposPolicy = policy + return gui.c.SaveAppState() } - // TODO: i18n - gui.c.Confirm(types.ConfirmOpts{ - Title: "Add to recent repos", - Prompt: "Do you want to add this to the recent repos list?", - HandleClose: func() error { - return setRecentRepos(originalRepos) + menuItems := []*types.MenuItem{ + { + Label: "Accept", + OnPress: acceptRepo, }, - HandleConfirm: func() error { - return setRecentRepos(updatedRepos) + { + Label: "Deny", + OnPress: denyRepo, }, - }) + { + Label: "Per-repo confirmation", + Widget: types.MakeMenuRadioButton(getRadioState(config.RecentReposPolicyPerRepoConfirmation)), + OnPress: func() error { return setRecentReposPolicy(config.RecentReposPolicyPerRepoConfirmation) }, + Section: &menuSection, + }, + { + Label: "Accept all", + Widget: types.MakeMenuRadioButton(getRadioState(config.RecentReposPolicyAcceptAll)), + OnPress: func() error { return setRecentReposPolicy(config.RecentReposPolicyAcceptAll) }, + Section: &menuSection, + }, + { + Label: "Reject all", + Widget: types.MakeMenuRadioButton(getRadioState(config.RecentReposPolicyRejectAll)), + OnPress: func() error { return setRecentReposPolicy(config.RecentReposPolicyRejectAll) }, + Section: &menuSection, + }, + } - return nil + return gui.c.Menu(types.CreateMenuOptions{ + Title: "Add to recent repos", + Prompt: "Repo: " + currentRepo, + Items: menuItems, + HideCancel: true, + }) } // newRecentReposList returns a new repo list with a new entry but only when it doesn't exist yet From f51faabefceb2c7e1aa0d9f0449418256f643867 Mon Sep 17 00:00:00 2001 From: William Parsons-Heins Date: Thu, 28 Nov 2024 21:55:57 +0000 Subject: [PATCH 3/3] change the delete menu to a prompt instead --- pkg/gui/controllers/helpers/repos_helper.go | 45 +++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/pkg/gui/controllers/helpers/repos_helper.go b/pkg/gui/controllers/helpers/repos_helper.go index decebba3699..0da5be259f2 100644 --- a/pkg/gui/controllers/helpers/repos_helper.go +++ b/pkg/gui/controllers/helpers/repos_helper.go @@ -5,6 +5,7 @@ import ( "fmt" "os" "path/filepath" + "slices" "strings" "sync" @@ -137,9 +138,53 @@ func (self *ReposHelper) CreateRecentReposMenu() error { } }) + // TODO: At this point maybe just re-do the recent repos menu to a prompt? I'm basically re-doing it... + section := types.MenuSection{ + Title: "Actions", + } + + menuItems = append(menuItems, &types.MenuItem{ + // TODO: i18n + Label: "Delete item", + OpensMenu: true, + Section: §ion, + OnPress: func() error { + self.c.Prompt(types.PromptOpts{ + // TODO: i18n + Title: "Delete from recent repositories", + AllowEditSuggestion: false, + FindSuggestionsFunc: self.GetRecentReposSuggestionsFunc(recentRepoPaths), + HandleConfirm: func(string) error { return nil }, + HandleClose: func() error { return nil }, + HandleDeleteSuggestion: func(index int) error { + // TODO: copied from the shell command one, might be worth pulling this out into a shared function? + item := self.c.Contexts().Suggestions.GetItems()[index].Value + fullIndex := lo.IndexOf(self.c.GetAppState().RecentRepos, item) + if fullIndex == -1 { + self.c.Log.Warnf("Failed to find this repo in the app state %s", item) + return nil + } + + self.c.GetAppState().RecentRepos = slices.Delete(self.c.GetAppState().RecentRepos, fullIndex, fullIndex+1) + self.c.SaveAppStateAndLogError() + self.c.Contexts().Suggestions.RefreshSuggestions() + return nil + }, + }) + + return nil + }, + }) + return self.c.Menu(types.CreateMenuOptions{Title: self.c.Tr.RecentRepos, Items: menuItems}) } +func (self *ReposHelper) GetRecentReposSuggestionsFunc(recentRepoPaths []string) func(string) []*types.Suggestion { + return func(input string) []*types.Suggestion { + return FilterFunc(recentRepoPaths, self.c.UserConfig().Gui.UseFuzzySearch())(input) + } +} + func (self *ReposHelper) DispatchSwitchToRepo(path string, contextKey types.ContextKey) error { return self.DispatchSwitchTo(path, self.c.Tr.ErrRepositoryMovedOrDeleted, contextKey) }