VIM-like-text-editor/controllers.py

105 lines
5.5 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.

import curses
class EditController:
def __init__(self, model, view):
self.model = model
self.view = view
def handle_input(self, symbolCode):
"""Обработка ввода пользователя"""
if symbolCode == 27: # EXIT
return False
elif symbolCode == curses.KEY_LEFT:
if self.model.currentCol > 0:
self.model.currentCol -= 1
elif self.model.currentLine > 0:
self.model.currentLine -= 1
self.model.currentCol = len(self.model.displayBuffer[self.model.currentLine])
elif symbolCode == curses.KEY_RIGHT:
if self.model.currentCol < len(self.model.displayBuffer[self.model.currentLine]):
self.model.currentCol += 1
elif self.model.currentLine < len(self.model.displayBuffer) - 1:
self.model.currentLine += 1
self.model.currentCol = 0
elif symbolCode == curses.KEY_UP:
if self.model.currentLine > 0:
self.model.currentLine -= 1
self.model.currentCol = min(self.model.currentCol, len(self.model.displayBuffer[self.model.currentLine]))
elif symbolCode == curses.KEY_DOWN:
if self.model.currentLine < len(self.model.displayBuffer) - 1:
self.model.currentLine += 1
self.model.currentCol = min(self.model.currentCol, len(self.model.displayBuffer[self.model.currentLine]))
# BACKSPACE
elif symbolCode in (127, 8): # Backspace
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()