Replace Monaco with CodeMirror#36764
Conversation
- Replace monaco-editor with @codemirror/* packages for the code editor - Use @codemirror/language-data for automatic language detection - Use @lezer/highlight classHighlighter for CSS class-based syntax highlighting - Define --color-syntax-* CSS variables in both themes, shared by CodeMirror 6 and EasyMDE - Move all editor styling to CSS (codeeditor.css), no CSS-in-JS - Add placeholder, rectangularSelection, crosshairCursor, highlightSelectionMatches extensions - Add translatable placeholder text for the editor textarea - Add e2e test for the code editor - Remove MonacoWebpackPlugin and monaco-editor dependencies Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The function was only returning false after Monaco removal and served no purpose. Flatten the remaining error check into a single condition. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This comment was marked as resolved.
This comment was marked as resolved.
There was a problem hiding this comment.
Pull request overview
This PR replaces the existing Monaco-based repository code editor with a CodeMirror 6 implementation to improve mobile usability and reduce frontend build/bundle size, while also aligning syntax highlighting across the code editor and EasyMDE via shared CSS variables.
Changes:
- Remove Monaco (and its webpack worker/plugin setup) and introduce a new CodeMirror 6 editor module with matching CSS.
- Add shared
--color-syntax-*theme variables and update EasyMDE highlighting to use them. - Add a Playwright e2e test to verify editor-to-textarea synchronization.
Reviewed changes
Copilot reviewed 20 out of 22 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
webpack.config.ts |
Removes Monaco webpack plugin/worker configuration. |
web_src/js/modules/codeeditor.ts |
New CodeMirror 6 editor implementation (creation, language detection, option handling). |
web_src/js/features/repo-editor.ts |
Switches repo editor to the new CodeMirror module and updates value-setting logic. |
web_src/js/features/repo-settings.ts |
Switches git hook editor to the new CodeMirror module. |
web_src/js/globals.d.ts |
Clarifies exported window.codeEditors contents for customization. |
web_src/js/bootstrap.ts / web_src/js/bootstrap.test.ts |
Removes Monaco-specific ignored-error logic and its unit test. |
web_src/css/themes/theme-gitea-{light,dark}.css |
Adds new --color-syntax-* variables for highlighting. |
web_src/css/modules/codeeditor.css |
New CodeMirror-focused styling for the code editor UI. |
web_src/css/index.css |
Switches code editor CSS import from features/ to modules/. |
web_src/css/easymde.css |
Updates EasyMDE token colors to use shared --color-syntax-* variables. |
web_src/css/features/codeeditor.css |
Removes Monaco-specific styling. |
web_src/css/codemirror/{light,dark}.css |
Removes legacy CodeMirror theme overrides/imports. |
templates/repo/editor/{edit,patch}.tmpl |
Adds a textarea placeholder used by the new CodeMirror editor. |
options/locale/locale_en-US.json |
Adds translation for the new placeholder string. |
tests/e2e/codeeditor.test.ts |
Adds e2e coverage for editor-to-textarea updates. |
package.json / pnpm-lock.yaml |
Removes Monaco deps and adds CodeMirror 6 + Lezer highlight deps. |
Files not reviewed (1)
- pnpm-lock.yaml: Language not supported
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
The drawSelection() extension renders the selection layer behind the content layer, so the active line background was covering it entirely. Override CodeMirror's transparent ::selection with the selection color at higher specificity so native selection renders on top of everything. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Fixed in 3734024. |
Address Copilot review feedback: - Align default indent size to 4 to match the UI dropdown default - Unify indent style/size change handlers so both indentUnit and tabSize update together when either dropdown changes - Use synthetic .sh filename for git hooks to enable shell highlighting Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The drawSelection() extension renders selection behind the content layer, so the active line background was covering it. Disable the active line highlight to let the selection layer show through cleanly. Also increase ::selection specificity to properly override CodeMirror's injected styles for text color. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Use a semi-transparent active line highlight (40% opacity via color-mix) so it's visible but doesn't dominate the selection. Override ::selection at higher specificity to render native selection on top of the active line, ensuring text selection is clearly visible in both light and dark themes. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace color-mix with direct hex colors for the active line highlight, keeping the blue hue but much closer to the code background so the selection remains clearly visible on top. Dark: #1a2433 (was #193450), Light: #ecf2f8 (was #d9e6f3) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Set uniform 12px font size on .cm-editor for consistent gutter/content sizing - Use SVG octicon chevrons for fold gutter markers - Use octicon-kebab-horizontal for fold placeholders - Move search panel to top of editor - Restyle search panel with GitHub-like two-row flexbox layout - Use proportional font in search/replace panels - Override all CodeMirror hardcoded colors with CSS variables - Theme buttons, textfields, tooltips, and checkboxes to match Gitea Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Merge chroma/base.css, chroma/light.css, and chroma/dark.css into a single modules/chroma.css where all colors reference --color-syntax-* CSS variables defined in each theme. This makes syntax highlighting fully themeable without per-theme chroma files. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
bircni
left a comment
There was a problem hiding this comment.
trim_trailing_whitespace is now only done in backend - previously I think it was also done in frontend?
CodeMirror does not have such a feature currently, but maybe it can be re-implemented. |
Read the trim_trailing_whitespace setting from .editorconfig (already passed by the backend) and apply it in the CodeMirror editor: - Visually highlight trailing whitespace via highlightTrailingWhitespace() - Trim all trailing whitespace on commit via trimTrailingWhitespaceFromView() Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Implemented in 8f09499. |
Cool already saw it!! 😄 |
Co-Authored-By: Claude (Opus 4.6) <noreply@anthropic.com>
|
When you're ready feel free to tag me |
Co-Authored-By: Claude (Opus 4.6) <noreply@anthropic.com>
|
It is ready for review. All monaco feature besides hover tooltips are implemented. Besides a few small tweaks, I don't expect any more major changes. |
|
Could you update the description? it still states webpack |
I will benchmark size and speed again later.
Yes the fold chevrons are a bit visually distracting. I will probably make them only show when cursor hovers over that column, like in VSCode. |
Show fold triangles only on gutter hover, reduce their size to 13px, fix cut-off on first line, reduce fold placeholder to 13px, and add --color-editor-selection variable for text selection background. Co-Authored-By: Claude (Opus 4.6) <noreply@anthropic.com>
Use replaceWith to atomically swap the loading placeholder with the editor container, and add min-height: 90vh to the container to match the loading placeholder height. Co-Authored-By: Claude (Opus 4.6) <noreply@anthropic.com>
|
All done:
|
|
Code review for #36764 (by Claude Sonnet 4.6) Issues to address before merging:
Minor:
|
Move lintGutter into getLinterExtension so it only appears when a linter is active. Skip linter for StreamLanguage-based languages which cannot produce Lezer error nodes. Avoid double-loading the language by passing the loaded result directly. Co-Authored-By: Claude (Opus 4.6) <noreply@anthropic.com>
Co-Authored-By: Claude (Opus 4.6) <noreply@anthropic.com>
Co-Authored-By: Claude (Opus 4.6) <noreply@anthropic.com>
There's only one editor per page currently. The FIXME is already there acknowledging this needs a broader refactor.
Fixed in 5bbf069.
These are inside an
This is the same approach VSCode takes. These are the well-known JSONC filenames. The regex is easy to extend if needed.
Both themes always define all variables. Custom themes inherit from the default themes. Fallback values would be dead code.
Inherent to styling CodeMirror internals. These selectors are pinned to the current CodeMirror version and would be reviewed on upgrades.
Valid, but a separate effort. More e2e tests can be added incrementally.
The current form is more concise and the
It's positioned above CodeMirror's internal z-indexes (which go up to 300) and below Gitea's modal overlays. Works correctly.
Intentional: This comment was written by Claude Opus 4.6. |
|
#36764 (comment) is updated and includes a table of build size and performance. |
This rule enablement belongs in a separate PR. Co-Authored-By: Claude (Opus 4.6) <noreply@anthropic.com>
Co-Authored-By: Claude (Opus 4.6) <noreply@anthropic.com>
Extend goToDefinitionAt to recognize identifier nodes from Go, Java, Rust, and C++ Lezer grammars in addition to JS/TS. Extend collectSymbols to find Go functions, methods, and type declarations. Co-Authored-By: Claude (Opus 4.6) <noreply@anthropic.com>
Listen on document instead of document.body for scroll events. Co-Authored-By: Claude (Opus 4.6) <noreply@anthropic.com>
Block all keyboard input while context menu is open except Escape and Enter. Use capture phase to prevent CodeMirror from handling arrow keys. Co-Authored-By: Claude (Opus 4.6) <noreply@anthropic.com>
…verrides Use the existing clippie library for Cut/Copy clipboard operations instead of raw navigator.clipboard.writeText. This handles errors internally and provides an execCommand fallback. Cut now only deletes text on successful clipboard write. Remove per-component kbd font-size overrides that are no longer needed since the global kbd rule provides the correct size. Co-Authored-By: Claude (Opus 4.6) <noreply@anthropic.com>







--color-syntax-*CSS variables for all syntax token types, shared by CodeMirror, Chroma and EasyMDEmodules/chroma.css)window.codeEditorsglobalFixes: #36311
Fixes: #14776
Fixes: #12171