fix auto-close pairs wrapping, normalize-indentation logic, cleanup
This commit is contained in:
parent
030b38a7a2
commit
5342ddbe5f
|
|
@ -1121,37 +1121,45 @@ struct EditorTextView: NSViewRepresentable {
|
|||
func textView(_ textView: NSTextView, shouldChangeTextIn range: NSRange, replacementString text: String?) -> Bool {
|
||||
guard let text = text, text.count == 1 else { return true }
|
||||
let ch = text.first!
|
||||
let hasSelection = range.length > 0
|
||||
|
||||
let closers: [Character: Character] = ["}": "{", ")": "(", "]": "["]
|
||||
if let opener = closers[ch] {
|
||||
// Skip over matching closer when cursor is right before it
|
||||
if !hasSelection {
|
||||
let closerChars: Set<Character> = ["}", ")", "]", "\"", "'"]
|
||||
if closerChars.contains(ch) {
|
||||
let str = textView.string as NSString
|
||||
if range.location < str.length {
|
||||
let next = str.character(at: range.location)
|
||||
if next == ch.asciiValue.map({ UInt16($0) }) ?? 0 {
|
||||
let next = Character(UnicodeScalar(str.character(at: range.location))!)
|
||||
if next == ch {
|
||||
textView.setSelectedRange(NSRange(location: range.location + 1, length: 0))
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let pairs: [Character: String] = ["{": "}", "(": ")", "[": "]"]
|
||||
if let close = pairs[ch] {
|
||||
textView.insertText(String(ch) + close, replacementRange: range)
|
||||
let pairClosers: [Character: Character] = ["{": "}", "(": ")", "[": "]"]
|
||||
if let close = pairClosers[ch] {
|
||||
if hasSelection {
|
||||
let selected = (textView.string as NSString).substring(with: range)
|
||||
textView.insertText(String(ch) + selected + String(close), replacementRange: range)
|
||||
textView.setSelectedRange(NSRange(location: range.location + 1, length: selected.count))
|
||||
} else {
|
||||
textView.insertText(String(ch) + String(close), replacementRange: range)
|
||||
textView.setSelectedRange(NSRange(location: range.location + 1, length: 0))
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
if ch == "\"" || ch == "'" {
|
||||
let str = textView.string as NSString
|
||||
if range.location < str.length {
|
||||
let next = str.character(at: range.location)
|
||||
if next == ch.asciiValue.map({ UInt16($0) }) ?? 0 {
|
||||
textView.setSelectedRange(NSRange(location: range.location + 1, length: 0))
|
||||
return false
|
||||
}
|
||||
}
|
||||
if hasSelection {
|
||||
let selected = (textView.string as NSString).substring(with: range)
|
||||
textView.insertText(String(ch) + selected + String(ch), replacementRange: range)
|
||||
textView.setSelectedRange(NSRange(location: range.location + 1, length: selected.count))
|
||||
} else {
|
||||
textView.insertText(String(ch) + String(ch), replacementRange: range)
|
||||
textView.setSelectedRange(NSRange(location: range.location + 1, length: 0))
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
|
|
@ -1207,17 +1215,16 @@ struct EditorTextView: NSViewRepresentable {
|
|||
continue
|
||||
}
|
||||
|
||||
let closesFirst = trimmed.hasPrefix("}") || trimmed.hasPrefix(")") || trimmed.hasPrefix("]")
|
||||
if closesFirst && depth > 0 { depth -= 1 }
|
||||
let opens = trimmed.filter { "{([".contains($0) }.count
|
||||
let closes = trimmed.filter { "})]".contains($0) }.count
|
||||
let delta = opens - closes
|
||||
|
||||
if delta < 0 { depth = max(0, depth + delta) }
|
||||
|
||||
let indent = String(repeating: " ", count: depth)
|
||||
result.append(indent + trimmed)
|
||||
|
||||
let opens = trimmed.filter { "{([".contains($0) }.count
|
||||
let closes = trimmed.filter { "})]".contains($0) }.count
|
||||
depth += opens - closes
|
||||
if closesFirst { depth += 1; depth -= 1 }
|
||||
if depth < 0 { depth = 0 }
|
||||
if delta > 0 { depth += delta }
|
||||
}
|
||||
|
||||
return result.joined(separator: "\n")
|
||||
|
|
@ -1244,14 +1251,13 @@ struct EditorTextView: NSViewRepresentable {
|
|||
indent += " "
|
||||
}
|
||||
|
||||
let cursorBeforeLineEnd = cursor < NSMaxRange(lineRange) - 1
|
||||
let charBeforeCursor: Character? = cursor > 0 ? Character(UnicodeScalar(str.character(at: cursor - 1))!) : nil
|
||||
let charAtCursor: Character? = cursor < str.length ? Character(UnicodeScalar(str.character(at: cursor))!) : nil
|
||||
|
||||
// Between matching pairs: insert extra newline
|
||||
if let before = charBeforeCursor, let after = charAtCursor,
|
||||
(before == "{" && after == "}") || (before == "(" && after == ")") || (before == "[" && after == "]") {
|
||||
let baseIndent = String(indent.dropLast(4).isEmpty ? "" : indent.dropLast(4))
|
||||
let baseIndent = indent.count >= 4 ? String(indent.dropLast(4)) : ""
|
||||
let insertion = "\n" + indent + "\n" + baseIndent
|
||||
textView.insertText(insertion, replacementRange: textView.selectedRange())
|
||||
textView.setSelectedRange(NSRange(location: cursor + 1 + indent.count, length: 0))
|
||||
|
|
|
|||
Loading…
Reference in New Issue