res-edit: proof-of-concept port from Bubble Tea to Limoni #30

Open
opened 2026-10-14 16:49:07 +00:00 by muse-lantern · 1 comment
Member

Goal

Proof-of-concept port of res-edit from Bubble Tea + lipgloss to the Limoni TUI library, to evaluate Limoni as the UI foundation for residual tools.

Why Limoni

  • Pure Go, no cgo. Deps: only golang.org/x/sys in the core path (x/crypto is docs/examples only). Fits the static-everything story.
  • uitest headless testing lets agents and CI drive the editor without a real terminal.
  • KeyEvent carries Ctrl/Alt/Shift modifiers — the Ctrl-modkey contract ports cleanly. Mouse events supported.
  • Go 1.25 required (matches residual).

Scope

  • core/lib/edit: decouple Editor from tea.Model (Init/Update/View) and lipgloss rendering. Buffer/highlight logic stays untouched; only the tea/lipgloss glue is replaced with a Limoni Draw-function mapping.
  • core/cmd/res-edit: rewrite the app model (keys, command palette, help overlay, status bar) for Limoni.
  • Preserve: amber palette (non-negotiable), Ctrl-modkey contract (never Alt), slow-terminal handling (TERM=linux/fbterm).
  • Branch: limoni-res-edit.

Acceptance

  • go build ./..., go vet ./..., go test ./... green in core/.
  • CGO_ENABLED=0 static binary builds.
  • Opens a file, renders it, basic edit/save/quit works — verified headlessly via Limoni uitest where possible.
  • No new colors; no Alt bindings.

Out of scope

  • res-code (separate issue, gated on this PoC).
  • Merging to main.
## Goal Proof-of-concept port of res-edit from Bubble Tea + lipgloss to the Limoni TUI library, to evaluate Limoni as the UI foundation for residual tools. ## Why Limoni - Pure Go, no cgo. Deps: only golang.org/x/sys in the core path (x/crypto is docs/examples only). Fits the static-everything story. - `uitest` headless testing lets agents and CI drive the editor without a real terminal. - KeyEvent carries Ctrl/Alt/Shift modifiers — the Ctrl-modkey contract ports cleanly. Mouse events supported. - Go 1.25 required (matches residual). ## Scope - `core/lib/edit`: decouple `Editor` from `tea.Model` (Init/Update/View) and lipgloss rendering. Buffer/highlight logic stays untouched; only the tea/lipgloss glue is replaced with a Limoni Draw-function mapping. - `core/cmd/res-edit`: rewrite the app model (keys, command palette, help overlay, status bar) for Limoni. - Preserve: amber palette (non-negotiable), Ctrl-modkey contract (never Alt), slow-terminal handling (TERM=linux/fbterm). - Branch: `limoni-res-edit`. ## Acceptance - `go build ./...`, `go vet ./...`, `go test ./...` green in `core/`. - `CGO_ENABLED=0` static binary builds. - Opens a file, renders it, basic edit/save/quit works — verified headlessly via Limoni uitest where possible. - No new colors; no Alt bindings. ## Out of scope - res-code (separate issue, gated on this PoC). - Merging to main.
Author
Member

PoC complete — limoni-res-edit pushed

The port is done and verified on branch limoni-res-edit (not merged, no PR opened).

Ported:

  • lib/edit: Editor decoupled from tea.Model; lipgloss → cell.Style with the exact amber hexes; View() string → DrawEditor(f, x, y, w, h); new HandleMouse. Buffer/highlight/config logic untouched.
  • cmd/res-edit: Bubble Tea model → Limoni Draw function; full key dispatch on limoni.KeyEvent (Ctrl chords via k.Ctrl); Limoni-native command palette (lib/cmd/ui is bubbletea-based and shared — left untouched); help overlay; status bar.

Verified: go build/go vet/go test green for lib/edit and cmd/res-edit; CGO_ENABLED=0 → 10MB static ELF; headless uitest (open → type → Ctrl+S → verify on disk → Ctrl+X). Ctrl-only bindings, no Alt. lib/log test failures confirmed pre-existing on base.

Finds:

  • Fixed a .gitignore bug (bare res-edit entry was ignoring new files under cmd/res-edit/; anchored to /res-edit).
  • Limoni API gap: F1/F2 key constants not re-exported at package root — used limoni/core/driver directly. Worth flagging upstream.
  • Shared libs (lib/cmd/ui, lib/tui/overlay, lib/tui/theme) still bubbletea-based; res-code will need its own Limoni chrome.
## PoC complete — `limoni-res-edit` pushed The port is done and verified on branch `limoni-res-edit` (not merged, no PR opened). **Ported:** - `lib/edit`: `Editor` decoupled from `tea.Model`; lipgloss → `cell.Style` with the exact amber hexes; `View() string` → `DrawEditor(f, x, y, w, h)`; new `HandleMouse`. Buffer/highlight/config logic untouched. - `cmd/res-edit`: Bubble Tea model → Limoni Draw function; full key dispatch on `limoni.KeyEvent` (Ctrl chords via `k.Ctrl`); Limoni-native command palette (`lib/cmd/ui` is bubbletea-based and shared — left untouched); help overlay; status bar. **Verified:** `go build`/`go vet`/`go test` green for `lib/edit` and `cmd/res-edit`; `CGO_ENABLED=0` → 10MB static ELF; headless uitest (open → type → Ctrl+S → verify on disk → Ctrl+X). Ctrl-only bindings, no Alt. `lib/log` test failures confirmed pre-existing on base. **Finds:** - Fixed a `.gitignore` bug (bare `res-edit` entry was ignoring new files under `cmd/res-edit/`; anchored to `/res-edit`). - Limoni API gap: F1/F2 key constants not re-exported at package root — used `limoni/core/driver` directly. Worth flagging upstream. - Shared libs (`lib/cmd/ui`, `lib/tui/overlay`, `lib/tui/theme`) still bubbletea-based; res-code will need its own Limoni chrome.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
residual/.agent#30
No description provided.