Files
Greg Shuflin 0a9f0b89a7 Generalize pane visibility with ShowPane/HidePane actions
Replace PopupHelp and ToggleFinder with a general pane visibility system:
- Add PanePosition enum (Main, Floating, future: Sidebar, Split)
- ShowPane { buffer, position } displays a buffer in specified layout
- HidePane { buffer, delete_buffer } removes from layout, optionally deletes

Commands now compose LoadBuffer + ShowPane for popups. Removed FinderBuffer
and Buffer::Finder variant - all buffers are now TextBuffer.

Also adds jj preference to CLAUDE.md, and does some other refactoring
2026-02-10 17:54:20 -08:00

3.0 KiB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Version Control

This repository uses both jujutsu (jj) and git. Prefer jj commands for all VCS operations:

jj status               # Instead of git status
jj diff                 # Instead of git diff
jj log                  # Instead of git log
jj new -m "message"     # Create new change with description
jj describe -m "msg"    # Update current change's description
jj squash               # Fold into parent

Use git only when jj doesn't support the operation (e.g., git push).

Build Commands

cargo build              # Build the project
cargo run                # Run the TUI editor
cargo run -- --gui       # GUI mode (stub, not yet implemented)
cargo clippy             # Lint
cargo test               # Run tests (no test suite yet)

Logs are written to ./pane-editor.log via tracing-appender.

Architecture

This is a Rust terminal text editor built with ratatui/crossterm, using an action-based state machine pattern. The editor core is designed to be frontend-agnostic.

Key Layers

Input Pipeline: Keyboard events (crossterm) → Input enum → Configuration maps Input to EditorAction based on current ModeEditorCore::handle_action() processes state changes.

EditorCore (src/core.rs): Central state manager. Owns all buffers (HashMap<BufferId, Buffer>), pane layout, mode (Normal/Insert/Command), and command system. All state mutations flow through handle_action(EditorAction).

EditorAction (src/core/actions.rs): Enum representing every possible state change — character insertion, cursor movement, mode transitions, file I/O, commands, etc.

TerminalUI (src/tui.rs): Async event loop using tokio. Dual-rate rendering: 30 FPS while typing, 2 FPS when idle (0.5s threshold).

Rendering (src/tui/render/): Three-area vertical layout — main editing area, info pane (2 lines), command pane (1 line). Supports floating panes for popups (Help, Finder).

Core Modules

  • src/core/buffer.rs — TextBuffer (editable text backed by crop::Rope via TextLines wrapper) and FinderBuffer (WIP)
  • src/core/cursor.rs — Cursor position tracking with UTF-8/grapheme-aware movement
  • src/core/commands.rs + commands/api.rs — Command-line parsing and execution (open, quit, write, help, finder)
  • src/core/pane_layout.rs — Buffer visibility and positioning (Main with tabs, Floating for popups)
  • src/configuration.rs — Mode-dependent keymap (Vi-inspired: hjkl navigation in Normal, i for Insert, : for Command)

Design Principles

  • The editor core is conceptually separate from frontends — EditorCore knows nothing about terminal rendering
  • Buffers have unique BufferIds and can be visible/invisible, read-only/read-write, text-editing or informational
  • handle_action runs in a tight loop processing a constant stream of EditorActions from any source (keyboard, filesystem, commands)