diff --git a/docs/Config.md b/docs/Config.md index 04e19881d95..1ba8720e6e5 100644 --- a/docs/Config.md +++ b/docs/Config.md @@ -106,6 +106,7 @@ git: parseEmoji: false diffContextSize: 3 # how many lines of context are shown around a change in diffs os: + copyToClipboardCmd: '' # See 'Custom Command for Copying to Clipboard' section editPreset: '' # see 'Configuring File Editing' section edit: '' editAtLine: '' @@ -278,6 +279,20 @@ os: open: 'open {{filename}}' ``` +### Custom Command for Copying to Clipboard +```yaml +os: + copyToClipboardCmd: '' +``` +Specify an external command to invoke when copying to clipboard is requested. `{{text}` will be replaced by text to be copied. Default is to copy to system clipboard. + +If you are working on a terminal that supports OSC52, the following command will let you take advantage of it: +``` +os: + copyToClipboardCmd: printf "\033]52;c;$(printf {{text}} | base64)\a" > /dev/tty +``` + + ### Configuring File Editing There are two commands for opening files, `o` for "open" and `e` for "edit". `o` diff --git a/pkg/commands/oscommands/os.go b/pkg/commands/oscommands/os.go index 78dad7a8e6e..3e305a96fb7 100644 --- a/pkg/commands/oscommands/os.go +++ b/pkg/commands/oscommands/os.go @@ -267,6 +267,13 @@ func (c *OSCommand) CopyToClipboard(str string) error { escaped := strings.Replace(str, "\n", "\\n", -1) truncated := utils.TruncateWithEllipsis(escaped, 40) c.LogCommand(fmt.Sprintf("Copying '%s' to clipboard", truncated), false) + 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() + } + return clipboard.WriteAll(str) } diff --git a/pkg/config/user_config.go b/pkg/config/user_config.go index 0ad6a316fe5..07fda67ce27 100644 --- a/pkg/config/user_config.go +++ b/pkg/config/user_config.go @@ -346,6 +346,9 @@ type OSConfig struct { // OpenLinkCommand is the command for opening a link // Deprecated: use OpenLink instead. OpenLinkCommand string `yaml:"openLinkCommand,omitempty"` + + // CopyToClipboardCmd is the command for copying to clipboard + CopyToClipboardCmd string `yaml:"copyToClipboardCmd,omitempty"` } type CustomCommandAfterHook struct { diff --git a/pkg/integration/tests/patch_building/copy_patch_to_clipboard.go b/pkg/integration/tests/patch_building/copy_patch_to_clipboard.go index 18c0cae09d4..93ac52348a8 100644 --- a/pkg/integration/tests/patch_building/copy_patch_to_clipboard.go +++ b/pkg/integration/tests/patch_building/copy_patch_to_clipboard.go @@ -8,42 +8,43 @@ import ( var CopyPatchToClipboard = NewIntegrationTest(NewIntegrationTestArgs{ Description: "Create a patch from the commits and copy the patch to clipbaord.", ExtraCmdArgs: []string{}, - Skip: true, // skipping because CI doesn't have clipboard functionality - SetupConfig: func(config *config.AppConfig) {}, + Skip: false, + SetupConfig: func(config *config.AppConfig) { + config.UserConfig.OS.CopyToClipboardCmd = "echo {{text}} > clipboard" + }, + + + SetupRepo: func(shell *Shell) { shell.NewBranch("branch-a") shell.CreateFileAndAdd("file1", "first line\n") shell.Commit("first commit") - - shell.NewBranch("branch-b") - shell.UpdateFileAndAdd("file1", "first line\nsecond line\n") - shell.Commit("update") - shell.Checkout("branch-a") }, + + Run: func(t *TestDriver, keys config.KeybindingConfig) { - t.Views().Branches(). - Focus(). - Lines( - Contains("branch-a").IsSelected(), - Contains("branch-b"), - ). - Press(keys.Universal.NextItem). - PressEnter(). - PressEnter() - t.Views(). - CommitFiles(). - Lines( - Contains("M file1").IsSelected(), - ). - PressPrimaryAction() - t.Views().Information().Content(Contains("Building patch")) + t.Views().Commits().TopLines( + Contains("first commit"), + ) + + // Copy to clipboard + t.Views().Commits(). + Focus(). + Press(keys.Universal.CopyToClipboard) - t.Common().SelectPatchOption(Contains("copy patch to clipboard")) + t.Views().Files(). + Focus() - t.ExpectToast(Contains("Patch copied to clipboard")) + // Refresh files + t.GlobalPress(keys.Files.RefreshFiles) - t.ExpectClipboard(Contains("diff --git a/file1 b/file1")) + // Expect to see the clipboard file with contents + t.Views().Files(). + IsFocused(). + Lines( + Contains("clipboard"), + ) }, })