Open
Conversation
…duh we calculate the position again and again which is totally wrong
Major architectural refactor to decouple high-frequency input handling from Electric's reactive graph, resolving main-thread blocking and GC thrashing. Changes: - Architecture: Switched from "Push" (Event-driven) to "Pull" (Atomic Sampling). Scroll inputs now mutate a raw atom bypassing the Electric DAG, which is sampled by a requestAnimationFrame loop. This enables true V-Sync at 120Hz/240Hz. - Memory: Implemented "Zero Allocation" rendering path in editor.cljs. Hoisted all Float32Array and clj->js object creation out of the hot loop into the setup phase. Mutating existing buffers instead of creating new ones eliminated GC spikes. - Logic: Implemented "Render on Invalidation". The render loop now sleeps (0% CPU) when idle and is woken up only by input events, preventing battery drain while maintaining instant responsiveness. - Modules: - app.client.webgpu.editor: Low-level, zero-alloc GPU command encoder. - app.client.webgpu.loop: Input scheduler, HUD, and RAF manager. - app.electric-flow: Lifecycle management and resource loading. - UX: Added performance HUD to track CPU dispatch time and FPS. - Fix: Synced Canvas DOM attributes to window pixel ratio to fix blurry text. - Fix: Added user-select: none to prevent text highlighting during scroll.
Implement interactive caret with full keyboard navigation:
- Blinking caret (530ms interval) rendered as 2px white rectangle
- Arrow key navigation with line wrapping at boundaries
- Home/End keys for line start/end movement
- Vim-style sticky column - preserves desired column position when
moving vertically through short or empty lines
- Auto-scroll viewport to keep caret visible with 1-line padding
- Reset caret blink on any navigation for visual feedback
Technical details:
- Caret reuses selection rect system: when sel-start == sel-end,
renders caret instead of selection highlight
- State tracks :sel-start, :sel-end, :desired-col, :caret-visible
- Keyboard events flow through Missionary mix into state reducer
- Hit-testing clamps to actual line lengths for accurate positioning
mplement full text editing capabilities with real-time re-tokenization: - Typing: Insert printable characters at caret position - Backspace: Delete character before cursor, join lines at line start - Enter: Split current line, create new line below cursor - Live re-tokenization: Watch !lines atom, re-parse and update GPU on change - Mutable text buffer: Store lines as vector of strings in atoms - Auto-scroll: Viewport follows caret during editing operations Technical implementation: - Extended keyboard handler to capture char-input, backspace, enter events - Added !lines, !line-lengths, !text-geo atoms for mutable state - Text update flow watches !lines, triggers tokenize-fn → layout-fn → GPU update - All line-length references updated to use @!line-lengths atom - start-loop! signature extended to receive lines, tokenize-fn, layout-fn, atlas
- Add bracket matching: highlights matching brackets (parens, brackets, braces)
when cursor is on or near a bracket using Lezer parse tree
- Add code folding: multi-line Clojure forms can be collapsed/expanded
via clickable indicators in left gutter (gold=expanded, blue=folded)
- Implement visual/logical line mapping to handle hidden lines correctly:
* layout-tokens returns line-mapping for visual↔logical conversion
* Hit-test uses visual→logical mapping for accurate cursor placement
* Caret/selection rendering uses logical→visual mapping for positioning
* All fold regions detected from Lezer parse tree (List, Vector, Map, Set)
- Add 40px gutter for fold indicators with smart positioning
Architecture: folding affects every component (layout, hit-test, rendering),
so we maintain two coordinate systems: logical (buffer) and visual (screen).
- Ctrl+K toggles command panel at bottom of screen
- Focus routing: keyboard input goes to active region (editor or panel)
- Command panel features:
- Background rect at fixed screen position
- Text input with blinking caret
- Placeholder text when empty ("Type a task...")
- Blue prompt prefix ("> ")
- Left/Right arrow navigation
- Backspace/Delete support
- Enter submits command and closes panel
- Escape closes panel
- Click to position cursor
- Separate text rendering flows for editor vs command panel
to avoid re-tokenizing editor on every panel keystroke
Electric archi
Features: - Settings panel (Ctrl+G) with font selector and parameter sliders - Font switching with manifest-based configuration - Sharpness control (-0.2 to +0.2) for MSDF edge crispness - Pixel snapping to DPR-aligned grid for sharper text - Diagnostics overlay toggle for debugging render params Architecture fixes: - Replace m/ap + m/?< with m/latest to prevent flow cancellation - Use m/eduction + deref for event filtering (avoids fork cancellation) - Consistent char-width (0.56) across cursor, layout, and hit-testing Rendering improvements: - MSDF shader clamps screenPxRange >= 1.0 (fixes blurry quotes) - Regenerated font atlas at size 128 (was 64) for better glyph detail - Atlas size read from JSON instead of hardcoded value Files changed: - loop.cljs: settings panel, font switching, reactive architecture - editor.cljs: MSDF shader params, shape-text with snap-step - electric_flow.cljc: manifest defaults alignment - font_atlas.png/json: regenerated at higher resolution
Features: - Theme selector in settings panel (Ctrl+G → Tab → ←/→) - 6 themes: Gruvbox Dark/Light, Rosé Pine, Kanagawa, Cyberdream, Classic Dark - Live theme switching via reactive pipeline GPU changes (Zed pattern): - Per-glyph colors in instance buffer (8 → 12 floats per glyph) - Vertex shader passes color to fragment - Fragment shader uses per-instance color instead of uniform Architecture: - Extract themes to themes.cljc (avoids circular dependency) - Colors flow: layout-tokens → shape-text → GPU buffer → shader
…ptimization
- File explorer sidebar (Ctrl+B): imperative DOM + HTTP API for browsing
and opening files from the server filesystem, open by default
- Fix canvas viewport: use ResizeObserver on canvas element instead of
window.innerWidth so text renders correctly when sidebar is visible
- Cached <fold-state and <bracket-match flows: fold detection and bracket
matching now only recompute on document changes, not on every blink tick
- Two-level identical? dirty checking in render reducer: idle frames skip
all work via O(1) pointer compare instead of deep structural equality
- Viewport-scoped text processing: large files (>500 lines) only tokenize
visible ~50 lines instead of the full document
- Data-level viewport culling replaces GPU-level culling in draw-frame
- Removed dead flows using banned m/ap+m/?< pattern
…and improve MSDF text rendering - Track currently open file in sidebar with highlight and breadcrumb - Switch default font to DejaVu Sans Mono at 19px (matches kitty 14pt) - Regenerate MSDF atlas (size=64, pxRange=16) for even glyph coverage - Set sharpness to 0.05 for proper stroke weight - Darken gruvbox background and brighten foreground to match nvim contrast - Boost delimiter alpha and restore original comment colors for readability - Seed sidebar with initial file on startup via server-resolved paths
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.