-
Notifications
You must be signed in to change notification settings - Fork 0
Innocent #52
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
The word was previously mispelled as 'araound'
…upporting files and docs
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Bumps [org.apache.maven.plugins:maven-jar-plugin](https://github.com/apache/maven-jar-plugin) from 3.2.0 to 3.4.2. - [Release notes](https://github.com/apache/maven-jar-plugin/releases) - [Commits](apache/maven-jar-plugin@maven-jar-plugin-3.2.0...maven-jar-plugin-3.4.2) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-jar-plugin dependency-version: 3.4.2 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com>
Bumps [org.apache.maven.plugins:maven-enforcer-plugin](https://github.com/apache/maven-enforcer) from 3.5.0 to 3.6.1. - [Release notes](https://github.com/apache/maven-enforcer/releases) - [Commits](apache/maven-enforcer@enforcer-3.5.0...enforcer-3.6.1) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-enforcer-plugin dependency-version: 3.6.1 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com>
Bumps [org.junit:junit-bom](https://github.com/junit-team/junit-framework) from 5.12.2 to 5.13.4. - [Release notes](https://github.com/junit-team/junit-framework/releases) - [Commits](junit-team/junit-framework@r5.12.2...r5.13.4) --- updated-dependencies: - dependency-name: org.junit:junit-bom dependency-version: 5.13.4 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com>
Bumps [org.apache.maven.plugins:maven-assembly-plugin](https://github.com/apache/maven-assembly-plugin) from 2.4.1 to 3.7.1. - [Release notes](https://github.com/apache/maven-assembly-plugin/releases) - [Commits](apache/maven-assembly-plugin@maven-assembly-plugin-2.4.1...maven-assembly-plugin-3.7.1) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-assembly-plugin dependency-version: 3.7.1 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com>
Bumps [org.bidib.jbidib.com.vldocking:vldocking](https://github.com/akuhtz/vldocking) from 3.0.10 to 3.0.11. - [Release notes](https://github.com/akuhtz/vldocking/releases) - [Changelog](https://github.com/akuhtz/vldocking/blob/master/CHANGELOG.md) - [Commits](akuhtz/vldocking@bidib-3.0.10...bidib-3.0.11) --- updated-dependencies: - dependency-name: org.bidib.jbidib.com.vldocking:vldocking dependency-version: 3.0.11 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com>
Bumps [org.antlr:antlr4-runtime](https://github.com/antlr/antlr4) from 4.9.3 to 4.13.2. - [Release notes](https://github.com/antlr/antlr4/releases) - [Changelog](https://github.com/antlr/antlr4/blob/dev/CHANGES.txt) - [Commits](antlr/antlr4@4.9.3...4.13.2) --- updated-dependencies: - dependency-name: org.antlr:antlr4-runtime dependency-version: 4.13.2 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com>
Bumps [org.graalvm.buildtools:native-maven-plugin](https://github.com/graalvm/native-build-tools) from 0.10.0 to 0.11.0. - [Release notes](https://github.com/graalvm/native-build-tools/releases) - [Commits](graalvm/native-build-tools@0.10.0...0.11.0) --- updated-dependencies: - dependency-name: org.graalvm.buildtools:native-maven-plugin dependency-version: 0.11.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com>
Bumps [com.formdev:flatlaf](https://github.com/JFormDesigner/FlatLaf) from 3.6 to 3.6.1. - [Release notes](https://github.com/JFormDesigner/FlatLaf/releases) - [Changelog](https://github.com/JFormDesigner/FlatLaf/blob/main/CHANGELOG.md) - [Commits](JFormDesigner/FlatLaf@3.6...3.6.1) --- updated-dependencies: - dependency-name: com.formdev:flatlaf dependency-version: 3.6.1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com>
Bumps [org.graalvm.buildtools:native-maven-plugin](https://github.com/graalvm/native-build-tools) from 0.11.0 to 0.11.1. - [Release notes](https://github.com/graalvm/native-build-tools/releases) - [Commits](graalvm/native-build-tools@0.11.0...0.11.1) --- updated-dependencies: - dependency-name: org.graalvm.buildtools:native-maven-plugin dependency-version: 0.11.1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com>
Bumps [org.junit:junit-bom](https://github.com/junit-team/junit-framework) from 5.13.4 to 6.0.0. - [Release notes](https://github.com/junit-team/junit-framework/releases) - [Commits](junit-team/junit-framework@r5.13.4...r6.0.0) --- updated-dependencies: - dependency-name: org.junit:junit-bom dependency-version: 6.0.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com>
Bumps [org.apache.maven.plugins:maven-enforcer-plugin](https://github.com/apache/maven-enforcer) from 3.6.1 to 3.6.2. - [Release notes](https://github.com/apache/maven-enforcer/releases) - [Commits](apache/maven-enforcer@enforcer-3.6.1...enforcer-3.6.2) --- updated-dependencies: - dependency-name: org.apache.maven.plugins:maven-enforcer-plugin dependency-version: 3.6.2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com>
This commit hopefully accomplishes the todo that was made to use the system object to get the current working directory
WalkthroughThis PR integrates graphics rendering capabilities into the Piccode language with corresponding Java native implementations, introduces theme management and settings dialogs, enhances the plugin system with dynamic loading, adds comprehensive README validation tests, and updates build configuration. Multiple new Piccode modules provide bindings for drawing operations, image handling, and filter effects. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant EditorWindow as EditorWindow<br/>(Theme Mgr)
participant CanvasFrame
participant PiccodeRuntime as Piccode<br/>Runtime
participant NativeGfx as Native<br/>Modules
User->>EditorWindow: set theme (dark/light)
EditorWindow->>EditorWindow: updateThemes(dark)
EditorWindow->>CanvasFrame: propagate theme
EditorWindow->>EditorWindow: setFlatLaf(dark)
User->>EditorWindow: compile code
EditorWindow->>CanvasFrame: compile(Supplier)
CanvasFrame->>PiccodeRuntime: invoke Supplier<br/>(Compiler.compile)
PiccodeRuntime->>NativeGfx: Render::getContext()
NativeGfx-->>PiccodeRuntime: Graphics2D ref
PiccodeRuntime->>NativeGfx: Pen::drawLine(...)<br/>Pen::drawRect(...)
NativeGfx->>CanvasFrame: render to buffer
CanvasFrame->>CanvasFrame: paintComponent()<br/>draw render buffer
CanvasFrame-->>User: display result
sequenceDiagram
participant PluginsPanel
participant PluginDisco as Plugin<br/>Discovery
participant URLClassLoader as ClassLoader
participant PluginJar as JAR
participant PluginImpl as Plugin<br/>Implementation
participant ThemeManager
PluginsPanel->>PluginsPanel: constructor
PluginsPanel->>PluginDisco: loadPlugins()
PluginDisco->>PluginDisco: walk ./etc/plugins/
PluginDisco->>PluginDisco: find *.jar files
loop for each JAR
PluginDisco->>URLClassLoader: scanJar(jarFile)
URLClassLoader->>PluginJar: open JAR stream
PluginJar-->>URLClassLoader: class entries
URLClassLoader->>URLClassLoader: filter by base<br/>(PiccodePluginPanel)
URLClassLoader->>PluginImpl: Class.forName<br/>or jar-loader
URLClassLoader->>PluginDisco: loadPlugin(class)
end
PluginDisco->>PluginImpl: instantiate
PluginImpl->>ThemeManager: register plugin
PluginImpl->>PluginsPanel: add to UI
Estimated code review effort🎯 4 (Complex) | ⏱️ ~50 minutes
Possibly related PRs
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (1 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 17
🧹 Nitpick comments (22)
src/main/java/org/editor/dialogs/NewProjectDialog.java (4)
4-7: Remove unused imports.The imports
java.io.FileWriterandjava.util.logging.Loggerare never used in this class.Apply this diff:
package org.editor.dialogs; import java.io.File; -import java.io.FileWriter; -import java.io.IOException; -import java.util.logging.Level; -import java.util.logging.Logger; import javax.swing.JFileChooser;
10-14: Replace boilerplate license header.This is a generic NetBeans template comment. Consider replacing it with your project's actual license or removing it.
31-32: Address initialization concerns.Line 31 sets
hasError = false, but this field (declared at line 351) is never checked or meaningfully used. Line 32 contains commented-out code that duplicates line 67.Apply this diff:
public NewProjectDialog() { initComponents(); this.setResizable(false); this.setTitle("Create a new project"); - this.hasError = false; - //this.setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); }
351-351: Unused fieldhasError.The
hasErrorfield is initialized in the constructor (line 31) but never read or meaningfully updated. Consider removing it or implementing proper error tracking.src/main/java/org/editor/events/MenuEvents.java (2)
85-98: openFile now uses current working directory but overrides file filterUsing
new JFileChooser(System.getProperty("user.dir"))aligns with the PR objective to base the dialog on the current working directory and is a reasonable default.However, calling
setFileFiltertwice means the second call (FileFilter.picsFilter) overrides the first (FileFilter.mdFilter), so only one filter is actually active. If you intend to offer both filters, consider:var fileChooser = new JFileChooser(System.getProperty("user.dir")); fileChooser.addChoosableFileFilter(FileFilter.mdFilter); fileChooser.addChoosableFileFilter(FileFilter.picsFilter); fileChooser.setFileFilter(FileFilter.picsFilter); // default, if desired
135-138: newFile TODO is acceptable
newFilesimply forwards toEditorWindow.addTab(e)and keeps a TODO about using a dedicated file‑creator dialog later. That’s a reasonable incremental step; no changes requested.In a follow‑up, you might want to capture a brief issue/ticket for the “file creator dialog” TODO so it doesn’t get lost.
pom.xml (1)
19-25: Consider the implications ofupdatePolicy=alwaysfor snapshot dependencies.Setting
updatePolicytoalwaysmeans Maven will check for updates on every build, which can lead to non-reproducible builds and potential build instability if upstream snapshots change unexpectedly. This is particularly risky when combined withmain-SNAPSHOTdependencies.Consider using
dailyinstead ofalwaysto balance freshness with build stability:<snapshots> <enabled>true</enabled> - <updatePolicy>always</updatePolicy> + <updatePolicy>daily</updatePolicy> </snapshots> <releases> - <updatePolicy>always</updatePolicy> + <updatePolicy>daily</updatePolicy> </releases>piccode/render/context.pics (1)
1-16: LGTM with minor documentation fix.The Render module provides a clean abstraction for obtaining the graphics context. The implementation correctly delegates to the native function registered by
PiccodeGfxModule.Minor typo in the documentation comment on Line 12:
- // - (Reference) a handler to the Graphics2D. + // - (Reference) a handle to the Graphics2D.src/main/java/org/editor/CodeEditor.java (1)
302-311: Improve error handling in theme loading.The comment "Never happens" for
IOExceptionis misleading—resource loading can fail if the theme file is missing or corrupted. UsingprintStackTrace()is not ideal for production code and provides poor user feedback.Consider logging the error properly or providing user feedback:
public void setThemeMode(boolean dark) { var themeName = dark ? "monokai" : "vs"; try { Theme theme = Theme.load(getClass().getResourceAsStream( "/org/fife/ui/rsyntaxtextarea/themes/" + themeName +".xml")); theme.apply(textArea); - } catch (IOException ioe) { // Never happens - ioe.printStackTrace(); + } catch (IOException ioe) { + Logger.getLogger(CodeEditor.class.getName()).log(Level.WARNING, + "Failed to load theme: " + themeName, ioe); + // Optionally notify user or fall back to default theme } }piccode/filters/filter.pics (1)
1-5: Add documentation for the Filter module.The module lacks documentation explaining its purpose, parameter types, and return values. This would help developers understand how to use the filter system.
Consider adding documentation:
+// Module: Filter +// Functions for applying image filters Filter :: module { + // Function: apply + // Applies a filter to an image + // + // Parameters: + // - filter: (Reference) A BufferedImageOp filter instance + // - image: (Reference) A BufferedImage to filter + // + // Returns: + // - (Reference) The filtered BufferedImage apply :: (filter, image) = pic_nat_filter_apply(filter, image) }src/main/java/org/piccode/piccode/Piccode.java (1)
27-33: LGTM! Clean centralized module initialization.The new
initializeNativeAppModules()method provides a clean, centralized way to register native modules before the editor window starts. The use of method references keeps the code concise and maintainable.Consider adding error handling if module registration could fail:
private static void initializeNativeAppModules() { + try { Compiler.addNativeFunctions(PiccodeGfxModule::addFunctions); Compiler.addNativeFunctions(PiccodePenModule::addFunctions); Compiler.addNativeFunctions(PiccodeBrushedMetalFilterModule::addFunctions); Compiler.addNativeFunctions(PiccodeFilterModule::addFunctions); Compiler.addNativeFunctions(PiccodeImageModule::addFunctions); + } catch (Exception e) { + System.err.println("Failed to initialize native modules: " + e.getMessage()); + System.exit(1); + } }However, this is only necessary if
addNativeFunctionsor the module initialization methods can throw exceptions.piccode/filters/metal/brushMetal.pics (1)
3-7: BrushMetal wrapper signatures look fine; consider clarifying parameter namesThe thin wrappers around the native brush metal functions are consistent and simple. For readability, you might consider renaming the second parameter of
amountandshinefromradiusto something likevalueoramount/shineto better reflect the underlying meaning.src/main/java/org/editor/nativemods/PiccodePenModule.java (2)
28-204: Consider extracting shared helpers for ctx resolution and numeric conversionEach drawing function repeats the same patterns (resolve
Context, getcaller, verify types, derefGraphics2D, convertPiccodeNumbertoint). This is correct but quite duplicated; extracting small helpers (e.g.,resolveGraphics2D(caller, _ctx)and a numeric conversion helper) would reduce boilerplate and keep behavior consistent if you tweak validation later.
205-232: Verify how PiccodeString is converted before drawing textHere
_textis validated asType.STRING, but the draw call uses:gfx.drawString(_text.toString(), _x, _y);Since
PiccodeStringis imported but not used, this may end up drawing the wrapper’stoString()(e.g., a debug representation) instead of the underlying string, depending onPiccodeString’s implementation. It might be safer to cast toPiccodeStringand use its underlying value accessor instead oftoString(), if one exists.src/main/java/org/editor/panels/PluginsPanel.java (1)
30-46: Plugin loading works; consider tightening path/error handlingThe plugin scanning logic is sound overall, but a few small tweaks could improve robustness:
- Before
Files.walk(pluginsDir), consider checkingFiles.isDirectory(pluginsDir)and returning early to avoid treating a missing plugins directory as an error.- Relying on
"./etc/plugins/"ties behavior to the process working directory; if you ever run from different CWDs, you might want a central “app root” or configuration-based path instead.- In
scanJar, you already catch per-class failures; you might also want more structured logging (or at least include the jar path) instead of plainSystem.outto make diagnosing plugin issues easier.Also applies to: 69-99
tests/test_readme_validation.py (1)
30-35: Project-name spelling tests are very brittle to future cleanupThese assertions hard‑code both
Piccaso CodeandPiccasso codeand later assert both variants exist. That will break as soon as the README is standardized to a single, correct spelling.Consider relaxing these checks (e.g., allow either variant, or assert only the canonical name) so README cleanup doesn’t require test rewrites every time the title changes.
src/main/java/org/editor/theme/ThemeManager.java (2)
17-23: Use generics and diamond operator on the editor/plugin listsTo avoid unchecked operations and make the intent explicit, you can give the lists concrete generic types and use the diamond operator:
- private static List<CodeEditor> editors = new ArrayList(); - private static List<PiccodePluginInterface> plugins = new ArrayList(); + private static final List<CodeEditor> editors = new ArrayList<>(); + private static final List<PiccodePluginInterface> plugins = new ArrayList<>();Marking them
finalalso documents that the list references themselves don’t change.
54-66: Consider callingFlatLaf.updateUI()instead of subclass-specificupdateUI()
updateUI()is defined on the FlatLaf base class; calling it viaFlatDarkLaf/FlatLightLafworks but is slightly non‑idiomatic. For clarity you could centralize the update:- if (dark) { - FlatDarkLaf.setup(); - FlatDarkLaf.updateUI(); - } else { - FlatLightLaf.setup(); - FlatLightLaf.updateUI(); - } + if (dark) { + FlatDarkLaf.setup(); + } else { + FlatLightLaf.setup(); + } + com.formdev.flatlaf.FlatLaf.updateUI();Optional, but it better reflects the FlatLaf API design.
piccode/pen/draw.pics (1)
48-65: FixdrawOvaldocstring and consider documentingdrawImage/drawTextThe implementation of
drawOvalis correct, but the comment still says “Draws a rect”, which is misleading. Also,drawImageanddrawTextare undocumented while the other functions are nicely described.You could align the docs like this:
- // Function: drawOval - // Draws a rect inside the specified context, based on the provided coordinates + // Function: drawOval + // Draws an oval inside the specified context, based on the provided coordinates @@ - drawOval :: (ctx, x, y, w, h) = pic_nat_draw_oval(ctx, x, y, w, h) + drawOval :: (ctx, x, y, w, h) = pic_nat_draw_oval(ctx, x, y, w, h) + + // Function: drawImage + // Draws an image at the specified position in the given context + drawImage :: (ctx, image, x, y) = pic_nat_draw_image(ctx, image, x, y) + + // Function: drawText + // Draws text at the specified position in the given context + drawText :: (ctx, text, x, y) = pic_nat_draw_text(ctx, text, x, y) - - drawImage :: (ctx, image, x, y) = pic_nat_draw_image(ctx, image, x, y) - - drawText :: (ctx, text, x, y) = pic_nat_draw_text(ctx, text, x, y)src/main/java/org/editor/nativemods/PiccodeGfxModule.java (1)
25-104: GFX native bindings look consistent; consider a small guard for nullgfxThe overall module (context resolution, type checks,
Graphics2Dvalidation, and disposal viagfx_drop) looks consistent and correct for the Piccode runtime.One minor defensive improvement you might consider:
- In
get_gfx, ifCanvasFrame.gfxcan ever benull(e.g., before the first successfulCanvasFrame.compile(...)), you may want to throw aPiccodeExceptionwith a clear message instead of returning aPiccodeReferencewrappingnull. That would keep error reporting aligned with the other functions that validate their inputs.This is non-blocking and can be deferred.
src/main/java/org/editor/CanvasFrame.java (1)
249-301:compile()ctor call is likely a no-op; verify expectations forCanvasFrame.gfxinitialization
compile(Supplier<PiccodeValue> fx)correctly sets up an ARGB buffer, clears it viaAlphaComposite.Clear, then switches back toSrcOverand invokes the supplier.drawGrid()now usesThemeManagercolors and disposes the gridGraphics2D, which is good resource hygiene.One behavioral nuance:
- When
compile(() -> null);is invoked from the constructor,getWidth()/getHeight()are typically0, socompile()returns early without initializingrenderorCanvasFrame.gfx.- This means
CanvasFrame.gfxwill remainnulluntil some later explicit call tocompile(...)when the component has a non-zero size.If the rest of the system assumes
get_gfx(from the native module) is only used after an explicit compile, this is fine. If not, you may want to:
- Either defer the initial
compileuntil the component is realized (or until the first explicit render), or- Add a guard/error path wherever
get_gfxis used to clearly indicate that compilation hasn’t run yet.This is more of a lifecycle gotcha than a bug, but worth double-checking.
Also applies to: 303-324
src/main/java/org/editor/EditorWindow.java (1)
46-47: ThemeManager integration and dark-mode wiring look coherentExposing
darkas a single static flag and routing LaF + editor theme updates throughThemeManager(constructor,addTab,addTab(Path, Void), and removal viaThemeManager.removeEditor) provides a clear centralization for theming.There is a small redundancy where
ThemeManager.setFlatLaf(dark)is called explicitly in the constructor and again fromThemeManager.updateThemes(dark), but this is harmless and can be cleaned up later if desired.Also applies to: 76-79, 92-93, 230-231, 254-256, 276-277
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (37)
.github/dependabot.yml(1 hunks).gitignore(1 hunks)README.md(3 hunks)examples/starrect.pics(1 hunks)piccode/context/ctx.pics(1 hunks)piccode/filters/filter.pics(1 hunks)piccode/filters/metal/brushMetal.pics(1 hunks)piccode/image/image.pics(1 hunks)piccode/pen/draw.pics(1 hunks)piccode/render/context.pics(1 hunks)pom.xml(9 hunks)pytest.ini(1 hunks)requirements-test.txt(1 hunks)run_readme_tests.py(1 hunks)src/main/java/org/editor/CanvasFrame.java(9 hunks)src/main/java/org/editor/CodeEditor.java(2 hunks)src/main/java/org/editor/EditorWindow.java(10 hunks)src/main/java/org/editor/dialogs/EditorSettingsDialog.form(1 hunks)src/main/java/org/editor/dialogs/EditorSettingsDialog.java(1 hunks)src/main/java/org/editor/dialogs/GeneralSettingsDialog.form(1 hunks)src/main/java/org/editor/dialogs/GeneralSettingsDialog.java(1 hunks)src/main/java/org/editor/dialogs/NewProjectDialog.form(1 hunks)src/main/java/org/editor/dialogs/NewProjectDialog.java(1 hunks)src/main/java/org/editor/dialogs/SettingsDialog.form(1 hunks)src/main/java/org/editor/dialogs/SettingsDialog.java(1 hunks)src/main/java/org/editor/events/AccessEvents.java(1 hunks)src/main/java/org/editor/events/MenuEvents.java(1 hunks)src/main/java/org/editor/nativemods/PiccodeBrushedMetalFilterModule.java(1 hunks)src/main/java/org/editor/nativemods/PiccodeFilterModule.java(1 hunks)src/main/java/org/editor/nativemods/PiccodeGfxModule.java(1 hunks)src/main/java/org/editor/nativemods/PiccodeImageModule.java(1 hunks)src/main/java/org/editor/nativemods/PiccodePenModule.java(1 hunks)src/main/java/org/editor/panels/AboutPanel.java(1 hunks)src/main/java/org/editor/panels/PluginsPanel.java(1 hunks)src/main/java/org/editor/theme/ThemeManager.java(1 hunks)src/main/java/org/piccode/piccode/Piccode.java(2 hunks)tests/test_readme_validation.py(1 hunks)
🧰 Additional context used
🧬 Code graph analysis (11)
src/main/java/org/editor/panels/PluginsPanel.java (2)
src/main/java/org/editor/EditorWindow.java (1)
EditorWindow(62-567)src/main/java/org/editor/theme/ThemeManager.java (1)
ThemeManager(15-67)
src/main/java/org/editor/nativemods/PiccodeGfxModule.java (1)
src/main/java/org/editor/CanvasFrame.java (1)
CanvasFrame(44-349)
src/main/java/org/editor/nativemods/PiccodeImageModule.java (1)
src/main/java/org/editor/icons/ImageLoader.java (1)
ImageLoader(16-92)
src/main/java/org/editor/nativemods/PiccodePenModule.java (1)
src/main/java/org/editor/CanvasFrame.java (1)
CanvasFrame(44-349)
tests/test_readme_validation.py (1)
run_readme_tests.py (1)
main(11-33)
src/main/java/org/editor/theme/ThemeManager.java (1)
src/main/java/org/editor/CodeEditor.java (1)
CodeEditor(43-312)
src/main/java/org/piccode/piccode/Piccode.java (5)
src/main/java/org/editor/nativemods/PiccodeBrushedMetalFilterModule.java (1)
PiccodeBrushedMetalFilterModule(24-112)src/main/java/org/editor/nativemods/PiccodeFilterModule.java (1)
PiccodeFilterModule(17-57)src/main/java/org/editor/nativemods/PiccodeGfxModule.java (1)
PiccodeGfxModule(23-106)src/main/java/org/editor/nativemods/PiccodeImageModule.java (1)
PiccodeImageModule(29-148)src/main/java/org/editor/nativemods/PiccodePenModule.java (1)
PiccodePenModule(24-235)
src/main/java/org/editor/CanvasFrame.java (1)
src/main/java/org/editor/theme/ThemeManager.java (1)
ThemeManager(15-67)
src/main/java/org/editor/events/AccessEvents.java (2)
src/main/java/org/editor/AccessFrame.java (1)
AccessFrame(40-279)src/main/java/org/editor/CanvasFrame.java (1)
CanvasFrame(44-349)
src/main/java/org/editor/events/MenuEvents.java (2)
src/main/java/org/editor/EditorWindow.java (1)
EditorWindow(62-567)src/main/java/org/editor/fs/FileFilter.java (1)
FileFilter(9-12)
src/main/java/org/editor/EditorWindow.java (1)
src/main/java/org/editor/theme/ThemeManager.java (1)
ThemeManager(15-67)
🪛 LanguageTool
README.md
[style] ~89-~89: You have already used ‘tries to’ in nearby sentences. Consider using one of the replacements to let your writing stand out.
Context: ...CAD](https://openscad.org/) program and tries to mimic its functionality ======= Picasso...
(REP_TRY)
[style] ~91-~91: You have already used ‘tries to’ in nearby sentences. Consider using one of the replacements to let your writing stand out.
Context: ...CAD](https://openscad.org/) program and tries to mimic its functionality >>>>>>> 455b066...
(REP_TRY)
🪛 markdownlint-cli2 (0.18.1)
README.md
17-17: Heading style
Expected: atx; Actual: setext
(MD003, heading-style)
24-24: Emphasis style
Expected: asterisk; Actual: underscore
(MD049, emphasis-style)
24-24: Emphasis style
Expected: asterisk; Actual: underscore
(MD049, emphasis-style)
28-28: Heading style
Expected: atx; Actual: setext
(MD003, heading-style)
29-29: Emphasis style
Expected: asterisk; Actual: underscore
(MD049, emphasis-style)
29-29: Emphasis style
Expected: asterisk; Actual: underscore
(MD049, emphasis-style)
66-66: Multiple headings with the same content
(MD024, no-duplicate-heading)
73-73: Multiple headings with the same content
(MD024, no-duplicate-heading)
80-80: Heading style
Expected: atx; Actual: setext
(MD003, heading-style)
89-89: Heading style
Expected: atx; Actual: setext
(MD003, heading-style)
🪛 Ruff (0.14.4)
run_readme_tests.py
1-1: Shebang is present but file is not executable
(EXE001)
19-19: subprocess call: check for execution of untrusted input
(S603)
25-25: Consider moving this statement to an else block
(TRY300)
31-31: Do not catch blind exception: Exception
(BLE001)
🔇 Additional comments (24)
.gitignore (2)
1-5: Inconsistency detected between PR objectives and provided changes.The PR objectives reference a TODO about using the system object to obtain the current working directory, and the AI summary describes extensive graphics rendering, plugin system, and theme management features. However, the only file provided contains
.gitignorechanges (adding*.jarand adjustingdocs/.obsidian).These are valid build artifact exclusion rules, but they don't align with the stated PR objectives. Please verify that the correct files are included in this review.
4-5: Ignore rules are appropriate for a Java project.The additions to
.gitignoreare sound:
- Line 5:
*.jarcorrectly excludes compiled JAR artifacts from version control.- Line 4:
docs/.obsidianpreserves IDE-specific configuration exclusion.Both changes follow standard best practices for Java projects.
src/main/java/org/editor/dialogs/NewProjectDialog.java (1)
1-377: Inconsistency: PR description does not match file contents.The PR description states this implements a TODO to use the system object to obtain the current working directory. However, these files implement a GUI dialog for creating new projects with no reference to any TODO or current working directory retrieval. Please verify that the correct files were included in this PR.
src/main/java/org/editor/dialogs/NewProjectDialog.form (1)
1-376: NetBeans auto-generated form file.This is an auto-generated NetBeans Form Editor XML file. It should only be modified through the NetBeans visual form designer, not manually. The form definition appears consistent with the corresponding Java file.
src/main/java/org/editor/dialogs/GeneralSettingsDialog.form (1)
1-197: Form structure looks good.The form defines a clear two-panel layout for General and Runtime settings with appropriate labels and input fields. The default entry file value "./main.pics" is reasonable, and the note about space-separated arguments provides helpful guidance.
src/main/java/org/editor/dialogs/GeneralSettingsDialog.java (1)
90-90: Verify the default entry file path convention.The entry file defaults to "./main.pics". Ensure this filename convention and relative path are consistent with the project's runtime expectations and documentation.
src/main/java/org/editor/dialogs/EditorSettingsDialog.form (1)
1-224: Form structure is well-organized.The form provides a clean three-section layout (Font, General, LookAndFeel) with appropriate UI controls for editor configuration. The checkbox labels and combo box options are clear and user-friendly.
.github/dependabot.yml (1)
2-7: Dependabot Maven configuration looks goodMinimal v2 config for weekly Maven updates at the repo root is valid and should work as intended. No changes requested.
requirements-test.txt (1)
1-4: Test requirements are reasonableThe chosen versions for pytest, pytest-mock, requests, and conditional pathlib2 support look sane for a standalone test requirements file.
src/main/java/org/editor/events/MenuEvents.java (5)
26-53: gotoLine handler looks correct but relies on initialized dialogsThe
gotoLineEventimplementation cleanly hides the find/replace dialogs, opensGoToDialog, and positions the caret correctly with proper bounds checking and error feedback.It assumes
EditorWindow.findDialogandEditorWindow.replaceDialogare non‑null; if there’s any path where these dialogs aren’t initialized before this handler runs, you may want null‑checks to avoid NPEs.
55-71: find/replace event handlers behave as expectedThe
replaceEventandfindEventmethods correctly ensure only one of the dialogs is visible at a time by toggling visibility betweenfindDialogandreplaceDialog. This matches typical editor UX.
73-83: About/close-all handlers are straightforward
aboutDialoginstantiates theAboutDialogwith the main window, andcloseAllTabsdelegates toEditorWindow.removeAllTabs(). Both are thin wrappers with clear behavior and no obvious issues.
100-109: saveFile handler is fineThe
saveFilemethod correctly no‑ops when there are no tabs or no selected editor and otherwise delegates toed.saveFile(). This is straightforward and safe.
122-133: Bulk save and quit behavior
saveAllFilesdelegating toEditorWindow.saveAll()andquitcallingcloseAllTabs(e)beforeSystem.exit(0)is consistent with expected editor behavior, assumingremoveAllTabs()already handles dirty‑file prompts.No issues from what’s visible here.
Please confirm that
EditorWindow.removeAllTabs()handles unsaved changes as expected beforeSystem.exit(0)is called.src/main/java/org/editor/events/AccessEvents.java (1)
32-34: LGTM! Cleaner compilation flow.The refactoring to use
CanvasFrame.the().compile(() -> ...)with a lambda is cleaner than the previous flag-based approach. Clearing messages before compilation provides good user feedback.run_readme_tests.py (2)
11-16: LGTM! This accomplishes the PR objective.This code successfully implements the TODO mentioned in the PR description: "use the system object to obtain the current working directory." The script uses
os.path.dirname(os.path.abspath(__file__))to get the repository root andos.chdir()to change to that directory, ensuring tests run from the correct location.
19-23: Consider security implications of subprocess usage.While the static analysis tool flags
subprocess.runfor potential security risks, in this context the command is constructed from trusted sources (sys.executableand hardcoded arguments), so this is a false positive.pom.xml (2)
78-91: All SNAPSHOT dependencies confirmed accessible.Verification shows all three JitPack dependencies (PiccodeScript, JHLabs, PiccodePlugin) are currently available. While SNAPSHOT versions do carry inherent stability risks if upstream branches change, this is an accepted trade-off of the current build approach, and no immediate accessibility issues prevent the build from proceeding.
100-100: JUnit 6.0.0 is a valid, released version and is available on Maven Central.JUnit BOM version 6.0.0 exists and release artifacts are available on Maven Central. The latest stable is 6.0.1 (published Oct 31, 2025), so if you prefer the absolute latest patch release, consider updating to that instead.
piccode/context/ctx.pics (1)
4-38: Context wrappers look consistent and minimalThe three functions are clean, direct wrappers around the native gfx APIs with matching parameter lists and documentation; no issues from this file alone.
src/main/java/org/editor/nativemods/PiccodeFilterModule.java (1)
19-52: filter_apply binding is straightforward and defensively typedArgument type checks, dereferencing, and instanceof validation for
BufferedImageOpandBufferedImageare consistent and make error cases explicit. The returnedPiccodeReferencefor the new image matches expected semantics.src/main/java/org/editor/nativemods/PiccodeBrushedMetalFilterModule.java (1)
26-110: BrushedMetalFilter native bindings look correct and defensiveArgument type checks, dereferencing, and object-type validation before calling
setRadius,setAmount, andsetShineare consistent and should prevent misuse. Returning a newPiccodeReferenceto the same underlyingBrushedMetalFilterobject keeps semantics clear.No functional issues stand out here.
piccode/image/image.pics (1)
2-16: Image module wrappers look coherent and minimalThe
Imagemodule cleanly exposes creation (new,newWithType,fromPath), context access, resizing, and a simpleTypeenum-like submodule. The API surface is cohesive and aligns well with typical image operations.src/main/java/org/editor/CanvasFrame.java (1)
5-5: Render buffer + staticgfxintegration looks goodThe additions of the
renderbuffer, the layered draw inpaintComponent, and the shared staticgfx(for consumption by native modules) are wired coherently. Drawingrenderafter the grid preserves the intended background and avoids interfering with selection/crosshair rendering.Also applies to: 52-55, 79-80, 117-119
| drawRect :: (ctx, x, y, w, h) = | ||
| ctx | ||
| |> Pen::drawLine(x, y, x + w, y) | ||
| |> Pen::drawLine(x, y + h, x + w, y + h) | ||
| |> Pen::drawLine(x, y, x, y + w) | ||
| |> Pen::drawLine(x + w, y, x + w, y + h) | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bug in drawRect: using w instead of h for the left edge height
The left vertical edge is using the width as its vertical extent:
|> Pen::drawLine(x, y, x, y + w)
This should use h to match the other sides and produce a proper rectangle.
- |> Pen::drawLine(x, y, x, y + w)
+ |> Pen::drawLine(x, y, x, y + h)🤖 Prompt for AI Agents
In examples/starrect.pics around lines 14 to 20, the drawRect function
mistakenly uses w for the left edge Y extent (x, y + w) causing a malformed
rectangle; change that call to use h (x, y + h) so the left vertical line
matches the rectangle height, ensuring all four edges use h for vertical extents
and w for horizontal extents.
| [tool:pytest] | ||
| testpaths = tests | ||
| python_files = test_*.py | ||
| python_classes = Test* | ||
| python_functions = test_* | ||
| addopts = -v --tb=short --strict-markers | ||
| markers = | ||
| slow: marks tests as slow (deselect with '-m "not slow"') | ||
| integration: marks tests as integration tests | ||
| unit: marks tests as unit tests No newline at end of file |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
❓ Verification inconclusive
pytest.ini section header is likely wrong and will be ignored
For a pytest.ini file, pytest expects the section header [pytest]. Using [tool:pytest] here is non‑standard and will likely cause pytest to ignore the entire configuration (testpaths, addopts, markers, etc.), so your settings may not take effect.
Recommend changing the header to:
[pytest]and keeping the rest of the options as‑is.
Please run pytest locally after changing the header to [pytest] to confirm that the options (e.g., --strict-markers, markers, and discovery patterns) are picked up as expected.
pytest.ini section header is incorrect and will be ignored
For pytest.ini files, pytest requires the section header [pytest]. The [tool:pytest] header is used only for setup.cfg files. Using the wrong header in your pytest.ini will cause pytest to ignore the entire configuration.
Change the header to:
[pytest]Keep the rest of the options as-is.
🤖 Prompt for AI Agents
In pytest.ini around lines 1 to 10, the section header is currently
"[tool:pytest]" which pytest ignores in a pytest.ini file; change the section
header to "[pytest]" and keep all other keys and values (testpaths,
python_files, python_classes, python_functions, addopts, markers) unchanged so
pytest will load the configuration.
| ## About | ||
| <<<<<<< HEAD | ||
| <<<<<<< HEAD | ||
| Picasso code is an image editor that uses code to create/edit an image. This allows powerful designs to be created with ease and | ||
| automation. The editor uses *PiccodeScript* as the scripting language for writing the image editing code. | ||
| ======= | ||
|
|
||
| Piccasso code is an image editor that uses code to create/edit an image. This allows powerful designs to be created with ease and | ||
| automation. The editor uses _glimr_ as the scripting language for writing the image editing code. | ||
| >>>>>>> 0064ac3 (fix: corrected a spelling error in the readme file) | ||
| ======= | ||
|
|
||
| Piccasso code is an image editor that uses code to create/edit an image. This allows powerful designs to be created with ease and | ||
| automation. The editor uses *glimr* as the scripting language for writing the image editing code. | ||
| automation. The editor uses _glimr_ as the scripting language for writing the image editing code. | ||
| ======= | ||
| Picasso code is an image editor that uses code to create/edit an image. This allows powerful designs to be created with ease and | ||
| automation. The editor uses *PiccodeScript* as the scripting language for writing the image editing code. | ||
| >>>>>>> 455b066 (README: Fixed mistakes in the README) | ||
| >>>>>>> 955b7fb (README: Fixed mistakes in the README) | ||
| ## Download | ||
| >> Coming soon | ||
|
|
||
| > > Coming soon | ||
| ## Building | ||
|
|
||
| ```sh | ||
| $ git clone git@github.com:hexaredecimal/Piccode.git | ||
| $ cd Piccode | ||
| <<<<<<< HEAD | ||
| <<<<<<< HEAD | ||
| $ git clone https://github.com/Glimmr-Lang/PicassoCode.git | ||
| $ cd PicassoCode | ||
| $ mvn package | ||
| ``` | ||
| ### Test your build | ||
| ```sh | ||
| $ java -jar target/Piccode-1.0-SNAPSHOT-jar-with-dependencies.jar | ||
| ======= | ||
| git clone git@github.com:hexaredecimal/Piccode.git | ||
| cd Piccode | ||
| mvn package | ||
| >>>>>>> 0064ac3 (fix: corrected a spelling error in the readme file) | ||
| ======= | ||
| git clone git@github.com:hexaredecimal/Piccode.git | ||
| cd Piccode | ||
| mvn package | ||
| ======= | ||
| $ git clone https://github.com/Glimmr-Lang/PicassoCode.git | ||
| $ cd PicassoCode | ||
| $ mvn package | ||
| ``` | ||
| ### Test your build | ||
| ```sh | ||
| $ java -jar target/Piccode-1.0-SNAPSHOT-jar-with-dependencies.jar | ||
| >>>>>>> 455b066 (README: Fixed mistakes in the README) | ||
| >>>>>>> 955b7fb (README: Fixed mistakes in the README) | ||
| ``` | ||
|
|
||
| ### Test your build | ||
|
|
||
| ```sh | ||
| java -jar target/Piccode-1.0-SNAPSHOT-jar-with-dependencies.jar | ||
| ``` | ||
|
|
||
| ## Inspired by | ||
| <<<<<<< HEAD | ||
| <<<<<<< HEAD | ||
| PicassoCode is heavily inspired by the [OpenSCAD](https://openscad.org/) program and tries to mimic its functionality | ||
| ======= | ||
|
|
||
| Piccassocode is heavily inspired by the [OpenSCAD](https://openscad.org/) program and tries to mimic its functionality | ||
| >>>>>>> 0064ac3 (fix: corrected a spelling error in the readme file) | ||
| ======= | ||
|
|
||
| Piccassocode is heavily inspired by the [OpenSCAD](https://openscad.org/) program and tries to mimic its functionality | ||
| ======= | ||
| PicassoCode is heavily inspired by the [OpenSCAD](https://openscad.org/) program and tries to mimic its functionality | ||
| >>>>>>> 455b066 (README: Fixed mistakes in the README) | ||
| >>>>>>> 955b7fb (README: Fixed mistakes in the README) | ||
| as much as it can while still being an image editor. I was stoked when I tried OpenSCAD for the first time and ended up | ||
| challenging myself to start a new project based araound the idea. A friend suggested something that has to do with graphics | ||
| and my first though was OpenSCAD, but 2D. The idea quickly grew and the small program became an image editor. | ||
| challenging myself to start a new project based around the idea. A friend suggested something that has to do with graphics | ||
| and my first though was OpenSCAD, but 2D. The idea quickly grew and the small program became an image editor. | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unresolved merge conflicts and duplicated content in README
The README currently contains unresolved merge‑conflict markers (<<<<<<<, =======, >>>>>>>), duplicated/contradictory sections (e.g., multiple “About”, “Building”, and “Test your build” variants), and inconsistent naming (“Picasso code”, “Piccasso code”, “Piccassocode”, _glimr_ vs *PiccodeScript*).
This makes the documentation hard to read and will likely break any automated README validation or linting you have.
Please fully resolve the conflicts by:
- Removing all conflict markers.
- Choosing a single, consistent project name and scripting language reference.
- Consolidating the build and “Test your build” instructions into one canonical version.
🧰 Tools
🪛 LanguageTool
[style] ~89-~89: You have already used ‘tries to’ in nearby sentences. Consider using one of the replacements to let your writing stand out.
Context: ...CAD](https://openscad.org/) program and tries to mimic its functionality ======= Picasso...
(REP_TRY)
[style] ~91-~91: You have already used ‘tries to’ in nearby sentences. Consider using one of the replacements to let your writing stand out.
Context: ...CAD](https://openscad.org/) program and tries to mimic its functionality >>>>>>> 455b066...
(REP_TRY)
🪛 markdownlint-cli2 (0.18.1)
17-17: Heading style
Expected: atx; Actual: setext
(MD003, heading-style)
24-24: Emphasis style
Expected: asterisk; Actual: underscore
(MD049, emphasis-style)
24-24: Emphasis style
Expected: asterisk; Actual: underscore
(MD049, emphasis-style)
28-28: Heading style
Expected: atx; Actual: setext
(MD003, heading-style)
29-29: Emphasis style
Expected: asterisk; Actual: underscore
(MD049, emphasis-style)
29-29: Emphasis style
Expected: asterisk; Actual: underscore
(MD049, emphasis-style)
66-66: Multiple headings with the same content
(MD024, no-duplicate-heading)
73-73: Multiple headings with the same content
(MD024, no-duplicate-heading)
80-80: Heading style
Expected: atx; Actual: setext
(MD003, heading-style)
89-89: Heading style
Expected: atx; Actual: setext
(MD003, heading-style)
🤖 Prompt for AI Agents
README.md lines 16-97: the file contains unresolved Git conflict markers and
duplicated/contradictory sections; remove all conflict markers, choose one
consistent project name (e.g., "PicassoCode") and one scripting language name
(e.g., "PiccodeScript" or "_glimr_") across the document, and consolidate the
duplicated "Building" and "Test your build" blocks into a single canonical
clone/build/test sequence (keep only one repository URL, one mvn package
instruction, and one java -jar test command), then proofread to ensure no
leftover markers or duplicate paragraphs remain.
| @@ -0,0 +1,36 @@ | |||
| #!/usr/bin/env python3 | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Make the script executable.
The shebang is present, but the file is not marked as executable.
Run the following command to fix:
#!/bin/bash
chmod +x run_readme_tests.py🧰 Tools
🪛 Ruff (0.14.4)
1-1: Shebang is present but file is not executable
(EXE001)
🤖 Prompt for AI Agents
In run_readme_tests.py around lines 1 to 1 the file contains a shebang but is
not marked executable; make the script executable by setting the executable
permission (e.g. run chmod +x run_readme_tests.py from the repository root) and
verify the file has the executable bit (ls -l) so the shebang will be honored
when invoked directly.
| public EditorSettingsDialog() { | ||
| initComponents(); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion | 🟠 Major
UI scaffolding requires event handlers and persistence logic.
The constructor initializes the UI components but there's no logic to load current settings, handle user interactions, or save changes. Essential next steps include:
- Wire event handlers for the "Pick Font" button
- Add listeners for checkboxes and combo box to enable/apply settings
- Implement logic to load and persist editor preferences
Would you like me to generate example event handler code for these components?
🤖 Prompt for AI Agents
In src/main/java/org/editor/dialogs/EditorSettingsDialog.java around lines 16 to
18, the constructor only calls initComponents() but does not load existing
preferences, wire UI event handlers, or persist changes; update the constructor
to call a loadSettings() method that reads stored editor preferences (e.g.,
java.util.prefs.Preferences) and sets initial states for checkboxes, combo box
and font display, add an ActionListener for the "Pick Font" button to open a
font chooser dialog and update the preview and a temporary settings model, add
ItemListeners/ActionListeners on checkboxes and combo box to enable/disable
related UI and update the model, and implement saveSettings() invoked from the
OK/Apply actions (and optionally on change) to persist values to Preferences and
notify the editor of changes.
| static void saveFileAs(ActionEvent e) { | ||
| if (EditorWindow.tabsCount() == 1) { | ||
| return; | ||
| } | ||
| var ed = EditorWindow.getSelectedEditor(); | ||
| if (ed == null) { | ||
| return; | ||
| } | ||
| ed.saveFileAs(); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
saveFileAs tab-count check appears inverted
The guard:
if (EditorWindow.tabsCount() == 1) {
return;
}prevents “Save As” when there is exactly one tab open, which is a common case where you’d want Save As to work. Conversely, it allows Save As when there are multiple tabs.
This condition likely intended to prevent Save As only when there are no tabs:
if (EditorWindow.tabsCount() == 0) {
return;
}Otherwise users with a single open file cannot use “Save As”.
🤖 Prompt for AI Agents
In src/main/java/org/editor/events/MenuEvents.java around lines 111 to 120, the
tab-count guard for saveFileAs is inverted: it returns when tabsCount() == 1,
preventing "Save As" for the common single-tab case. Change the guard to return
only when there are no tabs (tabsCount() == 0) so Save As is allowed when one or
more tabs exist; update the conditional accordingly and keep the remaining logic
(getting selected editor and calling saveFileAs) unchanged.
| NativeFunctionFactory.create("image_new_from_path", List.of("path"), (args, namedArgs, frame) -> { | ||
| var path = namedArgs.get("path"); | ||
|
|
||
| var ctx = frame == null ? | ||
| Context.top | ||
| : Context.getContextAt(frame); | ||
| var caller = ctx.getTopFrame().caller; | ||
|
|
||
| PiccodeValue.verifyType(caller, path, Type.STRING); | ||
|
|
||
| try { | ||
| BufferedImage image = ImageIO.read(new File(path.raw().toString())); | ||
| return new PiccodeReference(image); | ||
| } catch (IOException ex) { | ||
| var def = (BufferedImage) ImageLoader.getImage(-1); | ||
| return new PiccodeReference(def); | ||
| } | ||
| }, null); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Handle ImageIO.read returning null in image_new_from_path
image_new_from_path handles IOException and falls back to a default image, which is good. One additional edge case:
ImageIO.read(File)can returnnullwhen no appropriate reader is found, without throwing an exception. In that case, you currently wrapnullinPiccodeReference, which may later cause confusing failures when the script expects aBufferedImage.
Consider treating null like a load failure and using the same default image fallback:
- try {
- BufferedImage image = ImageIO.read(new File(path.raw().toString()));
- return new PiccodeReference(image);
- } catch (IOException ex) {
- var def = (BufferedImage) ImageLoader.getImage(-1);
- return new PiccodeReference(def);
- }
+ try {
+ BufferedImage image = ImageIO.read(new File(path.raw().toString()));
+ if (image == null) {
+ var def = (BufferedImage) ImageLoader.getImage(-1);
+ return new PiccodeReference(def);
+ }
+ return new PiccodeReference(image);
+ } catch (IOException ex) {
+ var def = (BufferedImage) ImageLoader.getImage(-1);
+ return new PiccodeReference(def);
+ }This keeps the behavior consistent between silent read failures and IO failures.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| NativeFunctionFactory.create("image_new_from_path", List.of("path"), (args, namedArgs, frame) -> { | |
| var path = namedArgs.get("path"); | |
| var ctx = frame == null ? | |
| Context.top | |
| : Context.getContextAt(frame); | |
| var caller = ctx.getTopFrame().caller; | |
| PiccodeValue.verifyType(caller, path, Type.STRING); | |
| try { | |
| BufferedImage image = ImageIO.read(new File(path.raw().toString())); | |
| return new PiccodeReference(image); | |
| } catch (IOException ex) { | |
| var def = (BufferedImage) ImageLoader.getImage(-1); | |
| return new PiccodeReference(def); | |
| } | |
| }, null); | |
| NativeFunctionFactory.create("image_new_from_path", List.of("path"), (args, namedArgs, frame) -> { | |
| var path = namedArgs.get("path"); | |
| var ctx = frame == null ? | |
| Context.top | |
| : Context.getContextAt(frame); | |
| var caller = ctx.getTopFrame().caller; | |
| PiccodeValue.verifyType(caller, path, Type.STRING); | |
| try { | |
| BufferedImage image = ImageIO.read(new File(path.raw().toString())); | |
| if (image == null) { | |
| var def = (BufferedImage) ImageLoader.getImage(-1); | |
| return new PiccodeReference(def); | |
| } | |
| return new PiccodeReference(image); | |
| } catch (IOException ex) { | |
| var def = (BufferedImage) ImageLoader.getImage(-1); | |
| return new PiccodeReference(def); | |
| } | |
| }, null); |
🤖 Prompt for AI Agents
In src/main/java/org/editor/nativemods/PiccodeImageModule.java around lines 74
to 91, image_new_from_path currently only catches IOExceptions but does not
handle ImageIO.read returning null; update the try block to check if the
BufferedImage returned is null and, in that case, use the existing default image
fallback (e.g., via ImageLoader.getImage(-1)) and return a PiccodeReference to
that default instead of wrapping null; keep the same behavior for IOException
and ensure the method always returns a non-null PiccodeReference.
| NativeFunctionFactory.create("image_resize", List.of("img" ,"w", "h"), (args, namedArgs, frame) -> { | ||
| var img = namedArgs.get("img"); | ||
| var w = namedArgs.get("w"); | ||
| var h = namedArgs.get("h"); | ||
|
|
||
| var ctx = frame == null ? | ||
| Context.top | ||
| : Context.getContextAt(frame); | ||
| var caller = ctx.getTopFrame().caller; | ||
|
|
||
| PiccodeValue.verifyType(caller, img, Type.REFERENCE); | ||
| PiccodeValue.verifyType(caller, w, Type.NUMBER); | ||
| PiccodeValue.verifyType(caller, h, Type.NUMBER); | ||
|
|
||
| var _buffered_image = ((PiccodeReference)img).deref(); | ||
|
|
||
| if (!(_buffered_image instanceof BufferedImage)) { | ||
| throw new PiccodeException(caller.file, caller.line, caller.column, "Expected a buffer image. Found " + _buffered_image); | ||
| } | ||
|
|
||
| var bufferedmage = (BufferedImage) _buffered_image; | ||
|
|
||
| var _w = (int) (double) ((PiccodeNumber) w).raw(); | ||
| var _h = (int) (double) ((PiccodeNumber) h).raw(); | ||
|
|
||
| Image resultingImage = bufferedmage.getScaledInstance(_w, _h, Image.SCALE_DEFAULT); | ||
| BufferedImage outputImage = new BufferedImage(_w, _h, BufferedImage.TYPE_INT_RGB); | ||
| outputImage.getGraphics().drawImage(resultingImage, 0, 0, null); | ||
|
|
||
| return new PiccodeReference(outputImage); | ||
| }, null); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
image_resize drops alpha and leaks a Graphics instance
The resize implementation is mostly correct but has two issues:
-
Alpha is lost
- You create the target as
BufferedImage.TYPE_INT_RGB, which strips any alpha channel even if the source image is ARGB (e.g., created viaimage_new). This can break rendering where transparency is expected.
- You create the target as
-
GraphicsfromoutputImageis never disposedoutputImage.getGraphics()allocates aGraphicsinstance that should bedispose()d after use to avoid leaking resources.
Suggested fix:
- Image resultingImage = bufferedmage.getScaledInstance(_w, _h, Image.SCALE_DEFAULT);
- BufferedImage outputImage = new BufferedImage(_w, _h, BufferedImage.TYPE_INT_RGB);
- outputImage.getGraphics().drawImage(resultingImage, 0, 0, null);
+ Image resultingImage = bufferedmage.getScaledInstance(_w, _h, Image.SCALE_DEFAULT);
+ // Preserve alpha if the source has it; default to ARGB for safety.
+ int type = bufferedmage.getColorModel().hasAlpha()
+ ? BufferedImage.TYPE_INT_ARGB
+ : BufferedImage.TYPE_INT_RGB;
+ BufferedImage outputImage = new BufferedImage(_w, _h, type);
+ var g = outputImage.createGraphics();
+ try {
+ g.drawImage(resultingImage, 0, 0, null);
+ } finally {
+ g.dispose();
+ }This preserves transparency when present and cleans up the interim Graphics.
| jLabel4.setText("Brought to you by Solaris Studio developers"); | ||
|
|
||
| jTextPane1.setEditable(false); | ||
| jTextPane1.setBackground(new java.awt.Color(255, 255, 255)); | ||
| jTextPane1.setText("\ndrawString(\"\n+--------------------------------------------+\n | ▄▖▘ ▌ |\n | ▙▌▌▛▘▀▌▛▘▛▘▛▌▛▘▛▌▛▌█▌ |\n | ▌ ▌▙▖█▌▄▌▄▌▙▌▙▖▙▌▙▌▙▖ |\n | Creativity + Logic + Math |\n+---------------------------------------------+\n\", 0, 0)\n\nBrought to you by glimmr developers\n\nLead developer: Gama Sibusiso Vincent\nAI and Plugin intergration: TODO\nDocumenentation: TODO\n\nCreated 100% in java using java swing, antlr4 and flatlaf. \nIcons pack dowloaded from icons8"); | ||
| jTextPane1.setText("\nPen::drawText(\"\n+--------------------------------------------+\n | ▄▖▘ ▌ |\n | ▙▌▌▛▘▀▌▛▘▛▘▛▌▛▘▛▌▛▌█▌ |\n | ▌ ▌▙▖█▌▄▌▄▌▙▌▙▖▙▌▙▌▙▖ |\n | Creativity + Logic + Math |\n+---------------------------------------------+\n\", 0, 0)\n\nBrought to you by glimmr developers\n\nLead developer: Gama Sibusiso Vincent\nAI and Plugin intergration: TODO\nDocumenentation: TODO\n\nCreated 100% in java using java swing, antlr4 and flatlaf. \nIcons pack dowloaded from icons8"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Inconsistent branding in About panel.
Line 41 updates the label to reference "Solaris Studio developers", but Line 45's text content still contains "Brought to you by glimmr developers" (note lowercase "glimmr"). This creates confusion about the project's identity.
Apply this diff to make the branding consistent:
-jTextPane1.setText("\nPen::drawText(\"\n+--------------------------------------------+\n | ▄▖▘ ▌ |\n | ▙▌▌▛▘▀▌▛▘▛▘▛▌▛▘▛▌▛▌█▌ |\n | ▌ ▌▙▖█▌▄▌▄▌▙▌▙▖▙▌▙▌▙▖ |\n | Creativity + Logic + Math |\n+---------------------------------------------+\n\", 0, 0)\n\nBrought to you by glimmr developers\n\nLead developer: Gama Sibusiso Vincent\nAI and Plugin intergration: TODO\nDocumenentation: TODO\n\nCreated 100% in java using java swing, antlr4 and flatlaf. \nIcons pack dowloaded from icons8");
+jTextPane1.setText("\nPen::drawText(\"\n+--------------------------------------------+\n | ▄▖▘ ▌ |\n | ▙▌▌▛▘▀▌▛▘▛▘▛▌▛▘▛▌▛▌█▌ |\n | ▌ ▌▙▖█▌▄▌▄▌▙▌▙▖▙▌▙▌▙▖ |\n | Creativity + Logic + Math |\n+---------------------------------------------+\n\", 0, 0)\n\nBrought to you by Solaris Studio developers\n\nLead developer: Gama Sibusiso Vincent\nAI and Plugin integration: TODO\nDocumentation: TODO\n\nCreated 100% in java using java swing, antlr4 and flatlaf. \nIcons pack downloaded from icons8");Note: This also fixes typos "intergration" → "integration" and "Documenentation" → "Documentation" and "dowloaded" → "downloaded".
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| jLabel4.setText("Brought to you by Solaris Studio developers"); | |
| jTextPane1.setEditable(false); | |
| jTextPane1.setBackground(new java.awt.Color(255, 255, 255)); | |
| jTextPane1.setText("\ndrawString(\"\n+--------------------------------------------+\n | ▄▖▘ ▌ |\n | ▙▌▌▛▘▀▌▛▘▛▘▛▌▛▘▛▌▛▌█▌ |\n | ▌ ▌▙▖█▌▄▌▄▌▙▌▙▖▙▌▙▌▙▖ |\n | Creativity + Logic + Math |\n+---------------------------------------------+\n\", 0, 0)\n\nBrought to you by glimmr developers\n\nLead developer: Gama Sibusiso Vincent\nAI and Plugin intergration: TODO\nDocumenentation: TODO\n\nCreated 100% in java using java swing, antlr4 and flatlaf. \nIcons pack dowloaded from icons8"); | |
| jTextPane1.setText("\nPen::drawText(\"\n+--------------------------------------------+\n | ▄▖▘ ▌ |\n | ▙▌▌▛▘▀▌▛▘▛▘▛▌▛▘▛▌▛▌█▌ |\n | ▌ ▌▙▖█▌▄▌▄▌▙▌▙▖▙▌▙▌▙▖ |\n | Creativity + Logic + Math |\n+---------------------------------------------+\n\", 0, 0)\n\nBrought to you by glimmr developers\n\nLead developer: Gama Sibusiso Vincent\nAI and Plugin intergration: TODO\nDocumenentation: TODO\n\nCreated 100% in java using java swing, antlr4 and flatlaf. \nIcons pack dowloaded from icons8"); | |
| jLabel4.setText("Brought to you by Solaris Studio developers"); | |
| jTextPane1.setEditable(false); | |
| jTextPane1.setBackground(new java.awt.Color(255, 255, 255)); | |
| jTextPane1.setText("\nPen::drawText(\"\n+--------------------------------------------+\n | ▄▖▘ ▌ |\n | ▙▌▌▛▘▀▌▛▘▛▘▛▌▛▘▛▌▛▌█▌ |\n | ▌ ▌▙▖█▌▄▌▄▌▙▌▙▖▙▌▙▌▙▖ |\n | Creativity + Logic + Math |\n+---------------------------------------------+\n\", 0, 0)\n\nBrought to you by Solaris Studio developers\n\nLead developer: Gama Sibusiso Vincent\nAI and Plugin integration: TODO\nDocumentation: TODO\n\nCreated 100% in java using java swing, antlr4 and flatlaf. \nIcons pack downloaded from icons8"); |
🤖 Prompt for AI Agents
In src/main/java/org/editor/panels/AboutPanel.java around lines 41 to 45, the
label text and the large jTextPane1 content have inconsistent branding and
several typos; update the jTextPane1 string to match "Solaris Studio developers"
(capitalize consistently), replace the "Brought to you by glimmr developers"
line with "Brought to you by Solaris Studio developers", and fix typos: change
"intergration" to "integration", "Documenentation" to "Documentation", and
"dowloaded" to "downloaded"; ensure the surrounding punctuation and spacing
remain valid for the Java string literal.
| def test_file_encoding_and_format(self): | ||
| """Test that README file has proper encoding and line endings.""" | ||
| readme_path = Path("README.md") | ||
| if readme_path.exists(): | ||
| # Test that file can be read as UTF-8 | ||
| try: | ||
| content = readme_path.read_text(encoding='utf-8') | ||
| assert len(content) > 0, "File should be readable as UTF-8" | ||
| except UnicodeDecodeError: | ||
| pytest.fail("README.md should be encoded in UTF-8") | ||
|
|
||
| # Test for reasonable line lengths (soft limit) | ||
| lines = content.split('\n') | ||
| long_lines = [i for i, line in enumerate(lines, 1) if len(line) > 120] | ||
| # This is a soft warning rather than hard failure | ||
| if len(long_lines) > 3: | ||
| pytest.warn(f"Many lines exceed 120 characters: lines {long_lines[:5]}") | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
pytest.warn will fail at runtime; use warnings.warn instead
pytest has warns (context manager) but no warn function, so pytest.warn(...) will raise an AttributeError and break the suite. For a soft warning, use the standard warnings module.
A minimal fix:
-import pytest
+import pytest
+import warnings
@@
- long_lines = [i for i, line in enumerate(lines, 1) if len(line) > 120]
- # This is a soft warning rather than hard failure
- if len(long_lines) > 3:
- pytest.warn(f"Many lines exceed 120 characters: lines {long_lines[:5]}")
+ long_lines = [i for i, line in enumerate(lines, 1) if len(line) > 120]
+ # This is a soft warning rather than hard failure
+ if len(long_lines) > 3:
+ warnings.warn(
+ f"Many lines in README.md exceed 120 characters: lines {long_lines[:5]}",
+ stacklevel=2,
+ )🏁 Script executed:
#!/bin/bash
# Check if file exists and examine lines 220-237
if [ -f "tests/test_readme_validation.py" ]; then
echo "=== File found. Examining lines 220-237 ==="
sed -n '220,237p' tests/test_readme_validation.py
echo ""
echo "=== Checking imports at top of file ==="
head -20 tests/test_readme_validation.py
else
echo "File not found at tests/test_readme_validation.py"
fiLength of output: 1555
🏁 Script executed:
#!/bin/bash
# Search for pytest.warn usage in the codebase
echo "=== Searching for pytest.warn usage ==="
rg -n "pytest\.warn\(" --type pyLength of output: 164
🏁 Script executed:
#!/bin/bash
# Verify pytest module capabilities
python3 << 'EOF'
import pytest
# Check if warn method exists on pytest
if hasattr(pytest, 'warn'):
print("pytest.warn exists")
else:
print("pytest.warn does NOT exist")
# Check what warn-related methods pytest has
warn_methods = [attr for attr in dir(pytest) if 'warn' in attr.lower()]
print(f"pytest has these warn-related attributes: {warn_methods}")
EOFLength of output: 486
pytest.warn() does not exist and will cause runtime failure; use warnings.warn() instead
Line 236 calls pytest.warn() which is not a valid pytest function (pytest only has warns as a context manager, not a warn function). This will raise AttributeError when the test runs. Use the standard warnings module instead.
Required fix:
import pytest
import re
import requests
+import warnings
from pathlib import Path long_lines = [i for i, line in enumerate(lines, 1) if len(line) > 120]
# This is a soft warning rather than hard failure
if len(long_lines) > 3:
- pytest.warn(f"Many lines exceed 120 characters: lines {long_lines[:5]}")
+ warnings.warn(
+ f"Many lines in README.md exceed 120 characters: lines {long_lines[:5]}",
+ stacklevel=2,
+ )Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In tests/test_readme_validation.py around lines 220 to 237, the test uses
pytest.warn(...) which does not exist and will raise an AttributeError at
runtime; replace the call with warnings.warn(<message>, category=UserWarning,
stacklevel=2) and ensure you import the warnings module at the top of the file
(import warnings) so the test emits a soft warning instead of failing.
This commit hopefully accomplishes the todo that was made to use the system object to get the current working directory
Summary by CodeRabbit
Release Notes
New Features
Chores