From 7242026608cf63176dc1b16a8bf850c59599ba89 Mon Sep 17 00:00:00 2001 From: serr Date: Mon, 10 Feb 2025 21:24:46 +0300 Subject: [PATCH] =?UTF-8?q?=D0=BE=D0=B1=D1=89=D0=B8=D0=B9=20=D0=BA=D0=BE?= =?UTF-8?q?=D0=B4=20=D0=B4=D0=BB=D1=8F=20=D0=B2=D1=81=D0=B5=D1=85=20=D1=81?= =?UTF-8?q?=D1=82=D1=80=D0=B0=D1=82=D0=B5=D0=B3=D0=B8=D0=B9=20=D0=B2=D1=8B?= =?UTF-8?q?=D0=BD=D0=B5=D1=81=20=D0=B2=20=D0=B4=D0=B5=D0=BA=D0=BE=D1=80?= =?UTF-8?q?=D0=B0=D1=82=D0=BE=D1=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main.py | 4 +- mvc/controllers.py | 102 +++++++++++++++++++-------------------------- tools.py | 3 ++ 3 files changed, 47 insertions(+), 62 deletions(-) diff --git a/main.py b/main.py index 738d100..ac9ed7b 100644 --- a/main.py +++ b/main.py @@ -13,14 +13,14 @@ def main(): strategy = NormalStrategy(model, view.curses_adapter) controller = Controller(strategy) - # Первинчая загрузка файла для редактирования + # load file from sys argv if len(sys.argv) > 1: model.LoadFile(sys.argv[1]) else: model.LoadFile("File not found but i create it"+str(tools.UnixSec())+".txt") view.SetModel(model) # view subscribe model while True: - + model.notify() symbolCode = view.curses_adapter.GetChar() diff --git a/mvc/controllers.py b/mvc/controllers.py index 6fd50a4..fe94763 100644 --- a/mvc/controllers.py +++ b/mvc/controllers.py @@ -3,8 +3,19 @@ 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 +def CommonInput(HandleInputFunc): + """common actions for all strategies decorator""" + def wrapper(self, symbolCode: int) -> int: + result = self.HandleCommonInput(symbolCode) + if result != ReturnCode.CONTINUE: # an action common to all strategies occurred + self.model.Scroll() + return result + + return_code = HandleInputFunc(self, symbolCode) + + self.model.Scroll() + return return_code + return wrapper class BaseStrategy(ABC): def __init__(self, model: VimModel, adapter: CursesAdapter, mode: str): @@ -12,8 +23,8 @@ class BaseStrategy(ABC): self.adapter = adapter self.mode = model.mode = mode - def handle_common_input(self, symbolCode: int) -> int: - """Обработка общих для всех стратегий действий""" + def HandleCommonInput(self, symbolCode: int) -> int: + """common actions for all strategies""" match symbolCode: case self.adapter.KEY_ESCAPE: return ReturnCode.SET_BASIC_MODE case self.adapter.KEY_LEFT: self.model.MoveLeft() @@ -21,7 +32,7 @@ class BaseStrategy(ABC): 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 # Не обрабатываем, передаем дальше + return ReturnCode.CONTINUE @abstractmethod def HandleInput(self, symbolCode: int) -> int: @@ -38,104 +49,75 @@ class Controller: return self.strategy.HandleInput(symbolCode) class CommandStrategy(BaseStrategy): - """Режим ввода команд""" + """command input mode""" def __init__(self, model: VimModel, adapter: CursesAdapter): super().__init__(model, adapter, mode="COMMAND") + @CommonInput def HandleInput(self, symbolCode) -> int: - """Обработка ввода пользователя""" - result = self.handle_common_input(symbolCode) - if result != ReturnCode.CONTINUE: return result + """user input processing""" returnCode = ReturnCode.GOOD - match symbolCode: case self.adapter.KEY_ENTER: returnCode = self.model.EnterCommand() case self.adapter.KEY_BACKSPACE_1 | self.adapter.KEY_BACKSPACE_2: self.model.BackspaceCommand() case _: - if not isAscii(symbolCode): return ReturnCode.GOOD + if not tools.isAscii(symbolCode): return ReturnCode.GOOD self.model.InsertCommandSymbol(symbolCode) - - self.model.Scroll() return returnCode class EditStrategy(BaseStrategy): - """Режим редактирования""" + """edit mode""" def __init__(self, model: VimModel, adapter: CursesAdapter): super().__init__(model, adapter, mode="EDIT") + @CommonInput def HandleInput(self, symbolCode) -> int: - """Обработка ввода пользователя""" - result = self.handle_common_input(symbolCode) - if result != ReturnCode.CONTINUE: return result - + """user input processing""" 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 + if not tools.isAscii(symbolCode): return ReturnCode.GOOD if not self.model.inputAfterCursor: self.model.InsertSymbol(symbolCode) else: self.model.InsertSymbolAfterCursor(symbolCode) - - self.model.Scroll() return ReturnCode.GOOD class NormalStrategy(BaseStrategy): - """Режим навигации""" + """navigation mode""" def __init__(self, model: VimModel, adapter: CursesAdapter): super().__init__(model, adapter, mode="NORMAL") + @CommonInput def HandleInput(self, symbolCode) -> int: - """Обработка ввода пользователя""" + """user input processing""" self.model.UpdateKeyLog(symbolCode) - result = self.handle_common_input(symbolCode) - if result != ReturnCode.CONTINUE: - self.model.Scroll() - return result - match symbolCode: - case self.adapter.KEY_TWO_DOTS: - return ReturnCode.SET_COMMAND_MODE - case self.adapter.KEY_NULL | self.adapter.KEY_XOR: - self.model.ToLineStart() - case self.adapter.KEY_DOLLAR: - self.model.ToLineEnd() - case self.adapter.KEY_p: - self.model.Paste() + case self.adapter.KEY_TWO_DOTS: return ReturnCode.SET_COMMAND_MODE + case self.adapter.KEY_NULL | self.adapter.KEY_XOR: self.model.ToLineStart() + case self.adapter.KEY_DOLLAR: self.model.ToLineEnd() + case self.adapter.KEY_p: self.model.Paste() case self.adapter.KEY_w: - if self.model.CombinationCheck("diw", 3): - self.model.DeleteWord() - elif self.model.CombinationCheck("yw", 3): - self.model.CopyWord() + if self.model.CombinationCheck("diw", 3): self.model.DeleteWord() + elif self.model.CombinationCheck("yw", 3): self.model.CopyWord() else: self.model.ToWordEnd() - case self.adapter.KEY_b: - self.model.ToWordStart() + case self.adapter.KEY_b: self.model.ToWordStart() case self.adapter.KEY_d: - if self.model.CombinationCheck("dd", 3): - self.model.CutLine() + if self.model.CombinationCheck("dd", 3): self.model.CutLine() case self.adapter.KEY_y: - if self.model.CombinationCheck("yy", 3): - self.model.CopyLine() - case self.adapter.KEY_x: - self.model.DeleteNext() - case self.adapter.KEY_U: - self.model.RecoverLine() + if self.model.CombinationCheck("yy", 3): self.model.CopyLine() + case self.adapter.KEY_x: self.model.DeleteNext() + case self.adapter.KEY_U: self.model.RecoverLine() case self.adapter.KEY_G: num, ind = tools.ExtracrtNumBeforeLastKey(''.join([chr(item[0]) for item in self.model.keyLog])) - if num != None and ind != None: - self.model.MoveToLine(num) - else: - self.model.ToFileEnd() + if num != None and ind != None: self.model.MoveToLine(num) + else: self.model.ToFileEnd() case self.adapter.KEY_g: if self.model.CombinationCheck("gg", 3): self.model.ToFileStart() - case self.adapter.KEY_PG_UP: - self.model.PageUp() - case self.adapter.KEY_PG_DOWN: - self.model.PageDown() - - self.model.Scroll() + case self.adapter.KEY_PG_UP: self.model.PageUp() + case self.adapter.KEY_PG_DOWN: self.model.PageDown() return ReturnCode.GOOD \ No newline at end of file diff --git a/tools.py b/tools.py index a724ff6..495bedb 100644 --- a/tools.py +++ b/tools.py @@ -23,5 +23,8 @@ def ExtracrtNumBeforeLastKey(s): return int(number), i return None, None +def isAscii(symbolCode: int) -> bool: + return 32 <= symbolCode <= 126 + def UnixSec() -> int: return int(time.time()) \ No newline at end of file