]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-111201: Add append to screen method to avoid recalculation (#119274)
authorLysandros Nikolaou <lisandrosnik@gmail.com>
Wed, 22 May 2024 02:35:44 +0000 (22:35 -0400)
committerGitHub <noreply@github.com>
Wed, 22 May 2024 02:35:44 +0000 (04:35 +0200)
Co-authored-by: Ɓukasz Langa <lukasz@langa.pl>
Lib/_pyrepl/commands.py
Lib/_pyrepl/completing_reader.py
Lib/_pyrepl/reader.py
Lib/_pyrepl/unix_console.py

index 51c7afebede5a87eaeadbe09438827572be89129..3d9722d1586c2a24dd58b2f95d766914db182518 100644 (file)
@@ -358,7 +358,10 @@ class backward_word(MotionCommand):
 class self_insert(EditCommand):
     def do(self) -> None:
         r = self.reader
-        r.insert(self.event * r.get_arg())
+        text = self.event * r.get_arg()
+        r.insert(text)
+        if len(text) == 1 and r.pos == len(r.buffer):
+            r.calc_screen = r.append_to_screen
 
 
 class insert_nl(EditCommand):
index 19fc06feaf3ced75b0250c20972f17d640cebb65..3f8506bfe8f8f8a26734835a79479dc8612f2b67 100644 (file)
@@ -187,8 +187,8 @@ class complete(commands.Command):
             if p:
                 r.insert(p)
             if last_is_completer:
-                if not r.cmpltn_menu_vis:
-                    r.cmpltn_menu_vis = 1
+                if not r.cmpltn_menu_visible:
+                    r.cmpltn_menu_visible = True
                 r.cmpltn_menu, r.cmpltn_menu_end = build_menu(
                     r.console, completions, r.cmpltn_menu_end,
                     r.use_brackets, r.sort_in_column)
@@ -208,7 +208,7 @@ class self_insert(commands.self_insert):
 
         commands.self_insert.do(self)
 
-        if r.cmpltn_menu_vis:
+        if r.cmpltn_menu_visible:
             stem = r.get_stem()
             if len(stem) < 1:
                 r.cmpltn_reset()
@@ -235,7 +235,7 @@ class CompletingReader(Reader):
 
     ### Instance variables
     cmpltn_menu: list[str] = field(init=False)
-    cmpltn_menu_vis: int = field(init=False)
+    cmpltn_menu_visible: bool = field(init=False)
     cmpltn_menu_end: int = field(init=False)
     cmpltn_menu_choices: list[str] = field(init=False)
 
@@ -255,9 +255,9 @@ class CompletingReader(Reader):
         if not isinstance(cmd, (complete, self_insert)):
             self.cmpltn_reset()
 
-    def calc_screen(self) -> list[str]:
-        screen = super().calc_screen()
-        if self.cmpltn_menu_vis:
+    def calc_complete_screen(self) -> list[str]:
+        screen = super().calc_complete_screen()
+        if self.cmpltn_menu_visible:
             ly = self.lxy[1]
             screen[ly:ly] = self.cmpltn_menu
             self.screeninfo[ly:ly] = [(0, [])]*len(self.cmpltn_menu)
@@ -270,7 +270,7 @@ class CompletingReader(Reader):
 
     def cmpltn_reset(self) -> None:
         self.cmpltn_menu = []
-        self.cmpltn_menu_vis = 0
+        self.cmpltn_menu_visible = False
         self.cmpltn_menu_end = 0
         self.cmpltn_menu_choices = []
 
index 2c8c9e7dc4b5dad6946f846d3b6f07cae1ba50c7..9a207a241d5f8d58afa41737f475653363721d71 100644 (file)
@@ -35,7 +35,9 @@ from .trace import trace
 # types
 Command = commands.Command
 if False:
+    from typing import Callable
     from .types import Callback, SimpleContextManager, KeySpec, CommandName
+    CalcScreen = Callable[[], list[str]]
 
 
 def disp_str(buffer: str) -> tuple[str, list[int]]:
@@ -231,9 +233,11 @@ class Reader:
     keymap: tuple[tuple[str, str], ...] = ()
     input_trans: input.KeymapTranslator = field(init=False)
     input_trans_stack: list[input.KeymapTranslator] = field(default_factory=list)
+    screen: list[str] = field(default_factory=list)
     screeninfo: list[tuple[int, list[int]]] = field(init=False)
     cxy: tuple[int, int] = field(init=False)
     lxy: tuple[int, int] = field(init=False)
+    calc_screen: CalcScreen = field(init=False)
 
     def __post_init__(self) -> None:
         # Enable the use of `insert` without a `prepare` call - necessary to
@@ -243,14 +247,36 @@ class Reader:
         self.input_trans = input.KeymapTranslator(
             self.keymap, invalid_cls="invalid-key", character_cls="self-insert"
         )
-        self.screeninfo = [(0, [0])]
+        self.screeninfo = [(0, [])]
         self.cxy = self.pos2xy()
         self.lxy = (self.pos, 0)
+        self.calc_screen = self.calc_complete_screen
 
     def collect_keymap(self) -> tuple[tuple[KeySpec, CommandName], ...]:
         return default_keymap
 
-    def calc_screen(self) -> list[str]:
+    def append_to_screen(self) -> list[str]:
+        new_screen = self.screen.copy() or ['']
+
+        new_character = self.buffer[-1]
+        new_character_len = wlen(new_character)
+
+        last_line_len = wlen(new_screen[-1])
+        if last_line_len + new_character_len >= self.console.width:  # We need to wrap here
+            new_screen[-1] += '\\'
+            self.screeninfo[-1][1].append(1)
+            new_screen.append(self.buffer[-1])
+            self.screeninfo.append((0, [new_character_len]))
+        else:
+            new_screen[-1] += self.buffer[-1]
+            self.screeninfo[-1][1].append(new_character_len)
+        self.cxy = self.pos2xy()
+
+        # Reset the function that is used for completing the screen
+        self.calc_screen = self.calc_complete_screen
+        return new_screen
+
+    def calc_complete_screen(self) -> list[str]:
         """The purpose of this method is to translate changes in
         self.buffer into changes in self.screen.  Currently it rips
         everything down and starts from scratch, which whilst not
@@ -563,8 +589,8 @@ class Reader:
     def refresh(self) -> None:
         """Recalculate and refresh the screen."""
         # this call sets up self.cxy, so call it first.
-        screen = self.calc_screen()
-        self.console.refresh(screen, self.cxy)
+        self.screen = self.calc_screen()
+        self.console.refresh(self.screen, self.cxy)
         self.dirty = False
 
     def do_cmd(self, cmd: tuple[str, list[str]]) -> None:
index 7c59f48df406e60f60745fb33dee01fa32d71d8e..ec7d0636b9aeb3faa6d69681e43a3e6e600000fe 100644 (file)
@@ -293,7 +293,7 @@ class UnixConsole(Console):
 
         self.__show_cursor()
 
-        self.screen = screen
+        self.screen = screen.copy()
         self.move_cursor(cx, cy)
         self.flushoutput()