Skip to content

Releases: matiaskorhonen/doop-editor

v0.13.5

Choose a tag to compare

@github-actions github-actions released this 04 Oct 10:52
Immutable release. Only release title and notes can be modified.
e424a8e

Changes

Fixes for crashes and stuck selections found by new randomized stress tests.

  • Fixed an NSInvalidArgumentException when undoing a multi-part edit. replaceCharacters scrolled to the
    selection from inside undo's batched edit, while the line storage was still stale.
  • Fixed an NSRangeException from bracket-pair emphasis when the search limit, taken from the visible rect,
    lagged a cursor that had just moved or text that had just shrunk.
  • Fixed delete-by-word and extend-by-word on text with emoji or combining marks. The range was measured in
    Characters rather than UTF-16 units and fell short of the word.
  • Fixed indenting and dedenting with several cursors. Only the selection being processed was updated, so the
    others could end up past the end of the text.
  • Fixed crashes when several cursors moved or deleted by word or line onto the same text. Overlapping
    selections are now merged, so shared text is no longer replaced once per selection.
  • Fixed a selection's length going negative when extending it past its pivot, and a stale pivot left behind by
    an edit anchoring the next extension to text that wasn't selected.
  • Fixed the editor having no selection after undoing or redoing a grouped edit.
  • Added opt-in randomized stress tests (DOOP_STRESS=1 swift test --filter StressTests).

v0.13.4

Choose a tag to compare

@github-actions github-actions released this 03 Oct 19:22
Immutable release. Only release title and notes can be modified.
v0.13.4
cba6ac8

Changes

  • Fixed an NSRangeException raised from a layout pass. A scroll in the middle of an edit (undo and
    paste select and scroll to the result) could start a pass after the text storage had changed and
    before the line storage had caught up, and typesetting a line from its stale range read past the end
    of the text. layoutLines now waits, and marks layout dirty, while the two lengths differ. An
    exception raised there had left the layout lock held, which skipped every later layout pass in 0.13.1
    and hung the main thread before that.
  • Removed the Objective-C exception catch added in 0.13.3. Catching an exception that has unwound
    through Swift frames skips their cleanup, and the app crashed in swift_beginAccess shortly after one.

v0.13.3

Choose a tag to compare

@github-actions github-actions released this 03 Oct 18:12
Immutable release. Only release title and notes can be modified.
v0.13.3
d4698dd

Changes

  • A layout pass that raises an Objective-C exception no longer leaves the editor's layout lock held and
    its CATransaction open. After one, every later layout pass was skipped (0.13.1) or hung the main
    thread (0.13.0), and views in other windows could stop being laid out. layoutLines now catches the
    exception, releases the lock, commits the transaction and logs the exception's name, reason and call
    stack as a fault in the TextLayoutManager category, so what raised it can be found.

v0.13.2

Choose a tag to compare

@github-actions github-actions released this 03 Oct 16:30
Immutable release. Only release title and notes can be modified.
v0.13.2
e4f5358

Changes

  • Fixed a crash while typing. An edit that took the asynchronous tree-sitter path reported its result
    from a background thread, and the result mutated the highlight provider's index sets, which are
    main-actor state, while the main thread was using them. The completion is now delivered on the main
    thread, as the synchronous and query paths already did. The race was older than 0.13.0, but 0.13.0's
    slow-edit fallback sent many more edits down the asynchronous path and made it easy to hit.

v0.13.1

Choose a tag to compare

@github-actions github-actions released this 03 Oct 13:39
Immutable release. Only release title and notes can be modified.
v0.13.1
e314b08

Changes

  • A layout pass no longer hangs the main thread when layoutLock is already held. A UI stress test
    deadlocked the editor with the main thread blocked on a lock it owned and no layout pass beneath
    it, so an earlier pass had leaked the lock. layoutLines now tries the lock: if it is held, it
    logs a fault in the TextLayoutManager category and skips that pass instead of waiting forever.
    This is a safety net; what leaks the lock is not yet known, and the fault log is how to find out.

v0.13.0

Choose a tag to compare

@github-actions github-actions released this 03 Oct 11:47
Immutable release. Only release title and notes can be modified.
v0.13.0
62252c9

Changes

  • A slow synchronous tree-sitter edit no longer keeps the editor on the main thread. An edit that
    takes longer than TreeSitterClient.Constants.maxSyncEditDuration (30ms) sends later edits to
    the asynchronous path, and an edit that comes back under it brings synchronous editing back. Every
    edit re-runs the language's query over the whole tree to look for injections, so its cost grows
    with the document (about 1.1µs per character in a release build), and the length checks alone
    couldn't keep that off the main thread. Multiple cursors multiply it, since each one reparses.
  • Documents over TreeSitterClient.Constants.maxHighlightableContentLength (250,000 characters,
    about 280ms per edit) are no longer highlighted. The client stops parsing and returns no
    highlights, and starts again over the whole document when it shrinks back under the limit or a
    new language is set. Text that was already highlighted when the document crossed the limit keeps
    its colours.

v0.12.1

Choose a tag to compare

@github-actions github-actions released this 20 Sep 15:48
Immutable release. Only release title and notes can be modified.
c1cd2c0

Fixes

  • An asynchronous highlight query no longer styles text that has since been deleted. Tree-sitter
    answers off the main thread for a long query or a long document, and the completion came back
    carrying the range the query was issued for, which went to NSTextStorage.setAttributes
    unchecked. If the document shrank in between — Doop replaces the whole document on every script
    run — the range ran past the end and NSMutableRLEArray raised NSRangeException, crashing the
    host app. The range is now clamped to the document as it stands when the result arrives.

v0.12.0

Choose a tag to compare

@github-actions github-actions released this 20 Sep 14:01
Immutable release. Only release title and notes can be modified.
95c11b4

Fixes

  • A line is now as tall as the font it is set in. Line fragments took their height and baseline
    from the fonts CoreText actually drew with, and a text font has no emoji glyph, so CoreText
    substituted Apple Color Emoji — about 40% taller at the same point size. Typing an emoji grew its
    line by ~5.7pt at Menlo 12 and moved every baseline below it. The editor's font is now carried
    down to the typesetter and text fragments are sized from it; width, line breaking and hit testing
    still come from the real CTLine.
  • Find-and-replace carried its offsets in the wrong direction. Every match after a replacement
    moves by the difference between the replacement's length and the match's, and replaceMatch
    subtracted that difference instead of adding it: replacing "a" with "alpha" in "a one a" put the
    second replacement inside the first — "alalphaha one a". Replace-all's text was unaffected, since
    it works back to front, but its final cursor landed short by the accumulated difference.
  • CEUndoManager.disable() now actually suppresses recording. Only undo() and redo() checked
    the flag; registerMutation did not, so the edits setMarkedText and unmarkText wrap in it
    went onto the undo stack anyway. Composing a character rewrites the marked range on every
    keystroke, so each intermediate state became its own undo entry — undoing after composing
    Japanese or Chinese walked back through composition states the user never typed as such.

Changes

  • Removed 352 lines with no callers here or in Doop: TextView+EditorMenus.swift (unwired CodeEdit
    IDE menu stubs), TreeSitterClient+Temporary, NSRange+NSTextRange.swift, and a handful of
    single members. Two were public and leave the binary package's swiftinterface with the source:
    NSTextRange's init/nsRange pair and TextLayoutManager.visibleLines().

Tests

  • CEUndoManager's grouping heuristic, driven through TextView, including the explicit grouping
    Doop's find-and-replace leans on.
  • Replacing from the find panel, against a real TextViewController: each sign of the length
    change, adjacent matches, and replace-all as one undo group.
  • DeleteWhitespaceFilter and TabReplacementFilter, which run on every backspace and tab in an
    indented document and had no coverage.

CI

  • Cache SwiftPM's working copies, not just its mirrors, and prune the grammar submodules' example
    corpora before the cache is written — 6.0GB of the checkouts' 6.9GB that no target compiles.

v0.11.1

Choose a tag to compare

@github-actions github-actions released this 20 Sep 08:08
Immutable release. Only release title and notes can be modified.
7c7f319

Fixes

  • Pasting over a column of multi-cursor selections left the cursors in the wrong places, and the
    next keystroke could crash the host app. Replacing each selection with a string of the same
    length reported the insertion as a net growth, so every cursor after the first accumulated a
    spurious shift — pasting Ipsum over three Ipsum selections put the last cursor ten characters
    past the end of the document, where the following edit hit an unconditional fatalError in
    TextStory. A replacement shorter than what it replaced drifted the same way without going out of
    bounds, misplacing cursors silently.

v0.11.0

Choose a tag to compare

@github-actions github-actions released this 19 Sep 20:43
Immutable release. Only release title and notes can be modified.
bee9b91
  • copy: now writes the selection as plain text. It wrote an NSAttributedString before, which
    carries RTF as well as a string, so code pasted into a rich text app arrived in the editor's
    theme colors — a dark theme's text landing unreadable on a white page.
  • The styled copy is still there as copyWithHighlighting(_:), for a host app to put behind its
    own menu item. It paints the editor's background onto the copied text, which its foreground
    colors were chosen against.
  • Both go through the new copySelection(to:withHighlighting:), which takes the pasteboard to
    write to.