From 3f362fbecf5a81acb58f2c4f033106bf13bb2bb0 Mon Sep 17 00:00:00 2001 From: Gautier P Date: Fri, 28 Feb 2020 17:36:51 +0100 Subject: [PATCH 1/7] Handle new line key ^M on windows --- suplemon/key_mappings.py | 1 + 1 file changed, 1 insertion(+) diff --git a/suplemon/key_mappings.py b/suplemon/key_mappings.py index caa79c8..3729beb 100644 --- a/suplemon/key_mappings.py +++ b/suplemon/key_mappings.py @@ -47,6 +47,7 @@ "KEY_ENTER": "enter", "\n": "enter", "^J": "enter", + "^M": "enter", 343: "shift+enter", curses.KEY_BACKSPACE: "backspace", From 3816e5c7281c6a7539ae676e8bdc73f817371bed Mon Sep 17 00:00:00 2001 From: Gautier P Date: Fri, 28 Feb 2020 17:36:56 +0100 Subject: [PATCH 2/7] Do not assume that TERM envvar is always defined --- suplemon/ui.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/suplemon/ui.py b/suplemon/ui.py index 5b3305b..57e6cc0 100644 --- a/suplemon/ui.py +++ b/suplemon/ui.py @@ -120,7 +120,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. From 0ac65143aaf2ba38e87ac6961b8906e17f698827 Mon Sep 17 00:00:00 2001 From: Gautier P Date: Mon, 2 Mar 2020 09:46:48 +0100 Subject: [PATCH 3/7] Do not init_pair(0) which causes ERR on windows --- suplemon/ui.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/suplemon/ui.py b/suplemon/ui.py index 57e6cc0..11ab658 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 @@ -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 From 00ea07b2095387b536807c3652f06d7fbdcb3162 Mon Sep 17 00:00:00 2001 From: Gautier P Date: Mon, 2 Mar 2020 17:15:40 +0100 Subject: [PATCH 4/7] Fix resizeterm call --- suplemon/ui.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/suplemon/ui.py b/suplemon/ui.py index 11ab658..02b2eee 100644 --- a/suplemon/ui.py +++ b/suplemon/ui.py @@ -326,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): From 0e57c6d8715a2c5458bc21a759e62b6cca225119 Mon Sep 17 00:00:00 2001 From: Gautier P Date: Mon, 2 Mar 2020 09:46:26 +0100 Subject: [PATCH 5/7] Avoid conflicts between ctrl+h and backspace --- suplemon/key_mappings.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/suplemon/key_mappings.py b/suplemon/key_mappings.py index 3729beb..991311e 100644 --- a/suplemon/key_mappings.py +++ b/suplemon/key_mappings.py @@ -53,6 +53,7 @@ curses.KEY_BACKSPACE: "backspace", "KEY_BACKSPACE": "backspace", "^?": "backspace", + "^H": "backspace", # on Windows curses.KEY_DC: "delete", curses.KEY_HOME: "home", @@ -81,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", From 932a1c88c8931f1757a0b9bbdc019f5cd75b82d2 Mon Sep 17 00:00:00 2001 From: Gautier P Date: Fri, 28 Feb 2020 17:36:48 +0100 Subject: [PATCH 6/7] Add dependency to windows-curses on windows --- setup.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/setup.py b/setup.py index ef9cba1..1a1edb7 100644 --- a/setup.py +++ b/setup.py @@ -21,7 +21,8 @@ include_package_data=True, install_requires=[ "pygments", - "wcwidth" + "wcwidth", + "windows-curses; platform_system=='Windows'" ], entry_points={ "console_scripts": ["suplemon=suplemon.cli:main"] From 21ec4f84a3285d78ec874f0bd0204471f6a1004c Mon Sep 17 00:00:00 2001 From: Gautier P Date: Fri, 28 Feb 2020 17:36:53 +0100 Subject: [PATCH 7/7] Use pyperclip library to support Windows as well --- setup.py | 1 + suplemon/modules/system_clipboard.py | 60 ++-------------------------- 2 files changed, 4 insertions(+), 57 deletions(-) diff --git a/setup.py b/setup.py index 1a1edb7..c9109be 100644 --- a/setup.py +++ b/setup.py @@ -20,6 +20,7 @@ package_data={"": files}, include_package_data=True, install_requires=[ + "pyperclip", "pygments", "wcwidth", "windows-curses; platform_system=='Windows'" 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 = {