2025-02-04 13:16:23 +03:00
|
|
|
|
import curses
|
|
|
|
|
|
2025-02-04 13:37:47 +03:00
|
|
|
|
from views import CursesAdapter
|
|
|
|
|
from models import VimModel
|
|
|
|
|
|
2025-02-04 13:16:23 +03:00
|
|
|
|
class EditController:
|
2025-02-04 13:37:47 +03:00
|
|
|
|
def __init__(self, model: VimModel, view: CursesAdapter):
|
2025-02-04 13:16:23 +03:00
|
|
|
|
self.model = model
|
|
|
|
|
self.view = view
|
|
|
|
|
|
|
|
|
|
def handle_input(self, symbolCode):
|
|
|
|
|
"""Обработка ввода пользователя"""
|
|
|
|
|
if symbolCode == 27: # EXIT
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
elif symbolCode == curses.KEY_LEFT:
|
2025-02-04 13:37:47 +03:00
|
|
|
|
self.model.MoveLeft()
|
2025-02-04 13:16:23 +03:00
|
|
|
|
|
|
|
|
|
elif symbolCode == curses.KEY_RIGHT:
|
2025-02-04 13:37:47 +03:00
|
|
|
|
self.model.MoveRight()
|
2025-02-04 13:16:23 +03:00
|
|
|
|
|
|
|
|
|
elif symbolCode == curses.KEY_UP:
|
2025-02-04 13:37:47 +03:00
|
|
|
|
self.model.MoveUp()
|
2025-02-04 13:16:23 +03:00
|
|
|
|
|
|
|
|
|
elif symbolCode == curses.KEY_DOWN:
|
2025-02-04 13:37:47 +03:00
|
|
|
|
self.model.MoveDown()
|
2025-02-04 13:16:23 +03:00
|
|
|
|
|
|
|
|
|
# BACKSPACE
|
2025-02-04 13:37:47 +03:00
|
|
|
|
elif symbolCode in (127, 8): # Backspace
|
2025-02-04 13:16:23 +03:00
|
|
|
|
if self.model.currentCol > 0: # Если символ существует в текущей строке
|
|
|
|
|
self.model.currentCol -= 1
|
|
|
|
|
del self.model.displayBuffer[self.model.currentLine][self.model.currentCol] # Удаляем символ
|
|
|
|
|
elif self.model.currentLine > 0: # Если текущая строка не первая
|
|
|
|
|
# Объединяем текущую строку с предыдущей
|
|
|
|
|
prev_line_length = len(self.model.displayBuffer[self.model.currentLine - 1])
|
|
|
|
|
self.model.displayBuffer[self.model.currentLine - 1].extend(self.model.displayBuffer[self.model.currentLine])
|
|
|
|
|
del self.model.displayBuffer[self.model.currentLine]
|
|
|
|
|
self.model.currentLine -= 1
|
|
|
|
|
self.model.currentCol = prev_line_length # Переходим в конец предыдущей строки
|
|
|
|
|
|
|
|
|
|
# ENTER
|
|
|
|
|
elif symbolCode == 10: # Enter
|
|
|
|
|
# Разделяем текущую строку на две части
|
|
|
|
|
new_line = self.model.displayBuffer[self.model.currentLine][self.model.currentCol:]
|
|
|
|
|
self.model.displayBuffer[self.model.currentLine] = self.model.displayBuffer[self.model.currentLine][:self.model.currentCol]
|
|
|
|
|
self.model.currentLine += 1 # Переходим на следующую строку
|
|
|
|
|
self.model.displayBuffer.insert(self.model.currentLine, new_line) # Вставляем новую строку
|
|
|
|
|
self.model.currentCol = 0 # Сбрасываем индекс колонки
|
|
|
|
|
|
|
|
|
|
# Сохранение файла (Ctrl+S)
|
|
|
|
|
elif symbolCode == 19: # Ctrl+S
|
|
|
|
|
result = self.model.save_file()
|
|
|
|
|
if result is True:
|
|
|
|
|
self.view.screen.addstr(self.view.lines - 1, 0, f"File {self.model.file_path} saved successfully.")
|
|
|
|
|
else:
|
|
|
|
|
self.view.screen.addstr(self.view.lines - 1, 0, f"Error saving file: {result}")
|
|
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
if self.model.currentCol <= len(self.model.displayBuffer[self.model.currentLine]): # проверяем, не превышает ли индекс колонки длину строки
|
|
|
|
|
self.model.displayBuffer[self.model.currentLine].insert(self.model.currentCol, chr(symbolCode))
|
|
|
|
|
self.model.currentCol += 1
|
|
|
|
|
|
|
|
|
|
# Прокрутка экрана
|
|
|
|
|
if self.model.currentLine < self.model.scrollY:
|
|
|
|
|
self.model.scrollY = self.model.currentLine
|
|
|
|
|
elif self.model.currentLine >= self.model.scrollY + self.view.lines - 1:
|
|
|
|
|
self.model.scrollY = self.model.currentLine - self.view.lines + 2
|
|
|
|
|
|
|
|
|
|
if self.model.currentCol < self.model.scrollX:
|
|
|
|
|
self.model.scrollX = self.model.currentCol
|
|
|
|
|
elif self.model.currentCol >= self.model.scrollX + self.view.cols:
|
|
|
|
|
self.model.scrollX = self.model.currentCol - self.view.cols + 1
|
|
|
|
|
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def render(self):
|
|
|
|
|
"""Отрисовка текущего состояния"""
|
|
|
|
|
self.view.screen.clear()
|
|
|
|
|
|
|
|
|
|
# Отображение видимой части текста
|
|
|
|
|
for i in range(self.view.lines - 1):
|
|
|
|
|
if i + self.model.scrollY < len(self.model.displayBuffer):
|
|
|
|
|
line = ''.join(self.model.displayBuffer[i + self.model.scrollY])
|
|
|
|
|
if self.model.scrollX < len(line):
|
|
|
|
|
self.view.SetString(i, 0, line[self.model.scrollX:self.model.scrollX + self.view.cols])
|
|
|
|
|
else:
|
|
|
|
|
self.view.SetString(i, 0, '')
|
|
|
|
|
else:
|
|
|
|
|
self.view.SetString(i, 0, '')
|
|
|
|
|
|
|
|
|
|
# Отображение панели режима
|
|
|
|
|
self.view.EditModeBar(self.model.currentLine, len(self.model.displayBuffer), self.model.file_path)
|
|
|
|
|
|
|
|
|
|
# Установка курсора
|
|
|
|
|
self.view.SetCursor(self.model.currentLine - self.model.scrollY, self.model.currentCol - self.model.scrollX)
|
|
|
|
|
self.view.Refresh()
|