forked from erikrose/blessings
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for Windows #110
Merged
Merged
Changes from all commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,157 @@ | ||
# encoding: utf-8 | ||
"""Module containing Windows version of :class:`Terminal`.""" | ||
|
||
from __future__ import absolute_import | ||
|
||
import contextlib | ||
import msvcrt # pylint: disable=import-error | ||
import time | ||
|
||
import jinxed.win32 as win32 # pylint: disable=import-error | ||
|
||
from .terminal import WINSZ, Terminal as _Terminal | ||
|
||
|
||
class Terminal(_Terminal): | ||
"""Windows subclass of :class:`Terminal`.""" | ||
|
||
def getch(self): | ||
r""" | ||
Read, decode, and return the next byte from the keyboard stream. | ||
|
||
:rtype: unicode | ||
:returns: a single unicode character, or ``u''`` if a multi-byte | ||
sequence has not yet been fully received. | ||
|
||
For versions of Windows 10.0.10586 and later, the console is expected | ||
to be in ENABLE_VIRTUAL_TERMINAL_INPUT mode and the default method is | ||
called. | ||
|
||
For older versions of Windows, msvcrt.getwch() is used. If the received | ||
character is ``\x00`` or ``\xe0``, the next character is | ||
automatically retrieved. | ||
""" | ||
if win32.VTMODE_SUPPORTED: | ||
return super(Terminal, self).getch() | ||
|
||
rtn = msvcrt.getwch() | ||
if rtn in ('\x00', '\xe0'): | ||
rtn += msvcrt.getwch() | ||
return rtn | ||
|
||
def kbhit(self, timeout=None, **_kwargs): | ||
""" | ||
Return whether a keypress has been detected on the keyboard. | ||
|
||
This method is used by :meth:`inkey` to determine if a byte may | ||
be read using :meth:`getch` without blocking. This is implemented | ||
by wrapping msvcrt.kbhit() in a timeout. | ||
|
||
:arg float timeout: When ``timeout`` is 0, this call is | ||
non-blocking, otherwise blocking indefinitely until keypress | ||
is detected when None (default). When ``timeout`` is a | ||
positive number, returns after ``timeout`` seconds have | ||
elapsed (float). | ||
:rtype: bool | ||
:returns: True if a keypress is awaiting to be read on the keyboard | ||
attached to this terminal. | ||
""" | ||
end = time.time() + (timeout or 0) | ||
while True: | ||
|
||
if msvcrt.kbhit(): | ||
return True | ||
|
||
if timeout is not None and end < time.time(): | ||
break | ||
|
||
return False | ||
|
||
@staticmethod | ||
def _winsize(fd): | ||
""" | ||
Return named tuple describing size of the terminal by ``fd``. | ||
|
||
:arg int fd: file descriptor queries for its window size. | ||
:rtype: WINSZ | ||
|
||
WINSZ is a :class:`collections.namedtuple` instance, whose structure | ||
directly maps to the return value of the :const:`termios.TIOCGWINSZ` | ||
ioctl return value. The return parameters are: | ||
|
||
- ``ws_row``: width of terminal by its number of character cells. | ||
- ``ws_col``: height of terminal by its number of character cells. | ||
- ``ws_xpixel``: width of terminal by pixels (not accurate). | ||
- ``ws_ypixel``: height of terminal by pixels (not accurate). | ||
""" | ||
window = win32.get_terminal_size(fd) | ||
return WINSZ(ws_row=window.lines, ws_col=window.columns, | ||
ws_xpixel=0, ws_ypixel=0) | ||
|
||
@contextlib.contextmanager | ||
def cbreak(self): | ||
""" | ||
Allow each keystroke to be read immediately after it is pressed. | ||
|
||
This is a context manager for ``jinxed.w32.setcbreak()``. | ||
|
||
.. note:: You must explicitly print any user input you would like | ||
displayed. If you provide any kind of editing, you must handle | ||
backspace and other line-editing control functions in this mode | ||
as well! | ||
|
||
**Normally**, characters received from the keyboard cannot be read | ||
by Python until the *Return* key is pressed. Also known as *cooked* or | ||
*canonical input* mode, it allows the tty driver to provide | ||
line-editing before shuttling the input to your program and is the | ||
(implicit) default terminal mode set by most unix shells before | ||
executing programs. | ||
""" | ||
if self._keyboard_fd is not None: | ||
|
||
filehandle = msvcrt.get_osfhandle(self._keyboard_fd) | ||
|
||
# Save current terminal mode: | ||
save_mode = win32.get_console_mode(filehandle) | ||
save_line_buffered = self._line_buffered | ||
win32.setcbreak(filehandle) | ||
try: | ||
self._line_buffered = False | ||
yield | ||
finally: | ||
win32.set_console_mode(filehandle, save_mode) | ||
self._line_buffered = save_line_buffered | ||
|
||
else: | ||
yield | ||
|
||
@contextlib.contextmanager | ||
def raw(self): | ||
""" | ||
A context manager for ``jinxed.w32.setcbreak()``. | ||
|
||
Although both :meth:`break` and :meth:`raw` modes allow each keystroke | ||
to be read immediately after it is pressed, Raw mode disables | ||
processing of input and output. | ||
|
||
In cbreak mode, special input characters such as ``^C`` are | ||
interpreted by the terminal driver and excluded from the stdin stream. | ||
In raw mode these values are receive by the :meth:`inkey` method. | ||
""" | ||
if self._keyboard_fd is not None: | ||
|
||
filehandle = msvcrt.get_osfhandle(self._keyboard_fd) | ||
|
||
# Save current terminal mode: | ||
save_mode = win32.get_console_mode(filehandle) | ||
save_line_buffered = self._line_buffered | ||
win32.setraw(filehandle) | ||
try: | ||
self._line_buffered = False | ||
yield | ||
finally: | ||
win32.set_console_mode(filehandle, save_mode) | ||
self._line_buffered = save_line_buffered | ||
|
||
else: | ||
yield |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,6 @@ | ||
wcwidth>=0.1.4 | ||
six>=1.9.0 | ||
# support python2.6 by using backport of 'orderedict' | ||
ordereddict==1.1; python_version < "2.7" | ||
# Windows requires jinxed | ||
jinxed>=0.5.4; platform_system == "Windows" | ||
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well I hope you will do nicely and not break
jinxed
any day in the future :)I don't typically care for these
>=
, anything could happen in the future, nefarious, even, but I'm a bit FOSS tired and feeling more trusting these days.