Skip to content

Commit e7502ec

Browse files
committed
folding, console input
1 parent e28fae5 commit e7502ec

20 files changed

+1101
-565
lines changed

Diff for: client/modules/CodeMirror/CodeMirrorEditor.jsx

+527
Large diffs are not rendered by default.

Diff for: client/modules/CodeMirror/CoreStyled.jsx

+4-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ import PropTypes from 'prop-types';
66

77
const StyledRoot = styled.article`
88
font-size: ${(props) => props.fontSize}px;
9+
.cm-editor.cm-focused {
10+
outline: none;
11+
}
912
`;
1013

1114
StyledRoot.propTypes = {
@@ -22,11 +25,11 @@ const ElementWithClasses = forwardRef((props, ref) => {
2225

2326
return (
2427
<StyledRoot
25-
className={classNames(`cm-s-p5-${theme}`, props.className)}
2628
fontSize={fontSize}
2729
lineWrap={lineWrap}
2830
lineNumbers={lineNumbers}
2931
{...props}
32+
className={classNames(`cm-s-p5-${theme}`, props.className)}
3033
ref={ref}
3134
/>
3235
);

Diff for: client/modules/CodeMirror/_p5-light-codemirror-theme.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ const p5LightCodemirrorTheme = EditorView.theme(
131131
'.cm-p5-variable': {
132132
color: pink
133133
},
134-
'.CodeMirror-foldmarker': {
134+
'.cm-foldPlaceholder': {
135135
backgroundColor: grays.dark,
136136
color: colors.white
137137
},

Diff for: client/modules/CodeMirror/baseTheme.js

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import { EditorView } from '@codemirror/view';
2+
import { remSize } from '../../theme';
3+
4+
const lintStyleOverrides = EditorView.baseTheme({
5+
'.cm-gutter-lint': {
6+
'& .cm-gutterElement': {
7+
padding: 0,
8+
'& .cm-lint-marker': {
9+
width: '100%',
10+
height: '100%',
11+
opacity: 0.2
12+
},
13+
'& .cm-lint-marker-error': {
14+
content: 'none',
15+
backgroundColor: 'rgb(255, 95, 82)'
16+
},
17+
'& .cm-lint-marker-warning': {
18+
content: 'none',
19+
backgroundColor: 'rgb(255, 190, 5)'
20+
}
21+
}
22+
}
23+
});
24+
// TODO: lintPoint, zig-zag underline
25+
26+
const foldStyleOverrides = EditorView.baseTheme({
27+
'.cm-foldGutter .cm-gutterElement': {
28+
cursor: 'pointer',
29+
textAlign: 'right',
30+
color: 'rgba(0,0,0,0.2)' // TODO: correct color based on theme
31+
},
32+
'.cm-foldPlaceholder': {
33+
// TODO: is currently in _editor.scss
34+
}
35+
});
36+
37+
const baseP5Theme = EditorView.baseTheme({
38+
'.cm-scroller': {
39+
fontFamily: 'Inconsolata, monospace'
40+
},
41+
'.cm-gutters': {
42+
width: remSize(48)
43+
},
44+
'.cm-gutter': {
45+
width: '100%',
46+
position: 'absolute'
47+
}
48+
});
49+
50+
export default [lintStyleOverrides, foldStyleOverrides, baseP5Theme];

Diff for: client/modules/CodeMirror/p5Autocomplete.js

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { autocompletion, completeFromList } from '@codemirror/autocomplete';
2+
import {
3+
p5FunctionKeywords,
4+
p5VariableKeywords
5+
} from '../../utils/p5-keywords';
6+
7+
const p5AutocompleteSource = completeFromList(
8+
Object.keys(p5FunctionKeywords)
9+
.map((keyword) => ({
10+
label: keyword,
11+
type: 'function',
12+
boost: 99 // TODO: detail
13+
}))
14+
.concat(
15+
Object.keys(p5VariableKeywords).map((keyword) => ({
16+
label: keyword,
17+
type: 'constant',
18+
boost: 50 // TODO: detail
19+
}))
20+
)
21+
);
22+
23+
// TODO: only if language is js!!
24+
const p5AutocompleteExt = autocompletion({
25+
override: [p5AutocompleteSource] // TODO: include native JS
26+
});
27+
28+
export default p5AutocompleteExt;

Diff for: client/modules/CodeMirror/runtimeErrors.js

+75
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
import { EditorView, Decoration } from '@codemirror/view';
2+
import {
3+
StateEffect,
4+
StateField,
5+
RangeSet,
6+
RangeSetBuilder
7+
} from '@codemirror/state';
8+
9+
export const setRuntimeErrorsEffect = StateEffect.define();
10+
11+
export const clearRuntimeErrorsEffect = StateEffect.define();
12+
13+
export const clearRuntimeErrors = (view) => {
14+
view.dispatch({
15+
effects: clearRuntimeErrorsEffect.of()
16+
});
17+
return true; // TODO: only return true if there were errors to clear.
18+
};
19+
20+
const lineError = Decoration.line({
21+
attributes: { class: 'line-runtime-error' }
22+
});
23+
24+
function createDecorations(errors, doc) {
25+
console.log('creating', errors);
26+
const builder = new RangeSetBuilder();
27+
errors.forEach((error) => {
28+
const line = doc.line(error.line);
29+
// Could add additional deco with the character range of the error.
30+
builder.add(line.from, line.to, lineError);
31+
});
32+
return builder.finish();
33+
}
34+
35+
const emptyState = () => {
36+
console.log('cleared error deco');
37+
return {
38+
lastClearedTime: Date.now(),
39+
decorations: RangeSet.empty
40+
};
41+
};
42+
43+
const runtimeErrorState = StateField.define({
44+
create() {
45+
return emptyState();
46+
},
47+
update(prevState, transaction) {
48+
let state = prevState;
49+
50+
if (transaction.docChanged) {
51+
state = emptyState();
52+
}
53+
54+
transaction.effects.forEach((effect) => {
55+
if (effect.is(setRuntimeErrorsEffect)) {
56+
state.decorations = createDecorations(
57+
[effect.value],
58+
transaction.state.doc
59+
);
60+
} else if (effect.is(clearRuntimeErrorsEffect)) {
61+
state = emptyState();
62+
}
63+
});
64+
65+
console.log('decorations', state.decorations.size);
66+
67+
return state;
68+
},
69+
provide: (field) =>
70+
EditorView.decorations.from(field, (state) => state.decorations)
71+
});
72+
73+
export default runtimeErrorState;
74+
75+
// Can also define plugin with EditorView.decorations.compute()

Diff for: client/modules/CodeMirror/util.js

+10
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,20 @@
11
/**
22
* @param {import('@codemirror/view').EditorView} editor
33
* @param {string} content
4+
* @return {void}
45
*/
56
// eslint-disable-next-line import/prefer-default-export
67
export function replaceContent(editor, content) {
78
editor.dispatch({
89
changes: { from: 0, to: editor.state.doc.length, insert: content }
910
});
1011
}
12+
13+
/**
14+
* @param {import('@codemirror/view').EditorView} editor
15+
* @return {number}
16+
*/
17+
export function cursorLineNumber(editor) {
18+
const cursor = editor.state.selection.main.head;
19+
return editor.state.doc.lineAt(cursor).number;
20+
}

Diff for: client/modules/IDE/components/Console.jsx

+1-2
Original file line numberDiff line numberDiff line change
@@ -273,9 +273,8 @@ const Console = () => {
273273
key={`${theme}-${fontSize}`}
274274
/>
275275
</div>
276-
{isExpanded && isPlaying && false && (
276+
{isExpanded && isPlaying && (
277277
<ConsoleInput
278-
theme={theme}
279278
dispatchConsoleEvent={dispatchConsoleEvent}
280279
fontSize={fontSize}
281280
/>

0 commit comments

Comments
 (0)