Skip to content

Commit 1428dcb

Browse files
committed
Update AsyncCodeBlock
1 parent ffe1018 commit 1428dcb

File tree

1 file changed

+64
-25
lines changed

1 file changed

+64
-25
lines changed

Tool/Sources/SharedUIComponents/AsyncCodeBlock.swift

Lines changed: 64 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -251,30 +251,63 @@ extension AsyncCodeBlock {
251251
commonPrecedingSpaceCount: Int,
252252
diffResult: CodeDiff.SnippetDiff
253253
) {
254-
for (index, mutableString) in highlightedCode.enumerated() {
255-
guard let line = diffResult.line(at: index, in: \.newSnippet) else { continue }
256-
guard case let .mutated(changes) = line.diff, !changes.isEmpty else { continue }
257-
258-
for change in changes {
259-
if change.offset == 0,
260-
change.element.count - commonPrecedingSpaceCount
261-
== mutableString.string.count
262-
{
263-
// ignore the whole line change
264-
continue
254+
let originalCodeIsSingleLine = diffResult.sections.count == 1
255+
&& diffResult.sections[0].oldSnippet.count <= 1
256+
if !originalCodeIsSingleLine {
257+
for (index, mutableString) in highlightedCode.enumerated() {
258+
guard let line = diffResult.line(at: index, in: \.newSnippet),
259+
case let .mutated(changes) = line.diff, !changes.isEmpty
260+
else { continue }
261+
262+
for change in changes {
263+
if change.offset == 0,
264+
change.element.count - commonPrecedingSpaceCount
265+
== mutableString.string.count
266+
{
267+
// ignore the whole line change
268+
continue
269+
}
270+
271+
let offset = change.offset - commonPrecedingSpaceCount
272+
let range = NSRange(
273+
location: max(0, offset),
274+
length: max(0, change.element.count + (offset < 0 ? offset : 0))
275+
)
276+
if range.location + range.length > mutableString.length {
277+
continue
278+
}
279+
mutableString.addAttributes([
280+
.backgroundColor: NSColor.systemGreen.withAlphaComponent(0.2),
281+
], range: range)
265282
}
266-
267-
let offset = change.offset - commonPrecedingSpaceCount
268-
let range = NSRange(
269-
location: max(0, offset),
270-
length: max(0, change.element.count + (offset < 0 ? offset : 0))
283+
}
284+
} else if let firstMutableString = highlightedCode.first,
285+
let oldLine = diffResult.line(at: 0, in: \.oldSnippet),
286+
oldLine.text.count > commonPrecedingSpaceCount
287+
{
288+
// Only highlight the diffs inside the dimmed area
289+
let scopeRange = NSRange(
290+
location: 0,
291+
length: min(
292+
oldLine.text.count - commonPrecedingSpaceCount,
293+
firstMutableString.length
271294
)
272-
if range.location + range.length > mutableString.length {
273-
continue
295+
)
296+
if let line = diffResult.line(at: 0, in: \.newSnippet),
297+
case let .mutated(changes) = line.diff, !changes.isEmpty
298+
{
299+
for change in changes {
300+
let offset = change.offset - commonPrecedingSpaceCount
301+
let range = NSRange(
302+
location: max(0, offset),
303+
length: max(0, change.element.count + (offset < 0 ? offset : 0))
304+
)
305+
guard let limitedRange = limitRange(range, inside: scopeRange)
306+
else { continue }
307+
firstMutableString.addAttributes([
308+
.backgroundColor: NSColor.systemGreen.withAlphaComponent(0.2),
309+
], range: limitedRange)
274310
}
275-
mutableString.addAttributes([
276-
.backgroundColor: NSColor.systemGreen.withAlphaComponent(0.2),
277-
], range: range)
278311
}
279312
}
280313

@@ -288,8 +321,8 @@ extension AsyncCodeBlock {
288321
{
289322
let lastLine = highlightedCode[lastLineIndex]
290323
lastLine.append(.init(string: String(change.element), attributes: [
291-
.foregroundColor: NSColor.systemRed.withAlphaComponent(0.4),
292-
.backgroundColor: NSColor.systemRed.withAlphaComponent(0.1),
324+
.foregroundColor: NSColor.systemRed.withAlphaComponent(0.5),
325+
.backgroundColor: NSColor.systemRed.withAlphaComponent(0.2),
293326
]))
294327
}
295328
}
@@ -400,6 +433,12 @@ extension AsyncCodeBlock {
400433
}
401434
}
402435
}
436+
437+
static func limitRange(_ nsRange: NSRange, inside another: NSRange) -> NSRange? {
438+
let intersection = NSIntersectionRange(nsRange, another)
439+
guard intersection.length > 0 else { return nil }
440+
return intersection
441+
}
403442
}
404443

405444
#Preview("Single Line Suggestion") {
@@ -435,7 +474,7 @@ extension AsyncCodeBlock {
435474
#Preview("Multiple Line Suggestion") {
436475
AsyncCodeBlock(
437476
code: " let foo = Bar()\n print(foo)",
438-
originalCode: " var foo // comment",
477+
originalCode: " var foo // comment\n print(bar)",
439478
language: "swift",
440479
startLineIndex: 10,
441480
scenario: "",
@@ -456,7 +495,7 @@ extension AsyncCodeBlock {
456495
}
457496

458497
let cases: [Case] = [
459-
.init(code: "foo(123)", originalCode: "bar(234)"),
498+
.init(code: "foo(123)\nprint(foo)", originalCode: "bar(234)\nprint(bar)"),
460499
.init(code: "bar(456)", originalCode: "baz(567)"),
461500
]
462501

0 commit comments

Comments
 (0)