aboutsummaryrefslogtreecommitdiff
path: root/python/src/types/state.py
blob: ca048aac2a05e1c0175ef17e284f1cf2d8f4f0a5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
from dataclasses import dataclass
from pathlib import Path

from .buffer import Buffer
from .selection import Selection


class StateChange:
    def invert(self) -> "StateChange" | None:
        return None


@dataclass
class SetCurrentSelection(StateChange):
    old_selection: Selection
    new_selection: Selection

    def invert(self) -> "SetCurrentSelection":
        return SetCurrentSelection(
            old_selection=self.new_selection,
            new_selection=self.old_selection,
        )


@dataclass
class SetCurrentBuffer(StateChange):
    old_buffer: Buffer
    new_buffer: Buffer

    def invert(self) -> "SetCurrentBuffer":
        return SetCurrentBuffer(
            old_buffer=self.new_buffer,
            new_buffer=self.old_buffer,
        )


@dataclass
class ModifyBuffer(StateChange):
    buffer: Buffer
    old_start: int
    old_end: int
    old_content: str
    new_content: str

    def invert(self) -> None:
        # TODO: implement
        return None


@dataclass
class CreateBuffer(StateChange):
    buffer: Buffer
    file: Path | None


@dataclass
class DeleteBuffer(StateChange):
    buffer: Buffer


@dataclass
class EditorState:
    current_buffer: Buffer
    current_selection: Selection
    buffer_to_file: dict[Buffer, Path | None]
    history: list[StateChange]

    def commit(self, change: StateChange) -> "EditorState":
        match change:
            case SetCurrentSelection(_, new_selection):
                self.current_selection = new_selection
            case SetCurrentBuffer(_, new_buffer):
                self.current_buffer = new_buffer
            case ModifyBuffer(buffer, old_start, old_end, _, new_content):
                self.current_buffer.content = (
                    self.current_buffer.content[:old_start]
                    + new_content
                    + self.current_buffer.content[old_end:]
                )
            case CreateBuffer(buffer, file):
                self.buffer_to_file[buffer] = file
            case DeleteBuffer(buffer):
                del self.buffer_to_file[buffer]
        self.history.append(change)
        return self

    def commit_changes(self, changes: list[StateChange]) -> "EditorState":
        for change in changes:
            self.commit(change)
        return self


Result = tuple[Selection, list[StateChange]]