mirror of
https://github.com/coteditor/CotEditor.git
synced 2024-09-11 11:25:57 +03:00
Improve duplicateLine(in:)
This commit is contained in:
parent
5c21038c6c
commit
9b30ec3d44
@ -9,6 +9,7 @@ Change Log
|
||||
|
||||
- Adjust the text baseline to draw characters vertically center in lines.
|
||||
- Adjust invisible characters position in the vertical text orientation.
|
||||
- Duplicate lines more intelligently.
|
||||
- Improve drawing performance.
|
||||
|
||||
|
||||
|
@ -361,8 +361,22 @@ extension String {
|
||||
var replacementRanges = [NSRange]()
|
||||
var selectedRanges = [NSRange]()
|
||||
|
||||
for range in ranges {
|
||||
let lineRange = string.lineRange(for: range)
|
||||
// group the ranges sharing the same lines
|
||||
let rangeGroups: [[NSRange]] = ranges.sorted(\.location)
|
||||
.reduce(into: []) { (groups, range) in
|
||||
if let last = groups.last?.last,
|
||||
string.lineRange(for: last).intersection(string.lineRange(for: range)) != nil
|
||||
{
|
||||
groups[groups.count - 1].append(range)
|
||||
} else {
|
||||
groups.append([range])
|
||||
}
|
||||
}
|
||||
|
||||
var offset = 0
|
||||
for group in rangeGroups {
|
||||
let unionRange = group.reduce(into: group[0]) { $0.formUnion($1) }
|
||||
let lineRange = string.lineRange(for: unionRange)
|
||||
let replacementRange = NSRange(location: lineRange.location, length: 0)
|
||||
var lineString = string.substring(with: lineRange)
|
||||
|
||||
@ -374,10 +388,10 @@ extension String {
|
||||
replacementStrings.append(lineString)
|
||||
replacementRanges.append(replacementRange)
|
||||
|
||||
let offset = replacementStrings.map { $0.length }.reduce(0, +)
|
||||
let selectedRange = range.shifted(offset: offset)
|
||||
|
||||
selectedRanges.append(selectedRange)
|
||||
offset += lineString.length
|
||||
for range in group {
|
||||
selectedRanges.append(range.shifted(offset: offset))
|
||||
}
|
||||
}
|
||||
|
||||
return (strings: replacementStrings, ranges: replacementRanges, selectedRanges: selectedRanges)
|
||||
|
@ -182,6 +182,16 @@ final class StringLineProcessingTests: XCTestCase {
|
||||
XCTAssertEqual(info?.strings, ["bbbb\n"])
|
||||
XCTAssertEqual(info?.ranges, [NSRange(3, 0)])
|
||||
XCTAssertEqual(info?.selectedRanges, [NSRange(9, 1)])
|
||||
|
||||
info = string.duplicateLine(in: [NSRange(4, 1), NSRange(6, 4)])
|
||||
XCTAssertEqual(info?.strings, ["bbbb\nccc\n"])
|
||||
XCTAssertEqual(info?.ranges, [NSRange(3, 0)])
|
||||
XCTAssertEqual(info?.selectedRanges, [NSRange(13, 1), NSRange(15, 4)])
|
||||
|
||||
info = string.duplicateLine(in: [NSRange(4, 1), NSRange(6, 1), NSRange(10, 0)])
|
||||
XCTAssertEqual(info?.strings, ["bbbb\n", "ccc\n"])
|
||||
XCTAssertEqual(info?.ranges, [NSRange(3, 0), NSRange(8, 0)])
|
||||
XCTAssertEqual(info?.selectedRanges, [NSRange(9, 1), NSRange(11, 1), NSRange(19, 0)])
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user