summaryrefslogtreecommitdiff
path: root/cmd2/rl_utils.py
diff options
context:
space:
mode:
authorEric Lin <anselor@gmail.com>2018-04-18 00:05:01 -0400
committerEric Lin <anselor@gmail.com>2018-04-18 00:05:01 -0400
commita448192c3747ac95c04d85c0da4abfb90297251a (patch)
tree4d980b26f595927016ba3fddbc8e5ba7dd107da4 /cmd2/rl_utils.py
parent93cc2461282067a3601d6ac546a99a40a60eef93 (diff)
parent01e434183d3333b1be03c293a82e36b034e0f78b (diff)
downloadcmd2-git-a448192c3747ac95c04d85c0da4abfb90297251a.tar.gz
Merge remote-tracking branch 'origin/master' into autocompleter
Updated AutoCompleter (#349) to match new directory structure from packaging effort.
Diffstat (limited to 'cmd2/rl_utils.py')
-rw-r--r--cmd2/rl_utils.py63
1 files changed, 63 insertions, 0 deletions
diff --git a/cmd2/rl_utils.py b/cmd2/rl_utils.py
new file mode 100644
index 00000000..1dc83d15
--- /dev/null
+++ b/cmd2/rl_utils.py
@@ -0,0 +1,63 @@
+# 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:
+ pass
+
+
+# Check what implementation of readline we are using
+class RlType(Enum):
+ GNU = 1
+ PYREADLINE = 2
+ NONE = 3
+
+
+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:
+ # 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:
+ # noinspection PyProtectedMember
+ readline.rl.mode._print_prompt()