Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 16 additions & 2 deletions client/modules/IDE/components/Editor/codemirror.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useRef, useEffect } from 'react';
import { EditorView, lineNumbers as lineNumbersExt } from '@codemirror/view';
import { closeBrackets } from '@codemirror/autocomplete';
import { autocompletion, closeBrackets } from '@codemirror/autocomplete';

// TODO: Check what the v6 variants of these addons are.
// import 'codemirror/addon/search/searchcursor';
Expand All @@ -13,7 +13,8 @@ import { debounce } from 'lodash';
import {
getFileMode,
createNewFileState,
updateFileStates
updateFileStates,
AUTOCOMPLETE_OPTIONS
} from './stateUtils';
import { useEffectWithComparison } from '../../hooks/custom-hooks';
import tidyCodeWithPrettier from './tidier';
Expand Down Expand Up @@ -141,6 +142,18 @@ export default function useCodeMirror({
reconfigureEffect
});
}, [autocloseBracketsQuotes]);
useEffect(() => {
const reconfigureEffect = (fileState) =>
fileState.autocompleteCpt.reconfigure(
autocompleteHinter ? autocompletion(AUTOCOMPLETE_OPTIONS) : []
);
updateFileStates({
fileStates: fileStates.current,
cmView: cmView.current,
file,
reconfigureEffect
});
}, [autocompleteHinter]);

// Initializes the files as CodeMirror states.
function initializeDocuments() {
Expand All @@ -160,6 +173,7 @@ export default function useCodeMirror({
linewrap,
lineNumbers,
autocloseBracketsQuotes,
autocomplete: autocompleteHinter,
onUpdateLinting,
onViewUpdate
}
Expand Down
54 changes: 54 additions & 0 deletions client/modules/IDE/components/Editor/p5JavaScript.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { LanguageSupport } from '@codemirror/language';
import { javascript } from '@codemirror/lang-javascript';
import { p5Hinter } from '../../../../utils/p5-hinter';

function testCompletions(context) {
const word = context.matchBefore(/\w*/);
if (word.from === word.to && !context.explicit) return null;

function addDomNodeInfo(item) {
const itemCopy = { ...item };

if (item.p5DocPath) {
// TODO: Use the option below to add the p5 link for *all* hints.
// https://codemirror.net/docs/ref/#autocomplete.autocompletion^config.addToOptions
itemCopy.info = () => {
const domNode = document.createElement('a');
domNode.href = `https://p5js.org/reference/p5/${item.p5DocPath}`;
domNode.role = 'link';
domNode.target = '_blank';
domNode.onclick = (event) => event.stopPropagation();
domNode.innerHTML = `
<span class="hint-hidden">open ${item.label} reference</span>
<span aria-hidden="true">&#10132;</span>
`;
return {
dom: domNode,
destroy: () => {
// Cleanup logic if needed
domNode.remove();
}
};
};
}

return itemCopy;
}

const hinterWithDomNodes = p5Hinter.map(addDomNodeInfo);

return {
from: word.from,
options: hinterWithDomNodes
};
}

export default function p5JavaScript() {
const jsLang = javascript();
return new LanguageSupport(jsLang.language, [
jsLang.extension,
jsLang.language.data.of({
autocomplete: testCompletions
})
]);
}
29 changes: 25 additions & 4 deletions client/modules/IDE/components/Editor/stateUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,11 @@ import {
defaultHighlightStyle
} from '@codemirror/language';
import { highlightSelectionMatches } from '@codemirror/search';
import { closeBrackets, closeBracketsKeymap } from '@codemirror/autocomplete';
import {
autocompletion,
closeBrackets,
closeBracketsKeymap
} from '@codemirror/autocomplete';
import {
defaultKeymap,
history,
Expand All @@ -36,7 +40,6 @@ import {
abbreviationTracker
} from '@emmetio/codemirror6-plugin';

import { javascript } from '@codemirror/lang-javascript';
import { css } from '@codemirror/lang-css';
import { html } from '@codemirror/lang-html';
import { json } from '@codemirror/lang-json';
Expand All @@ -47,6 +50,7 @@ import { HTMLHint } from 'htmlhint';
import { CSSLint } from 'csslint';
import { emmetConfig } from '@emmetio/codemirror6-plugin';

import p5JavaScript from './p5JavaScript';
import tidyCodeWithPrettier from './tidier';

// ----- TODOS -----
Expand Down Expand Up @@ -83,7 +87,7 @@ function getFileLanguage(fileName) {

switch (fileMode) {
case 'javascript':
return javascript;
return p5JavaScript;
case 'css':
return css;
case 'html':
Expand Down Expand Up @@ -255,6 +259,12 @@ function getFileEmmetConfig(fileName) {
const extraKeymaps = [{ key: 'Tab', run: insertTab, shift: indentLess }];
const emmetKeymaps = [{ key: 'Tab', run: expandAbbreviation }];

export const AUTOCOMPLETE_OPTIONS = {
tooltipClass: () => 'CodeMirror-hints',
optionClass: () => 'CodeMirror-hint',
closeOnBlur: false
};

/**
* Creates a new CodeMirror editor state with configurations,
* extensions, and keymaps tailored to the file type and settings.
Expand All @@ -265,13 +275,15 @@ export function createNewFileState(filename, document, settings) {
const {
linewrap,
lineNumbers,
autocomplete,
autocloseBracketsQuotes,
onUpdateLinting,
onViewUpdate
} = settings;
const lineNumbersCpt = new Compartment();
const lineWrappingCpt = new Compartment();
const closeBracketsCpt = new Compartment();
const autocompleteCpt = new Compartment();

// Depending on the file mode, we have a different tidier function.
const mode = getFileMode(filename);
Expand All @@ -294,6 +306,9 @@ export function createNewFileState(filename, document, settings) {
lineNumbersCpt.of(lineNumbers ? lineNumbersExt() : []),
lineWrappingCpt.of(linewrap ? EditorView.lineWrapping : []),
closeBracketsCpt.of(autocloseBracketsQuotes ? closeBrackets() : []),
autocompleteCpt.of(
autocomplete ? autocompletion(AUTOCOMPLETE_OPTIONS) : []
),

// Everything below here should always be on.
history(),
Expand Down Expand Up @@ -352,7 +367,13 @@ export function createNewFileState(filename, document, settings) {
}

const cmState = EditorState.create(stateOptions);
return { cmState, lineNumbersCpt, lineWrappingCpt, closeBracketsCpt };
return {
cmState,
lineNumbersCpt,
lineWrappingCpt,
closeBracketsCpt,
autocompleteCpt
};
}

/**
Expand Down
Loading