From 79888d3bdeae57bad17db4b0716a5f59e7c2df31 Mon Sep 17 00:00:00 2001 From: Farzad Majidfayyaz Date: Tue, 10 Nov 2020 14:57:50 -0500 Subject: [PATCH] Add mapping to copy a pull request URL to the clipboard --- pkg/commands/pull_request.go | 30 +++++++++++++++++++++++++----- pkg/config/user_config.go | 2 ++ pkg/gui/branches_panel.go | 13 +++++++++++++ pkg/gui/keybindings.go | 7 +++++++ pkg/i18n/dutch.go | 2 ++ pkg/i18n/english.go | 4 ++++ pkg/i18n/polish.go | 2 ++ 7 files changed, 55 insertions(+), 5 deletions(-) diff --git a/pkg/commands/pull_request.go b/pkg/commands/pull_request.go index 3a820dbfd..8bddbec50 100644 --- a/pkg/commands/pull_request.go +++ b/pkg/commands/pull_request.go @@ -91,10 +91,29 @@ func NewPullRequest(gitCommand *GitCommand) *PullRequest { // Create opens link to new pull request in browser func (pr *PullRequest) Create(branch *models.Branch) error { + pullRequestURL, err := pr.getPullRequestURL(branch) + if err != nil { + return err + } + + return pr.GitCommand.OSCommand.OpenLink(pullRequestURL) +} + +// CopyURL copies the pull request URL to the clipboard +func (pr *PullRequest) CopyURL(branch *models.Branch) error { + pullRequestURL, err := pr.getPullRequestURL(branch) + if err != nil { + return err + } + + return pr.GitCommand.OSCommand.CopyToClipboard(pullRequestURL) +} + +func (pr *PullRequest) getPullRequestURL(branch *models.Branch) (string, error) { branchExistsOnRemote := pr.GitCommand.CheckRemoteBranchExists(branch) if !branchExistsOnRemote { - return errors.New(pr.GitCommand.Tr.NoBranchOnRemote) + return "", errors.New(pr.GitCommand.Tr.NoBranchOnRemote) } repoURL := pr.GitCommand.GetRemoteURL() @@ -108,14 +127,15 @@ func (pr *PullRequest) Create(branch *models.Branch) error { } if gitService == nil { - return errors.New(pr.GitCommand.Tr.UnsupportedGitService) + return "", errors.New(pr.GitCommand.Tr.UnsupportedGitService) } repoInfo := getRepoInfoFromURL(repoURL) - - return pr.GitCommand.OSCommand.OpenLink(fmt.Sprintf( + pullRequestURL := fmt.Sprintf( gitService.PullRequestURL, repoInfo.Owner, repoInfo.Repository, branch.Name, - )) + ) + + return pullRequestURL, nil } func getRepoInfoFromURL(url string) *RepoInformation { diff --git a/pkg/config/user_config.go b/pkg/config/user_config.go index d8514db11..be13eaeff 100644 --- a/pkg/config/user_config.go +++ b/pkg/config/user_config.go @@ -169,6 +169,7 @@ type KeybindingFilesConfig struct { type KeybindingBranchesConfig struct { CreatePullRequest string `yaml:"createPullRequest"` + CopyPullRequestURL string `yaml:"copyPullRequestURL"` CheckoutBranchByName string `yaml:"checkoutBranchByName"` ForceCheckoutBranch string `yaml:"forceCheckoutBranch"` RebaseBranch string `yaml:"rebaseBranch"` @@ -383,6 +384,7 @@ func GetDefaultConfig() *UserConfig { Fetch: "f", }, Branches: KeybindingBranchesConfig{ + CopyPullRequestURL: "c", CreatePullRequest: "o", CheckoutBranchByName: "c", ForceCheckoutBranch: "F", diff --git a/pkg/gui/branches_panel.go b/pkg/gui/branches_panel.go index 29b70928b..aadb12af4 100644 --- a/pkg/gui/branches_panel.go +++ b/pkg/gui/branches_panel.go @@ -99,6 +99,19 @@ func (gui *Gui) handleCreatePullRequestPress(g *gocui.Gui, v *gocui.View) error return nil } +func (gui *Gui) handleCopyPullRequestURLPress(g *gocui.Gui, v *gocui.View) error { + pullRequest := commands.NewPullRequest(gui.GitCommand) + + branch := gui.getSelectedBranch() + if err := pullRequest.CopyURL(branch); err != nil { + return gui.surfaceError(err) + } + + return gui.createPopupPanel(createPopupPanelOpts{ + prompt: "Pull request URL copied to clipboard", + }) +} + func (gui *Gui) handleGitFetch(g *gocui.Gui, v *gocui.View) error { if err := gui.createLoaderPanel(gui.Tr.FetchWait); err != nil { return err diff --git a/pkg/gui/keybindings.go b/pkg/gui/keybindings.go index 2f005a442..db01c1455 100644 --- a/pkg/gui/keybindings.go +++ b/pkg/gui/keybindings.go @@ -505,6 +505,13 @@ func (gui *Gui) GetInitialKeybindings() []*Binding { Handler: gui.handleCreatePullRequestPress, Description: gui.Tr.LcCreatePullRequest, }, + { + ViewName: "branches", + Contexts: []string{LOCAL_BRANCHES_CONTEXT_KEY}, + Key: gui.getKey(config.Branches.CopyPullRequestURL), + Handler: gui.handleCopyPullRequestURLPress, + Description: gui.Tr.LcCopyPullRequestURL, + }, { ViewName: "branches", Contexts: []string{LOCAL_BRANCHES_CONTEXT_KEY}, diff --git a/pkg/i18n/dutch.go b/pkg/i18n/dutch.go index 296e3ddf4..9036f02b2 100644 --- a/pkg/i18n/dutch.go +++ b/pkg/i18n/dutch.go @@ -154,6 +154,7 @@ func dutchTranslationSet() TranslationSet { SwitchRepo: "wissel naar een recente repo", UnsupportedGitService: `Niet-ondersteunde git-service`, LcCreatePullRequest: `maak een pull-aanvraag`, + LcCopyPullRequestURL: `kopieer de URL van het pull-verzoek naar het klembord`, NoBranchOnRemote: `Deze branch bestaat niet op de remote. U moet het eerst naar de remote pushen.`, LcFetch: `fetch`, NoAutomaticGitFetchTitle: `Geen automatische git fetch`, @@ -380,5 +381,6 @@ func dutchTranslationSet() TranslationSet { NoFilesStagedPrompt: "Je hebt geen bestanden gestaged. Commit alle bestanden?", BranchNotFoundTitle: "Branch niet gevonden", BranchNotFoundPrompt: "Branch niet gevonden. Creëer een nieuwe branch genaamd", + PullRequestURLCopiedToClipboard: "Pull-aanvraag-URL gekopieerd naar klembord", } } diff --git a/pkg/i18n/english.go b/pkg/i18n/english.go index 2700246c2..50dea7d49 100644 --- a/pkg/i18n/english.go +++ b/pkg/i18n/english.go @@ -166,6 +166,7 @@ type TranslationSet struct { SwitchRepo string UnsupportedGitService string LcCreatePullRequest string + LcCopyPullRequestURL string NoBranchOnRemote string LcFetch string NoAutomaticGitFetchTitle string @@ -429,6 +430,7 @@ type TranslationSet struct { SubmodulesTitle string NavigationTitle string PushingTagStatus string + PullRequestURLCopiedToClipboard string } const englishReleaseNotes = `## lazygit 0.23.2 Release Notes @@ -664,6 +666,7 @@ func englishTranslationSet() TranslationSet { SwitchRepo: `switch to a recent repo`, UnsupportedGitService: `Unsupported git service`, LcCreatePullRequest: `create pull request`, + LcCopyPullRequestURL: `copy pull request URL to clipboard`, NoBranchOnRemote: `This branch doesn't exist on remote. You need to push it to remote first.`, LcFetch: `fetch`, NoAutomaticGitFetchTitle: `No automatic git fetch`, @@ -928,5 +931,6 @@ func englishTranslationSet() TranslationSet { SubmodulesTitle: "Submodules", NavigationTitle: "List Panel Navigation", PushingTagStatus: "pushing tag", + PullRequestURLCopiedToClipboard: "Pull request URL copied to clipboard", } } diff --git a/pkg/i18n/polish.go b/pkg/i18n/polish.go index f7d1174a7..0edb697d1 100644 --- a/pkg/i18n/polish.go +++ b/pkg/i18n/polish.go @@ -127,6 +127,7 @@ func polishTranslationSet() TranslationSet { ConfirmQuit: `Na pewno chcesz wyjść z programu?`, UnsupportedGitService: `Nieobsługiwana usługa git`, LcCreatePullRequest: `utwórz żądanie wyciągnięcia`, + LcCopyPullRequestURL: `skopiuj adres URL żądania ściągnięcia do schowka`, NoBranchOnRemote: `Ta gałąź nie istnieje na zdalnym. Najpierw musisz go odepchnąć na odległość.`, LcFetch: `fetch`, NoAutomaticGitFetchTitle: `No automatic git fetch`, @@ -250,5 +251,6 @@ func polishTranslationSet() TranslationSet { NoFilesStagedPrompt: "You have not staged any files. Commit all files?", BranchNotFoundTitle: "Branch not found", BranchNotFoundPrompt: "Branch not found. Create a new branch named", + PullRequestURLCopiedToClipboard: "URL żądania ściągnięcia skopiowany do schowka", } }