2025-02-10 20:57:28 +03:00
|
|
|
|
from abc import ABC, abstractmethod
|
2025-02-11 16:13:36 +03:00
|
|
|
|
from adapter import CursesAdapter
|
2025-02-10 20:57:28 +03:00
|
|
|
|
import mvc.models
|
2025-02-11 13:49:08 +03:00
|
|
|
|
from mystring import MyString as MyString
|
2025-02-04 20:01:25 +03:00
|
|
|
|
|
2025-02-11 16:13:36 +03:00
|
|
|
|
class Observer(ABC):
|
2025-02-10 20:57:28 +03:00
|
|
|
|
@abstractmethod
|
2025-02-11 16:13:36 +03:00
|
|
|
|
def Update(self) -> None:
|
2025-02-10 20:57:28 +03:00
|
|
|
|
pass
|
2025-02-04 20:01:25 +03:00
|
|
|
|
|
2025-02-10 20:57:28 +03:00
|
|
|
|
class VimView(Observer):
|
2025-02-05 00:24:14 +03:00
|
|
|
|
def __init__(self, adapter: CursesAdapter) -> None:
|
|
|
|
|
self.curses_adapter = adapter
|
2025-02-10 20:57:28 +03:00
|
|
|
|
self.model = None
|
|
|
|
|
|
2025-02-11 16:13:36 +03:00
|
|
|
|
def SetModel(self, model: mvc.models.VimModel) -> None:
|
2025-02-10 20:57:28 +03:00
|
|
|
|
self.model = model
|
|
|
|
|
model.attach(self)
|
|
|
|
|
|
2025-02-11 16:13:36 +03:00
|
|
|
|
def Update(self) -> None:
|
2025-02-10 20:57:28 +03:00
|
|
|
|
self.Render(
|
|
|
|
|
self.model.displayBuffer,
|
|
|
|
|
self.model.currentLine,
|
|
|
|
|
self.model.currentCol,
|
|
|
|
|
self.model.scrollX,
|
|
|
|
|
self.model.scrollY,
|
|
|
|
|
self.model.ModeBar(),
|
|
|
|
|
self.model.showLineNumbers
|
|
|
|
|
)
|
2025-02-04 20:01:25 +03:00
|
|
|
|
|
|
|
|
|
def Render(self,
|
2025-02-11 13:49:08 +03:00
|
|
|
|
displayBuffer: list[MyString],
|
2025-02-05 22:21:14 +03:00
|
|
|
|
currentLine: int, currentCol: int,
|
|
|
|
|
scrollX: int, scrollY: int,
|
|
|
|
|
modeBarData: str,
|
2025-02-11 16:13:36 +03:00
|
|
|
|
show_line_numbers: bool = False) -> None:
|
2025-02-04 20:01:25 +03:00
|
|
|
|
"""Отрисовка текущего состояния"""
|
|
|
|
|
|
|
|
|
|
self.curses_adapter.screen.clear()
|
|
|
|
|
|
2025-02-05 22:21:14 +03:00
|
|
|
|
# Ширина нумерации строк (6 символов + 1 пробел)
|
|
|
|
|
line_number_width = 7 if show_line_numbers else 0
|
|
|
|
|
|
2025-02-04 20:01:25 +03:00
|
|
|
|
# Отображение видимой части текста
|
|
|
|
|
for i in range(self.curses_adapter.lines - 1):
|
|
|
|
|
if i + scrollY < len(displayBuffer):
|
2025-02-11 13:49:08 +03:00
|
|
|
|
line = displayBuffer[i + scrollY].data()
|
2025-02-05 22:21:14 +03:00
|
|
|
|
# Если нужно отображать номера строк, добавляем их перед текстом
|
|
|
|
|
if show_line_numbers:
|
|
|
|
|
line_number = f"{i + scrollY + 1:6} " # 6 символов на номер строки
|
|
|
|
|
# Выводим номер строки фиолетовым цветом
|
2025-02-05 23:46:41 +03:00
|
|
|
|
self.curses_adapter.SetColorString(i, 0, line_number, self.curses_adapter.colorPairs[0])
|
2025-02-05 22:21:14 +03:00
|
|
|
|
|
|
|
|
|
# Выводим текст с учетом прокрутки и ширины нумерации
|
|
|
|
|
visible_text_start = scrollX # Начало видимой части текста
|
|
|
|
|
visible_text_end = scrollX + self.curses_adapter.cols - line_number_width # Конец видимой части текста
|
|
|
|
|
visible_text = line[visible_text_start:visible_text_end]
|
|
|
|
|
self.curses_adapter.SetString(i, line_number_width, visible_text)
|
2025-02-04 20:01:25 +03:00
|
|
|
|
else:
|
|
|
|
|
self.curses_adapter.SetString(i, 0, '')
|
|
|
|
|
|
|
|
|
|
# Обновление панели режима
|
|
|
|
|
self.SetModeBar(modeBarData)
|
|
|
|
|
|
2025-02-05 22:21:14 +03:00
|
|
|
|
# Установка курсора с учетом прокрутки и нумерации строк
|
2025-02-04 20:01:25 +03:00
|
|
|
|
cursor_x = currentLine - scrollY
|
2025-02-05 22:21:14 +03:00
|
|
|
|
cursor_y = currentCol - scrollX + line_number_width
|
2025-02-04 20:01:25 +03:00
|
|
|
|
|
|
|
|
|
# Проверка, чтобы курсор не вышел за пределы экрана
|
|
|
|
|
if 0 <= cursor_x < self.curses_adapter.lines - 1 and 0 <= cursor_y < self.curses_adapter.cols:
|
|
|
|
|
self.curses_adapter.SetCursor(cursor_x, cursor_y)
|
|
|
|
|
|
|
|
|
|
self.curses_adapter.Refresh()
|
|
|
|
|
|
2025-02-11 16:13:36 +03:00
|
|
|
|
def SetModeBar(self, modeBarData: str) -> None:
|
2025-02-04 20:01:25 +03:00
|
|
|
|
"""Print edit mode information panel"""
|
2025-02-05 00:24:14 +03:00
|
|
|
|
if len(modeBarData) > self.curses_adapter.cols - 1:
|
2025-02-05 22:21:14 +03:00
|
|
|
|
scrollX = len(modeBarData) - self.curses_adapter.cols
|
2025-02-05 23:46:41 +03:00
|
|
|
|
self.curses_adapter.SetColorString(self.curses_adapter.lines - 1, 0,
|
|
|
|
|
modeBarData[scrollX + 1:], self.curses_adapter.colorPairs[1])
|
2025-02-05 00:24:14 +03:00
|
|
|
|
else:
|
2025-02-05 23:46:41 +03:00
|
|
|
|
self.curses_adapter.SetColorString(self.curses_adapter.lines - 1, 0,
|
|
|
|
|
modeBarData, self.curses_adapter.colorPairs[1])
|