jupyter-ydoc 3.3.1__py3-none-any.whl → 3.3.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- jupyter_ydoc/_version.py +1 -1
- jupyter_ydoc/yunicode.py +39 -7
- {jupyter_ydoc-3.3.1.dist-info → jupyter_ydoc-3.3.2.dist-info}/METADATA +1 -1
- {jupyter_ydoc-3.3.1.dist-info → jupyter_ydoc-3.3.2.dist-info}/RECORD +7 -7
- {jupyter_ydoc-3.3.1.dist-info → jupyter_ydoc-3.3.2.dist-info}/WHEEL +1 -1
- {jupyter_ydoc-3.3.1.dist-info → jupyter_ydoc-3.3.2.dist-info}/entry_points.txt +0 -0
- {jupyter_ydoc-3.3.1.dist-info → jupyter_ydoc-3.3.2.dist-info}/licenses/LICENSE +0 -0
jupyter_ydoc/_version.py
CHANGED
jupyter_ydoc/yunicode.py
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
# Distributed under the terms of the Modified BSD License.
|
|
3
3
|
|
|
4
4
|
from collections.abc import Callable
|
|
5
|
+
from difflib import SequenceMatcher
|
|
5
6
|
from functools import partial
|
|
6
7
|
from typing import Any
|
|
7
8
|
|
|
@@ -9,6 +10,9 @@ from pycrdt import Awareness, Doc, Text
|
|
|
9
10
|
|
|
10
11
|
from .ybasedoc import YBaseDoc
|
|
11
12
|
|
|
13
|
+
# Heuristic threshold as recommended in difflib documentation
|
|
14
|
+
SIMILARITY_THREESHOLD = 0.6
|
|
15
|
+
|
|
12
16
|
|
|
13
17
|
class YUnicode(YBaseDoc):
|
|
14
18
|
"""
|
|
@@ -35,7 +39,7 @@ class YUnicode(YBaseDoc):
|
|
|
35
39
|
:type awareness: :class:`pycrdt.Awareness`, optional.
|
|
36
40
|
"""
|
|
37
41
|
super().__init__(ydoc, awareness)
|
|
38
|
-
self._ysource = self._ydoc.get("source", type=Text)
|
|
42
|
+
self._ysource: Text = self._ydoc.get("source", type=Text)
|
|
39
43
|
self.undo_manager.expand_scope(self._ysource)
|
|
40
44
|
|
|
41
45
|
@property
|
|
@@ -64,17 +68,45 @@ class YUnicode(YBaseDoc):
|
|
|
64
68
|
:param value: The content of the document.
|
|
65
69
|
:type value: str
|
|
66
70
|
"""
|
|
67
|
-
|
|
71
|
+
old_value = self.get()
|
|
72
|
+
if old_value == value:
|
|
68
73
|
# no-op if the values are already the same,
|
|
69
74
|
# to avoid side-effects such as cursor jumping to the top
|
|
70
75
|
return
|
|
71
76
|
|
|
72
77
|
with self._ydoc.transaction():
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
+
matcher = SequenceMatcher(a=old_value, b=value)
|
|
79
|
+
|
|
80
|
+
if (
|
|
81
|
+
matcher.real_quick_ratio() >= SIMILARITY_THREESHOLD
|
|
82
|
+
and matcher.ratio() >= SIMILARITY_THREESHOLD
|
|
83
|
+
):
|
|
84
|
+
operations = matcher.get_opcodes()
|
|
85
|
+
offset = 0
|
|
86
|
+
for tag, i1, i2, j1, j2 in operations:
|
|
87
|
+
match tag:
|
|
88
|
+
case "replace":
|
|
89
|
+
self._ysource[i1 + offset : i2 + offset] = value[j1:j2]
|
|
90
|
+
offset += (j2 - j1) - (i2 - i1)
|
|
91
|
+
case "delete":
|
|
92
|
+
del self._ysource[i1 + offset : i2 + offset]
|
|
93
|
+
offset -= i2 - i1
|
|
94
|
+
case "insert":
|
|
95
|
+
self._ysource.insert(i1 + offset, value[j1:j2])
|
|
96
|
+
offset += j2 - j1
|
|
97
|
+
case "equal":
|
|
98
|
+
pass
|
|
99
|
+
case _:
|
|
100
|
+
raise ValueError(f"Unknown tag '{tag}' in sequence matcher")
|
|
101
|
+
else:
|
|
102
|
+
# for very different strings, just replace the whole content;
|
|
103
|
+
# this avoids generating a huge number of operations
|
|
104
|
+
|
|
105
|
+
# clear document
|
|
106
|
+
self._ysource.clear()
|
|
107
|
+
# initialize document
|
|
108
|
+
if value:
|
|
109
|
+
self._ysource += value
|
|
78
110
|
|
|
79
111
|
def observe(self, callback: Callable[[str, Any], None]) -> None:
|
|
80
112
|
"""
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
jupyter_ydoc/__init__.py,sha256=itUidK7o0_wS6YcbKKIyt1su7hM3-YppQshFheTQQdw,428
|
|
2
|
-
jupyter_ydoc/_version.py,sha256=
|
|
2
|
+
jupyter_ydoc/_version.py,sha256=v4KIZUrlasa2fZGLAsEoZ179ShRb4xGFjH2KEtqJAUY,171
|
|
3
3
|
jupyter_ydoc/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
4
|
jupyter_ydoc/utils.py,sha256=yKvcuqhpylMinmjuscuZ_kY8KPEseFbwcg5K9VzYOfs,810
|
|
5
5
|
jupyter_ydoc/ybasedoc.py,sha256=c0jwhULtTNCjOYHbXhDhKaD6OJYn7hpL4hcLZWyGJsU,5115
|
|
6
6
|
jupyter_ydoc/yblob.py,sha256=JZiXQhONqFS8Cqdglx__AVeS18gyRq0yHq-AQKFPVfw,2316
|
|
7
7
|
jupyter_ydoc/yfile.py,sha256=XTMtAXDWgIOLU2KUQxkLJz2cGvSPlOxpvJc4daXCV6I,198
|
|
8
8
|
jupyter_ydoc/ynotebook.py,sha256=Xplr1x57Y6gWAU84u-Krh9_Xkn_-AN-Vte4DJY5VOfw,13452
|
|
9
|
-
jupyter_ydoc/yunicode.py,sha256=
|
|
10
|
-
jupyter_ydoc-3.3.
|
|
11
|
-
jupyter_ydoc-3.3.
|
|
12
|
-
jupyter_ydoc-3.3.
|
|
13
|
-
jupyter_ydoc-3.3.
|
|
14
|
-
jupyter_ydoc-3.3.
|
|
9
|
+
jupyter_ydoc/yunicode.py,sha256=nPNhXLT06TwxvbZL8IhFiMvRYkFoS6Hnpm1MNVlW4b4,4004
|
|
10
|
+
jupyter_ydoc-3.3.2.dist-info/METADATA,sha256=-2RhQiCsCQ_aryHI6YjqCnYIeL06LzjENOxtRduz8_8,2282
|
|
11
|
+
jupyter_ydoc-3.3.2.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
12
|
+
jupyter_ydoc-3.3.2.dist-info/entry_points.txt,sha256=lgvRG-rpsjRKf8cy7LpO7fqwwXy0sBVMCwhGOHgn4mc,164
|
|
13
|
+
jupyter_ydoc-3.3.2.dist-info/licenses/LICENSE,sha256=dqphsFbhnlzPK7Vlkc66Zc7g7PS-e1dln07GXIVpFCQ,1567
|
|
14
|
+
jupyter_ydoc-3.3.2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|