Skip to content

Decide the editor ceiling: keep the overlay, or adopt a real editor #40

Description

@vmillet-dev

The editor lays a transparent <textarea> over a syntax-coloured <app-code-viewer>. The complaint about that arrangement is fair, but it aims slightly off the target — so first, what is not wrong with it, to keep anyone from "fixing" it:

  • .editor-stack lets the parent container scroll rather than either layer, so the classic failure of this trick — the two layers drifting apart on scroll — is designed out, with no scrollTop synchronisation anywhere.
  • The font stack is monospace all the way down ('JetBrains Mono', ui-monospace, …, monospace) and the family is shipped with the binary through @fontsource, so character alignment cannot break on a missing webfont. The trailing , serif on those rules is unreachable noise, not a risk.
  • The <textarea> carries the accessible text and the viewer is aria-hidden, which is the right way round.

What is actually missing, and it is not the colouring

A <textarea> has no editing intelligence, and no amount of work on the layer underneath adds any:

  • No Tab to indent — Tab leaves the field. That is a deliberate accessibility choice, and for writing code it is a real handicap.
  • No auto-closing brackets or quotes, no bracket matching, no folding.
  • No find-and-replace inside a note, no multiple selections.
  • Nothing marks {{fields}}. They are coloured by whatever the language grammar happens to think they are — in a SQL snippet, {{host}} is just text. This is the one that matters most here, because fields are the application's own vocabulary, and it is impossible with the overlay and trivial with a real editor (a decoration).

The question that decides it

Do people write in DevBox, or file into it what they wrote elsewhere? If it is filing, the textarea is adequate and a real editor is dead weight. If it is writing — and mixed-content notes and runbooks point that way — it pays for itself.

Options

A — Keep the overlay, add what is cheap. Tab handling with an accessible escape (Tab indents, Escape then Tab leaves — the established pattern), auto-closing pairs. A session or two, ceiling unchanged, {{fields}} still invisible.

B — CodeMirror 6. Everything above, plus decorations for the fields. The costs, in full:

  • An imperative island in a zoneless, signal-based application: it owns its DOM, so it needs afterNextRender, an explicit teardown, and to stay out of the signal graph.
  • The draft path has to be rewired. Today the body is a linkedSignal keyed on the note id, committed on blur and on every closing path — Escape, backdrop and close button produce no blur, which is why requestClose() commits first. That contract has to survive the change.
  • Its own theming system, which must answer data-theme in both directions plus prefers-color-scheme, like every other colour in this codebase.
  • Two highlighters to maintain. The cards must stay on highlight.js — CodeMirror on a three-line truncated preview, multiplied by every card on the canvas, is absurd. So _code-theme.scss and a CodeMirror theme both have to track the palette.
  • Bundled locally, never from a CDN: the CSP forbids it.

C — Monaco. No. Heavy, worker-based, awkward under this CSP, and far more editor than a snippet needs.

Done when: the choice is written down with its reason — and if it is A, the cheap gaps are closed rather than left open indefinitely.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestquestionFurther information is requested

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions