mirror of
https://github.com/python/cpython.git
synced 2025-08-04 08:59:19 +00:00
gh-119896: Fix CTRL-Z behavior in the new REPL on Windows (GH-122217)
This commit is contained in:
parent
d27a53fc02
commit
d1a1bca1f0
4 changed files with 14 additions and 4 deletions
|
@ -21,6 +21,8 @@
|
||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import sys
|
||||||
|
|
||||||
from contextlib import contextmanager
|
from contextlib import contextmanager
|
||||||
from dataclasses import dataclass, field, fields
|
from dataclasses import dataclass, field, fields
|
||||||
import unicodedata
|
import unicodedata
|
||||||
|
@ -52,7 +54,10 @@ def disp_str(buffer: str) -> tuple[str, list[int]]:
|
||||||
b: list[int] = []
|
b: list[int] = []
|
||||||
s: list[str] = []
|
s: list[str] = []
|
||||||
for c in buffer:
|
for c in buffer:
|
||||||
if ord(c) < 128:
|
if c == '\x1a':
|
||||||
|
s.append(c)
|
||||||
|
b.append(2)
|
||||||
|
elif ord(c) < 128:
|
||||||
s.append(c)
|
s.append(c)
|
||||||
b.append(1)
|
b.append(1)
|
||||||
elif unicodedata.category(c).startswith("C"):
|
elif unicodedata.category(c).startswith("C"):
|
||||||
|
@ -110,7 +115,7 @@ default_keymap: tuple[tuple[KeySpec, CommandName], ...] = tuple(
|
||||||
(r"\C-w", "unix-word-rubout"),
|
(r"\C-w", "unix-word-rubout"),
|
||||||
(r"\C-x\C-u", "upcase-region"),
|
(r"\C-x\C-u", "upcase-region"),
|
||||||
(r"\C-y", "yank"),
|
(r"\C-y", "yank"),
|
||||||
(r"\C-z", "suspend"),
|
*(() if sys.platform == "win32" else ((r"\C-z", "suspend"), )),
|
||||||
(r"\M-b", "backward-word"),
|
(r"\M-b", "backward-word"),
|
||||||
(r"\M-c", "capitalize-word"),
|
(r"\M-c", "capitalize-word"),
|
||||||
(r"\M-d", "kill-word"),
|
(r"\M-d", "kill-word"),
|
||||||
|
|
|
@ -76,6 +76,7 @@ REPL_COMMANDS = {
|
||||||
"copyright": _sitebuiltins._Printer('copyright', sys.copyright),
|
"copyright": _sitebuiltins._Printer('copyright', sys.copyright),
|
||||||
"help": "help",
|
"help": "help",
|
||||||
"clear": _clear_screen,
|
"clear": _clear_screen,
|
||||||
|
"\x1a": _sitebuiltins.Quitter('\x1a', ''),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -21,4 +21,5 @@ def wlen(s: str) -> int:
|
||||||
length = sum(str_width(i) for i in s)
|
length = sum(str_width(i) for i in s)
|
||||||
# remove lengths of any escape sequences
|
# remove lengths of any escape sequences
|
||||||
sequence = ANSI_ESCAPE_SEQUENCE.findall(s)
|
sequence = ANSI_ESCAPE_SEQUENCE.findall(s)
|
||||||
return length - sum(len(i) for i in sequence)
|
ctrl_z_cnt = s.count('\x1a')
|
||||||
|
return length - sum(len(i) for i in sequence) + ctrl_z_cnt
|
||||||
|
|
|
@ -253,7 +253,7 @@ class WindowsConsole(Console):
|
||||||
else:
|
else:
|
||||||
self.__posxy = wlen(newline), y
|
self.__posxy = wlen(newline), y
|
||||||
|
|
||||||
if "\x1b" in newline or y != self.__posxy[1]:
|
if "\x1b" in newline or y != self.__posxy[1] or '\x1a' in newline:
|
||||||
# ANSI escape characters are present, so we can't assume
|
# ANSI escape characters are present, so we can't assume
|
||||||
# anything about the position of the cursor. Moving the cursor
|
# anything about the position of the cursor. Moving the cursor
|
||||||
# to the left margin should work to get to a known position.
|
# to the left margin should work to get to a known position.
|
||||||
|
@ -291,6 +291,9 @@ class WindowsConsole(Console):
|
||||||
self.__write("\x1b[?12l")
|
self.__write("\x1b[?12l")
|
||||||
|
|
||||||
def __write(self, text: str) -> None:
|
def __write(self, text: str) -> None:
|
||||||
|
if "\x1a" in text:
|
||||||
|
text = ''.join(["^Z" if x == '\x1a' else x for x in text])
|
||||||
|
|
||||||
if self.out is not None:
|
if self.out is not None:
|
||||||
self.out.write(text.encode(self.encoding, "replace"))
|
self.out.write(text.encode(self.encoding, "replace"))
|
||||||
self.out.flush()
|
self.out.flush()
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue