Stores readline-style history and current place in it
| 33 | |
| 34 | |
| 35 | class History: |
| 36 | """Stores readline-style history and current place in it""" |
| 37 | |
| 38 | def __init__( |
| 39 | self, |
| 40 | entries: Iterable[str] | None = None, |
| 41 | duplicates: bool = True, |
| 42 | hist_size: int = 100, |
| 43 | ) -> None: |
| 44 | if entries is None: |
| 45 | self.entries = [""] |
| 46 | else: |
| 47 | self.entries = list(entries) |
| 48 | # how many lines back in history is currently selected where 0 is the |
| 49 | # saved typed line, 1 the prev entered line |
| 50 | self.index = 0 |
| 51 | # what was on the prompt before using history |
| 52 | self.saved_line = "" |
| 53 | self.duplicates = duplicates |
| 54 | self.hist_size = hist_size |
| 55 | |
| 56 | def append(self, line: str) -> None: |
| 57 | self.append_to(self.entries, line) |
| 58 | |
| 59 | def append_to(self, entries: list[str], line: str) -> None: |
| 60 | line = line.rstrip("\n") |
| 61 | if line: |
| 62 | if not self.duplicates: |
| 63 | # remove duplicates |
| 64 | try: |
| 65 | while True: |
| 66 | entries.remove(line) |
| 67 | except ValueError: |
| 68 | pass |
| 69 | entries.append(line) |
| 70 | |
| 71 | def first(self) -> str: |
| 72 | """Move back to the beginning of the history.""" |
| 73 | if not self.is_at_end: |
| 74 | self.index = len(self.entries) |
| 75 | return self.entries[-self.index] |
| 76 | |
| 77 | def back( |
| 78 | self, |
| 79 | start: bool = True, |
| 80 | search: bool = False, |
| 81 | target: str | None = None, |
| 82 | include_current: bool = False, |
| 83 | ) -> str: |
| 84 | """Move one step back in the history.""" |
| 85 | if target is None: |
| 86 | target = self.saved_line |
| 87 | if not self.is_at_end: |
| 88 | if search: |
| 89 | self.index += self.find_partial_match_backward( |
| 90 | target, include_current |
| 91 | ) |
| 92 | elif start: |
no outgoing calls