summaryrefslogtreecommitdiff
path: root/cmd2/rl_utils.py
diff options
context:
space:
mode:
authorkotfu <kotfu@kotfu.net>2018-04-19 21:51:24 -0600
committerkotfu <kotfu@kotfu.net>2018-04-19 21:51:24 -0600
commit477666d0b3e097fb831729644b8861a983805981 (patch)
tree02217d3d2bb03499e511d8dd1774d161bb019a0f /cmd2/rl_utils.py
parentb7cfb130c7c914478936366b748b04234b031119 (diff)
parent58fdd089cc064e71502dc1f094fd906d30523886 (diff)
downloadcmd2-git-477666d0b3e097fb831729644b8861a983805981.tar.gz
Merge branch 'master' into ply
Diffstat (limited to 'cmd2/rl_utils.py')
-rw-r--r--cmd2/rl_utils.py66
1 files changed, 66 insertions, 0 deletions
diff --git a/cmd2/rl_utils.py b/cmd2/rl_utils.py
new file mode 100644
index 00000000..d5bef1ff
--- /dev/null
+++ b/cmd2/rl_utils.py
@@ -0,0 +1,66 @@
+# coding=utf-8
+"""
+Imports the proper readline for the platform and provides utility functions for it
+"""
+import sys
+
+try:
+ from enum34 import Enum
+except ImportError:
+ from enum import Enum
+
+# 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:
+ 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()