Skip to content

Commit 0ac83c7

Browse files
committed
update editor modal when code changes in a colab session
1 parent 6564a64 commit 0ac83c7

File tree

1 file changed

+58
-4
lines changed

1 file changed

+58
-4
lines changed

src/components/popups-etc/editor-modal.tsx

+58-4
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,15 @@ import { useEffect } from 'preact/hooks'
33
import { IoClose } from 'react-icons/io5'
44
import tinykeys from 'tinykeys'
55
import { usePopupCloseClick } from '../../lib/utils/popup-close-click'
6-
import { codeMirror, editors, openEditor } from '../../lib/state'
6+
import { codeMirror, editors, openEditor, codeMirrorEditorText, _foldRanges, _widgets } from '../../lib/state'
77
import styles from './editor-modal.module.css'
8+
import levenshtein from 'js-levenshtein'
9+
import { runGameHeadless } from '../../lib/engine'
810

911
export default function EditorModal() {
1012
const Content = openEditor.value ? editors[openEditor.value.kind].modalContent : () => null
1113
const text = useSignal(openEditor.value?.text ?? '')
1214

13-
// Sync code changes with editor text
1415
useSignalEffect(() => {
1516
if (openEditor.value) text.value = openEditor.value.text
1617
})
@@ -29,7 +30,7 @@ export default function EditorModal() {
2930
insert: _text
3031
}
3132
})
32-
33+
3334
openEditor.value = {
3435
..._openEditor,
3536
text: _text,
@@ -40,6 +41,59 @@ export default function EditorModal() {
4041
}
4142
})
4243

44+
// the challenge now is making the editor keep track of what map editor it's currently focused on and streaming the changes in the map editor
45+
// it's tricky because maps can grow and shrink
46+
47+
useEffect(() => {
48+
// just do this to sync the editor text with the code mirror text
49+
50+
const code = codeMirror.value?.state.doc.toString() ?? '';
51+
const levenshtainDistances = _foldRanges.value.map((foldRange, foldRangeIndex) => {
52+
const widgetKind = _widgets.value[foldRangeIndex]?.value.spec.widget.props.kind;
53+
54+
// if the widget kind is not the same as the open editor kind, don't do anything
55+
if (widgetKind !== openEditor.value?.kind) return -1;
56+
57+
const theCode = code.slice(foldRange?.from, foldRange?.to);
58+
59+
const distance = levenshtein(text.value, theCode)
60+
return distance;
61+
});
62+
63+
64+
65+
// if (levenshtainDistances.length === 0) alert(`You are currently editing a deleted ${openEditor.value?.kind}`);
66+
if (levenshtainDistances.length === 0) return;
67+
68+
// compute the index of the min distance
69+
let indexOfMinDistance = 0;
70+
levenshtainDistances.forEach((distance, didx) => {
71+
if (levenshtainDistances[indexOfMinDistance]! < 0) indexOfMinDistance = didx;
72+
const min = levenshtainDistances[indexOfMinDistance]!;
73+
if (distance >= 0 && distance <= min) indexOfMinDistance = didx;
74+
});
75+
76+
// update the open editor if the index is not -1
77+
if (indexOfMinDistance !== -1) {
78+
const editRange = _foldRanges.value[indexOfMinDistance]
79+
const openEditorCode = code.slice(editRange?.from, editRange?.to)
80+
81+
// the map editor needs to get the bitmaps after running the code
82+
if (openEditor.value?.kind === 'map') runGameHeadless(code ?? '');
83+
84+
openEditor.value = {
85+
...openEditor.value,
86+
editRange: {
87+
from: editRange!.from,
88+
to: editRange!.to
89+
},
90+
text: openEditorCode
91+
}
92+
}
93+
94+
}, [codeMirrorEditorText.value]);
95+
96+
4397
usePopupCloseClick(styles.content!, () => openEditor.value = null, !!openEditor.value)
4498
useEffect(() => tinykeys(window, {
4599
'Escape': () => openEditor.value = null
@@ -54,4 +108,4 @@ export default function EditorModal() {
54108
</div>
55109
</div>
56110
)
57-
}
111+
}

0 commit comments

Comments
 (0)