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