Skip to content

Global Editor: full editor experience — LSP, search, fullscreen, working tabs (#513)#515

Open
Juliusolsson05 wants to merge 15 commits into
mainfrom
feat/editor-full-experience
Open

Global Editor: full editor experience — LSP, search, fullscreen, working tabs (#513)#515
Juliusolsson05 wants to merge 15 commits into
mainfrom
feat/editor-full-experience

Conversation

@Juliusolsson05

Copy link
Copy Markdown
Owner

Closes #513.

Turns the Global Editor overlay from a half-wired file viewer into a real editor. Full plan (with WHY per task) in docs/superpowers/plans/2026-07-09-global-editor-full-experience.md.

Root-cause fixes

  1. Blank .tsx/.jsx highlightingnormalizeCodeLanguage produced typescriptreact/javascriptreact, which are VS Code language IDs Monaco doesn't ship; models silently fell back to the plaintext tokenizer. New monacoLanguageId() translates at every Monaco boundary (models + providers); TS worker gets JSX compiler options; worker semantic validation off (LSP owns semantics).
  2. Uncloseable tabscloseFile() refused dirty buffers and every caller dropped the false; no confirm dialog existed. Now: EditorWorkbench-owned ConfirmCloseDialog (Save & Close / Discard / Cancel), { force } close in both hosts, and save errors render as a banner above the editor instead of replacing the pane (a failed save used to hide your unsaved text).
  3. Semantic tokens computed but never painted — custom themes leave Monaco's semanticHighlighting off; now enabled at both editor-creation sites.
  4. Monaco theme wargetMonaco() re-asserted the slab theme on every CodeBlock mount, yanking the open editor's theme. Shared refcount (monacoThemeState.ts) gives the two theme owners one answer to "who owns the global theme" (kept the existing renderer test's contract; see plan execution notes).
  5. Worker fragilityMonacoEnvironment installs at module scope (was post-lazy-import), CSP gains worker-src 'self' blob:.

LSP in the real editor (was CodeBlock-only)

  • LspManager refactored onto a pluggable server registry (src/main/lsp/serverRegistry.ts): tsserver stays the bundled npm dep; pyright / rust-analyzer / gopls are detected on PATH and fail open. One server per (root × spec), single-flight spawn. No bundled binaries (third_party policy).
  • New protocol requests + IPC + preload: hover, definition, completion, references, documentSymbol (symbols are protocol-groundwork; no outline UI yet).
  • MonacoFileEditor now does full document sync (debounced didChange), diagnostics markers, semantic tokens, hover, completions, and cross-file go-to-definition via registerEditorOpeneropenFileInGlobalEditor (root containment enforced in main; definitions outside the active cwd fail closed).
  • Ref-counted model registry: models follow buffer lifetime, so undo history survives tab switches; disposal happens on real tab close.

Editor experience

  • File watcher (chokidar, per open file, refcounted): clean buffers follow external/agent writes live; dirty buffers get a conflict banner with Reload-from-disk / Overwrite.
  • Explorer mutations: context menu New File / New Folder / Rename / Delete (two-step confirm), inline edit rows, hidden-files toggle. Rename migrates open buffers; delete force-closes them.
  • Quick Open (⌘P): bounded recursive index (20k cap, junk-filtered) + basename-weighted fuzzy ranking.
  • Search in files (⌘⇧F): bounded main-process scan (2k matches / 20k files / 1MB-per-file caps, binary sniff), grouped results, opens at line:column. rg-via-third_party is the documented follow-up if the JS scan proves slow.
  • Fullscreen (⌥⌘E): editor takes 100% of the workspace area; the workspace stays mounted (display:none) so terminals/feeds survive; Esc exits.
  • Persistence: open-tab paths + geometry survive restarts (localStorage; contents are never persisted — tabs rehydrate by re-reading disk).

Isolation

  • Editor commands moved out of workspace/commands/layoutCommands.ts into an editor-owned palette module (features/global-editor/commands/), plus new quick-open / search / fullscreen commands.
  • Shared bufferOps (pure buffer transitions) ends the Global-Editor-vs-AI-Workspace buffer-lifecycle duplication; AI Workspace also gained the confirm-dialog/conflict-banner behaviors.
  • Stale comments referencing the deleted features/editor/store.ts rewritten.

Verification

  • npx tsc --noEmit on both projects (node + web): clean.
  • npm run test: 481/481 passing (one pre-existing agent-voice-dictation submodule suite failure, byte-identical on main).
  • npm run build (electron-vite production bundle): succeeds.
  • Manual checklist (needs a human in the app window — plan Task 17 step 3): open a .tsx → colors + semantic sharpening; type error → squiggle + hover; ⌘-click import → cross-file jump; dirty close → dialog; external write → live refresh / conflict banner; ⌘P / ⌘⇧F; ⌥⌘E + Esc; restart → tabs restored; ⌘Z after tab switch.

🤖 Generated with Claude Code

Juliusolsson05 and others added 15 commits July 9, 2026 17:53
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… highlighting (#513)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…hlighting (#513)

Leaner than the planned full controller-module consolidation: the
existing renderer test pins the split-listener contract (editor module
never touches setTheme while inactive), so instead of merging the two
theme owners we give them one shared refcount (monacoThemeState) and
stop getMonaco() from re-asserting the slab theme on every call.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…tructive save-error banner (#513)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…switches (#513)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ferences/symbols (#513)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… completions (#513)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ck-open/search backend (#513)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…en toggle (#513)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…creen (alt+cmd+E) (#513)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…tents never persisted (#513)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…lscreen commands (#513)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…fix stale store comments (#513)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…results (#513)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Global Editor → full editor experience: LSP-wired editing, file search, fullscreen, isolation

1 participant