johnandersen777.bsky.social/knotless
git that lives in your Atmosphere account
Forked from chadtmiller.com/knotless
0
0
import SwiftUI
/// Paints the ranges the server gives: `name:start,length,…;…`, each start
/// counted from the end of the one before, over lines taken as joined by
/// newlines, in UTF-16 units as the pages read them (`web/src/lib/highlight.ts`).
enum Highlight {
private static let colors: [String: Color] = [
"comment": Color(themed: { $0.syntax["comment"] ?? 0 }, light: 0x59636e, dark: 0x9198a1),
"string": Color(themed: { $0.syntax["string"] ?? 0 }, light: 0x0a3069, dark: 0xa5d6ff),
"keyword": Color(themed: { $0.syntax["keyword"] ?? 0 }, light: 0xcf222e, dark: 0xff7b72),
"number": Color(themed: { $0.syntax["number"] ?? 0 }, light: 0x0550ae, dark: 0x79c0ff),
"function": Color(themed: { $0.syntax["function"] ?? 0 }, light: 0x6639ba, dark: 0xd2a8ff),
"type": Color(themed: { $0.syntax["type"] ?? 0 }, light: 0x953800, dark: 0xffa657),
"tag": Color(themed: { $0.syntax["tag"] ?? 0 }, light: 0x116329, dark: 0x7ee787),
"attr": Color(themed: { $0.syntax["attr"] ?? 0 }, light: 0x0550ae, dark: 0x79c0ff),
]
static func paint(lines: [String], ranges: String?) -> [AttributedString] {
var painted = lines.map { AttributedString($0) }
guard let ranges, !ranges.isEmpty else { return painted }
var starts: [Int] = []
var at = 0
for line in lines {
starts.append(at)
at += line.utf16.count + 1
}
for group in ranges.split(separator: ";") {
let parts = group.split(separator: ":", maxSplits: 1)
guard parts.count == 2 else { continue }
let name = String(parts[0])
let x = parts[1].split(separator: ",").compactMap { Int($0) }
var offset = 0
var line = 0
var i = 0
while i + 1 < x.count {
offset += x[i]
let end = offset + x[i + 1]
while line < lines.count, starts[line] + lines[line].utf16.count <= offset { line += 1 }
var k = line
while k < lines.count, starts[k] < end {
apply(name, in: &painted[k], text: lines[k],
from: max(offset, starts[k]) - starts[k],
to: min(end, starts[k] + lines[k].utf16.count) - starts[k])
k += 1
}
offset = end
i += 2
}
}
return painted
}
private static func apply(_ name: String, in attributed: inout AttributedString, text: String, from: Int, to: Int) {
guard from < to,
let strings = Range(NSRange(location: from, length: to - from), in: text),
let range = Range(strings, in: attributed)
else { return }
switch name {
case "xins": attributed[range].backgroundColor = Color.success.opacity(0.3)
case "xdel": attributed[range].backgroundColor = Color.danger.opacity(0.3)
default:
if let color = colors[name] { attributed[range].foregroundColor = color }
}
}
}