VIM-like-text-editor/mvc/models.py

127 lines
5.6 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

from enum import Enum
class ReturnCode(Enum):
GOOD = -101
EXIT_CODE = -100
SET_BASIC_MODE = -99
SET_COMMAND_MODE = -98
SET_EDIT_MODE = -97
class VimModel:
def __init__(self):
self.displayBuffer = [] # буфер для хранения всех строк
self.currentLine = 0 # текущий индекс строки
self.currentCol = 0 # текущий индекс колонки
self.scrollY = 0 # вертикальная прокрутка
self.scrollX = 0 # горизонтальная прокрутка
self.file_path = "" # путь к файлу
self.mode = ""
self.commandBuffer = [] # буффер для команды
def ModeBar(self) -> str:
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, displayLines: int, displayCols: int) -> None:
if self.currentLine < self.scrollY:
self.scrollY = self.currentLine
elif self.currentLine >= self.scrollY + displayLines - 1:
self.scrollY = self.currentLine - displayLines + 2
if self.currentCol < self.scrollX:
self.scrollX = self.currentCol
elif self.currentCol >= self.scrollX + displayCols:
self.scrollX = self.currentCol - displayCols + 1
def InsertCommandSymbol(self, symbolCode: int) -> None:
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, chr(symbolCode))
self.currentCol += 1
def EnterCommand(self):
cmd = ''.join(self.commandBuffer)
self.commandBuffer.clear()
match cmd:
case "$":
self.currentCol = len(self.displayBuffer[self.currentLine])
return ReturnCode.GOOD
case "q":
return ReturnCode.EXIT_CODE
case "S":
self.currentCol = 0
self.displayBuffer[self.currentLine] = []
return ReturnCode.SET_EDIT_MODE
def Enter(self) -> None:
# Разделяем текущую строку на две части
new_line = self.displayBuffer[self.currentLine][self.currentCol:]
self.displayBuffer[self.currentLine] = self.displayBuffer[self.currentLine][:self.currentCol]
self.currentLine += 1 # Переходим на следующую строку
self.displayBuffer.insert(self.currentLine, new_line) # Вставляем новую строку
self.currentCol = 0 # Сбрасываем индекс колонки
def BackspaceCommand(self) -> None:
if len(self.commandBuffer) > 0:
self.commandBuffer.pop()
def Backspace(self) -> None:
if self.currentCol > 0: # Если символ существует в текущей строке
self.currentCol -= 1
del self.displayBuffer[self.currentLine][self.currentCol] # Удаляем символ
elif self.currentLine > 0: # Если текущая строка не первая
# Объединяем текущую строку с предыдущей
prev_line_length = len(self.displayBuffer[self.currentLine - 1])
self.displayBuffer[self.currentLine - 1].extend(self.displayBuffer[self.currentLine])
del self.displayBuffer[self.currentLine]
self.currentLine -= 1
self.currentCol = prev_line_length # Переходим в конец предыдущей строки
def MoveLeft(self) -> None:
if self.currentCol > 0:
self.currentCol -= 1
elif self.currentLine > 0:
self.currentLine -= 1
self.currentCol = len(self.displayBuffer[self.currentLine])
def MoveRight(self) -> None:
if self.currentCol < len(self.displayBuffer[self.currentLine]):
self.currentCol += 1
elif self.currentLine < len(self.displayBuffer) - 1:
self.currentLine += 1
self.currentCol = 0
def MoveUp(self) -> None:
if self.currentLine > 0:
self.currentLine -= 1
self.currentCol = min(self.currentCol, len(self.displayBuffer[self.currentLine]))
def MoveDown(self) -> None:
if self.currentLine < len(self.displayBuffer) - 1:
self.currentLine += 1
self.currentCol = min(self.currentCol, len(self.displayBuffer[self.currentLine]))
def LoadFile(self, file_path) -> None:
"""Загрузка файла для редактирования"""
self.file_path = file_path
try:
with open(file_path, "r") as file:
self.displayBuffer = [list(line.rstrip('\n')) for line in file.readlines()]
except FileNotFoundError:
print(f"File {file_path} not found. Starting with empty buffer.")
self.displayBuffer = []
def SaveFile(self) -> None:
"""Сохранение файла"""
try:
with open(self.file_path, "w") as file:
for line in self.displayBuffer:
file.write(''.join(line) + '\n')
print(f"File {self.file_path} saved successfully.")
except Exception as e:
print(f"Error saving file: {str(e)}")