Skip to content

Commit 5b71a6c

Browse files
committed
moves document management to the cm file
1 parent 36f1fa5 commit 5b71a6c

File tree

2 files changed

+59
-56
lines changed

2 files changed

+59
-56
lines changed

client/modules/IDE/components/Editor/codemirror.js

+53
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,11 @@ import 'codemirror-colorpicker';
2727
import { debounce } from 'lodash';
2828
import emmet from '@emmetio/codemirror-plugin';
2929

30+
import { useEffectWithComparison } from '../../hooks/custom-hooks';
3031
import { metaKey } from '../../../../utils/metaKey';
3132
import { showHint } from './hinter';
3233
import tidyCode from './tidier';
34+
import getFileMode from './utils';
3335

3436
const INDENTATION_AMOUNT = 2;
3537

@@ -45,6 +47,7 @@ export default function useCodeMirror({
4547
hideRuntimeErrorWarning,
4648
updateFileContent,
4749
file,
50+
files,
4851
autorefresh,
4952
isPlaying,
5053
clearConsole,
@@ -54,6 +57,7 @@ export default function useCodeMirror({
5457
onUpdateLinting
5558
}) {
5659
const cmInstance = useRef();
60+
const docs = useRef();
5761

5862
function onKeyUp() {
5963
const lineNumber = parseInt(cmInstance.current.getCursor().line + 1, 10);
@@ -189,6 +193,55 @@ export default function useCodeMirror({
189193
cmInstance.current.setOption('autoCloseBrackets', autocloseBracketsQuotes);
190194
}, [autocloseBracketsQuotes]);
191195

196+
const initializeDocuments = () => {
197+
docs.current = {};
198+
files.forEach((currentFile) => {
199+
if (currentFile.name !== 'root') {
200+
docs.current[currentFile.id] = CodeMirror.Doc(
201+
currentFile.content,
202+
getFileMode(currentFile.name)
203+
);
204+
}
205+
});
206+
};
207+
208+
useEffect(() => {
209+
initializeDocuments();
210+
}, [files]);
211+
212+
useEffectWithComparison(
213+
(_, prevProps) => {
214+
const fileMode = getFileMode(file.name);
215+
if (fileMode === 'javascript') {
216+
// Define the new Emmet configuration based on the file mode
217+
const emmetConfig = {
218+
preview: ['html'],
219+
markTagPairs: false,
220+
autoRenameTags: true
221+
};
222+
cmInstance.current.setOption('emmet', emmetConfig);
223+
}
224+
const oldDoc = cmInstance.current.swapDoc(docs.current[file.id]);
225+
if (prevProps?.file) {
226+
docs.current[prevProps.file.id] = oldDoc;
227+
}
228+
cmInstance.current.focus();
229+
230+
if (!prevProps?.unsavedChanges) {
231+
setTimeout(() => setUnsavedChanges(false), 400);
232+
}
233+
234+
for (let i = 0; i < cmInstance.current.lineCount(); i += 1) {
235+
cmInstance.current.removeLineClass(
236+
i,
237+
'background',
238+
'line-runtime-error'
239+
);
240+
}
241+
},
242+
[file.id]
243+
);
244+
192245
function teardownCodeMirror() {
193246
cmInstance.current.off('keyup', onKeyUp);
194247
cmInstance.current.off('change', debouncedOnChange);

client/modules/IDE/components/Editor/index.jsx

+6-56
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import PropTypes from 'prop-types';
22
import React, { useCallback, useEffect, useRef, useState } from 'react';
3-
import CodeMirror from 'codemirror';
43
import { withTranslation } from 'react-i18next';
54
import StackTrace from 'stacktrace-js';
65

@@ -36,7 +35,6 @@ import { FolderIcon } from '../../../../common/icons';
3635
import IconButton from '../../../../common/IconButton';
3736

3837
import { hideHinter } from './hinter';
39-
import getFileMode from './utils';
4038
import tidyCode from './tidier';
4139
import useCodeMirror from './codemirror';
4240
import { useEffectWithComparison } from '../../hooks/custom-hooks';
@@ -50,7 +48,6 @@ function Editor({
5048
lineNumbers,
5149
closeProjectOptions,
5250
setSelectedFile,
53-
unsavedChanges,
5451
setUnsavedChanges,
5552
lintMessages,
5653
lintWarning,
@@ -75,7 +72,6 @@ function Editor({
7572
}) {
7673
const [currentLine, setCurrentLine] = useState(1);
7774
const beep = useRef();
78-
const docs = useRef();
7975

8076
const updateLintingMessageAccessibility = debounce((annotations) => {
8177
clearLintMessage();
@@ -89,6 +85,8 @@ function Editor({
8985
}
9086
}, 2000);
9187

88+
// The useCodeMirror hook manages CodeMirror state and returns
89+
// a reference to the actual CM instance.
9290
const {
9391
setupCodeMirrorOnContainerMounted,
9492
teardownCodeMirror,
@@ -105,6 +103,7 @@ function Editor({
105103
hideRuntimeErrorWarning,
106104
updateFileContent,
107105
file,
106+
files,
108107
autorefresh,
109108
isPlaying,
110109
clearConsole,
@@ -124,22 +123,11 @@ function Editor({
124123
getContent
125124
});
126125

127-
const initializeDocuments = () => {
128-
docs.current = {};
129-
files.forEach((currentFile) => {
130-
if (currentFile.name !== 'root') {
131-
docs.current[currentFile.id] = CodeMirror.Doc(
132-
currentFile.content,
133-
getFileMode(currentFile.name)
134-
);
135-
}
136-
});
137-
};
138-
139-
// Component did mount
126+
// When the CM container div mounts, we set up CodeMirror.
140127
const onContainerMounted = useCallback(setupCodeMirrorOnContainerMounted, []);
141128

142-
// Component did mount
129+
// This is acting as a "componentDidMount" call where it runs once
130+
// at the start and never again. It also provides a cleanup function.
143131
useEffect(() => {
144132
beep.current = new Audio(beepUrl);
145133

@@ -156,43 +144,6 @@ function Editor({
156144
};
157145
}, []);
158146

159-
useEffect(() => {
160-
initializeDocuments();
161-
}, [files]);
162-
163-
useEffectWithComparison(
164-
(_, prevProps) => {
165-
const fileMode = getFileMode(file.name);
166-
if (fileMode === 'javascript') {
167-
// Define the new Emmet configuration based on the file mode
168-
const emmetConfig = {
169-
preview: ['html'],
170-
markTagPairs: false,
171-
autoRenameTags: true
172-
};
173-
cmInstance.current.setOption('emmet', emmetConfig);
174-
}
175-
const oldDoc = cmInstance.current.swapDoc(docs.current[file.id]);
176-
if (prevProps?.file) {
177-
docs.current[prevProps.file.id] = oldDoc;
178-
}
179-
cmInstance.current.focus();
180-
181-
if (!prevProps?.unsavedChanges) {
182-
setTimeout(() => setUnsavedChanges(false), 400);
183-
}
184-
185-
for (let i = 0; i < cmInstance.current.lineCount(); i += 1) {
186-
cmInstance.current.removeLineClass(
187-
i,
188-
'background',
189-
'line-runtime-error'
190-
);
191-
}
192-
},
193-
[file.id]
194-
);
195-
196147
useEffect(() => {
197148
// close the hinter window once the preference is turned off
198149
if (!autocompleteHinter) hideHinter(cmInstance.current);
@@ -358,7 +309,6 @@ Editor.propTypes = {
358309
autorefresh: PropTypes.bool.isRequired,
359310
isPlaying: PropTypes.bool.isRequired,
360311
theme: PropTypes.string.isRequired,
361-
unsavedChanges: PropTypes.bool.isRequired,
362312
files: PropTypes.arrayOf(
363313
PropTypes.shape({
364314
id: PropTypes.string.isRequired,

0 commit comments

Comments
 (0)