Skip to content

Only editor#33

Open
sid597 wants to merge 25 commits intomainfrom
full-editor
Open

Only editor#33
sid597 wants to merge 25 commits intomainfrom
full-editor

Conversation

@sid597
Copy link
Copy Markdown
Owner

@sid597 sid597 commented Nov 27, 2025

No description provided.

sid597 and others added 25 commits June 27, 2025 17:53
…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
  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
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.

2 participants