mirror of
https://github.com/python/cpython.git
synced 2025-10-21 22:22:48 +00:00
gh-111201: Allow bracketed paste to work (GH-118700)
This commit is contained in:
parent
ad3d877a12
commit
7d90b8aadb
4 changed files with 61 additions and 0 deletions
|
@ -462,3 +462,13 @@ class paste_mode(Command):
|
||||||
def do(self) -> None:
|
def do(self) -> None:
|
||||||
self.reader.paste_mode = not self.reader.paste_mode
|
self.reader.paste_mode = not self.reader.paste_mode
|
||||||
self.reader.dirty = True
|
self.reader.dirty = True
|
||||||
|
|
||||||
|
|
||||||
|
class enable_bracketed_paste(Command):
|
||||||
|
def do(self) -> None:
|
||||||
|
self.reader.paste_mode = True
|
||||||
|
|
||||||
|
class disable_bracketed_paste(Command):
|
||||||
|
def do(self) -> None:
|
||||||
|
self.reader.paste_mode = False
|
||||||
|
self.reader.insert("\n")
|
||||||
|
|
|
@ -127,6 +127,8 @@ default_keymap: tuple[tuple[KeySpec, CommandName], ...] = tuple(
|
||||||
(r"\M-9", "digit-arg"),
|
(r"\M-9", "digit-arg"),
|
||||||
# (r'\M-\n', 'insert-nl'),
|
# (r'\M-\n', 'insert-nl'),
|
||||||
("\\\\", "self-insert"),
|
("\\\\", "self-insert"),
|
||||||
|
(r"\x1b[200~", "enable_bracketed_paste"),
|
||||||
|
(r"\x1b[201~", "disable_bracketed_paste"),
|
||||||
]
|
]
|
||||||
+ [(c, "self-insert") for c in map(chr, range(32, 127)) if c != "\\"]
|
+ [(c, "self-insert") for c in map(chr, range(32, 127)) if c != "\\"]
|
||||||
+ [(c, "self-insert") for c in map(chr, range(128, 256)) if c.isalpha()]
|
+ [(c, "self-insert") for c in map(chr, range(128, 256)) if c.isalpha()]
|
||||||
|
|
|
@ -336,10 +336,13 @@ class UnixConsole(Console):
|
||||||
except ValueError:
|
except ValueError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
self.__enable_bracketed_paste()
|
||||||
|
|
||||||
def restore(self):
|
def restore(self):
|
||||||
"""
|
"""
|
||||||
Restore the console to the default state
|
Restore the console to the default state
|
||||||
"""
|
"""
|
||||||
|
self.__disable_bracketed_paste()
|
||||||
self.__maybe_write_code(self._rmkx)
|
self.__maybe_write_code(self._rmkx)
|
||||||
self.flushoutput()
|
self.flushoutput()
|
||||||
tcsetattr(self.input_fd, termios.TCSADRAIN, self.__svtermstate)
|
tcsetattr(self.input_fd, termios.TCSADRAIN, self.__svtermstate)
|
||||||
|
@ -525,6 +528,12 @@ class UnixConsole(Console):
|
||||||
self.__posxy = 0, 0
|
self.__posxy = 0, 0
|
||||||
self.screen = []
|
self.screen = []
|
||||||
|
|
||||||
|
def __enable_bracketed_paste(self) -> None:
|
||||||
|
os.write(self.output_fd, b"\x1b[?2004h")
|
||||||
|
|
||||||
|
def __disable_bracketed_paste(self) -> None:
|
||||||
|
os.write(self.output_fd, b"\x1b[?2004l")
|
||||||
|
|
||||||
def __setup_movement(self):
|
def __setup_movement(self):
|
||||||
"""
|
"""
|
||||||
Set up the movement functions based on the terminal capabilities.
|
Set up the movement functions based on the terminal capabilities.
|
||||||
|
|
|
@ -817,6 +817,46 @@ class TestPasteEvent(TestCase):
|
||||||
output = multiline_input(reader)
|
output = multiline_input(reader)
|
||||||
self.assertEqual(output, output_code)
|
self.assertEqual(output, output_code)
|
||||||
|
|
||||||
|
def test_bracketed_paste(self):
|
||||||
|
"""Test that bracketed paste using \x1b[200~ and \x1b[201~ works."""
|
||||||
|
# fmt: off
|
||||||
|
input_code = (
|
||||||
|
'def a():\n'
|
||||||
|
' for x in range(10):\n'
|
||||||
|
'\n'
|
||||||
|
' if x%2:\n'
|
||||||
|
' print(x)\n'
|
||||||
|
'\n'
|
||||||
|
' else:\n'
|
||||||
|
' pass\n'
|
||||||
|
)
|
||||||
|
# fmt: on
|
||||||
|
|
||||||
|
output_code = (
|
||||||
|
'def a():\n'
|
||||||
|
' for x in range(10):\n'
|
||||||
|
'\n'
|
||||||
|
' if x%2:\n'
|
||||||
|
' print(x)\n'
|
||||||
|
'\n'
|
||||||
|
' else:\n'
|
||||||
|
' pass\n'
|
||||||
|
'\n'
|
||||||
|
)
|
||||||
|
|
||||||
|
paste_start = "\x1b[200~"
|
||||||
|
paste_end = "\x1b[201~"
|
||||||
|
|
||||||
|
events = itertools.chain(
|
||||||
|
code_to_events(paste_start),
|
||||||
|
code_to_events(input_code),
|
||||||
|
code_to_events(paste_end),
|
||||||
|
code_to_events("\n"),
|
||||||
|
)
|
||||||
|
reader = self.prepare_reader(events)
|
||||||
|
output = multiline_input(reader)
|
||||||
|
self.assertEqual(output, output_code)
|
||||||
|
|
||||||
|
|
||||||
class TestReader(TestCase):
|
class TestReader(TestCase):
|
||||||
def assert_screen_equals(self, reader, expected):
|
def assert_screen_equals(self, reader, expected):
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue