Skip to content

v0.6.0 — block (rectangular) selection

Choose a tag to compare

@Ceesaxp Ceesaxp released this 25 Oct 03:02
· 62 commits to master since this release
a5ef0a8

Added

  • Block (rectangular) selection. Select a vertical rectangle across several lines and edit every line at once — the thing that otherwise costs one trip per line: turning N lines into a list, adding | borders to a table, stripping a column of leading junk.

    ⌥-drag with the mouse, or ⌥⇧↑/↓ to start a block and ⌥⇧←/→ to widen one that's already live. Esc drops it.

    Typing replaces every row's fragment. A zero-width block — a column of carets with no width — inserts at all of them at once, so parking one at column 0 across twenty lines and typing - makes a list in a single keystroke. Backspace and forward-delete take one grapheme per row and never cross a line boundary. ⌘C joins the rows with newlines, ⌘X cuts the rectangle, and ⌘V distributes a single clipboard line across every row. Every gesture is exactly one ⌘Z.

    ⌥⇧←/→ is the standard "extend selection by word" binding everywhere in macOS, so Writ only takes it over while a block is actually live. With no block, word-extend behaves as it always did.

Notes on the edges

A line shorter than the block's left edge gets a caret at its end rather than being padded with spaces — Writ never edits text you didn't select. Under soft wrap a block covers a wrapped line's first visual row only; it works on logical lines, which is what the list-and-table cases want. BBEdit disables rectangular selection under soft wrap entirely.

Undo restores the text but not the rectangle. ⌥-double-click collapses to a plain caret instead of selecting a word.

Under the hood

All the selection arithmetic lives in an AppKit-free model, which is why it could be tested properly: 113 tests, 57 of them new.

The project also gained a headless harness that drives the real NSTextView — the production view on the production TextKit 1 stack, in an off-screen window, with no run loop. App-level editor tests had been recorded as blocked by a Swift 6 toolchain conflict since 0.4.x; the blocker turned out to be the test host rather than the test bundle, so editor regressions can now be covered directly instead of by proxy.

Download: Writ-0.6.0.dmg (6.1 MB, notarized + stapled)