126 lines
5.3 KiB
Python
126 lines
5.3 KiB
Python
import tools
|
||
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()
|
||
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
|
||
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
|
||
self.model.InsertCommandSymbol(symbolCode)
|
||
|
||
self.model.Scroll()
|
||
return returnCode
|
||
|
||
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()
|
||
return ReturnCode.GOOD
|
||
|
||
class NormalStrategy(BaseStrategy):
|
||
"""Режим навигации"""
|
||
def __init__(self, model: VimModel, adapter: CursesAdapter):
|
||
super().__init__(model, adapter, mode="NORMAL")
|
||
|
||
def HandleInput(self, symbolCode) -> int:
|
||
"""Обработка ввода пользователя"""
|
||
self.model.UpdateKeyLog(symbolCode)
|
||
match symbolCode:
|
||
case self.adapter.KEY_TWO_DOTS: return ReturnCode.SET_COMMAND_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 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()
|
||
else: self.model.ToWordEnd()
|
||
case self.adapter.KEY_b: self.model.ToWordStart()
|
||
case self.adapter.KEY_d:
|
||
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_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()
|
||
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()
|
||
return ReturnCode.GOOD |