diff --git a/setup.py b/setup.py index ef9cba1..c9109be 100644 --- a/setup.py +++ b/setup.py @@ -20,8 +20,10 @@ package_data={"": files}, include_package_data=True, install_requires=[ + "pyperclip", "pygments", - "wcwidth" + "wcwidth", + "windows-curses; platform_system=='Windows'" ], entry_points={ "console_scripts": ["suplemon=suplemon.cli:main"] diff --git a/suplemon/key_mappings.py b/suplemon/key_mappings.py index caa79c8..991311e 100644 --- a/suplemon/key_mappings.py +++ b/suplemon/key_mappings.py @@ -47,11 +47,13 @@ "KEY_ENTER": "enter", "\n": "enter", "^J": "enter", + "^M": "enter", 343: "shift+enter", curses.KEY_BACKSPACE: "backspace", "KEY_BACKSPACE": "backspace", "^?": "backspace", + "^H": "backspace", # on Windows curses.KEY_DC: "delete", curses.KEY_HOME: "home", @@ -80,7 +82,7 @@ "^E": "ctrl+e", "^F": "ctrl+f", "^G": "ctrl+g", - "^H": "ctrl+h", + # "^H": "ctrl+h", # Conflicts with 'backspace' on Windows # "^I": "ctrl+i", # Conflicts with 'tab' # "^J": "ctrl+j", # Conflicts with 'enter' "^K": "ctrl+k", diff --git a/suplemon/modules/system_clipboard.py b/suplemon/modules/system_clipboard.py index 5cd41cd..12b9ac7 100644 --- a/suplemon/modules/system_clipboard.py +++ b/suplemon/modules/system_clipboard.py @@ -4,22 +4,13 @@ from suplemon.suplemon_module import Module +import pyperclip class SystemClipboard(Module): """Integrates the system clipboard with suplemon.""" def init(self): self.init_logging(__name__) - if self.has_xsel_support(): - self.clipboard_type = "xsel" - elif self.has_pb_support(): - self.clipboard_type = "pb" - elif self.has_xclip_support(): - self.clipboard_type = "xclip" - else: - self.logger.warning( - "Can't use system clipboard. Install 'xsel' or 'pbcopy' or 'xclip' for system clipboard support.") - return False self.bind_event_before("insert", self.insert) self.bind_event_after("copy", self.copy) self.bind_event_after("cut", self.copy) @@ -35,55 +26,10 @@ def insert(self, event): self.app.get_editor().set_buffer(lines) def get_clipboard(self): - try: - if self.clipboard_type == "xsel": - command = ["xsel", "-b"] - elif self.clipboard_type == "pb": - command = ["pbpaste", "-Prefer", "txt"] - elif self.clipboard_type == "xclip": - command = ["xclip", "-selection", "clipboard", "-out"] - else: - return False - data = subprocess.check_output(command, universal_newlines=True) - return data - except: - return False + return pyperclip.paste() def set_clipboard(self, data): - try: - if self.clipboard_type == "xsel": - command = ["xsel", "-i", "-b"] - elif self.clipboard_type == "pb": - command = ["pbcopy"] - elif self.clipboard_type == "xclip": - command = ["xclip", "-selection", "clipboard", "-in"] - else: - return False - p = subprocess.Popen(command, stdin=subprocess.PIPE) - out, err = p.communicate(input=bytes(data, "utf-8")) - return out - except: - return False - - def has_pb_support(self): - output = self.get_output(["which", "pbcopy"]) - return output - - def has_xsel_support(self): - output = self.get_output(["xsel", "--version"]) - return output - - def has_xclip_support(self): - output = self.get_output(["which", "xclip"]) # xclip -version outputs to stderr - return output - - def get_output(self, cmd): - try: - process = subprocess.Popen(cmd, stdout=subprocess.PIPE) - except (OSError, EnvironmentError): # can't use FileNotFoundError in Python 2 - return False - out, err = process.communicate() - return out + pyperclip.copy(data) module = { diff --git a/suplemon/ui.py b/suplemon/ui.py index 5b3305b..02b2eee 100644 --- a/suplemon/ui.py +++ b/suplemon/ui.py @@ -5,6 +5,7 @@ import os import sys +import platform import logging from wcwidth import wcswidth @@ -120,7 +121,7 @@ def init(self): global curses # Set ESC detection time os.environ["ESCDELAY"] = str(self.app.config["app"]["escdelay"]) - termenv = os.environ["TERM"] + termenv = os.environ.get("TERM", "") if termenv.endswith("-256color") and self.app.config["app"].get("imitate_256color"): # Curses doesn't recognize 'screen-256color' or 'tmux-256color' as 256-color terminals. # These terminals all seem to be identical to xterm-256color, which is recognized. @@ -199,7 +200,10 @@ def setup_colors(self): # curses.init_pair(10, -1, -1) # Default (white on black) # Colors for xterm (not xterm-256color) # Dark Colors - curses.init_pair(0, curses.COLOR_BLACK, bg) # 0 Black + + if platform.system() != 'Windows': + # it raises an exception on windows, cf https://github.com/zephyrproject-rtos/windows-curses/issues/10 + curses.init_pair(0, curses.COLOR_BLACK, bg) # 0 Black curses.init_pair(1, curses.COLOR_RED, bg) # 1 Red curses.init_pair(2, curses.COLOR_GREEN, bg) # 2 Green curses.init_pair(3, curses.COLOR_YELLOW, bg) # 3 Yellow @@ -230,7 +234,9 @@ def setup_colors(self): # TODO: Define RGB for these to avoid getting # different results in different terminals # xterm-256color chart http://www.calmar.ws/vim/256-xterm-24bit-rgb-color-chart.html - curses.init_pair(0, 242, bg) # 0 Black + if platform.system() != 'Windows': + # it raises an exception on windows, cf https://github.com/zephyrproject-rtos/windows-curses/issues/10 + curses.init_pair(0, 242, bg) # 0 Black curses.init_pair(1, 204, bg) # 1 Red curses.init_pair(2, 119, bg) # 2 Green curses.init_pair(3, 221, bg) # 3 Yellow @@ -320,7 +326,7 @@ def resize(self, yx=None): if yx is None: yx = self.screen.getmaxyx() self.screen.erase() - curses.resizeterm(yx[0], yx[1]) + curses.resize_term(yx[0], yx[1]) self.setup_windows() def check_resize(self):