My Journey with pr05 @
Description
This article details my work, development processes, and insights gained during the pr05 2024 “New Beginnings” software development grant with the . During the past four months, I have focussed on developing the Processing Language Server Extension for the Processing software (Processing is a flexible software sketchbook and a language for learning how to code) for VSCode. Currently, Processing is distributed as standalone software compatible with multiple platforms; this extension integrates .pde sketch files into VSCode, providing robust IntelliSense support to enhance the coding experience.
It was a privilege to work under the mentorship of and advisor Justin Gitlin. Together, we conducted bi-weekly project check-ins to review progress and address challenges in development.
The Language Server Extension includes a server-side implementation and a client interface within the VSCode editor, delivering IntelliSense functionality to developers working with .pde sketches. The complete project plan is accessible within the project’s roadmap.
What code got merged in:
- Run Processing Sketches:
The “Run” and “Stop” buttons toggle based on the sketch’s running state. The sketchbook can contain multiple sketches, each organized within a directory named after the sketch itself.
- Grammar: Defines a Processing-specific grammar model for parsing
textDocumentfiles within the workspace. - Parser: The
parser.tsfile includes functions for parsing Java code into an Abstract Syntax Tree (AST) and extracting tokenized information. The primary function,parseAST, processes Java code and returns an array of token pairs, representing each parse tree node and its parent. ThelineMapfunction creates mappings of each word in a line to its start and end positions, facilitating token location within specific lines. Theparsefunction utilizes thejava-astlibrary for parsing, with theredirectConsoleutility temporarily muting unnecessary logging during the process. - Sketch Runner: Defines a
SketchRunnerclass that manages the execution of Processing sketches in a Visual Studio Code extension. It provides functionality to initialize the sketch runner with a specified Java Runtime Environment (JRE) path and a sketch directory. The class can run and stop sketches while handling output from the Processing environment through buffered channels to manage the display in the VSCode output window. It also includes error logging to capture issues during execution and during the copying of compiled sketches. ThecopyCompiledSketchmethod ensures that.classfiles are correctly transferred from the source to the destination directory, maintaining the structure of the original sketch. Additionally, thedisposemethod cleans up resources when the sketch runner is no longer needed, preventing memory leaks. Overall, the class encapsulates the functionality required to run and manage Processing sketches effectively within the editor environment. - Sketch Errors: When a sketch is run, the LSP extension monitors it and logs any errors in the Output tab.
- On-Hover Documentation: The on-hover feature displays the documentation for every keyword of the Processing language stored in XML files.
- Code Completion: Keywords are reserved keywords in the Processing language. This feature displays a pop-up menu containing a list of keywords aligning with the triggering character.
- Goto Reference: This feature responds to the
onReferencesrequests by the user when they select the option, found in the context menu to navigate to the schemas that reference the location under the cursor.
- Goto Definition: This is vice-versa of the former issue i.e., jump to the schema a reference refers to. This is the same as going to the variable declaration through
Ctrl/Cmd + Clickor the context menu. This uses theonDefinitionrequest from the user in the extension host to redirect the cursor to the definition the reference refers to.
Current State of the Project:
As outlined in the project roadmap, the LSP extension has been developed for cross-platform compatibility. Packaging Processing’s latest version to bundle with the extension and run from its server was achieved by creating symlinks using Rust (a low-level language) for Windows. This eliminated the need for users to add the Processing path to their environment variable and enabled Processing to run in headless mode. This method in the future would enable the distribution to run directly from the extension on all platforms. The following milestones have been successfully achieved:
✅Stable Architecture
✅.vsix release and VSCode Marketplace release.
✅Integrate Processing 4.3
✅Workspace management
✅Run and Stop Buttons
✅On-hover documentation
✅Syntax highlights
✅Sketch Errors
✅Run Processing sketches headless
✅Run Multiple Sketches
✅Workspace Management (Sketch and Sketchbook)
✅Go-to-definitions
✅Go-to-References
✅Code Completion
Future Goals
The following objectives are prioritized for future contributions to the project:
- Establish a comprehensive testing strategy with full feature tests.
- Extend Processing’s AST and AST-supported features.
- Bundling of Processing distribution by creating symlinks for multiple platforms.
While VSCode remains one of the most widely used code editors, extending support for this LSP to other editors, including JetBrains, Eclipse, and CodeMirror, can also be a future goal.
Challenges Faced
Working on this project has been an invaluable learning experience, but I encountered several challenges, both technical and non-technical, especially during the initial stages. These are summarized below:
Technical challenges
In this project, I developed an LSP (Language Server Protocol) extension and gained in-depth knowledge of the Processing codebase to enable software invocation through JSON-RPC calls. One of my key objectives was to streamline the installation process. Initially, users had to manually download Processing, run scripts, and set up environment variables to execute sketches within the extension. While starting by reviving previous work, I quickly saw the need for a more robust setup that would require minimal prerequisites from users.
During development, I discovered the utility of symlinks — both hard and soft links — to interconnect the protocol, server, client, and extension folders. Inspired by the vscode-languageserver-node project, which leverages a symlink script executable via npm run symlink. It just executes a file called symlink.js. We implemented a similar approach for packaging this extension. This solution involved coordinating multiple technologies and concepts to ensure seamless integration.
The skills essential to this project included:
- Antlr4ts for creating a Java lexer/parser.
- Proficiency in symlinks and low-level programming to bundle the Processing distribution.
- A solid understanding of Client/Server & RPC architectural styles.
- Familiarity with observer patterns and adaptability to diverse system design patterns.
- LSP specification knowledge, alongside experience with the VSCode API and handling third-party dependencies.
- Expertise in managing automated testing and asynchronous code for reliable extension performance.
This journey of intertwining different technologies and paradigms taught me invaluable lessons on efficient software integration and the intricacies of developing a smooth user experience.
Non-Technical
Although I had prior experience building LSP extensions, this project, along with the townhall and progress meetings, pushed me to step out of my shell. It wasn’t just about coding behind the screen — I honed my communication skills by interacting with people from diverse backgrounds, presenting my updates, and gaining new insights during our meetings. The pr05 cohort also encouraged thorough technical documentation, which has been incredibly beneficial for me. This experience encouraged me to reach out beyond my mentors for Processing-related questions and connect with other Processing fellows and pr05 grantees.
Current Limitations:
- The full feature set of the LSP extension is currently compatible only with Windows. This is due to the extension’s JSON-RPC architecture, where a client and server communicate to support IntelliSense features. To implement this, a layered structure was set up, connecting the protocol, server, client, extension, and Processing distribution. Symlinks were created to package the Processing distribution and to invoke sketches from the sketch runner. So far, this setup has been completed only for Windows. A similar approach in the future would make the extension work for other platforms too.