Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
a79c2f1
context-aware hinter code
kammeows Jun 5, 2025
3e84dd5
Merge pull request #1 from kammeows/Branch_Kamakshi
kammeows Jun 5, 2025
5fc1c64
Merge branch 'processing:develop' into develop
kammeows Jun 5, 2025
9c4bc52
context-aware hinter code
kammeows Jun 5, 2025
cf71058
parse code with babel and warn when blacklisted function focused
kammeows Jun 8, 2025
e8bf752
updated the hinter to suggest class methods
kammeows Jun 13, 2025
819b9cb
Merge pull request #2 from kammeows/Branch_Kamakshi
kammeows Jun 13, 2025
5559967
user-defined context-aware variables, functions & classes suggestion
kammeows Jun 25, 2025
2c132e6
Merge branch 'processing:develop' into develop
kammeows Jun 25, 2025
761657a
Merge pull request #3 from kammeows/Branch_Kamakshi
kammeows Jun 25, 2025
b0ec598
added listOfAllFunctions.json
kammeows Jun 28, 2025
87d89a5
Merge pull request #4 from kammeows/Branch_Kamakshi
kammeows Jun 28, 2025
d28914a
implement context aware renaming + fixed bug to show inline hint sugg…
kammeows Jul 9, 2025
b0a0feb
fixed autocomplete bug
kammeows Jul 9, 2025
5120dce
bug fix: ensure renaming doesnt happen with commented code and keywords
kammeows Jul 12, 2025
bdb7d86
minor changes to ensure all features work smoothly
kammeows Jul 16, 2025
e3c7f18
fixed a minor bug in autocomplete method suggestions
kammeows Jul 17, 2025
093dccc
Merge pull request #5 from kammeows/Branch_Kamakshi
kammeows Jul 17, 2025
ea39d0e
implement jump to definition basic functionality
kammeows Jul 22, 2025
a627fde
Merge branch 'Branch_Kamakshi' of https://github.com/kammeows/p5.js-w…
kammeows Jul 24, 2025
990712a
Merge branch 'develop' into Branch_Kamakshi
kammeows Jul 24, 2025
b006d5d
Merge pull request #8 from kammeows/Branch_Kamakshi
kammeows Jul 24, 2025
f94b2fb
remove console statements
kammeows Jul 24, 2025
a7229da
add descriptive names for files & add a readme for new changes
kammeows Jul 25, 2025
f30b884
fix autocomplete and renaming behavior for same var and func name
kammeows Jul 28, 2025
01454d0
fix autocomplete suggestions behavior for same function and variable …
kammeows Jul 29, 2025
a67e89d
fix renaming behavior with same function name in different contexts
kammeows Jul 29, 2025
ce4ae68
fix logic for correct behavior of jump to definition with same functi…
kammeows Jul 30, 2025
2415953
fix renaming behavior
kammeows Aug 9, 2025
1779145
implement screen reader behavior for context aware renaming and jump …
kammeows Aug 9, 2025
c50566f
fix local renaming bug
kammeows Aug 10, 2025
88a9c65
Merge branch 'develop' of https://github.com/processing/p5.js-web-edi…
kammeows Aug 10, 2025
9172902
Merge pull request #10 from kammeows/processing-develop
kammeows Aug 10, 2025
0665cc6
add jump to definition from one file to another file
kammeows Aug 11, 2025
293b49e
modify jump to definition to work according to runtime behavior
kammeows Aug 13, 2025
842c46b
renaming logic for classes
kammeows Aug 17, 2025
a0569d0
fixes on renaming logic for classes and methods along with other mino…
kammeows Aug 18, 2025
fdcd37a
final edits to clean the code
kammeows Aug 23, 2025
26442f4
Merge branch 'develop' into develop
kammeows Aug 23, 2025
ca26d11
Merge branch 'develop' of https://github.com/kammeows/p5.js-web-edito…
kammeows Aug 23, 2025
77465e9
update files to ensure consistency and fix test errors
kammeows Aug 23, 2025
078b882
fix testing issues
kammeows Aug 24, 2025
63a384a
moved majority of the code into client/utils along with other minor c…
kammeows Aug 30, 2025
87dc886
update package.json
kammeows Aug 30, 2025
0d5121d
rename key trigger for mac users, add renaming in keyboard shortcuts,…
kammeows Sep 20, 2025
21ed2fa
minor fixes in renaming logic
kammeows Sep 20, 2025
4b61b10
Merge branch 'develop' into kammeows/develop
raclim Sep 23, 2025
2830289
add back in missing chnage from merging in develop
raclim Sep 23, 2025
c2a2410
use named export for isMac to fix tests
raclim Sep 23, 2025
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
26 changes: 16 additions & 10 deletions client/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -72,13 +72,19 @@ const App = () => (
</div>
);

render(
<Provider store={store}>
<ThemeProvider>
<Suspense fallback={<Loader />}>
<App />
</Suspense>
</ThemeProvider>
</Provider>,
document.getElementById('root')
);
// This prevents crashes in test environments (like Jest) where document.getElementById('root') may return null.
const rootEl = document.getElementById('root');
if (rootEl) {
render(
<Provider store={store}>
<ThemeProvider>
<Suspense fallback={<Loader />}>
<App />
</Suspense>
</ThemeProvider>
</Provider>,
rootEl
);
}

export default store;
115 changes: 84 additions & 31 deletions client/modules/IDE/components/Editor/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,13 @@ import { EditorContainer, EditorHolder } from './MobileEditor';
import { FolderIcon } from '../../../../common/icons';
import { IconButton } from '../../../../common/IconButton';

import contextAwareHinter from '../../../../utils/contextAwareHinter';
import showRenameDialog from '../../../../utils/showRenameDialog';
import handleRename from '../../../../utils/rename-variable';
import { jumpToDefinition } from '../../../../utils/jump-to-definition';
import { ensureAriaLiveRegion } from '../../../../utils/ScreenReaderHelper';
import { isMac } from '../../../../utils/device';

emmet(CodeMirror);

window.JSHINT = JSHINT;
Expand Down Expand Up @@ -109,6 +116,7 @@ class Editor extends React.Component {

componentDidMount() {
this.beep = new Audio(beepUrl);
ensureAriaLiveRegion();
// this.widgets = [];
this._cm = CodeMirror(this.codemirrorContainer, {
theme: `p5-${this.props.theme}`,
Expand Down Expand Up @@ -154,6 +162,17 @@ class Editor extends React.Component {

delete this._cm.options.lint.options.errors;

this._cm.getWrapperElement().addEventListener('click', (e) => {
const isCtrlClick = isMac() ? e.metaKey : e.ctrlKey;

if (isCtrlClick) {
const pos = this._cm.coordsChar({ left: e.clientX, top: e.clientY });
jumpToDefinition.call(this, pos);
}
});

const renameKey = isMac() ? 'Ctrl-F2' : 'F2';

const replaceCommand =
metaKey === 'Ctrl' ? `${metaKey}-H` : `${metaKey}-Option-F`;
this._cm.setOption('extraKeys', {
Expand All @@ -172,6 +191,7 @@ class Editor extends React.Component {
[`Shift-${metaKey}-E`]: (cm) => {
cm.getInputField().blur();
},
[renameKey]: (cm) => this.renameVariable(cm),
[`Shift-Tab`]: false,
[`${metaKey}-Enter`]: () => null,
[`Shift-${metaKey}-Enter`]: () => null,
Expand Down Expand Up @@ -209,7 +229,14 @@ class Editor extends React.Component {
}

this._cm.on('keydown', (_cm, e) => {
// Show hint
// Skip hinting if the user is pasting (Ctrl/Cmd+V) or using modifier keys (Ctrl/Alt)
if (
((e.ctrlKey || e.metaKey) && e.key === 'v') ||
e.ctrlKey ||
e.altKey
) {
return;
}
const mode = this._cm.getOption('mode');
if (/^[a-z]$/i.test(e.key) && (mode === 'css' || mode === 'javascript')) {
this.showHint(_cm);
Expand Down Expand Up @@ -395,12 +422,15 @@ class Editor extends React.Component {
}

showHint(_cm) {
if (!_cm) return;

if (!this.props.autocompleteHinter) {
CodeMirror.showHint(_cm, () => {}, {});
return;
}

let focusedLinkElement = null;

const setFocusedLinkElement = (set) => {
if (set && !focusedLinkElement) {
const activeItemLink = document.querySelector(
Expand All @@ -415,6 +445,7 @@ class Editor extends React.Component {
}
}
};

const removeFocusedLinkElement = () => {
if (focusedLinkElement) {
focusedLinkElement.classList.remove('focused-hint-link');
Expand All @@ -437,12 +468,8 @@ class Editor extends React.Component {
);
if (activeItemLink) activeItemLink.click();
},
Right: (cm, e) => {
setFocusedLinkElement(true);
},
Left: (cm, e) => {
removeFocusedLinkElement();
},
Right: (cm, e) => setFocusedLinkElement(true),
Left: (cm, e) => removeFocusedLinkElement(),
Up: (cm, e) => {
const onLink = removeFocusedLinkElement();
e.moveFocus(-1);
Expand All @@ -461,30 +488,28 @@ class Editor extends React.Component {
closeOnUnfocus: false
};

if (_cm.options.mode === 'javascript') {
// JavaScript
CodeMirror.showHint(
_cm,
() => {
const c = _cm.getCursor();
const token = _cm.getTokenAt(c);

const hints = this.hinter
.search(token.string)
.filter((h) => h.item.text[0] === token.string[0]);

return {
list: hints,
from: CodeMirror.Pos(c.line, token.start),
to: CodeMirror.Pos(c.line, c.ch)
};
},
hintOptions
);
} else if (_cm.options.mode === 'css') {
// CSS
CodeMirror.showHint(_cm, CodeMirror.hint.css, hintOptions);
}
const triggerHints = () => {
if (_cm.options.mode === 'javascript') {
CodeMirror.showHint(
_cm,
() => {
const c = _cm.getCursor();
const token = _cm.getTokenAt(c);
const hints = contextAwareHinter(_cm, { hinter: this.hinter });
return {
list: hints,
from: CodeMirror.Pos(c.line, token.start),
to: CodeMirror.Pos(c.line, c.ch)
};
},
hintOptions
);
} else if (_cm.options.mode === 'css') {
CodeMirror.showHint(_cm, CodeMirror.hint.css, hintOptions);
}
};

setTimeout(triggerHints, 0);
}

showReplace() {
Expand Down Expand Up @@ -522,6 +547,34 @@ class Editor extends React.Component {
}
}

renameVariable(cm) {
const cursorCoords = cm.cursorCoords(true, 'page');
const selection = cm.getSelection();
const pos = cm.getCursor(); // or selection start
const token = cm.getTokenAt(pos);
const tokenType = token.type;
if (!selection) {
return;
}

const sel = cm.listSelections()[0];
const fromPos =
CodeMirror.cmpPos(sel.anchor, sel.head) <= 0 ? sel.anchor : sel.head;

showRenameDialog(
cm,
fromPos,
tokenType,
cursorCoords,
selection,
(newName) => {
if (newName && newName.trim() !== '' && newName !== selection) {
handleRename(fromPos, selection, newName, cm);
}
}
);
}

initializeDocuments(files) {
this._docs = {};
files.forEach((file) => {
Expand Down
5 changes: 5 additions & 0 deletions client/modules/IDE/components/KeyboardShortcutModal.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ function KeyboardShortcutModal() {
metaKey === 'Ctrl' ? `${metaKeyName} + H` : `${metaKeyName} + ⌥ + F`;
const newFileCommand =
metaKey === 'Ctrl' ? `${metaKeyName} + Alt + N` : `${metaKeyName} + ⌥ + N`;
const renameCommand = metaKey === 'Ctrl' ? 'F2' : 'Ctrl + F2';
return (
<div className="keyboard-shortcuts">
<h3 className="keyboard-shortcuts__title">
Expand Down Expand Up @@ -75,6 +76,10 @@ function KeyboardShortcutModal() {
<span className="keyboard-shortcut__command">{newFileCommand}</span>
<span>{t('KeyboardShortcuts.CodeEditing.CreateNewFile')}</span>
</li>
<li className="keyboard-shortcut-item">
<span className="keyboard-shortcut__command">{renameCommand}</span>
<span>{t('KeyboardShortcuts.CodeEditing.RenameVariable')}</span>
</li>
</ul>
<h3 className="keyboard-shortcuts__title">
{t('KeyboardShortcuts.General')}
Expand Down
Loading
Loading