Skip to content

Commit

Permalink
Fix input line wrapping bug (#6)
Browse files Browse the repository at this point in the history
On most terminals, line wrapping would not work properly when using the input function with GNU readline and color escape codes. This PR adds special delimiters around the escape codes, signaling to readline that these are non-visible characters and un-confusing its line wrapping functionality.
  • Loading branch information
velovix authored Aug 20, 2020
1 parent 8e89a39 commit 8b9e8fd
Showing 1 changed file with 19 additions and 1 deletion.
20 changes: 19 additions & 1 deletion brainframe/cli/print_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,14 @@ class Color(Enum):
UNDERLINE = "\033[4m"


# These delimiters tell GNU readline that any characters between them are
# non-visible. These should be put before and after ASCII escape codes. Without
# these, escape codes mess up readline's text wrapping support.
# See: https://superuser.com/a/301355
_NON_VISIBLE_START = "\001"
_NON_VISIBLE_END = "\002"


def ask_yes_no(message_id, **kwargs) -> bool:
"""Prompts the user with a yes or no question. The default value is yes.
Expand Down Expand Up @@ -80,7 +88,13 @@ def print_color(message, color: Color, **kwargs) -> None:

def input_color(message, color: Color) -> str:
color = _check_no_color(color)
return input(f"{color.value}{message}{Color.END.value}")
# See https://superuser.com/a/301355 for why these non-visible delimiters
# are necessary for input()
return input(
f"{_NON_VISIBLE_START}{color.value}{_NON_VISIBLE_END}"
f"{message}"
f"{_NON_VISIBLE_START}{Color.END.value}{_NON_VISIBLE_END}"
)


def _check_no_color(color: Color) -> Color:
Expand Down Expand Up @@ -108,3 +122,7 @@ def _check_no_color(color: Color) -> Color:
Installer
"""

# Importing readline has the side-effect of augmenting the `input` function
# with GNU readline features.
_ = readline

0 comments on commit 8b9e8fd

Please sign in to comment.