Skip to content

Commit

Permalink
feat: add os.copyToClipboardCmd to allow for a custom command
Browse files Browse the repository at this point in the history
Issue jesseduffield#1055

test: CopyPatchToClipboard (temporary commit for review)
  • Loading branch information
redstreet committed Jul 20, 2023
1 parent 7e9f669 commit e2ac6cd
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 26 deletions.
15 changes: 15 additions & 0 deletions docs/Config.md
Original file line number Diff line number Diff line change
Expand Up @@ -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: ''
Expand Down Expand Up @@ -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`
Expand Down
7 changes: 7 additions & 0 deletions pkg/commands/oscommands/os.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}

Expand Down
3 changes: 3 additions & 0 deletions pkg/config/user_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
49 changes: 23 additions & 26 deletions pkg/integration/tests/patch_building/copy_patch_to_clipboard.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,42 +8,39 @@ 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().Commits().TopLines(
Contains("first commit"),
)

t.Views().Information().Content(Contains("Building patch"))
// 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"),
)
},
})

0 comments on commit e2ac6cd

Please sign in to comment.