1#!/usr/local/bin/python3.8 2# vim:fileencoding=utf-8 3# License: GPL v3 Copyright: 2018, Kovid Goyal <kovid at kovidgoyal.net> 4 5import os 6import sys 7from typing import List, NoReturn, Optional 8 9from kitty.cli import parse_args 10from kitty.cli_stub import ClipboardCLIOptions 11 12from ..tui.handler import Handler 13from ..tui.loop import Loop 14 15 16class Clipboard(Handler): 17 18 def __init__(self, data_to_send: Optional[bytes], args: ClipboardCLIOptions): 19 self.args = args 20 self.clipboard_contents: Optional[str] = None 21 self.data_to_send = data_to_send 22 self.quit_on_write = False 23 24 def initialize(self) -> None: 25 if self.data_to_send is not None: 26 self.cmd.write_to_clipboard(self.data_to_send, self.args.use_primary) 27 if not self.args.get_clipboard: 28 if self.args.wait_for_completion: 29 # ask kitty for the TN terminfo capability and 30 # only quit after a response is received 31 self.print('\x1bP+q544e\x1b\\', end='') 32 self.print('Waiting for completion...') 33 return 34 self.quit_on_write = True 35 return 36 self.cmd.request_from_clipboard(self.args.use_primary) 37 38 def on_writing_finished(self) -> None: 39 if self.quit_on_write: 40 self.quit_loop(0) 41 42 def on_clipboard_response(self, text: str, from_primary: bool = False) -> None: 43 self.clipboard_contents = text 44 self.quit_loop(0) 45 46 def on_capability_response(self, name: str, val: str) -> None: 47 self.quit_loop(0) 48 49 def on_interrupt(self) -> None: 50 self.quit_loop(1) 51 52 def on_eot(self) -> None: 53 self.quit_loop(1) 54 55 56OPTIONS = r''' 57--get-clipboard 58default=False 59type=bool-set 60Output the current contents of the clipboard to stdout. Note that this 61will not work if you have not enabled the option to allow reading the clipboard 62in kitty.conf 63 64 65--use-primary 66default=False 67type=bool-set 68Use the primary selection rather than the clipboard on systems that support it, 69such as X11. 70 71 72--wait-for-completion 73default=False 74type=bool-set 75Wait till the copy to clipboard is complete before exiting. Useful if running 76the kitten in a dedicated, ephemeral window. 77'''.format 78help_text = '''\ 79Read or write to the system clipboard. 80 81To set the clipboard text, pipe in the new text on stdin. Use the 82:option:`--get-clipboard` option to output the current clipboard contents to 83:file:`stdout`. Note that you must enable reading of clipboard in 84:file:`kitty.conf` first. 85''' 86 87usage = '' 88 89 90def main(args: List[str]) -> NoReturn: 91 cli_opts, items = parse_args(args[1:], OPTIONS, usage, help_text, 'kitty +kitten clipboard', result_class=ClipboardCLIOptions) 92 if items: 93 raise SystemExit('Unrecognized extra command line arguments') 94 data: Optional[bytes] = None 95 if not sys.stdin.isatty(): 96 data = sys.stdin.buffer.read() 97 sys.stdin = open(os.ctermid(), 'r') 98 loop = Loop() 99 handler = Clipboard(data, cli_opts) 100 loop.loop(handler) 101 if loop.return_code == 0 and handler.clipboard_contents: 102 sys.stdout.write(handler.clipboard_contents) 103 sys.stdout.flush() 104 raise SystemExit(loop.return_code) 105 106 107if __name__ == '__main__': 108 main(sys.argv) 109elif __name__ == '__doc__': 110 cd = sys.cli_docs # type: ignore 111 cd['usage'] = usage 112 cd['options'] = OPTIONS 113 cd['help_text'] = help_text 114