fix: wait for typed separator before completing list markers

This commit is contained in:
Valdemar Lorenzen
2026-10-19 14:01:49 +02:00
parent efabd3ae18
commit 21619c5420
3 changed files with 74 additions and 2 deletions
+27 -2
View File
@@ -216,14 +216,39 @@ final class NotesTextView: NSTextView, @MainActor NSLayoutManagerDelegate {
replacement = NSAttributedString(string: text, attributes: textTypingAttributes)
} else { return }
let range = replacementRange.location == NSNotFound ? selectedRange() : replacementRange
replaceSource(replacement, range: markdownInsertionRange(for: range), semantic: false)
replaceSource(replacement, range: markdownInsertionRange(for: range), semantic: false,
typedInput: insertString is String)
}
private func replaceSource(_ replacement: NSAttributedString, range: NSRange, semantic: Bool) {
private func replaceSource(_ replacement: NSAttributedString, range: NSRange, semantic: Bool, typedInput: Bool = false) {
guard isEditable else { return }
let source = NSMutableAttributedString(attributedString: Self.serialize(attributedString(), keepingMetadata: true))
guard range.location <= source.length, NSMaxRange(range) <= source.length else { return }
var existingWhitespace = false
if typedInput, range.length == 0, replacement.length > 0 {
var end = 0
(source.string as NSString).getLineStart(nil, end: nil, contentsEnd: &end,
for: NSRange(location: range.location, length: 0))
let tail = (source.string as NSString).substring(with: NSRange(location: range.location, length: max(0, end - range.location)))
existingWhitespace = !tail.isEmpty && tail.allSatisfy { $0 == " " || $0 == "\t" }
}
source.replaceCharacters(in: range, with: replacement)
if typedInput, range.length == 0, replacement.length > 0 {
let line = (source.string as NSString).lineRange(for: NSRange(location: range.location, length: 0))
if let match = Self.listPattern.firstMatch(in: source.string, range: line) {
var marker = match.range(at: 2)
if match.range(at: 4).location != NSNotFound {
marker.length = NSMaxRange(match.range(at: 4)) - marker.location
}
if range.location == NSMaxRange(marker),
replacement.string.allSatisfy({ $0 == " " || $0 == "\t" }) {
source.removeAttribute(literalTaskMarker, range: marker)
} else if existingWhitespace, range.location >= marker.location,
range.location + replacement.length == NSMaxRange(marker) {
source.addAttribute(literalTaskMarker, value: true, range: marker)
}
}
}
let rendered = Self.render(source)
let before = attributedString()
let old = before.string as NSString, new = rendered.string as NSString