Skip to content
This repository was archived by the owner on May 18, 2026. It is now read-only.

feat: replace Ace Editor with Monaco Editor#513

Merged
takaokouji merged 30 commits into
developfrom
feature/monaco-editor
Jan 12, 2026
Merged

feat: replace Ace Editor with Monaco Editor#513
takaokouji merged 30 commits into
developfrom
feature/monaco-editor

Conversation

@takaokouji

@takaokouji takaokouji commented Jan 11, 2026

Copy link
Copy Markdown

Summary

This PR replaces the Ace Editor with Monaco Editor (v0.55.1) in the Ruby tab, significantly improving the code editing experience in Smalruby 3.

Implementation Details

  • Core Migration: Switched from react-ace to @monaco-editor/react using CDN-based loading (v0.55.1).
  • Japanese Localization: Implemented UI translation (menus, context menus) for Japanese using Monaco NLS messages.
  • Improved UI/UX:
    • Enabled fixedOverflowWidgets to prevent error popups from being cut off.
    • Enabled scrollBeyondLastLine for a better editing experience at the end of files (similar to VS Code).
    • Automatically show the error widget (Peek view) when Ruby code errors or conversion failures occur.
    • Automatically clear markers and close active widgets when switching away from the Ruby tab.
    • Relocated the "Ruby Download" button to the bottom-right (next to zoom controls) to avoid overlapping with editor widgets.
  • Integration & Testing:
    • Exposed window.monacoEditor and window.monaco in production builds to support existing integration tests.
    • Updated ruby-helper.js and integration tests to compatible with Monaco API.
  • Dependency Cleanup: Removed ace-builds, react-ace, monaco-editor-webpack-plugin, and monaco-editor-nls.

Related Issue

Closes smalruby/smalruby3-develop#16 (Phase 1)

Testing

  • Verified all integration tests in test/integration/ruby-tab/ pass.
  • Verified Japanese UI localization works correctly.
  • Verified error widget behavior and button layout on various screen sizes.

🤖 Generated with Gemini Code

Co-Authored-By: Gemini noreply@google.com

takaokouji and others added 19 commits January 12, 2026 14:17
- Replace react-ace and ace-builds with @monaco-editor/react
- Implement basic Monaco Editor integration in RubyTab component
- Maintain Ruby syntax support and basic editor features
- Update editor focus and cursor positioning for conversion errors
- Fix: Ensure editor focuses correctly when switching tabs or on errors

This is the initial minimal implementation for Issue #16.

🤖 Generated with [Gemini Code](https://gemini.google.com/code)

Co-Authored-By: Gemini <noreply@google.com>
- Add Monaco-compatible completion provider using existing snippets
- Convert snippet documentation from HTML to Markdown
- Implement real-time error markers using setModelMarkers
- Ensure markers are cleared on successful conversion
- Improve tooltip formatting for code snippets

🤖 Generated with [Gemini Code](https://gemini.google.com/code)

Co-Authored-By: Gemini <noreply@google.com>
- Define custom 'smalruby' language with Monarch
- Highlight Smalruby-specific methods (move, turn_right, etc.) as distinct tokens
- Restrict syntax highlighting to keywords and methods relevant to Smalruby
- Update RubyTab to use the new 'smalruby' language mode
- Fix lint errors and improve regex robustness for the language definition

🤖 Generated with [Gemini Code](https://gemini.google.com/code)

Co-Authored-By: Gemini <noreply@google.com>
- Add fontSize state and updateRubyFontSize action to rubyCode reducer
- Implement font size selector UI in RubyTab
- Link Monaco Editor fontSize option to Redux state
- Fix varios lint errors and typos in reducer and container

🤖 Generated with [Gemini Code](https://gemini.google.com/code)

Co-Authored-By: Gemini <noreply@google.com>
- Implement zoom-in, zoom-out, and zoom-reset functionality for the Ruby editor
- Use Scratch-style SVG icons (zoom-in.svg, zoom-out.svg, zoom-reset.svg)
- Style zoom buttons to match Scratch UI conventions (stacked vertically above download button)
- Use a step-based sequence for font size adjustment

🤖 Generated with [Gemini Code](https://gemini.google.com/code)

Co-Authored-By: Gemini <noreply@google.com>
- Remove background, border, and hover effects from zoom buttons
- Set zoom icon size to 36x36px (2.25rem)
- Background is now transparent as requested

🤖 Generated with [Gemini Code](https://gemini.google.com/code)

Co-Authored-By: Gemini <noreply@google.com>
- Change .wrapper height from fixed 2.75rem to auto
- Remove border-radius: 100% from .wrapper
- This allows the zoom buttons to be properly positioned above the download button

🤖 Generated with [Gemini Code](https://gemini.google.com/code)

Co-Authored-By: Gemini <noreply@google.com>
- Set position to bottom: 12px and right: 27px (12px margin + 15px scrollbar)
- Use 36px fixed size for zoom buttons and icons
- Set 8px margin between buttons (MARGIN_BETWEEN)
- Center zoom buttons above the download button using flexbox

🤖 Generated with [Gemini Code](https://gemini.google.com/code)

Co-Authored-By: Gemini <noreply@google.com>
- Rename .button to .downloadButton and .img to .downloadIcon
- Set icon size to 28x28px
- Remove hover effect from download button
- Ensure proper positioning within the vertical flex container

🤖 Generated with [Gemini Code](https://gemini.google.com/code)

Co-Authored-By: Gemini <noreply@google.com>
…right

- Separate download and zoom controls into independent wrappers
- Position download button at top: 1rem, right: 1rem
- Position zoom controls at bottom: 12px, right: 27px (Blockly alignment)
- Remove unused .wrapper and .zoomWrapper classes

🤖 Generated with [Gemini Code](https://gemini.google.com/code)

Co-Authored-By: Gemini <noreply@google.com>
- Add minWidth: 0 to the Monaco Editor's container div
- This ensures the flex child can shrink below its initial content size,
  allowing Monaco's automaticLayout to respond correctly to window narrowing.

🤖 Generated with [Gemini Code](https://gemini.google.com/code)

Co-Authored-By: Gemini <noreply@google.com>
- Add ResizeObserver to monitor editor container size changes
- Manually trigger editor.layout() on resize events
- Add overflow: 'hidden' to the editor container to allow shrinking
- Implement proper cleanup for ResizeObserver in componentWillUnmount
- Call layout() when editor becomes visible to ensure correct initial size

🤖 Generated with [Gemini Code](https://gemini.google.com/code)

Co-Authored-By: Gemini <noreply@google.com>
- Revert previous failed ResizeObserver and minWidth attempts
- Implement window 'resize' listener to manually trigger editor.layout()
- Add minWidth: 0, overflow: 'hidden', and position: 'relative'
- This ensures the container can shrink and editor recalculates size.

🤖 Generated with [Gemini Code](https://gemini.google.com/code)

Co-Authored-By: Gemini <noreply@google.com>
- Add ResizeObserver to manually trigger editor.layout()
- Set minWidth: 0 and overflow: hidden on editor container
- This follows recommendations from Monaco Editor issue scratchfoundation#3393
- Ensures editor shrinks correctly when window size decreases

🤖 Generated with [Gemini Code](https://gemini.google.com/code)

Co-Authored-By: Gemini <noreply@google.com>
- Wrap Editor in a div with position: 'absolute' and inset: 0
- This ensures the editor doesn't inflate the flex container's min-width
- This allows the parent container to shrink correctly when the window narrows
- Retain manual layout() calls on window resize for maximum robustness

🤖 Generated with [Gemini Code](https://gemini.google.com/code)

Co-Authored-By: Gemini <noreply@google.com>
- Fix 'TypeError: Expected a function' caused by missing method in bindAll
- Ensure all methods bound in constructor are correctly defined in the class

🤖 Generated with [Gemini Code](https://gemini.google.com/code)

Co-Authored-By: Gemini <noreply@google.com>
- Move inline styles to CSS
- Remove redundant automaticLayout option (handled by ResizeObserver)
- Organize code and remove investigative comments/ignored variables
@takaokouji takaokouji force-pushed the feature/monaco-editor branch from a04dad0 to d6360b8 Compare January 12, 2026 05:17
takaokouji and others added 10 commits January 12, 2026 14:27
- Remove ace-builds and react-ace dependencies
- Fix regex escaping in smalruby-mode.js
- Implement localStorage persistence for rubyFontSize
- Dispose completionProvider in componentWillUnmount
- Fix typo in ruby-code reducer
- Always expose window.monacoEditor and window.monaco for integration tests
- Update Monaco markers when Redux errors change (fixes 'Go' button behavior)
- Add Monaco API-based error helper methods to RubyHelper
- Replace Ace-specific XPaths with Monaco error detection in ruby-tab.test.js

Co-Authored-By: Gemini <noreply@google.com>
- Implement dynamic localization using loader.config with fixed CDN path (0.55.1)
- Force re-mounting Editor on locale change to ensure i18n is applied
- Clear error markers and close zone widgets when switching away from Ruby tab
- Enable fixedOverflowWidgets to prevent error popups from being cut off at the top
- Clear error markers and close zone widgets when switching away from Ruby tab
- Enable fixedOverflowWidgets to prevent error popups from being cut off at the top
- Reverted unsuccessful dynamic localization changes for further investigation
… attempt)

- Clear error markers and close zone widgets when switching away from Ruby tab
- Enable fixedOverflowWidgets to prevent error popups from being cut off at the top
- Add .ttf support to webpack config to handle Monaco fonts
- Reverted failed local monaco-editor import for further investigation
- Added monaco-i18n-helper.js to handle Monaco UI localization (menus, context menus)
- Configured Monaco loader to use v0.55.1 from CDN with Japanese NLS messages
- Re-mount Monaco editor when locale changes to apply translation
- Removed unused monaco-editor-webpack-plugin and monaco-editor-nls
- Added "Hira" to cspell.json

🤖 Generated with [Gemini Code](https://gemini.google.com/code)

Co-Authored-By: Gemini <noreply@google.com>
- Trigger 'editor.action.marker.next' when errors are detected
- Applied to live updates and block conversion failures

🤖 Generated with [Gemini Code](https://gemini.google.com/code)

Co-Authored-By: Gemini <noreply@google.com>
- Moved download button from top-right to bottom-right to prevent overlap with Monaco error widgets
- Positioned it just left of the zoom controls
- Updated tooltip placement to 'top' and adjusted its arrow CSS

🤖 Generated with [Gemini Code](https://gemini.google.com/code)

Co-Authored-By: Gemini <noreply@google.com>
- Set scrollBeyondLastLine to true to allow scrolling past the end of the code

🤖 Generated with [Gemini Code](https://gemini.google.com/code)

Co-Authored-By: Gemini <noreply@google.com>
@takaokouji takaokouji merged commit c636db9 into develop Jan 12, 2026
2 checks passed
@takaokouji takaokouji deleted the feature/monaco-editor branch January 12, 2026 15:36
github-actions Bot pushed a commit that referenced this pull request Jan 12, 2026
…o-editor

feat: replace Ace Editor with Monaco Editor

closes #509
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Ace Editor を Monaco Editor にリプレースする

1 participant