feat: Implement CodeMirror 6 file editor with tab support

Implement Phase 1 of the file editor & chat UI redesign:
- CodeMirror 6 integration with syntax highlighting
- Multi-file tab support with dirty state tracking
- Custom dark theme matching GitHub's color scheme
- Keyboard shortcuts (Ctrl+S to save, Ctrl+W to close tab)
- Mobile-responsive design with proper touch targets
- Fallback to basic textarea if CodeMirror fails to load

Technical details:
- Import map for ESM modules from node_modules
- Language support for JS, Python, HTML, CSS, JSON, Markdown
- Auto-initialization on DOM ready
- Global window.fileEditor instance for integration
- Serve node_modules at /claude/node_modules for import map

Files added:
- public/claude-ide/components/file-editor.js (main component)
- public/claude-ide/components/file-editor.css (responsive styles)

Files modified:
- public/claude-ide/index.html (import map, script tags)
- public/claude-ide/ide.js (updated loadFile function)
- server.js (serve node_modules for CodeMirror)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
uroma
2026-01-21 08:49:01 +00:00
Unverified
parent 9e445bf653
commit b765c537fc
5 changed files with 1185 additions and 49 deletions

View File

@@ -10,7 +10,41 @@
<link rel="stylesheet" href="/claude/claude-ide/preview-manager.css">
<link rel="stylesheet" href="/claude/claude-ide/chat-enhanced.css">
<link rel="stylesheet" href="/claude/claude-ide/terminal.css">
<link rel="stylesheet" href="/claude/claude-ide/components/file-editor.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/github-dark.min.css">
<!-- Import Map for CodeMirror 6 -->
<script type="importmap">
{
"imports": {
"@codemirror/state": "/claude/node_modules/@codemirror/state/dist/index.cjs",
"@codemirror/view": "/claude/node_modules/@codemirror/view/dist/index.cjs",
"@codemirror/commands": "/claude/node_modules/@codemirror/commands/dist/index.cjs",
"@codemirror/language": "/claude/node_modules/@codemirror/language/dist/index.cjs",
"@codemirror/autocomplete": "/claude/node_modules/@codemirror/autocomplete/dist/index.cjs",
"@codemirror/search": "/claude/node_modules/@codemirror/search/dist/index.cjs",
"@codemirror/lint": "/claude/node_modules/@codemirror/lint/dist/index.cjs",
"@codemirror/lang-javascript": "/claude/node_modules/@codemirror/lang-javascript/dist/index.cjs",
"@codemirror/lang-python": "/claude/node_modules/@codemirror/lang-python/dist/index.cjs",
"@codemirror/lang-html": "/claude/node_modules/@codemirror/lang-html/dist/index.cjs",
"@codemirror/lang-css": "/claude/node_modules/@codemirror/lang-css/dist/index.cjs",
"@codemirror/lang-json": "/claude/node_modules/@codemirror/lang-json/dist/index.cjs",
"@codemirror/lang-markdown": "/claude/node_modules/@codemirror/lang-markdown/dist/index.cjs",
"@codemirror/gutter": "/claude/node_modules/@codemirror/gutter/dist/index.cjs",
"@codemirror/fold": "/claude/node_modules/@codemirror/fold/dist/index.cjs",
"@codemirror/panel": "/claude/node_modules/@codemirror/panel/dist/index.cjs",
"@lezer/highlight": "/claude/node_modules/@lezer/highlight/dist/index.cjs",
"@lezer/common": "/claude/node_modules/@lezer/common/dist/index.cjs",
"@lezer/javascript": "/claude/node_modules/@lezer/javascript/dist/index.cjs",
"@lezer/python": "/claude/node_modules/@lezer/python/dist/index.cjs",
"@lezer/html": "/claude/node_modules/@lezer/html/dist/index.cjs",
"@lezer/css": "/claude/node_modules/@lezer/css/dist/index.cjs",
"@lezer/json": "/claude/node_modules/@lezer/json/dist/index.cjs",
"@lezer/markdown": "/claude/node_modules/@lezer/markdown/dist/index.cjs",
"@codemirror/basic-setup": "/claude/node_modules/@codemirror/basic-setup/dist/index.cjs"
}
}
</script>
</head>
<body>
<div id="app">
@@ -344,6 +378,7 @@
<script src="/claude/claude-ide/preview-manager.js"></script>
<script src="/claude/claude-ide/chat-enhanced.js"></script>
<script src="/claude/claude-ide/terminal.js"></script>
<script type="module" src="/claude/claude-ide/components/file-editor.js"></script>
<!-- Debug Panel Toggle Script -->
<script>