Skip to content

Commit 3740cd8

Browse files
Support undo manager expand_scope (#128)
1 parent 611b481 commit 3740cd8

File tree

4 files changed

+53
-0
lines changed

4 files changed

+53
-0
lines changed

python/pycrdt/_pycrdt.pyi

+3
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,9 @@ class Map:
176176
class UndoManager:
177177
"""Undo manager."""
178178

179+
def expand_scope(self, scope: Text | Array | Map) -> None:
180+
"""Extends a list of shared types tracked by current undo manager by a given scope."""
181+
179182
def can_undo(self) -> bool:
180183
"""Whether there is any change to undo."""
181184

python/pycrdt/_undo.py

+4
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ def __init__(self, scope: BaseType, capture_timeout_millis: int = 500) -> None:
1010
method = getattr(undo_manager, f"from_{scope.type_name}")
1111
self._undo_manager = method(scope.doc._doc, scope._integrated, capture_timeout_millis)
1212

13+
def expand_scope(self, scope: BaseType) -> None:
14+
method = getattr(self._undo_manager, f"expand_scope_{scope.type_name}")
15+
method(scope._integrated)
16+
1317
def can_undo(self) -> bool:
1418
return self._undo_manager.can_undo()
1519

src/undo.rs

+12
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,18 @@ impl UndoManager {
4848
UndoManager { undo_manager: Some(undo_manager) }
4949
}
5050

51+
pub fn expand_scope_text(&mut self, scope: &Text) {
52+
self.undo_manager.as_mut().unwrap().expand_scope(&scope.text);
53+
}
54+
55+
pub fn expand_scope_array(&mut self, scope: &Array) {
56+
self.undo_manager.as_mut().unwrap().expand_scope(&scope.array);
57+
}
58+
59+
pub fn expand_scope_map(&mut self, scope: &Map) {
60+
self.undo_manager.as_mut().unwrap().expand_scope(&scope.map);
61+
}
62+
5163
pub fn can_undo(&mut self) -> bool {
5264
self.undo_manager.as_ref().unwrap().can_undo()
5365
}

tests/test_undo.py

+34
Original file line numberDiff line numberDiff line change
@@ -72,3 +72,37 @@ def test_map_undo():
7272
data.update(val2)
7373
assert data.to_py() == val3
7474
undo_redo(data, undo_manager, val0, val1, val3)
75+
76+
77+
def test_scopes():
78+
doc = Doc()
79+
doc["text"] = text = Text()
80+
doc["array"] = array = Array()
81+
doc["map"] = map = Map()
82+
undo_manager = UndoManager(text, capture_timeout_millis=0)
83+
84+
text += "Hello"
85+
text += ", World!"
86+
assert str(text) == "Hello, World!"
87+
undo_manager.undo()
88+
assert str(text) == "Hello"
89+
90+
array.append(0)
91+
assert array.to_py() == [0]
92+
undo_manager.undo()
93+
assert array.to_py() == [0]
94+
undo_manager.expand_scope(array)
95+
array.append(1)
96+
assert array.to_py() == [0, 1]
97+
undo_manager.undo()
98+
assert array.to_py() == [0]
99+
100+
map["key0"] = "val0"
101+
assert map.to_py() == {"key0": "val0"}
102+
undo_manager.undo()
103+
assert map.to_py() == {"key0": "val0"}
104+
undo_manager.expand_scope(map)
105+
map["key1"] = "val1"
106+
assert map.to_py() == {"key0": "val0", "key1": "val1"}
107+
undo_manager.undo()
108+
assert map.to_py() == {"key0": "val0"}

0 commit comments

Comments
 (0)