-
Notifications
You must be signed in to change notification settings - Fork 141
Add copy command #1044
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 copy command #1044
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,63 @@ | ||
| # frozen_string_literal: true | ||
|
|
||
| module IRB | ||
| module Command | ||
| class Copy < Base | ||
| category "Workspace" | ||
| description "Copy command output to clipboard" | ||
|
|
||
| help_message(<<~HELP) | ||
| Usage: copy [command] | ||
| HELP | ||
|
|
||
| def execute(arg) | ||
| # Copy last value if no expression was supplied | ||
| arg = '_' if arg.to_s.strip.empty? | ||
|
|
||
| value = irb_context.workspace.binding.eval(arg) | ||
| output = irb_context.inspect_method.inspect_value(value, colorize: false) | ||
|
|
||
| if clipboard_available? | ||
| copy_to_clipboard(output) | ||
| else | ||
| warn "System clipboard not found" | ||
| end | ||
| rescue StandardError => e | ||
| warn "Error: #{e}" | ||
| end | ||
|
|
||
| private | ||
|
|
||
| def copy_to_clipboard(text) | ||
| IO.popen(clipboard_program, 'w') do |io| | ||
| io.write(text) | ||
| end | ||
|
|
||
| raise IOError.new("Copying to clipboard failed") unless $? == 0 | ||
|
|
||
| puts "Copied to system clipboard" | ||
| rescue Errno::ENOENT => e | ||
| warn e.message | ||
| warn "Is IRB.conf[:COPY_COMMAND] set to a bad value?" | ||
| end | ||
|
|
||
| def clipboard_program | ||
| @clipboard_program ||= if IRB.conf[:COPY_COMMAND] | ||
| IRB.conf[:COPY_COMMAND] | ||
| elsif executable?("pbcopy") | ||
| "pbcopy" | ||
| elsif executable?("xclip") | ||
| "xclip -selection clipboard" | ||
| end | ||
| end | ||
|
|
||
| def executable?(command) | ||
| system("which #{command} > /dev/null 2>&1") | ||
| end | ||
|
|
||
| def clipboard_available? | ||
| !!clipboard_program | ||
| end | ||
| end | ||
| end | ||
| end | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -227,6 +227,8 @@ or | |
| .Sy type | ||
| . | ||
| .Pp | ||
| .It Ev IRB_COPY_COMMAND | ||
| Overrides the default program used to interface with the system clipboard. | ||
|
Comment on lines
+230
to
+231
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| .El | ||
| .Pp | ||
| Also | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,70 @@ | ||
| # frozen_string_literal: true | ||
|
|
||
| require 'irb' | ||
|
|
||
| require_relative "../helper" | ||
|
|
||
| module TestIRB | ||
| class CopyTest < IntegrationTestCase | ||
| def setup | ||
| super | ||
| @envs['IRB_COPY_COMMAND'] = "ruby -e \"puts 'foo' + STDIN.read\"" | ||
| end | ||
|
|
||
| def test_copy_with_pbcopy | ||
| write_ruby <<~'ruby' | ||
| class Answer | ||
| def initialize(answer) | ||
| @answer = answer | ||
| end | ||
| end | ||
|
|
||
| binding.irb | ||
| ruby | ||
|
|
||
| output = run_ruby_file do | ||
| type "copy Answer.new(42)" | ||
| type "exit" | ||
| end | ||
|
|
||
| assert_match(/foo#<Answer:0x[0-9a-f]+ @answer=42/, output) | ||
| assert_match(/Copied to system clipboard/, output) | ||
| end | ||
|
|
||
| # copy puts 5 should: | ||
| # - Print value to the console | ||
| # - Copy nil to clipboard, since that is what the puts call evaluates to | ||
| def test_copy_when_expression_has_side_effects | ||
| write_ruby <<~'ruby' | ||
| binding.irb | ||
| ruby | ||
|
|
||
| output = run_ruby_file do | ||
| type "copy puts 42" | ||
| type "exit" | ||
| end | ||
|
|
||
| assert_match(/^42\r\n/, output) | ||
| assert_match(/foonil/, output) | ||
| assert_match(/Copied to system clipboard/, output) | ||
| refute_match(/foo42/, output) | ||
| end | ||
|
|
||
| def test_copy_when_copy_command_is_invalid | ||
| @envs['IRB_COPY_COMMAND'] = "lulz" | ||
|
|
||
| write_ruby <<~'ruby' | ||
| binding.irb | ||
| ruby | ||
|
|
||
| output = run_ruby_file do | ||
| type "copy 42" | ||
| type "exit" | ||
| end | ||
|
|
||
| assert_match(/No such file or directory - lulz/, output) | ||
| assert_match(/Is IRB\.conf\[:COPY_COMMAND\] set to a bad value/, output) | ||
| refute_match(/Copied to system clipboard/, output) | ||
| end | ||
| end | ||
| end |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -163,6 +163,26 @@ def test_use_autocomplete_environment_variable | |
| IRB.conf[:USE_AUTOCOMPLETE] = orig_use_autocomplete_conf | ||
| end | ||
|
|
||
| def test_copy_command_environment_variable | ||
| orig_copy_command_env = ENV['IRB_COPY_COMMAND'] | ||
| orig_copy_command_conf = IRB.conf[:COPY_COMMAND] | ||
|
|
||
| ENV['IRB_COPY_COMMAND'] = nil | ||
| IRB.setup(__FILE__) | ||
| refute IRB.conf[:COPY_COMMAND] | ||
|
|
||
| ENV['IRB_COPY_COMMAND'] = '' | ||
| IRB.setup(__FILE__) | ||
| assert_equal('', IRB.conf[:COPY_COMMAND]) | ||
|
Comment on lines
+174
to
+176
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Unsure what the behavior here should be. Setting this env var overrides the other clipboard programs we use, so right now this would cause However, we could just as easily interpret |
||
|
|
||
| ENV['IRB_COPY_COMMAND'] = 'blah' | ||
| IRB.setup(__FILE__) | ||
| assert_equal('blah', IRB.conf[:COPY_COMMAND]) | ||
| ensure | ||
| ENV['IRB_COPY_COMMAND'] = orig_copy_command_env | ||
| IRB.conf[:COPY_COMMAND] = orig_copy_command_conf | ||
| end | ||
|
|
||
| def test_completor_environment_variable | ||
| orig_use_autocomplete_env = ENV['IRB_COMPLETOR'] | ||
| orig_use_autocomplete_conf = IRB.conf[:COMPLETOR] | ||
|
|
||

Uh oh!
There was an error while loading. Please reload this page.