XcodeKit: XCSourceTextRange multi-line selection replace
Saturday, June 4, 2022
visibility 229
XcodeKit: XCSourceTextRange multi-line selection replace
The code below will allow you to remove the selected text range, by getting the range that is selected within the buffer.
This will allow you to replace selected text for a single mult-line selection range.
import XcodeKit
let newLineRegex = try! NSRegularExpression(pattern: "\\n", options: [])
/// Returns the range in the Editor `completeBuffer` of the specified range
func stringRange(inTextRange range: XCSourceTextRange) -> Range<String.Index> {
if isSameLine(range) {
return lineStringRange(forTextRange: range)
}
let buffer = invocation.buffer.completeBuffer
var startIndex = buffer.startIndex
var endIndex = buffer.startIndex
var lineIndex = 0
// get the range for the start and end line
newLineRegex.enumerateMatches(in: buffer, range: NSRange(..<buffer.endIndex, in: buffer)) { result, _, stop in
// -1, to account for the target range being before the \n char
if lineIndex == range.start.line - 1 {
startIndex = Range(result!.range, in: buffer)!.lowerBound
}
if lineIndex == range.end.line - 1 {
endIndex = Range(result!.range, in: buffer)!.lowerBound
stop.pointee = true
}
lineIndex += 1
}
// +1, for the \n char
let start = range.start.column + 1
let end = range.end.column + 1
let range = buffer.index(startIndex, offsetBy: start)..<buffer.index(endIndex, offsetBy: end)
return range
}
Usage
let selectedBufferRange = stringRange(inTextRange: selectedSourceTextRange)
let selectedText = String(invocation.buffer.completeBuffer[selectedBufferRange])
// replace selected text with some other text
invocation.buffer.completeBuffer.replaceSubrange(selectedRange, with: someOtherText)