From 68edfa20b43848f337da6eeb9e0098c88205550a Mon Sep 17 00:00:00 2001 From: Stefan Haller Date: Wed, 26 Jun 2024 22:19:03 +0200 Subject: [PATCH 1/2] Add function os.PasteFromClipboard And a user config to override it with a custom command. --- docs/Config.md | 14 ++++++++++++-- pkg/commands/oscommands/os.go | 17 +++++++++++++++++ pkg/config/user_config.go | 6 +++++- schema/config.json | 6 +++++- 4 files changed, 39 insertions(+), 4 deletions(-) diff --git a/docs/Config.md b/docs/Config.md index 67d73ebd4..88df40621 100644 --- a/docs/Config.md +++ b/docs/Config.md @@ -415,9 +415,13 @@ os: openLinkCommand: "" # CopyToClipboardCmd is the command for copying to clipboard. - # See https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#custom-command-for-copying-to-clipboard + # See https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#custom-command-for-copying-to-and-pasting-from-clipboard copyToClipboardCmd: "" + # ReadFromClipboardCmd is the command for reading the clipboard. + # See https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#custom-command-for-copying-to-and-pasting-from-clipboard + readFromClipboardCmd: "" + # If true, don't display introductory popups upon opening Lazygit. disableStartupPopups: false @@ -620,7 +624,7 @@ os: open: 'open {{filename}}' ``` -## Custom Command for Copying to Clipboard +## Custom Command for Copying to and Pasting from Clipboard ```yaml os: copyToClipboardCmd: '' @@ -633,6 +637,12 @@ os: copyToClipboardCmd: printf "\033]52;c;$(printf {{text}} | base64)\a" > /dev/tty ``` +A custom command for reading from the clipboard can be set using +```yaml +os: + readFromClipboardCmd: '' +``` +It is used, for example, when pasting a commit message into the commit message panel. The command is supposed to output the clipboard content to stdout. ## Configuring File Editing diff --git a/pkg/commands/oscommands/os.go b/pkg/commands/oscommands/os.go index 0a6bf7397..7771dffba 100644 --- a/pkg/commands/oscommands/os.go +++ b/pkg/commands/oscommands/os.go @@ -302,6 +302,23 @@ func (c *OSCommand) CopyToClipboard(str string) error { return clipboard.WriteAll(str) } +func (c *OSCommand) PasteFromClipboard() (string, error) { + var s string + var err error + if c.UserConfig.OS.CopyToClipboardCmd != "" { + cmdStr := c.UserConfig.OS.ReadFromClipboardCmd + s, err = c.Cmd.NewShell(cmdStr).RunWithOutput() + } else { + s, err = clipboard.ReadAll() + } + + if err != nil { + return "", err + } + + return strings.ReplaceAll(s, "\r\n", "\n"), nil +} + func (c *OSCommand) RemoveFile(path string) error { msg := utils.ResolvePlaceholderString( c.Tr.Log.RemoveFile, diff --git a/pkg/config/user_config.go b/pkg/config/user_config.go index 7ab567fbe..26d10f73a 100644 --- a/pkg/config/user_config.go +++ b/pkg/config/user_config.go @@ -565,8 +565,12 @@ type OSConfig struct { OpenLinkCommand string `yaml:"openLinkCommand,omitempty"` // CopyToClipboardCmd is the command for copying to clipboard. - // See https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#custom-command-for-copying-to-clipboard + // See https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#custom-command-for-copying-to-and-pasting-from-clipboard CopyToClipboardCmd string `yaml:"copyToClipboardCmd,omitempty"` + + // ReadFromClipboardCmd is the command for reading the clipboard. + // See https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#custom-command-for-copying-to-and-pasting-from-clipboard + ReadFromClipboardCmd string `yaml:"readFromClipboardCmd,omitempty"` } type CustomCommandAfterHook struct { diff --git a/schema/config.json b/schema/config.json index 802069bed..daaf4ada6 100644 --- a/schema/config.json +++ b/schema/config.json @@ -796,7 +796,11 @@ }, "copyToClipboardCmd": { "type": "string", - "description": "CopyToClipboardCmd is the command for copying to clipboard.\nSee https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#custom-command-for-copying-to-clipboard" + "description": "CopyToClipboardCmd is the command for copying to clipboard.\nSee https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#custom-command-for-copying-to-and-pasting-from-clipboard" + }, + "readFromClipboardCmd": { + "type": "string", + "description": "ReadFromClipboardCmd is the command for reading the clipboard.\nSee https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#custom-command-for-copying-to-and-pasting-from-clipboard" } }, "additionalProperties": false, From d146d834c29c4e410b9e0f654ab51be542d4e5af Mon Sep 17 00:00:00 2001 From: WaterLemons2k <62788816+WaterLemons2k@users.noreply.github.com> Date: Tue, 18 Jun 2024 20:49:02 +0800 Subject: [PATCH 2/2] Add command to paste commit message from clipboard Resolves #3672 --- pkg/gui/controllers/helpers/commits_helper.go | 32 +++++++++++ pkg/i18n/english.go | 4 ++ .../tests/commit/paste_commit_message.go | 49 +++++++++++++++++ .../paste_commit_message_over_existing.go | 54 +++++++++++++++++++ pkg/integration/tests/test_list.go | 2 + 5 files changed, 141 insertions(+) create mode 100644 pkg/integration/tests/commit/paste_commit_message.go create mode 100644 pkg/integration/tests/commit/paste_commit_message_over_existing.go diff --git a/pkg/gui/controllers/helpers/commits_helper.go b/pkg/gui/controllers/helpers/commits_helper.go index 6e1a181c7..216f55f8e 100644 --- a/pkg/gui/controllers/helpers/commits_helper.go +++ b/pkg/gui/controllers/helpers/commits_helper.go @@ -238,6 +238,13 @@ func (self *CommitsHelper) OpenCommitMenu(suggestionFunc func(string) []*types.S }, Key: 'c', }, + { + Label: self.c.Tr.PasteCommitMessageFromClipboard, + OnPress: func() error { + return self.pasteCommitMessageFromClipboard() + }, + Key: 'p', + }, } return self.c.Menu(types.CreateMenuOptions{ Title: self.c.Tr.CommitMenuTitle, @@ -257,3 +264,28 @@ func (self *CommitsHelper) addCoAuthor(suggestionFunc func(string) []*types.Sugg }, }) } + +func (self *CommitsHelper) pasteCommitMessageFromClipboard() error { + message, err := self.c.OS().PasteFromClipboard() + if err != nil { + return err + } + if message == "" { + return nil + } + + if currentMessage := self.JoinCommitMessageAndUnwrappedDescription(); currentMessage == "" { + self.SetMessageAndDescriptionInView(message) + return nil + } + + // Confirm before overwriting the commit message + return self.c.Confirm(types.ConfirmOpts{ + Title: self.c.Tr.PasteCommitMessageFromClipboard, + Prompt: self.c.Tr.SurePasteCommitMessage, + HandleConfirm: func() error { + self.SetMessageAndDescriptionInView(message) + return nil + }, + }) +} diff --git a/pkg/i18n/english.go b/pkg/i18n/english.go index 0c8f00479..3665ae8b1 100644 --- a/pkg/i18n/english.go +++ b/pkg/i18n/english.go @@ -582,6 +582,8 @@ type TranslationSet struct { CommitHash string CommitURL string CopyCommitMessageToClipboard string + PasteCommitMessageFromClipboard string + SurePasteCommitMessage string CommitMessage string CommitSubject string CommitAuthor string @@ -1553,6 +1555,8 @@ func EnglishTranslationSet() *TranslationSet { CommitHash: "Commit hash", CommitURL: "Commit URL", CopyCommitMessageToClipboard: "Copy commit message to clipboard", + PasteCommitMessageFromClipboard: "Paste commit message from clipboard", + SurePasteCommitMessage: "Pasting will overwrite the current commit message, continue?", CommitMessage: "Commit message", CommitSubject: "Commit subject", CommitAuthor: "Commit author", diff --git a/pkg/integration/tests/commit/paste_commit_message.go b/pkg/integration/tests/commit/paste_commit_message.go new file mode 100644 index 000000000..130d1885f --- /dev/null +++ b/pkg/integration/tests/commit/paste_commit_message.go @@ -0,0 +1,49 @@ +package commit + +import ( + "github.com/jesseduffield/lazygit/pkg/config" + . "github.com/jesseduffield/lazygit/pkg/integration/components" +) + +var PasteCommitMessage = NewIntegrationTest(NewIntegrationTestArgs{ + Description: "Paste a commit message into the commit message panel", + ExtraCmdArgs: []string{}, + Skip: false, + SetupConfig: func(config *config.AppConfig) { + config.UserConfig.OS.CopyToClipboardCmd = "echo {{text}} > ../clipboard" + config.UserConfig.OS.ReadFromClipboardCmd = "cat ../clipboard" + }, + SetupRepo: func(shell *Shell) { + shell.EmptyCommit("subject\n\nbody 1st line\nbody 2nd line") + shell.CreateFileAndAdd("file", "file content") + }, + Run: func(t *TestDriver, keys config.KeybindingConfig) { + t.Views().Commits(). + Focus(). + ContainsLines( + Contains("subject").IsSelected(), + ). + Press(keys.Commits.CopyCommitAttributeToClipboard) + + t.ExpectPopup().Menu().Title(Equals("Copy to clipboard")). + Select(Contains("Commit message")).Confirm() + + t.ExpectToast(Equals("Commit message copied to clipboard")) + + t.Views().Files(). + Focus(). + Press(keys.Files.CommitChanges) + + t.ExpectPopup().CommitMessagePanel(). + OpenCommitMenu() + + t.ExpectPopup().Menu().Title(Equals("Commit Menu")). + Select(Contains("Paste commit message from clipboard")). + Confirm() + + t.ExpectPopup().CommitMessagePanel(). + Content(Equals("subject")). + SwitchToDescription(). + Content(Equals("body 1st line\nbody 2nd line")) + }, +}) diff --git a/pkg/integration/tests/commit/paste_commit_message_over_existing.go b/pkg/integration/tests/commit/paste_commit_message_over_existing.go new file mode 100644 index 000000000..52f6d44f5 --- /dev/null +++ b/pkg/integration/tests/commit/paste_commit_message_over_existing.go @@ -0,0 +1,54 @@ +package commit + +import ( + "github.com/jesseduffield/lazygit/pkg/config" + . "github.com/jesseduffield/lazygit/pkg/integration/components" +) + +var PasteCommitMessageOverExisting = NewIntegrationTest(NewIntegrationTestArgs{ + Description: "Paste a commit message into the commit message panel when there is already text in the panel, causing a confirmation", + ExtraCmdArgs: []string{}, + Skip: false, + SetupConfig: func(config *config.AppConfig) { + config.UserConfig.OS.CopyToClipboardCmd = "echo {{text}} > ../clipboard" + config.UserConfig.OS.ReadFromClipboardCmd = "cat ../clipboard" + }, + SetupRepo: func(shell *Shell) { + shell.EmptyCommit("subject\n\nbody 1st line\nbody 2nd line") + shell.CreateFileAndAdd("file", "file content") + }, + Run: func(t *TestDriver, keys config.KeybindingConfig) { + t.Views().Commits(). + Focus(). + ContainsLines( + Contains("subject").IsSelected(), + ). + Press(keys.Commits.CopyCommitAttributeToClipboard) + + t.ExpectPopup().Menu().Title(Equals("Copy to clipboard")). + Select(Contains("Commit message")).Confirm() + + t.ExpectToast(Equals("Commit message copied to clipboard")) + + t.Views().Files(). + Focus(). + Press(keys.Files.CommitChanges) + + t.ExpectPopup().CommitMessagePanel(). + Type("existing message"). + OpenCommitMenu() + + t.ExpectPopup().Menu().Title(Equals("Commit Menu")). + Select(Contains("Paste commit message from clipboard")). + Confirm() + + t.ExpectPopup().Alert().Title(Equals("Paste commit message from clipboard")). + Content(Equals("Pasting will overwrite the current commit message, continue?")). + Confirm() + + t.ExpectPopup().CommitMessagePanel(). + Content(Equals("subject")). + SwitchToDescription(). + Content(Equals("body 1st line\nbody 2nd line")) + }, +}) diff --git a/pkg/integration/tests/test_list.go b/pkg/integration/tests/test_list.go index c879b8638..b6ebad021 100644 --- a/pkg/integration/tests/test_list.go +++ b/pkg/integration/tests/test_list.go @@ -89,6 +89,8 @@ var tests = []*components.IntegrationTest{ commit.History, commit.HistoryComplex, commit.NewBranch, + commit.PasteCommitMessage, + commit.PasteCommitMessageOverExisting, commit.PreserveCommitMessage, commit.ResetAuthor, commit.ResetAuthorRange,