Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for reading and writing bytes directly, without converting to string #46

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 11 additions & 7 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
language: go

go:
- go1.4.3
- go1.5.4
- go1.6.4
- go1.7.6
- go1.8.7
- go1.9.4
- go1.10
- "1.4"
- "1.5"
- "1.6"
- "1.7"
- "1.8"
- "1.9"
- "1.10"
- "1.11"
- "1.12"
- "1.13"
- "1.14"

before_install:
- export DISPLAY=:99.0
Expand Down
35 changes: 15 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,45 +4,40 @@

# Clipboard for Go

Provide copying and pasting to the Clipboard for Go.
Provide functionality for copying from and pasting to the clipboard.

Build:
### Build

$ go get github.com/atotto/clipboard
$ go get -u github.com/atotto/clipboard

Platforms:
### Platforms

* OSX
* Windows 7 (probably work on other Windows)
* Linux, Unix (requires 'xclip' or 'xsel' command to be installed)
* macOS
* Windows 7 (probably works on later editions too)
* Linux, Unix (requires `xclip` and `xsel` to be installed (or `wlpaste` and `wlcopy`, for Wayland)


Document:
### Documentation

* http://godoc.org/github.com/atotto/clipboard

Notes:
### Notes

* Text string only
* UTF-8 text encoding only (no conversion)
* For functions that takes or return a string, only UTF-8 is supported

TODO:
### TODO

* Clipboard watcher(?)
- [ ] Clipboard watcher(?)

## Commands:
## Commands

paste shell command:

$ go get github.com/atotto/clipboard/cmd/gopaste
$ go get -u github.com/atotto/clipboard/cmd/gopaste
$ # example:
$ gopaste > document.txt

copy shell command:

$ go get github.com/atotto/clipboard/cmd/gocopy
$ go get -u github.com/atotto/clipboard/cmd/gocopy
$ # example:
$ cat document.txt | gocopy



14 changes: 12 additions & 2 deletions clipboard.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,26 @@
// Package clipboard read/write on clipboard
package clipboard

// ReadAll read string from clipboard
// ReadAll will read a string from the clipboard
func ReadAll() (string, error) {
return readAll()
}

// WriteAll write string to clipboard
// WriteAll will write a string to the clipboard
func WriteAll(text string) error {
return writeAll(text)
}

// ReadAllBytes will read bytes from the clipboard
func ReadAllBytes() ([]byte, error) {
return readAllBytes()
}

// WriteAllBytes will write bytes to the clipboard
func WriteAllBytes(b []byte) error {
return writeAllBytes(b)
}

// Unsupported might be set true during clipboard init, to help callers decide
// whether or not to offer clipboard options.
var Unsupported bool
45 changes: 45 additions & 0 deletions clipboard_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,37 @@ func TestCopyAndPaste(t *testing.T) {
}
}

func TestCopyAndPasteBytes(t *testing.T) {
expected := []byte{0, 1, 2, 3, 4, 5, 6, 7}

err := WriteAllBytes(expected)
if err != nil {
t.Fatal(err)
}

actual, err := ReadAllBytes()
if err != nil {
t.Fatal(err)
}

min := func(a, b int) int {
if a < b {
return a
}
return b
}

// For testing the test
// expected[0] = 42

for i := 0; i < min(len(actual), len(expected)); i++ {
if actual[i] != expected[i] {
t.Errorf("want %s, got %s", expected, actual)
break
}
}
}

func TestMultiCopyAndPaste(t *testing.T) {
expected1 := "French: éèêëàùœç"
expected2 := "Weird UTF-8: 💩☃"
Expand Down Expand Up @@ -71,3 +102,17 @@ func BenchmarkWriteAll(b *testing.B) {
WriteAll(text)
}
}

func BenchmarkReadAllBytes(b *testing.B) {
for i := 0; i < b.N; i++ {
ReadAllBytes()
}
}

var bs = []byte("いろはにほへと")

func BenchmarkWriteAllBytes(b *testing.B) {
for i := 0; i < b.N; i++ {
WriteAllBytes(bs)
}
}
36 changes: 24 additions & 12 deletions clipboard_unix.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ import (
const (
xsel = "xsel"
xclip = "xclip"
wlcopy = "wl-copy"
wlpaste = "wl-paste"
wlcopy = "wl-copy"
wlpaste = "wl-paste"
termuxClipboardGet = "termux-clipboard-get"
termuxClipboardSet = "termux-clipboard-set"
)
Expand All @@ -34,18 +34,18 @@ var (
xclipCopyArgs = []string{xclip, "-in", "-selection", "clipboard"}

wlpasteArgs = []string{wlpaste, "--no-newline"}
wlcopyArgs = []string{wlcopy}
wlcopyArgs = []string{wlcopy}

termuxPasteArgs = []string{termuxClipboardGet}
termuxCopyArgs = []string{termuxClipboardSet}

missingCommands = errors.New("No clipboard utilities available. Please install xsel, xclip, wl-clipboard or Termux:API add-on for termux-clipboard-get/set.")
errMissingCommands = errors.New("No clipboard utilities available. Please install xsel, xclip, wl-clipboard or Termux:API add-on for termux-clipboard-get/set.")
)

func init() {
if os.Getenv("WAYLAND_DISPLAY") != "" {
pasteCmdArgs = wlpasteArgs;
copyCmdArgs = wlcopyArgs;
pasteCmdArgs = wlpasteArgs
copyCmdArgs = wlcopyArgs

if _, err := exec.LookPath(wlcopy); err == nil {
if _, err := exec.LookPath(wlpaste); err == nil {
Expand Down Expand Up @@ -94,21 +94,29 @@ func getCopyCommand() *exec.Cmd {
return exec.Command(copyCmdArgs[0], copyCmdArgs[1:]...)
}

func readAll() (string, error) {
func readAllBytes() ([]byte, error) {
if Unsupported {
return "", missingCommands
return []byte{}, errMissingCommands
}
pasteCmd := getPasteCommand()
out, err := pasteCmd.Output()
if err != nil {
return []byte{}, err
}
return out, nil
}

func readAll() (string, error) {
b, err := readAllBytes()
if err != nil {
return "", err
}
return string(out), nil
return string(b), nil
}

func writeAll(text string) error {
func writeAllBytes(b []byte) error {
if Unsupported {
return missingCommands
return errMissingCommands
}
copyCmd := getCopyCommand()
in, err := copyCmd.StdinPipe()
Expand All @@ -119,11 +127,15 @@ func writeAll(text string) error {
if err := copyCmd.Start(); err != nil {
return err
}
if _, err := in.Write([]byte(text)); err != nil {
if _, err := in.Write(b); err != nil {
return err
}
if err := in.Close(); err != nil {
return err
}
return copyCmd.Wait()
}

func writeAll(text string) error {
return writeAllBytes([]byte(text))
}