from abc import ABC, abstractmethod from mvc.views import CursesAdapter from mvc.models import VimModel, ReturnCode def isAscii(symbolCode: int) -> bool: return 32 <= symbolCode <= 126 class BaseStrategy(ABC): def __init__(self, model: VimModel, adapter: CursesAdapter, mode: str): self.model = model self.adapter = adapter self.mode = model.mode = mode def handle_common_input(self, symbolCode: int) -> int: """Обработка общих для всех стратегий действий""" match symbolCode: case self.adapter.KEY_ESCAPE: return ReturnCode.SET_BASIC_MODE case self.adapter.KEY_LEFT: self.model.MoveLeft() case self.adapter.KEY_RIGHT: self.model.MoveRight() case self.adapter.KEY_UP: self.model.MoveUp() case self.adapter.KEY_DOWN: self.model.MoveDown() case self.adapter.KEY_CTRL_S: self.model.SaveFile() case _: return ReturnCode.CONTINUE # Не обрабатываем, передаем дальше self.model.Scroll(self.adapter.lines, self.adapter.cols) return ReturnCode.GOOD @abstractmethod def HandleInput(self, symbolCode: int) -> int: pass class Controller: def __init__(self, strategy: BaseStrategy): self.strategy = strategy def SetStrategy(self, strategy: BaseStrategy): self.strategy = strategy def HandleInput(self, symbolCode: int): return self.strategy.HandleInput(symbolCode) class CommandStrategy(BaseStrategy): """Режим ввода команд""" def __init__(self, model: VimModel, adapter: CursesAdapter): super().__init__(model, adapter, mode="COMMAND") def HandleInput(self, symbolCode) -> int: """Обработка ввода пользователя""" result = self.handle_common_input(symbolCode) if result != ReturnCode.CONTINUE: return result match symbolCode: case self.adapter.KEY_ENTER: code = self.model.EnterCommand() self.model.Scroll(self.adapter.lines, self.adapter.cols) return code case self.adapter.KEY_BACKSPACE_1 | self.adapter.KEY_BACKSPACE_2: self.model.BackspaceCommand() case _: if not isAscii(symbolCode): return ReturnCode.GOOD self.model.InsertCommandSymbol(symbolCode) self.model.Scroll(self.adapter.lines, self.adapter.cols) return ReturnCode.GOOD class EditStrategy(BaseStrategy): """Режим редактирования""" def __init__(self, model: VimModel, adapter: CursesAdapter): super().__init__(model, adapter, mode="EDIT") def HandleInput(self, symbolCode) -> int: """Обработка ввода пользователя""" result = self.handle_common_input(symbolCode) if result != ReturnCode.CONTINUE: return result match symbolCode: case self.adapter.KEY_ENTER: self.model.Enter() case self.adapter.KEY_BACKSPACE_1 | self.adapter.KEY_BACKSPACE_2: self.model.Backspace() case _: if not isAscii(symbolCode): return ReturnCode.GOOD self.model.InsertSymbol(symbolCode) self.model.Scroll(self.adapter.lines, self.adapter.cols) return ReturnCode.GOOD class NormalStrategy(BaseStrategy): """Режим навигации""" def __init__(self, model: VimModel, adapter: CursesAdapter): super().__init__(model, adapter, mode="NORMAL") def HandleInput(self, symbolCode) -> int: """Обработка ввода пользователя""" result = self.handle_common_input(symbolCode) if result != ReturnCode.CONTINUE: return result match symbolCode: case self.adapter.KEY_TWO_DOTS: return ReturnCode.SET_COMMAND_MODE self.model.Scroll(self.adapter.lines, self.adapter.cols) return ReturnCode.GOOD