def __init__(self, stdscr): self.stdscr = stdscr self.user_interface = UserInterface(self) self.all_entries = { 0: sort(read(PYTHON_HISTORY)), 1: sort(read(FAVORITES)), 2: remove_duplicates(read(PYTHON_HISTORY)) } self.to_restore = self.all_entries.copy() self.case_sensitivity = False self.view = 0 # 0 = sorted; 1 = favorites; 2 = history self.regex_match = False
def __init__(self, stdscr: _CursesWindow): self.stdscr = stdscr self.user_interface = UserInterface(self) self.raw_history: List[str] = self.get_history() self.commands: Dict[View, List[str]] = { View.SORTED: sort(self.raw_history), View.FAVORITES: sort(read(SHELLS[SHELL]["fav"])), View.ALL: remove_duplicates(self.raw_history), } self.to_restore = self.commands.copy() self.regex_mode: bool = False self.case_sensitivity: bool = False self.view: View = View.SORTED self.search_string = ""
class App: def __init__(self, stdscr): self.stdscr = stdscr self.user_interface = UserInterface(self) self.all_entries = { 0: sort(read(PYTHON_HISTORY)), 1: sort(read(FAVORITES)), 2: remove_duplicates(read(PYTHON_HISTORY)) } self.to_restore = self.all_entries.copy() self.case_sensitivity = False self.view = 0 # 0 = sorted; 1 = favorites; 2 = history self.regex_match = False def search(self): self.user_interface.page.selected.value = 0 self.user_interface.page.value = 1 self.all_entries[self.view] = [ cmd for cmd in self.all_entries[self.view] if self.user_interface.create_search_string_regex().search(cmd) ] self.user_interface.populate_screen() def delete_from_history(self, command): self.user_interface.prompt_for_deletion(command) answer = self.stdscr.getch() if answer == ord("y"): for cmd in self.all_entries[2]: if cmd == command: self.all_entries[2].remove(cmd) write(PYTHON_HISTORY, self.all_entries[2]) self.user_interface.populate_screen() elif answer == ord("n"): self.user_interface.populate_screen() def toggle_case(self): self.case_sensitivity = not self.case_sensitivity def toggle_view(self): self.view = (self.view + 1) % 3 def toggle_match(self): self.regex_match = not self.regex_match def add_to_or_remove_from_favorites(self, command): if command not in self.all_entries[1]: self.all_entries[1].append(command) else: self.all_entries[1].remove(command) write(FAVORITES, self.all_entries[1])
def test_total_pages(fake_curses, fake_stdscr, fake_standard): user_interface = UserInterface(App(fake_stdscr)) assert user_interface.total_pages() == 4
def test_init_color_pairs(fake_curses, fake_stdscr): user_interface = UserInterface(App(fake_stdscr)) user_interface.init_color_pairs() for v in COLORS.values(): assert v != 0
def test_show_regex_error(fake_curses, fake_stdscr, fake_standard): user_interface = UserInterface(App(fake_stdscr)) user_interface.show_regex_error() assert (1, 1, "Invalid regex. Try again.", 0) in fake_stdscr.addstred
def test_prompt_for_deletion(fake_curses, fake_stdscr, fake_standard): user_interface = UserInterface(App(fake_stdscr)) command = '__import__("math").pi' user_interface.prompt_for_deletion(command) assert (1, 1, f"Do you want to delete all occurences of {command}? y/n", 0) in fake_stdscr.addstred
class App: def __init__(self, stdscr: _CursesWindow): self.stdscr = stdscr self.user_interface = UserInterface(self) self.raw_history: List[str] = self.get_history() self.commands: Dict[View, List[str]] = { View.SORTED: sort(self.raw_history), View.FAVORITES: sort(read(SHELLS[SHELL]["fav"])), View.ALL: remove_duplicates(self.raw_history), } self.to_restore = self.commands.copy() self.regex_mode: bool = False self.case_sensitivity: bool = False self.view: View = View.SORTED self.search_string = "" def get_history(self) -> List[str]: # pylint: disable=no-self-use if SHELL == Shell.IPYTHON: return get_ipython_history() return read(SHELLS[SHELL]["hist"]) def search(self) -> None: self.user_interface.page.selected = 0 self.user_interface.page.value = 1 search_regex = self.create_search_regex() if search_regex is not None: self.commands[self.view] = [ cmd for cmd in self.commands[self.view] if search_regex.search(cmd) ] self.stdscr.clear() self.user_interface.populate_screen() else: self.commands[self.view] = [] self.stdscr.clear() self.user_interface.populate_screen() self.user_interface.show_regex_error() def create_search_regex(self) -> Optional[Pattern]: try: search_string = (self.search_string if self.regex_mode else re.escape(self.search_string)) return re.compile( search_string, re.IGNORECASE if not self.case_sensitivity else 0) except re.error: return None def delete_from_history(self, command: str) -> None: if SHELL == Shell.STANDARD: self.delete_python_history(command) elif SHELL == Shell.IPYTHON: self.delete_ipython_history(command) elif SHELL == Shell.BPYTHON: self.delete_bpython_history(command) else: pass # future implementations self.delete_from_pyhstr(command) self.to_restore = self.commands.copy() def delete_python_history(self, command: str) -> None: # pylint: disable=no-self-use readline_history = [ readline.get_history_item(i + 1) for i in range(readline.get_current_history_length()) ] cmd_indexes = [ i for i, cmd in enumerate(readline_history) if cmd == command ] for cmd_idx in reversed(cmd_indexes): readline.remove_history_item(cmd_idx) readline.write_history_file(str(SHELLS[Shell.STANDARD]["hist"])) def delete_ipython_history(self, command: str) -> None: # pylint: disable=no-self-use IPython.get_ipython().history_manager.db.execute( "DELETE FROM history WHERE source=(?)", (command, )) def delete_bpython_history(self, command: str) -> None: self.raw_history = [cmd for cmd in self.raw_history if cmd != command] write(SHELLS[Shell.BPYTHON]["hist"], self.raw_history) def delete_from_pyhstr(self, command: str) -> None: for view in self.commands.values(): for cmd in view: if cmd == command: view.remove(cmd) def add_or_rm_fav(self, command: str) -> None: favorites = self.commands[View.FAVORITES] if command not in favorites: favorites.append(command) else: favorites.remove(command) write(SHELLS[SHELL]["fav"], favorites) def toggle_regex_mode(self) -> None: self.regex_mode = not self.regex_mode def toggle_case(self) -> None: self.case_sensitivity = not self.case_sensitivity def toggle_view(self) -> None: self.view = View((self.view.value + 1) % 3)