fix: wait for typed separator before completing list markers
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user