Insert soft tabs to all insertion points

This commit is contained in:
1024jp 2019-10-21 19:49:48 +09:00
parent 78ae737881
commit 89396481b5
3 changed files with 38 additions and 13 deletions

View File

@ -5,6 +5,12 @@ Change Log
3.8.4 (unreleased)
--------------------------
### Improvements
- Insert soft tabs to all insertion points when typing the tab key.
### Fixes
- Fix an issue on macOS 10.13-14 where the application became instabil with some specific actions when the cursor locates the end of the document.

View File

@ -524,10 +524,16 @@ final class EditorTextView: NSTextView, Themable, CurrentLineHighlighting, Multi
return
}
if self.isAutomaticTabExpansionEnabled {
let softTab = self.string.softTab(at: self.rangeForUserTextChange.location, tabWidth: self.tabWidth)
// insert soft tab
if
self.isAutomaticTabExpansionEnabled,
let insertionRanges = rangesForUserTextChange as? [NSRange]
{
let softTabs = insertionRanges
.map { self.string.softTab(at: $0.location, tabWidth: self.tabWidth) }
return super.insertText(softTab, replacementRange: self.rangeForUserTextChange)
self.replace(with: softTabs, ranges: insertionRanges, selectedRanges: nil)
return
}
super.insertTab(sender)
@ -1027,16 +1033,7 @@ final class EditorTextView: NSTextView, Themable, CurrentLineHighlighting, Multi
let blanks = [String](repeating: "", count: ranges.count - multipleTexts.count)
let strings = multipleTexts + blanks
var offset = 0
let selectedRanges: [NSRange] = zip(ranges, strings).map { (range, string) in
let length = string.length
let location = range.lowerBound + offset + length
offset += length - range.length
return NSRange(location: location, length: 0)
}
return self.replace(with: strings, ranges: ranges, selectedRanges: selectedRanges)
return self.replace(with: strings, ranges: ranges, selectedRanges: nil)
}
return super.readSelection(from: pboard, type: type)

View File

@ -59,6 +59,28 @@ extension NSTextView {
if let actionName = actionName {
self.undoManager?.setActionName(actionName)
}
// manually calculate the cursor locations after the replacement for multiple insertions
let selectedRanges: [NSRange]? = {
// use ones when explicitly specified
if let selectedRanges = selectedRanges { return selectedRanges }
// let NSTextView culculate by single insertion editing
guard
let insertionRanges = self.rangesForUserTextChange as? [NSRange],
insertionRanges.count > 1,
insertionRanges == ranges
else { return nil }
var offset = 0
return zip(ranges, strings).map { (range, string) in
let length = string.length
let location = range.lowerBound + offset + length
offset += length - range.length
return NSRange(location: location, length: 0)
}
}()
textStorage.beginEditing()
// use a backward enumeration to skip adjustment of applying location