fix: render additional spaces after list markers
This commit is contained in:
@@ -537,11 +537,11 @@ func listNavigationSkipsHiddenSeparatorsAndKeepsSelectionAnchorsAndDeletionUndo(
|
||||
let body = "🦊e\u{301} z"
|
||||
// Prefix source, rendered prefix, marker, separator, backward/forward expansions.
|
||||
let fixtures = [
|
||||
("", "", "-", " \t", "", ""),
|
||||
("\t", "\t", "+", "\t ", "", ""),
|
||||
(" ", " ", "009)", "\t \t", "009", "09)"),
|
||||
("- parent\n ", "\u{fffc} parent\n ", "- [X]", " \t ", "- [X", " [X]"),
|
||||
("\t", "\t", "12)\t[]", "\t \t", "12)\t[", "2)\t[]"),
|
||||
("", "", "-", " ", "", ""),
|
||||
("\t", "\t", "+", "\t", "", ""),
|
||||
(" ", " ", "009)", "\t", "009", "09)"),
|
||||
("- parent\n ", "\u{fffc} parent\n ", "- [X]", " ", "- [X", " [X]"),
|
||||
("\t", "\t", "12)\t[]", "\t", "12)\t[", "2)\t[]"),
|
||||
]
|
||||
for (prefix, renderedPrefix, marker, separator, backwardExpansion, forwardExpansion) in fixtures {
|
||||
let source = prefix + marker + separator + body
|
||||
@@ -838,10 +838,10 @@ func mixedListMarkersAlignBodyGlyphsAndWrappedLinesWithoutChangingMarkdown() thr
|
||||
let continuation = String(repeating: " wrapped words", count: 24)
|
||||
let rows = [
|
||||
("", "-", " ", "bullet"), ("", "*", "\t", "asterisk"),
|
||||
("", "+", " ", "plus"), ("", "1.", " ", "ordered"),
|
||||
("", "123456789)", " ", "long"), ("", "- [ ]", " ", "task"),
|
||||
("", "+", " ", "plus"), ("", "1.", " ", "ordered"),
|
||||
("", "123456789)", " ", "long"), ("", "- [ ]", " ", "task"),
|
||||
(" ", "+", " ", "nestedBullet"), (" ", "00012.", "\t", "nestedNumber"),
|
||||
(" ", "* [X]", " ", "nestedTask"),
|
||||
(" ", "* [X]", " ", "nestedTask"),
|
||||
]
|
||||
let source = rows.map { $0.0 + $0.1 + $0.2 + $0.3 + continuation }.joined(separator: "\n")
|
||||
editor.insertText(source, replacementRange: editor.selectedRange())
|
||||
@@ -1005,20 +1005,22 @@ func listBodyInsertionUsesVisiblePositionForTypingPasteAndReplacementRanges() th
|
||||
editor.breakUndoCoalescing()
|
||||
editor.undoManager?.removeAllActions()
|
||||
editor.insertText("🦊", replacementRange: explicitRange ? insertion : NSRange(location: NSNotFound, length: 0))
|
||||
#expect(editor.markdownString == marker + separator + "🦊tail")
|
||||
let position = max(1, offset)
|
||||
#expect(editor.markdownString == marker + String(separator.prefix(position)) + "🦊" + String(separator.dropFirst(position)) + "tail")
|
||||
#expect((editor.string as NSString).range(of: "\u{fffc}").location != NSNotFound)
|
||||
#expect(editor.selectedRange().location == NSMaxRange(token) + separator.utf16.count + 2)
|
||||
#expect(editor.selectedRange().location == NSMaxRange(token) + position + 2)
|
||||
editor.breakUndoCoalescing()
|
||||
editor.undoManager?.undo()
|
||||
#expect(editor.markdownString == original)
|
||||
editor.undoManager?.redo()
|
||||
#expect(editor.markdownString == marker + separator + "🦊tail")
|
||||
#expect(editor.markdownString == marker + String(separator.prefix(position)) + "🦊" + String(separator.dropFirst(position)) + "tail")
|
||||
}
|
||||
editor.setMarkdownContents(NSAttributedString(string: original))
|
||||
let token = (editor.string as NSString).range(of: "\u{fffc}")
|
||||
editor.setSelectedRange(NSRange(location: NSMaxRange(token) + offset, length: 0))
|
||||
#expect(editor.readSelection(from: board))
|
||||
#expect(editor.markdownString == marker + separator + "pastedtail")
|
||||
let position = max(1, offset)
|
||||
#expect(editor.markdownString == marker + String(separator.prefix(position)) + "pasted" + String(separator.dropFirst(position)) + "tail")
|
||||
}
|
||||
editor.setMarkdownContents(NSAttributedString(string: ""))
|
||||
editor.setSelectedRange(NSRange(location: 0, length: 0))
|
||||
@@ -1038,3 +1040,58 @@ func listBodyInsertionUsesVisiblePositionForTypingPasteAndReplacementRanges() th
|
||||
editor.insertText("!", replacementRange: separator)
|
||||
#expect(editor.markdownString == "-!abXcd")
|
||||
}
|
||||
|
||||
@Test @MainActor
|
||||
func extraListBodyWhitespaceIsVisibleAndHasNormalCursorStops() throws {
|
||||
_ = NSApplication.shared
|
||||
let editor = NotesTextView(frame: NSRect(x: 0, y: 0, width: 520, height: 200))
|
||||
editor.isRichText = true
|
||||
editor.allowsUndo = true
|
||||
let window = NSWindow(contentRect: editor.frame, styleMask: .borderless, backing: .buffered, defer: false)
|
||||
window.contentView = editor
|
||||
defer { window.orderOut(nil) }
|
||||
window.makeFirstResponder(editor)
|
||||
let layout = try #require(editor.layoutManager)
|
||||
let container = try #require(editor.textContainer)
|
||||
func bodyX() -> CGFloat {
|
||||
layout.ensureLayout(for: container)
|
||||
let range = (editor.string as NSString).range(of: "tail")
|
||||
let glyph = layout.glyphIndexForCharacter(at: range.location)
|
||||
return layout.lineFragmentRect(forGlyphAt: glyph, effectiveRange: nil).minX + layout.location(forGlyphAt: glyph).x
|
||||
}
|
||||
for marker in ["-", "+", "*", "12.", "99)", "- []", "- [x]", " - [ ]"] {
|
||||
for whitespace in [" ", " ", "\t", "\t "] {
|
||||
let source = marker + " tail"
|
||||
editor.setMarkdownContents(NSAttributedString(string: source))
|
||||
let token = (editor.string as NSString).range(of: "\u{fffc}")
|
||||
let start = NSMaxRange(token) + 1
|
||||
let originalX = bodyX()
|
||||
editor.setSelectedRange(NSRange(location: start, length: 0))
|
||||
editor.breakUndoCoalescing()
|
||||
editor.undoManager?.removeAllActions()
|
||||
editor.insertText(whitespace, replacementRange: editor.selectedRange())
|
||||
#expect(editor.markdownString == marker + " " + whitespace + "tail")
|
||||
#expect(bodyX() > originalX, "Additional body whitespace must advance the rendered text")
|
||||
#expect(editor.selectedRange().location == start + whitespace.utf16.count)
|
||||
editor.setSelectedRange(NSRange(location: token.location, length: 0))
|
||||
editor.moveRight(nil)
|
||||
#expect(editor.selectedRange().location == start)
|
||||
for index in 1...whitespace.utf16.count {
|
||||
editor.moveRight(nil)
|
||||
#expect(editor.selectedRange().location == start + index)
|
||||
}
|
||||
for index in stride(from: whitespace.utf16.count - 1, through: 0, by: -1) {
|
||||
editor.moveLeft(nil)
|
||||
#expect(editor.selectedRange().location == start + index)
|
||||
}
|
||||
editor.moveLeft(nil)
|
||||
#expect(editor.selectedRange().location == token.location)
|
||||
editor.breakUndoCoalescing()
|
||||
editor.undoManager?.undo()
|
||||
#expect(editor.markdownString == source)
|
||||
#expect(abs(bodyX() - originalX) < 0.5)
|
||||
editor.undoManager?.redo()
|
||||
#expect(bodyX() > originalX)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user