clipboard 1.4.1 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +26 -0
- data/Gemfile +7 -0
- data/README.md +39 -24
- data/Rakefile +39 -0
- data/clipboard.gemspec +10 -9
- data/lib/clipboard/clipboard_load_error.rb +6 -0
- data/lib/clipboard/cygwin.rb +6 -6
- data/lib/clipboard/file.rb +8 -8
- data/lib/clipboard/gtk.rb +28 -18
- data/lib/clipboard/implementation.rb +27 -0
- data/lib/clipboard/java.rb +8 -8
- data/lib/clipboard/linux.rb +30 -27
- data/lib/clipboard/linux_wayland.rb +33 -13
- data/lib/clipboard/mac.rb +5 -6
- data/lib/clipboard/osc52.rb +41 -0
- data/lib/clipboard/utils.rb +29 -0
- data/lib/clipboard/version.rb +1 -1
- data/lib/clipboard/windows.rb +10 -7
- data/lib/clipboard/wsl.rb +5 -6
- data/lib/clipboard.rb +22 -35
- data/spec/clipboard_file_spec.rb +5 -3
- data/spec/clipboard_java_spec.rb +25 -0
- data/spec/clipboard_linux_spec.rb +27 -0
- data/spec/clipboard_linux_wayland_spec.rb +29 -0
- data/spec/clipboard_mac_spec.rb +27 -0
- data/spec/clipboard_spec.rb +25 -12
- data/spec/clipboard_windows_spec.rb +27 -0
- data/spec/spec_helper.rb +1 -1
- metadata +36 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 26af5bebb02475904f8047927426e95fd93f85f2e6d1621f1caf1b36ae162416
|
4
|
+
data.tar.gz: bea335752871a978d4eaf1897bcc86846d81d6d6a8b4104dc90dcec8ec367333
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c01a2858756e7cf11f46fb6dd12a4913bb5cb2a0c267b74f650acef1410775de5130a865fe6ee06114e6a76c455d7545c7587bbdefa9eda3013c90b304b296d7
|
7
|
+
data.tar.gz: c4b021d55aaa8f93491fcb805749a6041950a6ffdb8891e707ac1e91271fdcc7c6e6f94ec8eda0cd745b6f93515ef17e592c7149b120d072db6573e4237d2408
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,31 @@
|
|
1
1
|
# CHANGELOG
|
2
2
|
|
3
|
+
## 2.0.0
|
4
|
+
|
5
|
+
### Major Changes
|
6
|
+
* Requires Ruby 3.0
|
7
|
+
* `Clipboard.copy` and `.clear` now always return true instead of the pasted string
|
8
|
+
|
9
|
+
### New Features
|
10
|
+
* Add experimental OSC52 implementation (only `Clipboard.copy`)
|
11
|
+
* Linux-based `Clipboard.copy` methods now take a clipboard argument `clipboard:`
|
12
|
+
to choose which clipboard to copy to (default is "all").
|
13
|
+
For example: `Clipboard.copy("data", clipboard: "primary")` copies only to primary clipboard
|
14
|
+
* Linux-based `Clipboard.paste` methods use either the `clipboard:` keyword argument or the
|
15
|
+
single positional argument for choosing the clipboard to paste from
|
16
|
+
* Allow setting the clipboard implementation with snake-cased symbol/string:
|
17
|
+
`Clipboard.implementation = :linux_wayland`
|
18
|
+
|
19
|
+
### Refactorings / Minor API Changes
|
20
|
+
* Change `copy`, `paste`, and `clear` to always accept keyword arguments
|
21
|
+
* All implementations are now based on `Clipboard::Implementation`
|
22
|
+
* Move implementation detection to `utils.rb`
|
23
|
+
* Be sure to pass a valid lowercase clipboard selection name (or `"all"`) when choosing clipboards,
|
24
|
+
it will now raise an `ArgumentError` if the clipboard name is not supported by the implementation
|
25
|
+
|
26
|
+
### Other
|
27
|
+
* Add more specs and run them on GitHub Actions CI
|
28
|
+
|
3
29
|
## 1.4.1
|
4
30
|
* Always use plaintext mimetype for wl-clipboard
|
5
31
|
* Do not include newline when pasting from wl-clipboard
|
data/Gemfile
ADDED
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
# Clipboard Ruby Gem [![version](https://badge.fury.io/rb/clipboard.svg)](https://badge.fury.io/rb/clipboard) [![[ci]](https://github.com/janlelis/clipboard/workflows/Test/badge.svg)](https://github.com/janlelis/clipboard/actions?query=workflow%3ATest)
|
1
|
+
# Clipboard Ruby Gem 📋︎ [![version](https://badge.fury.io/rb/clipboard.svg)](https://badge.fury.io/rb/clipboard) [![[ci]](https://github.com/janlelis/clipboard/workflows/Test/badge.svg)](https://github.com/janlelis/clipboard/actions?query=workflow%3ATest)
|
2
2
|
|
3
|
-
Lets you access the clipboard from everywhere. Currently supported platforms:
|
3
|
+
Lets you access the system clipboard from everywhere. Currently supported platforms:
|
4
4
|
|
5
5
|
- Linux (X11)
|
6
6
|
- Linux (Wayland)
|
@@ -10,10 +10,11 @@ Lets you access the clipboard from everywhere. Currently supported platforms:
|
|
10
10
|
- WSL (Windows Subsystem for Linux)
|
11
11
|
- Gtk+ (Cross Platform Widget Toolkit)
|
12
12
|
- Java (on JRuby)
|
13
|
+
- *Experimental:* OSC52 (ANSI escape sequence) **only copying** - see note below
|
13
14
|
|
14
15
|
Supported Rubies: **3.3**, **3.2**, **3.1**, **3.0**
|
15
16
|
|
16
|
-
Unsupported, but might still work: **2.X**
|
17
|
+
Unsupported, but might still work: **2.X** (use clipboard gem version 1.x)
|
17
18
|
|
18
19
|
## Usage
|
19
20
|
|
@@ -23,51 +24,73 @@ Unsupported, but might still work: **2.X**
|
|
23
24
|
|
24
25
|
## Setup
|
25
26
|
|
26
|
-
|
27
|
+
Run `gem install clipboard` (and `gem install ffi` on Windows) or add the following lines to your `Gemfile`:
|
27
28
|
|
28
29
|
```ruby
|
29
30
|
gem "clipboard"
|
30
|
-
gem "ffi", :platforms => [:mswin, :mingw] #
|
31
|
+
gem "ffi", :platforms => [:mswin, :mingw] # Necessary on Windows
|
31
32
|
```
|
32
33
|
|
33
|
-
|
34
|
+
**Important note for Linux** users: The clipboard gem requires additional programs to be available:
|
35
|
+
|
36
|
+
- On X11: **xsel** or **xclip**
|
37
|
+
- On Wayland: **wl-copy** and **wl-paste** (wl-clipboard) - depending on your system, just having **xsel** / **xclip** might also work
|
38
|
+
|
34
39
|
|
35
40
|
## Clipboard Implementations
|
36
41
|
|
37
42
|
In most environments, the appropriate clipboard implementation can be detected automatically. If none is found, the gem will fallback to a file based one, which will just write to/read from `~/.clipboard` instead of the system clipboard.
|
38
43
|
|
39
|
-
You can check the implementation used with
|
44
|
+
You can check the implementation used with `Clipboard.implementation` or set a specific implementation with `Clipboard.implementation = ...`
|
40
45
|
|
41
46
|
### Alternative Clipboard Providers
|
42
47
|
|
43
|
-
There are
|
48
|
+
There are more implementations included in this gem, which are not activated by default. You can opt-in to use them if you think they are a better fit for your application environment:
|
44
49
|
|
45
50
|
#### Java
|
46
51
|
|
47
|
-
Activate with: `Clipboard.implementation =
|
52
|
+
Activate with: `Clipboard.implementation = :java`
|
48
53
|
|
49
54
|
This is an option for [JRuby users](https://www.jruby.org/) which will use the clipboard functionality from the Java standard library.
|
50
55
|
|
51
56
|
#### GTK+
|
52
57
|
|
53
|
-
Activate with: `Clipboard.implementation =
|
58
|
+
Activate with: `Clipboard.implementation = :gtk`
|
54
59
|
|
55
60
|
This utilizes the **GTK+** library. See [Ruby-GNOME2](https://github.com/ruby-gnome2/ruby-gnome2#ruby-gnome2) for more info.
|
56
61
|
|
57
62
|
Requires the `gtk3` or `gtk2` gem to be installed.
|
58
63
|
|
64
|
+
#### OSC52
|
65
|
+
|
66
|
+
Activate with: `Clipboard.implementation = :osc52`
|
67
|
+
|
68
|
+
OSC52 is an ANSI escape sequence that some terminals support to access the system clipboard. One advantage of using this clipboard proider is that it is possible to copy from remote ssh sessions to your system clipboard.
|
69
|
+
|
70
|
+
As of the current version, only **copy** and **clear** commands are supported (no **paste**).
|
71
|
+
|
72
|
+
**Please note**: Even if your terminal includes OSC52 functionality, the feature could be (partially) disabled to prevent malicious scripts from accessing (or setting) your clipboard.
|
73
|
+
|
59
74
|
## Tips & Tricks
|
60
75
|
|
61
76
|
### Linux: Using Clipboard via SSH
|
62
77
|
|
63
|
-
To be able to use the clipboard through SSH, you need to install `xauth` on your server and connect via `ssh -X` or `ssh -Y`. Please note that some server settings restrict this feature.
|
78
|
+
To be able to use the clipboard through SSH (using the `xsel`/`xclip` based implementation), you need to install `xauth` on your server and connect via `ssh -X` or `ssh -Y`. Please note that some server settings restrict this feature.
|
79
|
+
|
80
|
+
### Linux: Copy To or Paste From Specific Clipboard / Selection
|
64
81
|
|
65
|
-
|
82
|
+
The clipboard on Linux is divided into multiple clipboard selections. You can choose from which clipboard you want to `paste` from by passing it as the first argument. The default is *:clipboard*, other options are *:primary* and, for some implementations, *:secondary*:
|
66
83
|
|
67
|
-
|
68
|
-
|
84
|
+
```ruby
|
85
|
+
Clipboard.paste("primary") # or
|
86
|
+
Clipboard.paste(clipboard: "primary")
|
87
|
+
```
|
69
88
|
|
70
|
-
`Clipboard.copy`
|
89
|
+
`Clipboard.copy` will copy to all available clipboards, except if you specifiy a clipboard using the `clipboard:` keyword argument:
|
90
|
+
|
91
|
+
```ruby
|
92
|
+
Clipboard.copy("only goes to primary clipboard", clipboard: "primary")
|
93
|
+
```
|
71
94
|
|
72
95
|
### Windows: Encoding Info
|
73
96
|
|
@@ -79,7 +102,7 @@ Clipboard.paste.encode('UTF-8')
|
|
79
102
|
|
80
103
|
### CLI Utility: blip
|
81
104
|
|
82
|
-
The [blip gem](
|
105
|
+
The [blip gem](https://rubygems.org/gems/blip) is a handy command-line wrapper for the clipboard gem. It lets you quickly copy a file's content to your clipboard:
|
83
106
|
|
84
107
|
```
|
85
108
|
$ blip FILE_NAME
|
@@ -87,14 +110,6 @@ $ blip FILE_NAME
|
|
87
110
|
|
88
111
|
Without any arguments, it will just paste the contents of the clipboard.
|
89
112
|
|
90
|
-
## Further Development
|
91
|
-
|
92
|
-
This is a list of nice-to-have features - feel free to open a PR or let me know if you want to work on one of these:
|
93
|
-
|
94
|
-
- Native support for clipboard on X11 or Wayland
|
95
|
-
- Support more platforms
|
96
|
-
- Support clipboard meta data
|
97
|
-
|
98
113
|
## MIT
|
99
114
|
|
100
115
|
Copyright (c) 2010-2024 Jan Lelis <https://janlelis.com> released under the MIT license. Contributions by and thanks to [Michael Grosser and all the other contributors!](https://github.com/janlelis/clipboard/graphs/contributors)
|
data/Rakefile
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# # #
|
4
|
+
# Get gemspec info
|
5
|
+
|
6
|
+
gemspec_file = Dir['*.gemspec'].first
|
7
|
+
gemspec = eval File.read(gemspec_file), binding, gemspec_file
|
8
|
+
info = "#{gemspec.name} | #{gemspec.version} | " \
|
9
|
+
"#{gemspec.runtime_dependencies.size} dependencies | " \
|
10
|
+
"#{gemspec.files.size} files"
|
11
|
+
|
12
|
+
# # #
|
13
|
+
# Gem build and install task
|
14
|
+
|
15
|
+
desc info
|
16
|
+
task :gem do
|
17
|
+
puts info + "\n\n"
|
18
|
+
print " "; sh "gem build #{gemspec_file}"
|
19
|
+
FileUtils.mkdir_p 'pkg'
|
20
|
+
FileUtils.mv "#{gemspec.name}-#{gemspec.version}.gem", 'pkg'
|
21
|
+
puts; sh %{gem install --no-document pkg/#{gemspec.name}-#{gemspec.version}.gem}
|
22
|
+
end
|
23
|
+
|
24
|
+
# # #
|
25
|
+
# Start an IRB session with the gem loaded
|
26
|
+
|
27
|
+
desc "#{gemspec.name} | IRB"
|
28
|
+
task :irb do
|
29
|
+
sh "irb -I ./lib -r #{gemspec.name.tr '-', '/'}"
|
30
|
+
end
|
31
|
+
|
32
|
+
# # #
|
33
|
+
# Run Specs
|
34
|
+
|
35
|
+
desc "#{gemspec.name} | Spec"
|
36
|
+
task :spec do
|
37
|
+
sh "rspec"
|
38
|
+
end
|
39
|
+
task default: :spec
|
data/clipboard.gemspec
CHANGED
@@ -1,27 +1,28 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
require 'clipboard/version'
|
3
|
+
require_relative 'lib/clipboard/version'
|
5
4
|
|
6
5
|
Gem::Specification.new do |s|
|
7
6
|
s.name = 'clipboard'
|
8
7
|
s.version = Clipboard::VERSION
|
9
8
|
s.authors = ["Jan Lelis"]
|
10
9
|
s.email = ["hi@ruby.consulting"]
|
11
|
-
s.summary = "Access
|
12
|
-
s.description = "Access
|
10
|
+
s.summary = "Access the system clipboard 📋︎ on Linux, MacOS, Windows, WSL, Cygwin, GTK, or Java."
|
11
|
+
s.description = "Access the system clipboard 📋︎ on Linux, MacOS, Windows, WSL, Cygwin, GTK, or Java. Usage is as simple as calling Clipboard.copy or Clipboard.paste!"
|
13
12
|
s.homepage = "https://github.com/janlelis/clipboard"
|
14
13
|
s.license = "MIT"
|
15
14
|
s.metadata = { "rubygems_mfa_required" => "true" }
|
16
15
|
s.requirements = [
|
17
|
-
"Linux:
|
18
|
-
"
|
16
|
+
"Linux-X11: xclip or xsel",
|
17
|
+
"Linux-Wayland: wl-clipboard",
|
18
|
+
"Windows: ffi gem",
|
19
19
|
]
|
20
|
-
s.files = Dir.glob(%w[{lib,spec}/**/*.rb [A-Z]*.txt [A-Z]*.md]) + %w
|
20
|
+
s.files = Dir.glob(%w[{lib,spec}/**/*.rb [A-Z]*.txt [A-Z]*.md]) + %w[clipboard.gemspec Gemfile Rakefile]
|
21
21
|
|
22
|
-
s.required_ruby_version = '>=
|
23
|
-
s.add_development_dependency 'rake', '~> 13.
|
22
|
+
s.required_ruby_version = '>= 3.0'
|
23
|
+
s.add_development_dependency 'rake', '~> 13.2'
|
24
24
|
s.add_development_dependency 'rspec', '~> 3'
|
25
|
+
s.add_development_dependency 'rubocop', '~> 1.6'
|
25
26
|
# s.add_development_dependency 'ffi', '~> 1.9'
|
26
27
|
# s.add_development_dependency 'gtk3', '~> 3'
|
27
28
|
end
|
data/lib/clipboard/cygwin.rb
CHANGED
@@ -1,20 +1,20 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative "implementation"
|
4
|
+
|
3
5
|
module Clipboard
|
4
6
|
module Cygwin
|
7
|
+
include Implementation
|
5
8
|
extend self
|
6
9
|
|
7
|
-
def paste(_ = nil)
|
10
|
+
def paste(_ = nil, **)
|
8
11
|
::File.read("/dev/clipboard")
|
9
12
|
end
|
10
13
|
|
11
|
-
def copy(data)
|
14
|
+
def copy(data, **)
|
12
15
|
::File.open("/dev/clipboard", "w"){ |f| f.write(data) }
|
13
|
-
paste
|
14
|
-
end
|
15
16
|
|
16
|
-
|
17
|
-
copy ''
|
17
|
+
true
|
18
18
|
end
|
19
19
|
end
|
20
20
|
end
|
data/lib/clipboard/file.rb
CHANGED
@@ -1,22 +1,22 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative "implementation"
|
4
|
+
|
3
5
|
module Clipboard
|
4
6
|
module File
|
7
|
+
include Implementation
|
5
8
|
extend self
|
6
9
|
|
7
10
|
FILE = ::File.expand_path("~/.clipboard")
|
8
11
|
|
9
|
-
def copy(
|
10
|
-
::File.open(FILE, 'w', 0o0600) { |f| f.write(
|
11
|
-
paste
|
12
|
-
end
|
12
|
+
def copy(data, **)
|
13
|
+
::File.open(FILE, 'w', 0o0600) { |f| f.write(data) } rescue ''
|
13
14
|
|
14
|
-
|
15
|
-
::File.read(FILE) rescue ''
|
15
|
+
true
|
16
16
|
end
|
17
17
|
|
18
|
-
def
|
19
|
-
|
18
|
+
def paste(_ = nil, **)
|
19
|
+
::File.read(FILE) rescue ''
|
20
20
|
end
|
21
21
|
end
|
22
22
|
end
|
data/lib/clipboard/gtk.rb
CHANGED
@@ -1,13 +1,15 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
# Requires either the gtk3 or the gtk2 gem
|
3
|
+
require_relative "implementation"
|
5
4
|
|
6
5
|
module Clipboard
|
6
|
+
# Ruby-Gnome2 based implementation
|
7
|
+
# Requires either the gtk3 or the gtk2 gem
|
7
8
|
module Gtk
|
9
|
+
include Implementation
|
8
10
|
extend self
|
9
11
|
|
10
|
-
CLIPBOARDS = %w[
|
12
|
+
CLIPBOARDS = %w[clipboard primary secondary].freeze
|
11
13
|
|
12
14
|
unless defined? ::Gtk
|
13
15
|
begin
|
@@ -21,27 +23,35 @@ module Clipboard
|
|
21
23
|
end
|
22
24
|
end
|
23
25
|
|
24
|
-
def
|
25
|
-
|
26
|
-
|
27
|
-
}
|
28
|
-
paste
|
29
|
-
end
|
30
|
-
|
31
|
-
def paste(which = nil)
|
32
|
-
if !which || !CLIPBOARDS.include?(which_normalized = which.to_s.upcase)
|
33
|
-
which_normalized = CLIPBOARDS.first
|
34
|
-
end
|
26
|
+
def paste(which = nil, clipboard: "clipboard")
|
27
|
+
selection = which || clipboard
|
28
|
+
raise ArgumentError, "unknown clipboard selection" unless CLIPBOARDS.include?(selection)
|
35
29
|
|
36
30
|
::Gtk::Clipboard.get(
|
37
|
-
Gdk::Selection.const_get(
|
31
|
+
Gdk::Selection.const_get(selection.to_s.upcase)
|
38
32
|
).wait_for_text || ""
|
39
33
|
end
|
40
34
|
|
41
|
-
def
|
42
|
-
|
43
|
-
|
35
|
+
def copy(data, clipboard: "all")
|
36
|
+
selections = clipboard.to_s == "all" ? CLIPBOARDS : [clipboard]
|
37
|
+
selections.each{ |selection|
|
38
|
+
raise ArgumentError, "unknown clipboard selection" unless CLIPBOARDS.include?(selection)
|
39
|
+
|
40
|
+
::Gtk::Clipboard.get(Gdk::Selection.const_get(selection.to_s.upcase)).set_text(data).store
|
44
41
|
}
|
42
|
+
|
43
|
+
true
|
44
|
+
end
|
45
|
+
|
46
|
+
def clear(clipboard: "all")
|
47
|
+
selections = clipboard.to_s == "all" ? CLIPBOARDS : [clipboard]
|
48
|
+
selections.each{ |selection|
|
49
|
+
raise ArgumentError, "unknown clipboard selection" unless CLIPBOARDS.include?(selection)
|
50
|
+
|
51
|
+
::Gtk::Clipboard.get(Gdk::Selection.const_get(selection.to_s.upcase)).clear
|
52
|
+
}
|
53
|
+
|
54
|
+
true
|
45
55
|
end
|
46
56
|
end
|
47
57
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Clipboard
|
4
|
+
module Implementation
|
5
|
+
extend self
|
6
|
+
|
7
|
+
# Implement paste
|
8
|
+
# Should take an optional argument
|
9
|
+
def paste(_clipboard_name = nil, **)
|
10
|
+
raise NotImplementedError, "pasting not supported by this implementation, try another"
|
11
|
+
end
|
12
|
+
|
13
|
+
# Takes the data to copy as argument
|
14
|
+
# Should return true
|
15
|
+
def copy(_data, **)
|
16
|
+
raise NotImplementedError, "copying not supported by this implementation, try another"
|
17
|
+
end
|
18
|
+
|
19
|
+
# Can be used to add a native clear implementation
|
20
|
+
# Should return true
|
21
|
+
def clear(**kwargs)
|
22
|
+
copy('', **kwargs)
|
23
|
+
|
24
|
+
true
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
data/lib/clipboard/java.rb
CHANGED
@@ -1,26 +1,26 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative "implementation"
|
4
|
+
|
3
5
|
module Clipboard
|
4
6
|
# Basic java clipboard access (jruby). No fun to use on X.
|
5
7
|
module Java
|
8
|
+
include Implementation
|
6
9
|
extend self
|
7
10
|
|
8
11
|
FLAVOR = ::Java::JavaAwtDatatransfer::DataFlavor.stringFlavor
|
9
12
|
|
10
|
-
def copy(
|
11
|
-
selection_string = ::Java::JavaAwtDatatransfer::StringSelection.new
|
13
|
+
def copy(data, **)
|
14
|
+
selection_string = ::Java::JavaAwtDatatransfer::StringSelection.new data
|
12
15
|
::Java::JavaAwt::Toolkit.default_toolkit.system_clipboard.set_contents selection_string, nil
|
13
|
-
|
16
|
+
|
17
|
+
true
|
14
18
|
end
|
15
19
|
|
16
|
-
def paste(_ = nil)
|
20
|
+
def paste(_ = nil, **)
|
17
21
|
::Java::JavaAwt::Toolkit.default_toolkit.system_clipboard.get_data(FLAVOR)
|
18
22
|
rescue
|
19
23
|
''
|
20
24
|
end
|
21
|
-
|
22
|
-
def clear
|
23
|
-
copy ''
|
24
|
-
end
|
25
25
|
end
|
26
26
|
end
|
data/lib/clipboard/linux.rb
CHANGED
@@ -1,52 +1,55 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative "implementation"
|
3
4
|
require_relative "utils"
|
4
5
|
|
5
6
|
module Clipboard
|
6
7
|
module Linux
|
8
|
+
include Implementation
|
7
9
|
extend self
|
8
10
|
|
9
11
|
CLIPBOARDS = %w[clipboard primary secondary].freeze
|
10
12
|
|
11
|
-
# check
|
13
|
+
# First check for xsel, fallback to xclip
|
12
14
|
if Utils.executable_installed? "xsel"
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
'clipboard' => '
|
18
|
-
'primary' => '
|
19
|
-
'secondary' => '
|
15
|
+
WRITE_COMMAND = 'xsel -i'
|
16
|
+
READ_COMMAND = 'xsel -o'
|
17
|
+
READ_OUTPUT_STREAM = true
|
18
|
+
SELECTION = {
|
19
|
+
'clipboard' => '--clipboard',
|
20
|
+
'primary' => '--primary',
|
21
|
+
'secondary' => '--secondary'
|
20
22
|
}.freeze
|
23
|
+
|
21
24
|
elsif Utils.executable_installed? "xclip"
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
25
|
+
WRITE_COMMAND = 'xclip'
|
26
|
+
READ_COMMAND = 'xclip -o'
|
27
|
+
READ_OUTPUT_STREAM = false
|
28
|
+
SELECTION = proc{ |x|
|
26
29
|
"-selection #{x}"
|
27
30
|
}.freeze
|
31
|
+
|
28
32
|
else
|
29
|
-
raise Clipboard::ClipboardLoadError,
|
30
|
-
|
31
|
-
"If your system is Wayland-based, please install wl-clipboard"
|
33
|
+
raise Clipboard::ClipboardLoadError,
|
34
|
+
"clipboard: Could not find required program xsl or xclip (X11) or wl-clipboard (Wayland)"
|
32
35
|
end
|
33
36
|
|
34
|
-
def paste(which = nil)
|
35
|
-
|
36
|
-
|
37
|
-
end
|
38
|
-
`#{ReadCommand} #{Selection[which_normalized]} 2> /dev/null`
|
39
|
-
end
|
37
|
+
def paste(which = nil, clipboard: "clipboard")
|
38
|
+
selection = which || clipboard
|
39
|
+
raise ArgumentError, "unknown clipboard selection" unless CLIPBOARDS.include?(selection)
|
40
40
|
|
41
|
-
|
42
|
-
copy ''
|
41
|
+
`#{READ_COMMAND} #{SELECTION[selection]} 2> /dev/null`
|
43
42
|
end
|
44
43
|
|
45
|
-
def copy(data)
|
46
|
-
|
47
|
-
|
44
|
+
def copy(data, clipboard: "all")
|
45
|
+
selections = clipboard.to_s == "all" ? CLIPBOARDS : [clipboard]
|
46
|
+
selections.each{ |selection|
|
47
|
+
raise ArgumentError, "unknown clipboard selection" unless CLIPBOARDS.include?(selection)
|
48
|
+
|
49
|
+
Utils.popen "#{WRITE_COMMAND} #{SELECTION[selection]}", data, READ_OUTPUT_STREAM
|
48
50
|
}
|
49
|
-
|
51
|
+
|
52
|
+
true
|
50
53
|
end
|
51
54
|
end
|
52
55
|
end
|
@@ -1,35 +1,55 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative "implementation"
|
3
4
|
require_relative "utils"
|
4
5
|
|
5
6
|
module Clipboard
|
6
7
|
module LinuxWayland
|
8
|
+
include Implementation
|
7
9
|
extend self
|
8
10
|
|
11
|
+
CLIPBOARDS = %w[clipboard primary].freeze
|
12
|
+
|
9
13
|
TEST_COMMAND = "wl-copy"
|
10
14
|
WRITE_COMMAND = "wl-copy --type text/plain"
|
11
15
|
READ_COMMAND = "wl-paste --type text/plain --no-newline"
|
12
16
|
|
13
17
|
if !Utils.executable_installed?(TEST_COMMAND)
|
14
|
-
raise Clipboard::ClipboardLoadError,
|
15
|
-
|
18
|
+
raise Clipboard::ClipboardLoadError,
|
19
|
+
"clipboard: Could not find required program wl-clipboard"
|
16
20
|
end
|
17
21
|
|
18
|
-
def paste(
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
22
|
+
def paste(which = nil, clipboard: "clipboard")
|
23
|
+
selection = which || clipboard
|
24
|
+
raise ArgumentError, "unknown clipboard selection" unless CLIPBOARDS.include?(selection)
|
25
|
+
|
26
|
+
primary_flag = selection == "primary" ? " --primary" : ""
|
27
|
+
|
28
|
+
`#{READ_COMMAND}#{primary_flag}`
|
24
29
|
end
|
25
30
|
|
26
|
-
def copy(data)
|
27
|
-
|
28
|
-
|
31
|
+
def copy(data, clipboard: "all")
|
32
|
+
selections = clipboard.to_s == "all" ? CLIPBOARDS : [clipboard]
|
33
|
+
selections.each{ |selection|
|
34
|
+
raise ArgumentError, "unknown clipboard selection" unless CLIPBOARDS.include?(selection)
|
35
|
+
|
36
|
+
primary_flag = selection == "primary" ? " --primary" : ""
|
37
|
+
Utils.popen("#{WRITE_COMMAND}#{primary_flag}", data)
|
38
|
+
}
|
39
|
+
|
40
|
+
true
|
29
41
|
end
|
30
42
|
|
31
|
-
def clear
|
32
|
-
|
43
|
+
def clear(clipboard: "all")
|
44
|
+
selections = clipboard.to_s == "all" ? CLIPBOARDS : [clipboard]
|
45
|
+
selections.each{ |selection|
|
46
|
+
raise ArgumentError, "unknown clipboard selection" unless CLIPBOARDS.include?(selection)
|
47
|
+
|
48
|
+
primary_flag = selection.to_s == "primary" ? " --primary" : ""
|
49
|
+
`#{WRITE_COMMAND}#{primary_flag} --clear`
|
50
|
+
}
|
51
|
+
|
52
|
+
true
|
33
53
|
end
|
34
54
|
end
|
35
55
|
end
|
data/lib/clipboard/mac.rb
CHANGED
@@ -1,22 +1,21 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative "implementation"
|
3
4
|
require_relative "utils"
|
4
5
|
|
5
6
|
module Clipboard
|
6
7
|
module Mac
|
8
|
+
include Implementation
|
7
9
|
extend self
|
8
10
|
|
9
|
-
def paste(_ = nil)
|
11
|
+
def paste(_ = nil, **)
|
10
12
|
`pbpaste`
|
11
13
|
end
|
12
14
|
|
13
|
-
def copy(data)
|
15
|
+
def copy(data, **)
|
14
16
|
Utils.popen "pbcopy", data
|
15
|
-
paste
|
16
|
-
end
|
17
17
|
|
18
|
-
|
19
|
-
copy ''
|
18
|
+
true
|
20
19
|
end
|
21
20
|
end
|
22
21
|
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "implementation"
|
4
|
+
|
5
|
+
module Clipboard
|
6
|
+
module Osc52
|
7
|
+
include Implementation
|
8
|
+
extend self
|
9
|
+
|
10
|
+
CLIPBOARDS = %w[clipboard primary].freeze
|
11
|
+
OSC52 = "]52;%<selection_option>s;%<data_base64>s"
|
12
|
+
|
13
|
+
def copy(data, clipboard: "all")
|
14
|
+
selections = clipboard.to_s == "all" ? CLIPBOARDS : [clipboard]
|
15
|
+
selections.each{ |selection|
|
16
|
+
raise ArgumentError, "unknown clipboard selection" unless CLIPBOARDS.include?(selection)
|
17
|
+
|
18
|
+
print OSC52 % {
|
19
|
+
selection_option: selection == "primary" ? "p" : "c",
|
20
|
+
data_base64: [data].pack("m0"),
|
21
|
+
}
|
22
|
+
}
|
23
|
+
|
24
|
+
true
|
25
|
+
end
|
26
|
+
|
27
|
+
def clear(clipboard: "all")
|
28
|
+
selections = clipboard.to_s == "all" ? CLIPBOARDS : [clipboard]
|
29
|
+
selections.each{ |selection|
|
30
|
+
raise ArgumentError, "unknown clipboard selection" unless CLIPBOARDS.include?(selection)
|
31
|
+
|
32
|
+
print OSC52 % {
|
33
|
+
selection_option: selection == "primary" ? "p" : "c",
|
34
|
+
data_base64: ?! # anything non-base64 / question mark clears
|
35
|
+
}
|
36
|
+
}
|
37
|
+
|
38
|
+
true
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
data/lib/clipboard/utils.rb
CHANGED
@@ -1,11 +1,40 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "rbconfig"
|
3
4
|
require "open3"
|
4
5
|
|
6
|
+
require_relative "clipboard_load_error"
|
7
|
+
|
5
8
|
module Clipboard
|
6
9
|
module Utils
|
7
10
|
extend self
|
8
11
|
|
12
|
+
# Find out which implementation is best to use
|
13
|
+
def autodetect_implementation
|
14
|
+
os = case RbConfig::CONFIG['host_os']
|
15
|
+
when /mac|darwin/ then :Mac
|
16
|
+
when /linux|bsd/ then :Linux
|
17
|
+
when /mswin|mingw/ then :Windows
|
18
|
+
when /cygwin/ then :Cygwin
|
19
|
+
else
|
20
|
+
raise ClipboardLoadError, "clipboard: Could not find suitable implementation for OS(#{ RbConfig::CONFIG['host_os'] })"
|
21
|
+
end
|
22
|
+
|
23
|
+
# Running additional check to detect if running in Microsoft WSL or Wayland
|
24
|
+
if os == :Linux
|
25
|
+
require "etc"
|
26
|
+
if Etc.uname[:release] =~ /Microsoft/
|
27
|
+
os = :Wsl
|
28
|
+
# Only choose Wayland implementation if wl-copy is found, since xclip / xsel *might* work
|
29
|
+
elsif ENV["XDG_SESSION_TYPE"] == "wayland" && executable_installed?("wl-copy")
|
30
|
+
os = :LinuxWayland
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
os
|
35
|
+
end
|
36
|
+
|
37
|
+
# Check if a necessary command is available
|
9
38
|
def executable_installed?(cmd)
|
10
39
|
ENV['PATH'].split(::File::PATH_SEPARATOR).any? do |path|
|
11
40
|
::File.executable?(::File.join(path, cmd))
|
data/lib/clipboard/version.rb
CHANGED
data/lib/clipboard/windows.rb
CHANGED
@@ -1,9 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative
|
3
|
+
require_relative "implementation"
|
4
|
+
require_relative "utils"
|
4
5
|
|
5
6
|
module Clipboard
|
6
7
|
module Windows
|
8
|
+
include Implementation
|
7
9
|
extend self
|
8
10
|
|
9
11
|
CF_TEXT = 1
|
@@ -41,7 +43,7 @@ module Clipboard
|
|
41
43
|
end
|
42
44
|
|
43
45
|
# see http://www.codeproject.com/KB/clipboard/archerclipboard1.aspx
|
44
|
-
def paste(_ = nil)
|
46
|
+
def paste(_ = nil, **)
|
45
47
|
return String.new unless User32.open(nil)
|
46
48
|
|
47
49
|
hclip = User32.get( CF_UNICODETEXT )
|
@@ -57,14 +59,15 @@ module Clipboard
|
|
57
59
|
User32.close
|
58
60
|
end
|
59
61
|
|
60
|
-
def clear
|
62
|
+
def clear(**)
|
61
63
|
User32.empty if User32.open(nil)
|
62
|
-
|
64
|
+
|
65
|
+
true
|
63
66
|
ensure
|
64
67
|
User32.close
|
65
68
|
end
|
66
69
|
|
67
|
-
def copy(data_to_copy)
|
70
|
+
def copy(data_to_copy, **)
|
68
71
|
if User32.open(nil)
|
69
72
|
User32.empty
|
70
73
|
data = data_to_copy.encode(Encoding::UTF_16LE) # TODO: catch bad encodings
|
@@ -77,11 +80,11 @@ module Clipboard
|
|
77
80
|
Kernel32.unlock( handler )
|
78
81
|
end
|
79
82
|
User32.set( CF_UNICODETEXT, handler )
|
80
|
-
data.chop
|
81
83
|
else # don't touch anything
|
82
84
|
Utils.popen "clip", data_to_copy # depends on clip (available by default since Vista)
|
83
|
-
paste
|
84
85
|
end
|
86
|
+
|
87
|
+
true
|
85
88
|
ensure
|
86
89
|
User32.close
|
87
90
|
end
|
data/lib/clipboard/wsl.rb
CHANGED
@@ -1,22 +1,21 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative "implementation"
|
3
4
|
require_relative "utils"
|
4
5
|
|
5
6
|
module Clipboard
|
6
7
|
module Wsl
|
8
|
+
include Implementation
|
7
9
|
extend self
|
8
10
|
|
9
|
-
def paste(_ = nil)
|
11
|
+
def paste(_ = nil, **)
|
10
12
|
`powershell.exe -Command Get-Clipboard`
|
11
13
|
end
|
12
14
|
|
13
|
-
def copy(data)
|
15
|
+
def copy(data, **)
|
14
16
|
Utils.popen "clip.exe", data
|
15
|
-
paste
|
16
|
-
end
|
17
17
|
|
18
|
-
|
19
|
-
copy ''
|
18
|
+
true
|
20
19
|
end
|
21
20
|
end
|
22
21
|
end
|
data/lib/clipboard.rb
CHANGED
@@ -1,16 +1,12 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'rbconfig'
|
4
|
-
|
5
3
|
require_relative 'clipboard/version'
|
6
4
|
require_relative 'clipboard/utils'
|
5
|
+
require_relative 'clipboard/clipboard_load_error'
|
7
6
|
|
8
7
|
module Clipboard
|
9
8
|
extend self
|
10
9
|
|
11
|
-
class ClipboardLoadError < StandardError
|
12
|
-
end
|
13
|
-
|
14
10
|
unless defined? Ocra # see gh#9
|
15
11
|
autoload :Linux, 'clipboard/linux'
|
16
12
|
autoload :LinuxWayland, 'clipboard/linux_wayland'
|
@@ -19,6 +15,7 @@ module Clipboard
|
|
19
15
|
autoload :Cygwin, 'clipboard/cygwin'
|
20
16
|
autoload :Wsl, 'clipboard/wsl'
|
21
17
|
autoload :Gtk, 'clipboard/gtk'
|
18
|
+
autoload :Osc52, 'clipboard/osc52'
|
22
19
|
end
|
23
20
|
autoload :Windows, 'clipboard/windows'
|
24
21
|
autoload :File, 'clipboard/file'
|
@@ -26,46 +23,36 @@ module Clipboard
|
|
26
23
|
def self.implementation
|
27
24
|
return @implementation if @implementation
|
28
25
|
|
29
|
-
|
30
|
-
|
31
|
-
when /linux|bsd/ then :Linux
|
32
|
-
when /mswin|mingw/ then :Windows
|
33
|
-
when /cygwin/ then :Cygwin
|
34
|
-
else
|
35
|
-
raise ClipboardLoadError, "Your OS(#{ RbConfig::CONFIG['host_os'] }) is not supported"
|
36
|
-
end
|
37
|
-
|
38
|
-
# Running additional check to detect if running in Microsoft WSL or Wayland
|
39
|
-
if os == :Linux
|
40
|
-
require "etc"
|
41
|
-
if Etc.respond_to?(:uname) && Etc.uname[:release] =~ /Microsoft/ # uname was added in ruby 2.2
|
42
|
-
os = :Wsl
|
43
|
-
# Only choose Wayland implementation if wl-copy is found, since xclip / xsel *might* work
|
44
|
-
elsif ENV["XDG_SESSION_TYPE"] == "wayland" && Utils.executable_installed?("wl-copy")
|
45
|
-
os = :LinuxWayland
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
@implementation = Clipboard.const_get(os)
|
50
|
-
rescue ClipboardLoadError => e
|
26
|
+
@implementation = Clipboard.const_get(Utils.autodetect_implementation)
|
27
|
+
rescue ClipboardLoadError, NameError => e
|
51
28
|
$stderr.puts "#{e.message}\nUsing file-based (fake) clipboard" unless $VERBOSE == nil
|
52
29
|
@implementation = Clipboard::File
|
53
30
|
end
|
54
31
|
|
55
|
-
def self.implementation=(
|
56
|
-
|
32
|
+
def self.implementation=(implementation)
|
33
|
+
if !implementation
|
34
|
+
@implementation = nil
|
35
|
+
elsif implementation.is_a? Module
|
36
|
+
@implementation = implementation
|
37
|
+
else
|
38
|
+
camel_cased_implementation_name = implementation.to_s.gsub(/(?:^|_)([a-z])/) do $1.upcase end
|
39
|
+
@implementation = Clipboard.const_get(camel_cased_implementation_name)
|
40
|
+
end
|
41
|
+
rescue ClipboardLoadError, NameError => e
|
42
|
+
$stderr.puts "#{e.message}\nUsing file-based (fake) clipboard" unless $VERBOSE == nil
|
43
|
+
@implementation = Clipboard::File
|
57
44
|
end
|
58
45
|
|
59
|
-
def paste(
|
60
|
-
Clipboard.implementation.paste(
|
46
|
+
def paste(...)
|
47
|
+
Clipboard.implementation.paste(...)
|
61
48
|
end
|
62
49
|
|
63
|
-
def clear(
|
64
|
-
Clipboard.implementation.clear(
|
50
|
+
def clear(...)
|
51
|
+
Clipboard.implementation.clear(...)
|
65
52
|
end
|
66
53
|
|
67
|
-
def copy(
|
68
|
-
Clipboard.implementation.copy(
|
54
|
+
def copy(...)
|
55
|
+
Clipboard.implementation.copy(...)
|
69
56
|
end
|
70
57
|
end
|
71
58
|
|
data/spec/clipboard_file_spec.rb
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
require_relative "spec_helper"
|
4
4
|
|
5
|
+
require 'clipboard/file'
|
5
6
|
require "fileutils"
|
6
7
|
|
7
8
|
describe 'Clipboard::File' do
|
@@ -16,12 +17,13 @@ describe 'Clipboard::File' do
|
|
16
17
|
end
|
17
18
|
|
18
19
|
it "can copy & paste" do
|
19
|
-
|
20
|
-
expect( Clipboard.paste ).to eq '
|
20
|
+
Clipboard.copy('123file')
|
21
|
+
expect( Clipboard.paste ).to eq '123file'
|
21
22
|
end
|
22
23
|
|
23
24
|
it "can clear" do
|
24
|
-
|
25
|
+
Clipboard.copy('123file')
|
26
|
+
expect( Clipboard.paste ).to eq '123file'
|
25
27
|
Clipboard.clear
|
26
28
|
expect( Clipboard.paste ).to eq ''
|
27
29
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "spec_helper"
|
4
|
+
|
5
|
+
if RUBY_ENGINE === "jruby"
|
6
|
+
require 'clipboard/java'
|
7
|
+
|
8
|
+
describe "Clipboard::Java" do
|
9
|
+
before :all do
|
10
|
+
Clipboard.implementation = Clipboard::Java
|
11
|
+
end
|
12
|
+
|
13
|
+
it "can copy & paste" do
|
14
|
+
Clipboard.copy('123java')
|
15
|
+
expect( Clipboard.paste ).to eq '123java'
|
16
|
+
end
|
17
|
+
|
18
|
+
it "can clear" do
|
19
|
+
Clipboard.copy('123java')
|
20
|
+
expect( Clipboard.paste ).to eq '123java'
|
21
|
+
Clipboard.clear
|
22
|
+
expect( Clipboard.paste ).to eq ''
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "spec_helper"
|
4
|
+
|
5
|
+
require "rbconfig"
|
6
|
+
|
7
|
+
if RbConfig::CONFIG['host_os'] =~ /linux|bsd/
|
8
|
+
require 'clipboard/linux'
|
9
|
+
|
10
|
+
describe "Clipboard::Linux" do
|
11
|
+
before :all do
|
12
|
+
Clipboard.implementation = Clipboard::Linux
|
13
|
+
end
|
14
|
+
|
15
|
+
it "can copy & paste" do
|
16
|
+
Clipboard.copy('123linux')
|
17
|
+
expect( Clipboard.paste ).to eq '123linux'
|
18
|
+
end
|
19
|
+
|
20
|
+
it "can clear" do
|
21
|
+
Clipboard.copy('123linux')
|
22
|
+
expect( Clipboard.paste ).to eq '123linux'
|
23
|
+
Clipboard.clear
|
24
|
+
expect( Clipboard.paste ).to eq ''
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "spec_helper"
|
4
|
+
|
5
|
+
require "rbconfig"
|
6
|
+
|
7
|
+
if RbConfig::CONFIG['host_os'] =~ /linux|bsd/ &&
|
8
|
+
ENV["XDG_SESSION_TYPE"] == "wayland" &&
|
9
|
+
Clipboard::Utils.executable_installed?("wl-copy")
|
10
|
+
require 'clipboard/linux_wayland'
|
11
|
+
|
12
|
+
describe "Clipboard::LinuxWayland" do
|
13
|
+
before :all do
|
14
|
+
Clipboard.implementation = Clipboard::LinuxWayland
|
15
|
+
end
|
16
|
+
|
17
|
+
it "can copy & paste" do
|
18
|
+
Clipboard.copy('123wayland')
|
19
|
+
expect( Clipboard.paste ).to eq '123wayland'
|
20
|
+
end
|
21
|
+
|
22
|
+
it "can clear" do
|
23
|
+
Clipboard.copy('123wayland')
|
24
|
+
expect( Clipboard.paste ).to eq '123wayland'
|
25
|
+
Clipboard.clear
|
26
|
+
expect( Clipboard.paste ).to eq ''
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "spec_helper"
|
4
|
+
|
5
|
+
require "rbconfig"
|
6
|
+
|
7
|
+
if RbConfig::CONFIG['host_os'] =~ /mac|darwin/
|
8
|
+
require 'clipboard/mac'
|
9
|
+
|
10
|
+
describe "Clipboard::Mac" do
|
11
|
+
before :all do
|
12
|
+
Clipboard.implementation = Clipboard::Mac
|
13
|
+
end
|
14
|
+
|
15
|
+
it "can copy & paste" do
|
16
|
+
Clipboard.copy('123mac')
|
17
|
+
expect( Clipboard.paste ).to eq '123mac'
|
18
|
+
end
|
19
|
+
|
20
|
+
it "can clear" do
|
21
|
+
Clipboard.copy('123mac')
|
22
|
+
expect( Clipboard.paste ).to eq '123mac'
|
23
|
+
Clipboard.clear
|
24
|
+
expect( Clipboard.paste ).to eq ''
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
data/spec/clipboard_spec.rb
CHANGED
@@ -1,12 +1,14 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
# Please note: cannot test, if it really accesses your platform clipboard.
|
4
|
-
|
5
3
|
require_relative "spec_helper"
|
6
4
|
|
7
5
|
os_to_restore = RbConfig::CONFIG['host_os']
|
8
6
|
|
9
7
|
describe Clipboard do
|
8
|
+
before :all do
|
9
|
+
Clipboard.implementation = Clipboard::Utils.autodetect_implementation
|
10
|
+
end
|
11
|
+
|
10
12
|
before do
|
11
13
|
RbConfig::CONFIG['host_os'] = os_to_restore
|
12
14
|
@is_windows = Clipboard.implementation.name == 'Clipboard::Windows'
|
@@ -14,10 +16,6 @@ describe Clipboard do
|
|
14
16
|
|
15
17
|
let(:expected) { ->(text) { @is_windows ? text.encode(Encoding::UTF_16LE) : text } }
|
16
18
|
|
17
|
-
it "has a VERSION" do
|
18
|
-
expect( Clipboard::VERSION ).to match /^\d+\.\d+\.\d+$/
|
19
|
-
end
|
20
|
-
|
21
19
|
it "can copy & paste" do
|
22
20
|
text = "FOO\nBAR"
|
23
21
|
Clipboard.copy(text)
|
@@ -31,14 +29,14 @@ describe Clipboard do
|
|
31
29
|
expect( Clipboard.paste ).to eq expected.(text)
|
32
30
|
end
|
33
31
|
|
34
|
-
it "returns
|
32
|
+
it "returns true on copy" do
|
35
33
|
text = 'xxx'
|
36
|
-
expect( Clipboard.copy(text) ).to eq
|
34
|
+
expect( Clipboard.copy(text) ).to eq true
|
37
35
|
end
|
38
36
|
|
39
37
|
it "can clear" do
|
40
38
|
Clipboard.copy('xxx')
|
41
|
-
Clipboard.clear
|
39
|
+
expect( Clipboard.clear ).to eq true
|
42
40
|
expect( Clipboard.paste ).to eq expected.('')
|
43
41
|
end
|
44
42
|
|
@@ -50,7 +48,7 @@ describe Clipboard do
|
|
50
48
|
it "can copy & paste & clear" do
|
51
49
|
a = A.new
|
52
50
|
text = 'XXX'
|
53
|
-
expect( a.send(:copy, text) ).to eq
|
51
|
+
expect( a.send(:copy, text) ).to eq true
|
54
52
|
expect( a.send(:paste) ).to eq expected.(text)
|
55
53
|
a.send(:clear)
|
56
54
|
expect( a.send(:paste) ).to eq expected.('')
|
@@ -61,13 +59,15 @@ describe Clipboard do
|
|
61
59
|
it "can copy more than 8192 bytes" do
|
62
60
|
# first batch
|
63
61
|
data1 = Random.new.bytes(2**14).unpack("H*").first
|
64
|
-
|
62
|
+
Clipboard.copy(data1)
|
63
|
+
data2 = Clipboard.paste
|
65
64
|
|
66
65
|
expect(data2).to eq expected.(data1)
|
67
66
|
|
68
67
|
# second batch
|
69
68
|
data1 = Random.new.bytes(2**14).unpack("H*").first
|
70
|
-
|
69
|
+
Clipboard.copy(data1)
|
70
|
+
data2 = Clipboard.paste
|
71
71
|
|
72
72
|
expect(data2).to eq expected.(data1)
|
73
73
|
end
|
@@ -98,5 +98,18 @@ describe Clipboard do
|
|
98
98
|
expect( $stderr ).not_to receive(:puts)
|
99
99
|
Clipboard.implementation
|
100
100
|
end
|
101
|
+
|
102
|
+
it "is possible to set implementation with snake-cased string" do
|
103
|
+
module Clipboard::TestImplementation
|
104
|
+
end
|
105
|
+
Clipboard.implementation = "test_implementation"
|
106
|
+
expect( Clipboard.implementation ).to eq Clipboard::TestImplementation
|
107
|
+
end
|
108
|
+
|
109
|
+
it "warns when unknown implementation name is given" do
|
110
|
+
expect( $stderr ).to receive(:puts)
|
111
|
+
Clipboard.implementation = "unknown"
|
112
|
+
expect( Clipboard.implementation ).to eq Clipboard::File
|
113
|
+
end
|
101
114
|
end
|
102
115
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "spec_helper"
|
4
|
+
|
5
|
+
require "rbconfig"
|
6
|
+
|
7
|
+
if RbConfig::CONFIG['host_os'] =~ /mswin|mingw/
|
8
|
+
require 'clipboard/windows'
|
9
|
+
|
10
|
+
describe "Clipboard::Windows" do
|
11
|
+
before :all do
|
12
|
+
Clipboard.implementation = Clipboard::Windows
|
13
|
+
end
|
14
|
+
|
15
|
+
it "can copy & paste" do
|
16
|
+
Clipboard.copy('123windows')
|
17
|
+
expect( Clipboard.paste ).to eq '123windows'.encode("UTF-16LE")
|
18
|
+
end
|
19
|
+
|
20
|
+
it "can clear" do
|
21
|
+
Clipboard.copy('123windows')
|
22
|
+
expect( Clipboard.paste ).to eq '123windows'.encode("UTF-16LE")
|
23
|
+
Clipboard.clear
|
24
|
+
expect( Clipboard.paste ).to eq ''
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: clipboard
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jan Lelis
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-04-
|
11
|
+
date: 2024-04-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '13.
|
19
|
+
version: '13.2'
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '13.
|
26
|
+
version: '13.2'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rspec
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -38,8 +38,22 @@ dependencies:
|
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '3'
|
41
|
-
|
42
|
-
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rubocop
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.6'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.6'
|
55
|
+
description: "Access the system clipboard \U0001F4CB︎ on Linux, MacOS, Windows, WSL,
|
56
|
+
Cygwin, GTK, or Java. Usage is as simple as calling Clipboard.copy or Clipboard.paste!"
|
43
57
|
email:
|
44
58
|
- hi@ruby.consulting
|
45
59
|
executables: []
|
@@ -48,23 +62,33 @@ extra_rdoc_files: []
|
|
48
62
|
files:
|
49
63
|
- CHANGELOG.md
|
50
64
|
- CODE_OF_CONDUCT.md
|
65
|
+
- Gemfile
|
51
66
|
- MIT-LICENSE.txt
|
52
67
|
- README.md
|
68
|
+
- Rakefile
|
53
69
|
- clipboard.gemspec
|
54
70
|
- lib/clipboard.rb
|
71
|
+
- lib/clipboard/clipboard_load_error.rb
|
55
72
|
- lib/clipboard/cygwin.rb
|
56
73
|
- lib/clipboard/file.rb
|
57
74
|
- lib/clipboard/gtk.rb
|
75
|
+
- lib/clipboard/implementation.rb
|
58
76
|
- lib/clipboard/java.rb
|
59
77
|
- lib/clipboard/linux.rb
|
60
78
|
- lib/clipboard/linux_wayland.rb
|
61
79
|
- lib/clipboard/mac.rb
|
80
|
+
- lib/clipboard/osc52.rb
|
62
81
|
- lib/clipboard/utils.rb
|
63
82
|
- lib/clipboard/version.rb
|
64
83
|
- lib/clipboard/windows.rb
|
65
84
|
- lib/clipboard/wsl.rb
|
66
85
|
- spec/clipboard_file_spec.rb
|
86
|
+
- spec/clipboard_java_spec.rb
|
87
|
+
- spec/clipboard_linux_spec.rb
|
88
|
+
- spec/clipboard_linux_wayland_spec.rb
|
89
|
+
- spec/clipboard_mac_spec.rb
|
67
90
|
- spec/clipboard_spec.rb
|
91
|
+
- spec/clipboard_windows_spec.rb
|
68
92
|
- spec/spec_helper.rb
|
69
93
|
homepage: https://github.com/janlelis/clipboard
|
70
94
|
licenses:
|
@@ -79,17 +103,19 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
79
103
|
requirements:
|
80
104
|
- - ">="
|
81
105
|
- !ruby/object:Gem::Version
|
82
|
-
version:
|
106
|
+
version: '3.0'
|
83
107
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
84
108
|
requirements:
|
85
109
|
- - ">="
|
86
110
|
- !ruby/object:Gem::Version
|
87
111
|
version: '0'
|
88
112
|
requirements:
|
89
|
-
- 'Linux:
|
90
|
-
- '
|
113
|
+
- 'Linux-X11: xclip or xsel'
|
114
|
+
- 'Linux-Wayland: wl-clipboard'
|
115
|
+
- 'Windows: ffi gem'
|
91
116
|
rubygems_version: 3.5.3
|
92
117
|
signing_key:
|
93
118
|
specification_version: 4
|
94
|
-
summary: Access
|
119
|
+
summary: "Access the system clipboard \U0001F4CB︎ on Linux, MacOS, Windows, WSL, Cygwin,
|
120
|
+
GTK, or Java."
|
95
121
|
test_files: []
|