Make the clipboard command user-configurable
Add config item clipboard_cmd, with a default of 'pbcopy w' on Darwin and 'xclip' on everything else. This will allow the user to use any command for the clipboard, including 'wl-copy' for Wayland (addressing issue #693 on Github). With his change, significant simplifications could be made to clipboard.py - the copy_*() functions have been removed and combined into copy(). With this simplification, the old OSX test is obsolete, and new OSX tests are needed (need a way to simulate sys.platform).
This commit is contained in:
@@ -4,48 +4,22 @@ from __future__ import unicode_literals
|
|||||||
import sys
|
import sys
|
||||||
import subprocess
|
import subprocess
|
||||||
|
|
||||||
from .exceptions import ProgramError
|
|
||||||
|
|
||||||
|
|
||||||
def _subprocess_copy(text, args_list):
|
def _subprocess_copy(text, args_list):
|
||||||
p = subprocess.Popen(args_list, stdin=subprocess.PIPE, close_fds=True)
|
p = subprocess.Popen(args_list, stdin=subprocess.PIPE, close_fds=True)
|
||||||
p.communicate(input=text.encode('utf-8'))
|
p.communicate(input=text.encode('utf-8'))
|
||||||
|
|
||||||
|
|
||||||
def copy(text):
|
def copy(text, cmd):
|
||||||
"""
|
"""
|
||||||
Copy text to OS clipboard.
|
Copy text to OS clipboard.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
# If no command is specified (i.e. the config option is empty) try
|
||||||
|
# to find a reasonable default based on the operating system
|
||||||
|
if cmd is None:
|
||||||
if sys.platform == 'darwin':
|
if sys.platform == 'darwin':
|
||||||
copy_osx(text)
|
cmd = 'pbcopy w'
|
||||||
else:
|
else: # For Linux, BSD, cygwin, etc.
|
||||||
# For Linux, BSD, cygwin, etc.
|
cmd = 'xclip'
|
||||||
copy_linux(text)
|
|
||||||
|
|
||||||
|
_subprocess_copy(text, cmd.split())
|
||||||
def copy_osx(text):
|
|
||||||
_subprocess_copy(text, ['pbcopy', 'w'])
|
|
||||||
|
|
||||||
|
|
||||||
def copy_linux(text):
|
|
||||||
|
|
||||||
def get_command_name():
|
|
||||||
# Checks for the installation of xsel or xclip
|
|
||||||
for cmd in ['xsel', 'xclip']:
|
|
||||||
cmd_exists = subprocess.call(
|
|
||||||
['which', cmd],
|
|
||||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE) == 0
|
|
||||||
if cmd_exists:
|
|
||||||
return cmd
|
|
||||||
return None
|
|
||||||
|
|
||||||
cmd_args = {
|
|
||||||
'xsel': ['xsel', '-b', '-i'],
|
|
||||||
'xclip': ['xclip', '-selection', 'c']}
|
|
||||||
cmd_name = get_command_name()
|
|
||||||
|
|
||||||
if cmd_name is None:
|
|
||||||
raise ProgramError("External copy application not found")
|
|
||||||
|
|
||||||
_subprocess_copy(text, cmd_args.get(cmd_name))
|
|
||||||
|
|||||||
@@ -542,7 +542,7 @@ class Page(object):
|
|||||||
return
|
return
|
||||||
|
|
||||||
try:
|
try:
|
||||||
clipboard_copy(url)
|
clipboard_copy(url, self.config['clipboard_cmd'])
|
||||||
except (ProgramError, OSError) as e:
|
except (ProgramError, OSError) as e:
|
||||||
_logger.exception(e)
|
_logger.exception(e)
|
||||||
self.term.show_notification(
|
self.term.show_notification(
|
||||||
|
|||||||
@@ -16,6 +16,12 @@ ascii = False
|
|||||||
; Turn on monochrome mode to disable color.
|
; Turn on monochrome mode to disable color.
|
||||||
monochrome = False
|
monochrome = False
|
||||||
|
|
||||||
|
; Data being copied is piped into this command
|
||||||
|
;clipboard_cmd = xclip
|
||||||
|
;clipboard_cmd = xsel -b -i
|
||||||
|
;clipboard_cmd = wl-copy
|
||||||
|
;clipboard_cmd = pbcopy w
|
||||||
|
|
||||||
; Flash when an invalid action is executed.
|
; Flash when an invalid action is executed.
|
||||||
flash = True
|
flash = True
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ from __future__ import unicode_literals
|
|||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from rtv.clipboard import copy_linux, copy_osx
|
from rtv.clipboard import copy
|
||||||
from rtv.exceptions import ProgramError
|
from rtv.exceptions import ProgramError
|
||||||
|
|
||||||
|
|
||||||
@@ -23,20 +23,13 @@ def test_copy():
|
|||||||
p.communicate = mock.Mock()
|
p.communicate = mock.Mock()
|
||||||
Popen.return_value = p
|
Popen.return_value = p
|
||||||
|
|
||||||
# If the `which` command can't find a program to use
|
|
||||||
call.return_value = 1 # Returns an error code
|
|
||||||
with pytest.raises(ProgramError):
|
|
||||||
copy_linux('test')
|
|
||||||
|
|
||||||
call.return_value = 0
|
call.return_value = 0
|
||||||
copy_linux('test')
|
copy('test', 'xsel -b -i')
|
||||||
assert Popen.call_args[0][0] == ['xsel', '-b', '-i']
|
assert Popen.call_args[0][0] == ['xsel', '-b', '-i']
|
||||||
p.communicate.assert_called_with(input='test'.encode('utf-8'))
|
p.communicate.assert_called_with(input='test'.encode('utf-8'))
|
||||||
copy_linux('test ❤')
|
|
||||||
|
copy('test ❤', 'xclip')
|
||||||
|
assert Popen.call_args[0][0] == ['xclip']
|
||||||
p.communicate.assert_called_with(input='test ❤'.encode('utf-8'))
|
p.communicate.assert_called_with(input='test ❤'.encode('utf-8'))
|
||||||
|
|
||||||
copy_osx('test')
|
# Need OSX tests, can't simulate sys.platform
|
||||||
assert Popen.call_args[0][0] == ['pbcopy', 'w']
|
|
||||||
p.communicate.assert_called_with(input='test'.encode('utf-8'))
|
|
||||||
copy_osx('test ❤')
|
|
||||||
p.communicate.assert_called_with(input='test ❤'.encode('utf-8'))
|
|
||||||
|
|||||||
Reference in New Issue
Block a user