blob: 8ef65d28cf7ce0cd200975af5856d1761bd995cc (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
|
# coding=utf-8
"""
Imports the proper readline for the platform and provides utility functions for it
"""
from enum import Enum
import sys
# Prefer statically linked gnureadline if available (for macOS compatibility due to issues with libedit)
try:
import gnureadline as readline
except ImportError:
# Try to import readline, but allow failure for convenience in Windows unit testing
# Note: If this actually fails, you should install readline on Linux or Mac or pyreadline on Windows
try:
# noinspection PyUnresolvedReferences
import readline
except ImportError: # pragma: no cover
pass
class RlType(Enum):
"""Readline library types we recognize"""
GNU = 1
PYREADLINE = 2
NONE = 3
# Check what implementation of readline we are using
rl_type = RlType.NONE
# The order of this check matters since importing pyreadline will also show readline in the modules list
if 'pyreadline' in sys.modules:
rl_type = RlType.PYREADLINE
elif 'gnureadline' in sys.modules or 'readline' in sys.modules:
# We don't support libedit
if 'libedit' not in readline.__doc__:
rl_type = RlType.GNU
# Load the readline lib so we can access members of it
import ctypes
readline_lib = ctypes.CDLL(readline.__file__)
def rl_force_redisplay() -> None:
"""
Causes readline to redraw prompt and input line
"""
if not sys.stdout.isatty():
return
if rl_type == RlType.GNU: # pragma: no cover
# rl_forced_update_display() is the proper way to redraw the prompt and line, but we
# have to use ctypes to do it since Python's readline API does not wrap the function
readline_lib.rl_forced_update_display()
# After manually updating the display, readline asks that rl_display_fixed be set to 1 for efficiency
display_fixed = ctypes.c_int.in_dll(readline_lib, "rl_display_fixed")
display_fixed.value = 1
elif rl_type == RlType.PYREADLINE: # pragma: no cover
# noinspection PyProtectedMember
readline.rl.mode._print_prompt()
|