From 97ed42831a632c3911e6d6f7da0706761e738448 Mon Sep 17 00:00:00 2001 From: Florent Xicluna Date: Thu, 21 May 2026 15:21:50 +0200 Subject: [PATCH] Fix readline support on Linux bug #4135 --- CHANGELOG.md | 10 ++++++++++ CONTRIBUTORS.md | 1 + docs/source/console.rst | 6 +++++- rich/console.py | 22 ++++++++++++++++++---- 4 files changed, 34 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8b016d4846..91e78f380e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,16 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [Unreleased] + +### Added + +- Added `Console.enable_readline` method. + +### Fixed + +- Fixed `readline` support: correct cursor position https://github.com/Textualize/rich/pull/4135 + ## [15.0.0] - 2026-04-12 ### Changed diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 2155a42a4d..a77cd978c0 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -98,6 +98,7 @@ The following people have contributed to the development of Rich: - [chthollyphile](https://github.com/chthollyphile) - [Jonathan Helmus](https://github.com/jjhelmus) - [Brandon Capener](https://github.com/bcapener) +- [Florent Xicluna](https://github.com/florentx) - [Alex Zheng](https://github.com/alexzheng111) - [Sebastian Speitel](https://github.com/SebastianSpeitel) - [Kevin Turcios](https://github.com/KRRT7) diff --git a/docs/source/console.rst b/docs/source/console.rst index dbb09603c3..3164fc3b24 100644 --- a/docs/source/console.rst +++ b/docs/source/console.rst @@ -244,7 +244,11 @@ The console class has an :meth:`~rich.console.Console.input` method which works console = Console() console.input("What is [i]your[/i] [bold red]name[/]? :smiley: ") -If Python's builtin :mod:`readline` module is previously loaded, elaborate line editing and history features will be available. +Python's builtin :mod:`readline` module can be loaded, in order to get elaborate line editing and history features:: + + from rich.console import Console + + Console.enable_readline() Exporting --------- diff --git a/rich/console.py b/rich/console.py index 0bdce76987..8450b5465f 100644 --- a/rich/console.py +++ b/rich/console.py @@ -786,6 +786,14 @@ def _theme_stack(self) -> ThemeStack: """Get the thread local theme stack.""" return self._thread_locals.theme_stack + @staticmethod + def enable_readline(): + """Load :mod:`readline` globally, if available.""" + try: + import readline + except ImportError: + pass + def _detect_color_system(self) -> Optional[ColorSystem]: """Detect color system from env vars.""" if self.is_jupyter: @@ -2176,17 +2184,23 @@ def input( Returns: str: Text read from stdin. """ - if prompt: - self.print(prompt, markup=markup, emoji=emoji, end="") + if prompt and not stream and not WINDOWS and self.file == sys.stdout: + with self.capture() as capture: + self.print(prompt, markup=markup, emoji=emoji, end="") + rendered = capture.get() + else: + if prompt: + self.print(prompt, markup=markup, emoji=emoji, end="") + rendered = "" if password: import getpass as _getpass_mod - result = _getpass_mod.getpass("", stream=stream) + result = _getpass_mod.getpass(rendered, stream=stream) else: if stream: result = stream.readline() else: - result = input() + result = input(rendered) return result def export_text(self, *, clear: bool = True, styles: bool = False) -> str: