Compare commits
No commits in common. "rewrite-MyString-class" and "master" have entirely different histories.
rewrite-My
...
master
7
main.py
7
main.py
|
@ -4,7 +4,6 @@ from mvc.views import VimView, CursesAdapter
|
|||
from mvc.controllers import Controller, ReturnCode
|
||||
from mvc.controllers import EditStrategy, CommandStrategy, NormalStrategy
|
||||
import tools
|
||||
from mystring import MyString as MyString
|
||||
|
||||
def main():
|
||||
adapter = CursesAdapter()
|
||||
|
@ -15,10 +14,8 @@ def main():
|
|||
controller = Controller(strategy)
|
||||
|
||||
# load file from sys argv
|
||||
if len(sys.argv) > 1: model.LoadFile(MyString(sys.argv[1]))
|
||||
else: model.LoadFile(MyString("File not found but i create it").data()+\
|
||||
MyString(str(tools.UnixSec())).data()+\
|
||||
MyString(".txt").data())
|
||||
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
|
||||
|
||||
|
|
|
@ -2,7 +2,6 @@ import tools
|
|||
from abc import ABC, abstractmethod
|
||||
from mvc.views import CursesAdapter
|
||||
from mvc.models import VimModel, ReturnCode
|
||||
from mystring import MyString as MyString
|
||||
|
||||
def CommonInput(HandleInputFunc):
|
||||
"""common actions for all strategies decorator"""
|
||||
|
@ -52,7 +51,7 @@ class Controller:
|
|||
class CommandStrategy(BaseStrategy):
|
||||
"""command input mode"""
|
||||
def __init__(self, model: VimModel, adapter: CursesAdapter):
|
||||
super().__init__(model, adapter, mode=MyString("COMMAND"))
|
||||
super().__init__(model, adapter, mode="COMMAND")
|
||||
|
||||
@CommonInput
|
||||
def HandleInput(self, symbolCode) -> int:
|
||||
|
@ -71,7 +70,7 @@ class CommandStrategy(BaseStrategy):
|
|||
class EditStrategy(BaseStrategy):
|
||||
"""edit mode"""
|
||||
def __init__(self, model: VimModel, adapter: CursesAdapter):
|
||||
super().__init__(model, adapter, mode=MyString("EDIT"))
|
||||
super().__init__(model, adapter, mode="EDIT")
|
||||
|
||||
@CommonInput
|
||||
def HandleInput(self, symbolCode) -> int:
|
||||
|
@ -91,7 +90,7 @@ class EditStrategy(BaseStrategy):
|
|||
class NormalStrategy(BaseStrategy):
|
||||
"""navigation mode"""
|
||||
def __init__(self, model: VimModel, adapter: CursesAdapter):
|
||||
super().__init__(model, adapter, mode=MyString("NORMAL"))
|
||||
super().__init__(model, adapter, mode="NORMAL")
|
||||
|
||||
@CommonInput
|
||||
def HandleInput(self, symbolCode) -> int:
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
import tools
|
||||
from enum import Enum
|
||||
from typing import List
|
||||
from mystring import MyString as MyString
|
||||
|
||||
class ReturnCode(Enum):
|
||||
GOOD = -101
|
||||
|
@ -12,42 +10,24 @@ class ReturnCode(Enum):
|
|||
CONTINUE = -96
|
||||
|
||||
class VimModel:
|
||||
observers: List
|
||||
displayLinesCount: int
|
||||
displayColsCount: int
|
||||
showLineNumbers: bool
|
||||
lastSearch: tuple[str, int] # tuple (search str, direction)
|
||||
displayBuffer: List[List[MyString]]
|
||||
dump: List[List[MyString]]
|
||||
currentLine: int
|
||||
currentCol: int
|
||||
scrollY: int
|
||||
scrollX: int
|
||||
file_path: MyString # filepath
|
||||
mode: MyString
|
||||
inputAfterCursor: bool
|
||||
keyLog: List[tuple[int, int]] # key log for check combinations (tuples (symbol code, tap unix time))
|
||||
commandBuffer: List[MyString] # buffer for command
|
||||
exchangeBuffer: List[MyString] # buffer for exchange
|
||||
|
||||
def __init__(self, displayLinesCount: int, displayColsCount: int):
|
||||
self.observers = []
|
||||
self.displayLinesCount = displayLinesCount
|
||||
self.displayColsCount = displayColsCount
|
||||
self.showLineNumbers = True
|
||||
self.lastSearch = ()
|
||||
self.displayBuffer = []
|
||||
self.displayBuffer = [] # буфер для хранения всех строк
|
||||
self.dump = []
|
||||
self.currentLine = 0
|
||||
self.currentCol = 0
|
||||
self.scrollY = 0
|
||||
self.scrollX = 0
|
||||
self.file_path = MyString()
|
||||
self.mode = MyString()
|
||||
self.currentLine = 0 # текущий индекс строки
|
||||
self.currentCol = 0 # текущий индекс колонки
|
||||
self.scrollY = 0 # вертикальная прокрутка
|
||||
self.scrollX = 0 # горизонтальная прокрутка
|
||||
self.file_path = "" # путь к файлу
|
||||
self.mode = ""
|
||||
self.inputAfterCursor = False
|
||||
self.keyLog = []
|
||||
self.commandBuffer = []
|
||||
self.exchangeBuffer = []
|
||||
self.keyLog = [] # лог нажатий клавиш (кортежи вида (код символа, юникс время нажатия))
|
||||
self.commandBuffer = [] # буффер для команды
|
||||
self.exchangeBuffer = [] # буффер обмена
|
||||
|
||||
def attach(self, observer):
|
||||
self.observers.append(observer)
|
||||
|
@ -77,9 +57,9 @@ class VimModel:
|
|||
return False
|
||||
|
||||
def ModeBar(self) -> str:
|
||||
modeBar = f"MODE: {self.mode.data()} | FILE: {self.file_path.data()} | LINE: {self.currentLine+1}/{len(self.displayBuffer)}"
|
||||
if self.mode == MyString("COMMAND"):
|
||||
modeBar += f" | COMMAND BUFFER: {''.join(item.data() for item in self.commandBuffer)}"
|
||||
modeBar = f"MODE: {self.mode} | FILE: {self.file_path} | LINE: {self.currentLine+1}/{len(self.displayBuffer)}"
|
||||
if self.mode == "COMMAND":
|
||||
modeBar += f" | COMMAND BUFFER: {''.join(self.commandBuffer)}"
|
||||
return modeBar
|
||||
|
||||
def Scroll(self) -> None:
|
||||
|
@ -101,16 +81,16 @@ class VimModel:
|
|||
self.scrollX = self.currentCol - visible_text_width + 1
|
||||
|
||||
def InsertCommandSymbol(self, symbolCode: int) -> None:
|
||||
self.commandBuffer.append(MyString(chr(symbolCode)))
|
||||
self.commandBuffer.append(chr(symbolCode))
|
||||
|
||||
def InsertSymbol(self, symbolCode: int) -> None:
|
||||
if self.currentCol <= len(self.displayBuffer[self.currentLine]): # проверяем, не превышает ли индекс колонки длину строки
|
||||
self.displayBuffer[self.currentLine].insert(self.currentCol, MyString(chr(symbolCode)))
|
||||
self.displayBuffer[self.currentLine].insert(self.currentCol, chr(symbolCode))
|
||||
self.currentCol += 1
|
||||
|
||||
def InsertSymbolAfterCursor(self, symbolCode: int) -> None:
|
||||
if self.currentCol <= len(self.displayBuffer[self.currentLine]): # проверяем, не превышает ли индекс колонки длину строки
|
||||
self.displayBuffer[self.currentLine].insert(self.currentCol, MyString(chr(symbolCode)))
|
||||
self.displayBuffer[self.currentLine].insert(self.currentCol, chr(symbolCode))
|
||||
|
||||
def ToLineStart(self) -> None:
|
||||
self.currentCol = 0
|
||||
|
@ -119,7 +99,7 @@ class VimModel:
|
|||
self.currentCol = len(self.displayBuffer[self.currentLine])
|
||||
|
||||
def ToWordEnd(self) -> None:
|
||||
line = ''.join(item.data() for item in self.displayBuffer[self.currentLine])
|
||||
line = ''.join(self.displayBuffer[self.currentLine])
|
||||
# Находим ближайший непробельный символ
|
||||
non_space_index = next((i for i, char in enumerate(line[self.currentCol:]) if char != ' '), None)
|
||||
if non_space_index is not None:
|
||||
|
@ -128,7 +108,7 @@ class VimModel:
|
|||
self.currentCol = right_space_index if right_space_index != -1 else len(line)
|
||||
|
||||
def ToWordStart(self) -> None:
|
||||
line = ''.join(item.data() for item in self.displayBuffer[self.currentLine])
|
||||
line = ''.join(self.displayBuffer[self.currentLine])
|
||||
non_space_index = next((i for i in range(self.currentCol - 1, -1, -1) if line[i] != ' '), None)
|
||||
if non_space_index is not None:
|
||||
left_space_index = line.rfind(' ', 0, non_space_index)
|
||||
|
@ -163,7 +143,7 @@ class VimModel:
|
|||
def DeleteWord(self) -> None:
|
||||
start_index, end_index = self.WordUnderCursor()
|
||||
line = self.displayBuffer[self.currentLine]
|
||||
if end_index < len(line) and line[end_index] == MyString(' '):
|
||||
if end_index < len(line) and line[end_index] == ' ':
|
||||
end_index += 1
|
||||
self.displayBuffer[self.currentLine] = line[:start_index] + line[end_index:]
|
||||
self.currentCol = start_index
|
||||
|
@ -192,7 +172,7 @@ class VimModel:
|
|||
|
||||
def EnterCommand(self):
|
||||
"""Обработка введенной команды"""
|
||||
cmd = ''.join(item.data() for item in self.commandBuffer)
|
||||
cmd = ''.join(self.commandBuffer)
|
||||
self.commandBuffer.clear()
|
||||
match cmd:
|
||||
case "q": # Выход из программы
|
||||
|
@ -245,20 +225,18 @@ class VimModel:
|
|||
self.lastSearch = (self.lastSearch[0], (self.lastSearch[1]+1)%2)
|
||||
case "e!":
|
||||
self.displayBuffer = [sublist.copy() for sublist in self.dump]
|
||||
self.currentCol = 0
|
||||
self.currentLine = 0
|
||||
case "set num":
|
||||
self.showLineNumbers = not self.showLineNumbers
|
||||
case _:
|
||||
# Открывает файл filename
|
||||
if len(cmd) > 2 and cmd[:2] == 'o ':
|
||||
filename = cmd[2:]
|
||||
self.LoadFile(MyString(filename))
|
||||
self.LoadFile(filename)
|
||||
return ReturnCode.SET_BASIC_MODE
|
||||
# Запись в файл filename
|
||||
elif len(cmd) > 2 and cmd[:2] == 'w ':
|
||||
filename = cmd[2:]
|
||||
self.WriteFile(MyString(filename))
|
||||
self.WriteFile(filename)
|
||||
# Заменяет символ на указанный
|
||||
elif len(cmd) == 3 and cmd[:2] == 'r ':
|
||||
self.displayBuffer[self.currentLine][self.currentCol] = cmd[2]
|
||||
|
@ -290,7 +268,7 @@ class VimModel:
|
|||
|
||||
def WordUnderCursor(self)-> tuple[int, int]:
|
||||
"""Возвращает индекс начала и индекс конца слова под курсором"""
|
||||
line = ''.join(item.data() for item in self.displayBuffer[self.currentLine])
|
||||
line = ''.join(self.displayBuffer[self.currentLine])
|
||||
start_index = line.rfind(' ', 0, self.currentCol)
|
||||
start_index = 0 if start_index == -1 else start_index + 1
|
||||
end_index = line.find(' ', self.currentCol)
|
||||
|
@ -357,13 +335,13 @@ class VimModel:
|
|||
"""Загрузка файла для редактирования"""
|
||||
self.Reset()
|
||||
self.file_path = file_path
|
||||
self.mode = MyString("NORMAL")
|
||||
self.mode = "NORMAL"
|
||||
try:
|
||||
with open(file_path.data(), "r") as file:
|
||||
self.displayBuffer = [[MyString(char) for char in line.rstrip('\n')] for line in file.readlines()]
|
||||
with open(file_path, "r") as file:
|
||||
self.displayBuffer = [list(line.rstrip('\n')) for line in file.readlines()]
|
||||
self.Dump()
|
||||
except FileNotFoundError:
|
||||
print(f"File '{file_path.data()}' not found. Starting with empty buffer.")
|
||||
print(f"File '{file_path}' not found. Starting with empty buffer.")
|
||||
self.displayBuffer = []
|
||||
self.displayBuffer.append([])
|
||||
|
||||
|
@ -374,11 +352,11 @@ class VimModel:
|
|||
def WriteFile(self, file_path) -> None:
|
||||
"""Запись в файл по указанному пути"""
|
||||
try:
|
||||
with open(file_path.data(), "w") as file:
|
||||
with open(file_path, "w") as file:
|
||||
for line in self.displayBuffer:
|
||||
file.write(''.join(item.data() for item in line) + '\n')
|
||||
file.write(''.join(line) + '\n')
|
||||
self.Dump()
|
||||
print(f"In file '{file_path.data()}' written successfully.")
|
||||
print(f"In file '{file_path}' written successfully.")
|
||||
except Exception as e:
|
||||
print(f"Error writing file: {str(e)}")
|
||||
|
||||
|
@ -391,8 +369,8 @@ class VimModel:
|
|||
self.currentCol = 0 # текущий индекс колонки
|
||||
self.scrollY = 0 # вертикальная прокрутка
|
||||
self.scrollX = 0 # горизонтальная прокрутка
|
||||
self.file_path = MyString() # путь к файлу
|
||||
self.mode = MyString()
|
||||
self.file_path = "" # путь к файлу
|
||||
self.mode = ""
|
||||
self.inputAfterCursor = False
|
||||
self.keyLog = [] # лог нажатий клавиш (кортежи вида (код символа, юникс время нажатия))
|
||||
self.commandBuffer = [] # буффер для команды
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
from abc import ABC, abstractmethod
|
||||
import curses
|
||||
import mvc.models
|
||||
from mystring import MyString as MyString
|
||||
|
||||
class CursesAdapter:
|
||||
def __init__(self) -> None:
|
||||
|
@ -94,7 +93,7 @@ class VimView(Observer):
|
|||
)
|
||||
|
||||
def Render(self,
|
||||
displayBuffer: list[list[MyString]],
|
||||
displayBuffer: list[list[str]],
|
||||
currentLine: int, currentCol: int,
|
||||
scrollX: int, scrollY: int,
|
||||
modeBarData: str,
|
||||
|
@ -109,7 +108,7 @@ class VimView(Observer):
|
|||
# Отображение видимой части текста
|
||||
for i in range(self.curses_adapter.lines - 1):
|
||||
if i + scrollY < len(displayBuffer):
|
||||
line = ''.join(item.data() for item in displayBuffer[i + scrollY])
|
||||
line = ''.join(displayBuffer[i + scrollY])
|
||||
# Если нужно отображать номера строк, добавляем их перед текстом
|
||||
if show_line_numbers:
|
||||
line_number = f"{i + scrollY + 1:6} " # 6 символов на номер строки
|
||||
|
|
Loading…
Reference in New Issue