Skip to content

Conversation

kammeows
Copy link
Contributor

@kammeows kammeows commented Aug 18, 2025

This PR completes the GSoC project by introducing context-awareness to the p5.js web editor's autocomplete and refactoring features. It includes:

  • Context-Aware Autocomplete
    The autocomplete hinter now filters suggestions based on the current code context. It uses a JSON of blacklisted functions and parses the code’s AST to show only relevant suggestions:
image
  • User-Defined Code Suggestions
    Autocomplete now suggests user-defined variables, functions, and classes, as well as methods for both user-defined and p5 classes.
image image
  • Context-Aware Renaming
    Select a word, press F2, and enter the new name in the dialog. All occurrences are renamed correctly according to the context.
image
  • Jump to Definition
    Hold Ctrl and click a word to jump to where the variable or function is defined.

  • Accessibility
    All new features are fully accessible to users relying on digital accessibility tools.

kammeows and others added 30 commits June 5, 2025 17:12
user-defined context-aware variables, functions & classes suggestion
added listOfAllFunctions.json
minor bug fix in autocomplete suggestions
.env.example Outdated
@@ -19,7 +19,7 @@ MAILGUN_KEY=<your-mailgun-api-key>
ML5_LIBRARY_USERNAME=ml5
ML5_LIBRARY_EMAIL=[email protected]
ML5_LIBRARY_PASS=helloml5
MONGO_URL=mongodb://localhost:27017/p5js-web-editor
MONGO_URL=mongodb://127.0.0.1:27017/p5js-web-editor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suppose this was committed by mistake.

Used to:

- Differentiate between built-in and user-defined functions
- Filter out redefinitions or incorrect hints

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's keep the README as a separate GitHub Gist, and not include it in the final PR to be merged.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree with @diyaayay here!

It'd be great if you could move this into the contributor_docs folder, and I can update how it's organized and referenced afterwards!

@diyaayay
Copy link

I tested a few things, such as the autocomplete for p5-specific functions and the warnings triggered when functions like setup or draw are used in undesired places. They work well.
The Jump to Definition feature also works fine. I tested it across multiple files, and it correctly jumps to the function declaration in another file when the function is called from there. When multiple functions with the same name exist in different files, it follows the runtime behavior. However, instead of just moving the cursor to the function declaration, it would look visually better if the function name were briefly highlighted, for example:
image

But the functionality works well.

@diyaayay
Copy link

The context-aware renaming feature works with Fn + F2 on some systems. I tested it with variable scopes:

function setup() {
  createCanvas(400, 400);
}

var x = 10; 

function draw() {
  var x = 10; // local variable (shadows global x)
  background(220);
  x = 20;     // modifies only the local x
}

I tested context-aware renaming and it works for functions within the same file.
However, when I rename a function in sketch.js that is defined in another file, the function definition in that other file is not renamed.
Example:
sketch.js

function setup() {
  createCanvas(400, 400);
}

function draw() {
  background(220);
  hello(); // call
}

hi.js

function hello() { // definition
  console.log("Hello");
}

Renaming hello() in sketch.js does not update the function definition in hello.js.
Is this the intended behavior?

@kammeows
Copy link
Contributor Author

Regarding context-aware renaming, yes, that’s the expected behavior. From what I’ve seen in most code editors, the renaming only works within a single file. It won’t rename the same function or variable if it’s defined in another file. It would also make the browser editor's functionality more complicated so I thought it would be best to not include such a feature.

@kammeows
Copy link
Contributor Author

Thank you for your feedback and all your suggestions! I'll also try to add the jump to definition highlight feature.

@raclim
Copy link
Collaborator

raclim commented Aug 22, 2025

Thanks so much for your work on this @kammeows!

I think this looks really great so far, and I really love how much smoother this overall looks! I don't think I have too much to add on to @diyaayay's comments, and I feel that they covered most of my initial thoughts while testing out the feature!

I do have a quick question—while loading this branch, I ran into a small version mismatch issue between eslint and eslint-plugin-storybook, which I resolved by changing these versions. I was wondering, was this something that you faced as well?

@kammeows
Copy link
Contributor Author

Hey @raclim! Thank you for taking a look on this. No I did not encounter any such issue. If it comes up again, we can look into whether we need to adjust the package versions in the repo to prevent others from hitting the same issue.

@kammeows kammeows marked this pull request as ready for review August 24, 2025 05:43
@kammeows kammeows changed the title introducing context awareness to the autocomplete hinter in addition to context aware renaming, jump to definition and other refactoring changes (draft work for review) GSoC PR: Context-Aware Autocomplete, Renaming, and Refactoring Enhancements Aug 24, 2025
@kammeows kammeows changed the title GSoC PR: Context-Aware Autocomplete, Renaming, and Refactoring Enhancements Final GSoC Work: Context-Aware Autocomplete, Renaming, and Refactoring Enhancements Aug 24, 2025
Copy link
Collaborator

@raclim raclim left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks so much again for your work on this, this looks really awesome! 🙌

I was able to give it a closer review and added in a few more comments. I think on top of them, it'd be great if you could organize some of the files within client/modules/IDE!

Some ways you could approach organizing them are grouping them into subfolders within client/modules/IDE, storing in other client folders (like client/utils), or creating new folders (like client/helpers). Feel free to go with what you feel might be best, or let me know if you have any questions about it!

@@ -53,3 +53,5 @@ render(
</Provider>,
document.getElementById('root')
);

export default store;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since it seems like client/storeInstance.js is exporting the Redux store, can we remove this line here? I don't think I see any other references to here, but we may also want to update any other references to store to point to storeInstance instead!

Used to:

- Differentiate between built-in and user-defined functions
- Filter out redefinitions or incorrect hints
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree with @diyaayay here!

It'd be great if you could move this into the contributor_docs folder, and I can update how it's organized and referenced afterwards!

const liveRegion = document.getElementById('rename-aria-live');
if (!liveRegion) return;

// liveRegion.setAttribute('aria-live', assertive ? 'assertive' : 'polite');
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It'd be best to remove any extraneous comments, or note why it should be kept commented out!

@@ -0,0 +1,26 @@
export default function announceToScreenReader(message, assertive = false) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a great add and will be so helpful in other parts of the app as well!

@@ -154,6 +161,16 @@ class Editor extends React.Component {

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

this._cm.getWrapperElement().addEventListener('click', (e) => {
const isMac = /Mac/.test(navigator.platform);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to use this pre-existing device util here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it alright if I changed the function in device util from export function isMac() to export default function isMac() or if you want named export, then should I disable the eslint rule for this file instead?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants