clipboard_unix.go 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. // Copyright 2013 @atotto. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. // +build freebsd linux netbsd openbsd solaris dragonfly
  5. package clipboard
  6. import (
  7. "errors"
  8. "os"
  9. "os/exec"
  10. )
  11. const (
  12. xsel = "xsel"
  13. xclip = "xclip"
  14. powershellExe = "powershell.exe"
  15. clipExe = "clip.exe"
  16. wlcopy = "wl-copy"
  17. wlpaste = "wl-paste"
  18. termuxClipboardGet = "termux-clipboard-get"
  19. termuxClipboardSet = "termux-clipboard-set"
  20. )
  21. var (
  22. Primary bool
  23. trimDos bool
  24. pasteCmdArgs []string
  25. copyCmdArgs []string
  26. xselPasteArgs = []string{xsel, "--output", "--clipboard"}
  27. xselCopyArgs = []string{xsel, "--input", "--clipboard"}
  28. xclipPasteArgs = []string{xclip, "-out", "-selection", "clipboard"}
  29. xclipCopyArgs = []string{xclip, "-in", "-selection", "clipboard"}
  30. powershellExePasteArgs = []string{powershellExe, "Get-Clipboard"}
  31. clipExeCopyArgs = []string{clipExe}
  32. wlpasteArgs = []string{wlpaste, "--no-newline"}
  33. wlcopyArgs = []string{wlcopy}
  34. termuxPasteArgs = []string{termuxClipboardGet}
  35. termuxCopyArgs = []string{termuxClipboardSet}
  36. missingCommands = errors.New("No clipboard utilities available. Please install xsel, xclip, wl-clipboard or Termux:API add-on for termux-clipboard-get/set.")
  37. )
  38. func init() {
  39. if os.Getenv("WAYLAND_DISPLAY") != "" {
  40. pasteCmdArgs = wlpasteArgs
  41. copyCmdArgs = wlcopyArgs
  42. if _, err := exec.LookPath(wlcopy); err == nil {
  43. if _, err := exec.LookPath(wlpaste); err == nil {
  44. return
  45. }
  46. }
  47. }
  48. pasteCmdArgs = xclipPasteArgs
  49. copyCmdArgs = xclipCopyArgs
  50. if _, err := exec.LookPath(xclip); err == nil {
  51. return
  52. }
  53. pasteCmdArgs = xselPasteArgs
  54. copyCmdArgs = xselCopyArgs
  55. if _, err := exec.LookPath(xsel); err == nil {
  56. return
  57. }
  58. pasteCmdArgs = termuxPasteArgs
  59. copyCmdArgs = termuxCopyArgs
  60. if _, err := exec.LookPath(termuxClipboardSet); err == nil {
  61. if _, err := exec.LookPath(termuxClipboardGet); err == nil {
  62. return
  63. }
  64. }
  65. pasteCmdArgs = powershellExePasteArgs
  66. copyCmdArgs = clipExeCopyArgs
  67. trimDos = true
  68. if _, err := exec.LookPath(clipExe); err == nil {
  69. if _, err := exec.LookPath(powershellExe); err == nil {
  70. return
  71. }
  72. }
  73. Unsupported = true
  74. }
  75. func getPasteCommand() *exec.Cmd {
  76. if Primary {
  77. pasteCmdArgs = pasteCmdArgs[:1]
  78. }
  79. return exec.Command(pasteCmdArgs[0], pasteCmdArgs[1:]...)
  80. }
  81. func getCopyCommand() *exec.Cmd {
  82. if Primary {
  83. copyCmdArgs = copyCmdArgs[:1]
  84. }
  85. return exec.Command(copyCmdArgs[0], copyCmdArgs[1:]...)
  86. }
  87. func readAll() (string, error) {
  88. if Unsupported {
  89. return "", missingCommands
  90. }
  91. pasteCmd := getPasteCommand()
  92. out, err := pasteCmd.Output()
  93. if err != nil {
  94. return "", err
  95. }
  96. result := string(out)
  97. if trimDos && len(result) > 1 {
  98. result = result[:len(result)-2]
  99. }
  100. return result, nil
  101. }
  102. func writeAll(text string) error {
  103. if Unsupported {
  104. return missingCommands
  105. }
  106. copyCmd := getCopyCommand()
  107. in, err := copyCmd.StdinPipe()
  108. if err != nil {
  109. return err
  110. }
  111. if err := copyCmd.Start(); err != nil {
  112. return err
  113. }
  114. if _, err := in.Write([]byte(text)); err != nil {
  115. return err
  116. }
  117. if err := in.Close(); err != nil {
  118. return err
  119. }
  120. return copyCmd.Wait()
  121. }