Add a kitten to get/set the clipboard via OSC 52
This commit is contained in:
parent
3d37348c2b
commit
d3edd2e73f
0
kittens/clipboard/__init__.py
Normal file
0
kittens/clipboard/__init__.py
Normal file
80
kittens/clipboard/main.py
Normal file
80
kittens/clipboard/main.py
Normal file
@ -0,0 +1,80 @@
|
||||
#!/usr/bin/env python
|
||||
# vim:fileencoding=utf-8
|
||||
# License: GPL v3 Copyright: 2018, Kovid Goyal <kovid at kovidgoyal.net>
|
||||
|
||||
import sys
|
||||
from kitty.cli import parse_args
|
||||
|
||||
from ..tui.handler import Handler
|
||||
from ..tui.loop import Loop
|
||||
|
||||
|
||||
class Clipboard(Handler):
|
||||
|
||||
def __init__(self, data_to_send, args):
|
||||
self.args = args
|
||||
self.print_on_fail = None
|
||||
self.clipboard_contents = None
|
||||
self.data_to_send = data_to_send
|
||||
|
||||
def initialize(self):
|
||||
if self.data_to_send is not None:
|
||||
self.cmd.write_to_clipboard(self.data_to_send, self.args.use_primary)
|
||||
if not self.args.get_clipboard:
|
||||
self.quit_loop(0)
|
||||
return
|
||||
self.cmd.request_from_clipboard(self.args.use_primary)
|
||||
|
||||
def on_clipboard_response(self, text, from_primary=False):
|
||||
self.clipboard_contents = text
|
||||
self.quit_loop(0)
|
||||
|
||||
|
||||
OPTIONS = r'''
|
||||
--get-clipboard
|
||||
default=False
|
||||
type=bool-set
|
||||
Output the current contents of the clipboard to stdout. Note that this
|
||||
will hang if you have not enabled the option to allow reading the clipboard
|
||||
in kitty.conf
|
||||
|
||||
|
||||
--use-primary
|
||||
default=False
|
||||
type=bool-set
|
||||
Use the primary selection rather than the clipboard on systems that support it,
|
||||
such as X11.
|
||||
'''.format
|
||||
|
||||
|
||||
def main(args):
|
||||
msg = '''\
|
||||
Read or write to the system clipboard.
|
||||
|
||||
To set the clipboard text, pipe in the new text on stdin. Use the --get-clipboard option \
|
||||
to output the current clipboard contents to stdout. Note that you must enable reading of clipboard in kitty.conf first. '''
|
||||
args, items = parse_args(args[1:], OPTIONS, '', msg, 'clipboard')
|
||||
if items:
|
||||
raise SystemExit('Unrecognized extra command line arguments')
|
||||
data = None
|
||||
if not sys.stdin.isatty():
|
||||
data = sys.stdin.buffer.read()
|
||||
sys.stdin = open('/dev/tty', 'r')
|
||||
loop = Loop()
|
||||
handler = Clipboard(data, args)
|
||||
loop.loop(handler)
|
||||
if loop.return_code == 0 and handler.clipboard_contents:
|
||||
sys.stdout.write(handler.clipboard_contents)
|
||||
sys.stdout.flush()
|
||||
if handler.print_on_fail:
|
||||
print(handler.print_on_fail)
|
||||
input('Press Enter to quit')
|
||||
raise SystemExit(loop.return_code)
|
||||
|
||||
|
||||
def handle_result(args, data, target_window_id, boss):
|
||||
pass
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main(sys.argv)
|
||||
@ -67,6 +67,9 @@ class Handler:
|
||||
def on_kitty_cmd_response(self, response):
|
||||
pass
|
||||
|
||||
def on_clipboard_response(self, text, from_primary=False):
|
||||
pass
|
||||
|
||||
def write(self, data):
|
||||
if isinstance(data, str):
|
||||
data = data.encode('utf-8')
|
||||
|
||||
@ -265,7 +265,15 @@ class Loop:
|
||||
pass
|
||||
|
||||
def _on_osc(self, osc):
|
||||
pass
|
||||
m = re.match(r'(\d+);', osc)
|
||||
if m is not None:
|
||||
code = int(m.group(1))
|
||||
rest = osc[m.end():]
|
||||
if code == 52:
|
||||
where, rest = rest.partition(';')[::2]
|
||||
from_primary = 'p' in where
|
||||
from base64 import standard_b64decode
|
||||
self.handler.on_clipboard_response(standard_b64decode(rest).decode('utf-8'), from_primary)
|
||||
|
||||
def _on_apc(self, apc):
|
||||
if apc.startswith('K'):
|
||||
|
||||
@ -231,6 +231,17 @@ def set_default_colors(fg=None, bg=None) -> str:
|
||||
return ans
|
||||
|
||||
|
||||
def write_to_clipboard(data, use_primary=False) -> str:
|
||||
if isinstance(data, str):
|
||||
data = data.encode('utf-8')
|
||||
from base64 import standard_b64encode
|
||||
return '\x1b]52;{};{}\x07'.format('p' if use_primary else 'c', standard_b64encode(data).decode('ascii'))
|
||||
|
||||
|
||||
def request_from_clipboard(use_primary=False) -> str:
|
||||
return '\x1b]52;{};?\x07'.format('p' if use_primary else 'c')
|
||||
|
||||
|
||||
all_cmds = tuple(
|
||||
(name, obj) for name, obj in globals().items()
|
||||
if hasattr(obj, '__annotations__') and obj.__annotations__.get('return') is str)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user