Skip to content

Commit cb96dcb

Browse files
authored
Merge pull request #4141 from parthjadhao01/fix/p5-syntax-highlighting-cm6
fix: restored p5.js keyword highlighting for CM6 #3868
2 parents 1e21512 + 76cef81 commit cb96dcb

2 files changed

Lines changed: 68 additions & 3 deletions

File tree

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

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,57 @@
1-
import { LanguageSupport } from '@codemirror/language';
1+
import { LanguageSupport, syntaxTree } from '@codemirror/language';
22
import { javascript } from '@codemirror/lang-javascript';
3+
import { ViewPlugin, Decoration } from '@codemirror/view';
4+
import { RangeSetBuilder } from '@codemirror/state';
35
import { p5Hinter } from '../../../../utils/p5-hinter';
46
import { p5CompletionPreview } from './p5CompletionPreview';
57
import contextAwareHinter from '../../../../utils/contextAwareHinter';
8+
import {
9+
p5FunctionKeywords,
10+
p5VariableKeywords
11+
} from '../../../../utils/p5-keywords';
12+
13+
const p5Functions = new Set(Object.keys(p5FunctionKeywords));
14+
const p5Variables = new Set(Object.keys(p5VariableKeywords));
15+
16+
const p5FunctionMark = Decoration.mark({ class: 'cm-p5-function' });
17+
const p5VariableMark = Decoration.mark({ class: 'cm-p5-variable' });
18+
19+
function buildDecorations(view) {
20+
const builder = new RangeSetBuilder();
21+
view.visibleRanges.forEach(({ from, to }) => {
22+
syntaxTree(view.state).iterate({
23+
from,
24+
to,
25+
enter(node) {
26+
const isVariable = node.name === 'VariableName';
27+
const isDefinition = node.name === 'VariableDefinition';
28+
if (!isVariable && !isDefinition) return;
29+
const name = view.state.doc.sliceString(node.from, node.to);
30+
if (p5Functions.has(name)) {
31+
builder.add(node.from, node.to, p5FunctionMark);
32+
} else if (p5Variables.has(name)) {
33+
builder.add(node.from, node.to, p5VariableMark);
34+
}
35+
}
36+
});
37+
});
38+
return builder.finish();
39+
}
40+
41+
const p5Highlight = ViewPlugin.fromClass(
42+
class {
43+
constructor(view) {
44+
this.decorations = buildDecorations(view);
45+
}
46+
47+
update(update) {
48+
if (update.docChanged || update.viewportChanged) {
49+
this.decorations = buildDecorations(update.view);
50+
}
51+
}
52+
},
53+
{ decorations: (v) => v.decorations }
54+
);
655

756
function addCompletions(context) {
857
const word = context.matchBefore(/\w*/);
@@ -23,6 +72,7 @@ export default function p5JavaScript() {
2372
jsLang.language.data.of({
2473
autocomplete: addCompletions
2574
}),
26-
p5CompletionPreview()
75+
p5CompletionPreview(),
76+
p5Highlight
2777
]);
2878
}

client/styles/components/_editor.scss

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -306,7 +306,22 @@
306306
// contentSeparator, monospace, strikethrough, inserted, deleted, changed, invalid, meta,
307307
// documentMeta, annotation, processingInstruction, standard, special, macroName
308308

309-
// TODO(connie): Add p5 specific highlighting styles, like .cm-p5-function, .cm-p5-variable
309+
// CM6 uses EditorView.theme() instead of cm-s-* classes, so the p5 highlight styles
310+
// from the CM5 theme files do not apply. These rules replicate them for CM6.
311+
.cm-p5-function,
312+
.cm-p5-function .cm-variable {
313+
@include themify() {
314+
color: getThemifyVariable('highlight-style-variable-color');
315+
font-weight: bold;
316+
}
317+
}
318+
319+
.cm-p5-variable,
320+
.cm-p5-variable .cm-variable {
321+
@include themify() {
322+
color: getThemifyVariable('highlight-style-atom-color');
323+
}
324+
}
310325

311326
// Additional matching selection styling
312327
.cm-matchingBracket {

0 commit comments

Comments
 (0)