From 06763ac9acc39023511ac017414809eb90c6bd8f Mon Sep 17 00:00:00 2001 From: Markus Unterwaditzer Date: Sat, 10 Oct 2015 20:38:02 +0200 Subject: [PATCH 1/2] Introduce raw_terminal --- click/_termui_impl.py | 23 ++++++++++++++++------- click/termui.py | 5 +++++ 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/click/_termui_impl.py b/click/_termui_impl.py index a4e421ecb..323b0c248 100644 --- a/click/_termui_impl.py +++ b/click/_termui_impl.py @@ -13,7 +13,7 @@ import sys import time import math - +import contextlib from ._compat import _default_text_stdout, range_type, PY2, isatty, \ open_stream, strip_ansi, term_len, get_best_encoding, WIN, int_types, \ CYGWIN @@ -525,6 +525,10 @@ def _translate_ch_to_exc(ch): if WIN: import msvcrt + @contextlib.contextmanager + def raw_terminal(): + yield + def getchar(echo): rv = msvcrt.getch() if echo: @@ -541,7 +545,8 @@ def getchar(echo): import tty import termios - def getchar(echo): + @contextlib.contextmanager + def raw_terminal(): if not isatty(sys.stdin): f = open('/dev/tty') fd = f.fileno() @@ -552,9 +557,7 @@ def getchar(echo): old_settings = termios.tcgetattr(fd) try: tty.setraw(fd) - ch = os.read(fd, 32) - if echo and isatty(sys.stdout): - sys.stdout.write(ch) + yield fd finally: termios.tcsetattr(fd, termios.TCSADRAIN, old_settings) sys.stdout.flush() @@ -562,5 +565,11 @@ def getchar(echo): f.close() except termios.error: pass - _translate_ch_to_exc(ch) - return ch.decode(get_best_encoding(sys.stdin), 'replace') + + def getchar(echo): + with raw_terminal(): + ch = os.read(fd, 32) + if echo and isatty(sys.stdout): + sys.stdout.write(ch) + _translate_ch_to_exc(ch) + return ch.decode(get_best_encoding(sys.stdin), 'replace') diff --git a/click/termui.py b/click/termui.py index f3dee0bdb..98bf6bd31 100644 --- a/click/termui.py +++ b/click/termui.py @@ -567,6 +567,11 @@ def getchar(echo=False): return f(echo) +def raw_terminal(): + from ._termui_impl import raw_terminal as f + return f() + + def pause(info='Press any key to continue ...', err=False): """This command stops execution and waits for the user to press any key to continue. This is similar to the Windows batch "pause" From 622e85fbf5032a699217485f2089481f4d5abd53 Mon Sep 17 00:00:00 2001 From: JosiahDub Date: Tue, 15 May 2018 10:48:13 -0400 Subject: [PATCH 2/2] with raw_terminal() needs an as fd to fully work. --- click/_termui_impl.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/click/_termui_impl.py b/click/_termui_impl.py index 323b0c248..f44db5900 100644 --- a/click/_termui_impl.py +++ b/click/_termui_impl.py @@ -567,7 +567,7 @@ def raw_terminal(): pass def getchar(echo): - with raw_terminal(): + with raw_terminal() as fd: ch = os.read(fd, 32) if echo and isatty(sys.stdout): sys.stdout.write(ch)