Editing at Scale
Every edit in Caxton is a piece-table splice: a 10 GB document takes keystrokes with about a millisecond of apply latency, and bulk operations are engineered as single passes.
Multi-cursor editing
⌥Click adds a cursor (click one again to remove it). ⌃⌘G places a cursor on every occurrence of the selection. Typing, deleting, and pasting apply at every cursor simultaneously and land as one undo step.
Eight carets, one keystroke each. The cap is 1,000 cursors; a keystroke at the full cap on a 10 GB file applies in under 120 ms.
Rectangular selection
⌥Drag selects a column of text across rows. The result is an ordinary multi-cursor selection, so typing or deleting edits every row at once. ⌥⇧Click is the click version: click one spot, Option-Shift-click another, and the column selection sweeps every line between the caret and the click.
Option-drag for column selection: each row gets its own selection span, clamped to shorter lines.
Smart selection & word-wise movement
⌃⇧⌘→ grows the selection structurally (word, dotted token, quoted string, brackets, line, paragraph) and ⌃⇧⌘← steps back exactly the way it came (Edit ▸ Expand / Contract Selection). ⌥←/⌥→ move by word, ⌥⌫ deletes a word at a time, and ⌘⌫ clears to the start of the visual row, all multi-cursor aware, and all correct under soft wrap.
Comment toggling
⌘/ toggles line comments, language-aware: uncomment wins only when every non-blank selected line is already commented, markers land in a straight column at the shallowest indent, blank lines stay untouched, and multi-cursor selections comment all their lines as one undo step. ⌥⌘/ toggles a block comment around the selection; an empty selection drops the pair and parks the caret inside. Languages without a line marker (HTML, XML) route ⌘/ to the block pair automatically.
Brackets
Typing (, [, {, or a quote auto-closes with the caret between; typing the closer walks over the auto-inserted one, and backspace on a fresh pair removes both. The guards keep it polite: type-over applies only to the most recently auto-inserted pair, quotes stay single against a word character, apostrophes pair only in code languages, and a selection wraps instead of being replaced. The matching bracket at the caret gets a ring highlight. Edit ▸ Brackets carries Jump to Matching (⌃⌘B), Select Surrounding Pair (⌃⇧⌘B), Delete and Change Surrounding Pair, and the Auto-Close toggle.
Snippets
Author snippets in Edit ▸ Snippets…: a name, the abbreviation that triggers it, an optional language list, and a body using $1…$9 tab stops, ${1:default} placeholders, $0 for the final caret, repeated stops as simultaneous-cursor mirrors, and $DATE $TIME $FILENAME $CLIPBOARD variables (\$ for a literal dollar). Type the abbreviation and press ⇥: it expands as one undo step with the first placeholder selected, ⇥ walks the remaining stops while they track your typing, and ⎋ ends the session. Malformed syntax passes through literally; a snippet never eats text.
Word completion
⌥⎋ (or Edit ▸ Complete Word) pops a panel at the caret listing identifiers from the document itself, frequency-ordered, matching what you have typed. Keep typing to narrow; Return or Tab accepts. No dictionaries and no guessing: the document is the source of truth, and the scan is a bounded window around the caret, so it stays instant at any file size.
Clipboard history
⇧⌘V opens the history of everything cut or copied inside Caxton. It is editor-local by design: the system pasteboard is never monitored, so other apps' clipboards are structurally invisible to it. Unpinned entries live in memory and end with the app; ⌘P pins an entry to persist (capped at 20); entries over 1 MB and copies from sensitive-looking files (.env, key material, credentials) are never recorded. Return pastes and becomes the live clipboard; with multiple cursors, ⌥Return spreads an N-line entry one line per cursor.
Undo, redo, and bulk operations
- Undo history is unlimited in count and capped by memory; batch operations (Replace All, multi-cursor edits) are single entries.
- Undoing a 1.6-million-site Replace All takes milliseconds; the batch replays through the same bulk engine that applied it.
- Replace batches beyond roughly a million sites can exceed the undo memory cap; Caxton applies them but reports that the step can't be undone, instead of silently dropping history.
The Text toolbox
The Text menu is a full toolbox that operates on the selection (or the whole document) at engine speed. Every operation lands as one undo step, and the caret-scoped line operations work on raw bytes: duplicating or moving a line is byte-exact even around invalid UTF-8.
- Case: Uppercase, Lowercase, Title Case, Sentence Case, Toggle Case, and an Identifier Case submenu with all seven programmer casings: camelCase, PascalCase, snake_case, kebab-case, CONSTANT_CASE, dot.case, space case (acronym-aware;
HTTPServersplits correctly). - Lines: Duplicate ⌘⇧D, Delete ⌘⇧K, Copy Line, Move Up/Down ⌥⌘↑↓, Join ⌃J, Split at Delimiter…, Shuffle, Remove Empty, Keep Only Duplicates, Indent / Outdent ⌘] ⌘[, Number Lines…, Add Prefix/Suffix…, plus the original Sort (plain, descending, numeric, by length), Reverse, Delete Duplicate Lines, and Delete Lines Matching… (which streams to a new document when the result is enormous).
- Paragraphs: Hard Wrap to Column…, Reflow to Column…, and Unwrap Paragraphs. Quote and comment prefixes (
>,//,#) are preserved on every wrapped line, and a list dash isn't multiplied into new bullets. - Whitespace: trim trailing or leading+trailing, collapse repeated spaces, convert non-breaking spaces, tabs ↔ spaces (column-aware), Normalize Indentation…, Detect Mixed Indentation, and a configurable Tab Width (2/3/4/8) that the editor actually renders with.
- Numbers: Increment/Decrement every number in the selection, Apply Arithmetic…, Pad Numbers… (zero-padding keeps its width:
007+ 1 is008), Convert Number Base… (2/8/10/16, word-bounded), and Sum Numbers with count and average. - Insert Date/Time: six locale-stable formats (ISO 8601 local and UTC, epoch seconds, and friends), inserted at every cursor.
- Escapes: HTML entities, XML, JSON strings (full surrogate handling; malformed input is refused, never mangled), hex,
\uXXXXUnicode escapes, ROT13, and Unicode normalization (NFC/NFD/NFKC/NFKD), alongside the original Base64 and URL encode/decode. - Hash: SHA-256, SHA-512, SHA-1, MD5 of the selection, shown in a panel with a Copy button. Your text is never replaced.
- Formatters: Format JSON and Format XML pretty-print in place.
- Narrow to Selection / Widen: temporarily restrict the view and edits to a region; Widen restores the full document.
- Word Count and Statistics…: the quick banner, or the full panel: bytes, characters, Unicode scalars, words, lines, paragraphs, sentences, blank and unique lines, longest and average line, reading time, and an indentation report, for the document or the selection.
Saving
Saves are atomic by default: the file is rewritten alongside and swapped in, so a crash mid-save can never leave a truncated original. Editing near the front of a 10 GB file and saving costs an ~11 s full rewrite (measured, ~880 MB/s); in-place saves handle append-only cases much faster, protected by a patch journal (see Sessions & Recovery).