Skip to content

Commit ee242bb

Browse files
authored
Merge pull request CodeEditApp#59 from thecoolwinter/incremental-highlighting
Incremental Highlighting
2 parents 832505b + 712cb58 commit ee242bb

14 files changed

+690
-197
lines changed
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
//
2+
// STTextViewController+CaptureNames.swift
3+
// CodeEditTextView
4+
//
5+
// Created by Lukas Pistrol on 16.08.22.
6+
//
7+
8+
/// A collection of possible capture names for `tree-sitter` with their respected raw values.
9+
public enum CaptureName: String, CaseIterable {
10+
case include
11+
case constructor
12+
case keyword
13+
case boolean
14+
case `repeat`
15+
case conditional
16+
case tag
17+
case comment
18+
case variable
19+
case property
20+
case function
21+
case method
22+
case number
23+
case float
24+
case string
25+
case type
26+
case parameter
27+
case typeAlternate = "type_alternate"
28+
case variableBuiltin = "variable.builtin"
29+
case keywordReturn = "keyword.return"
30+
case keywordFunction = "keyword.function"
31+
32+
/// Returns a specific capture name case from a given string.
33+
/// - Parameter string: A string to get the capture name from
34+
/// - Returns: A `CaptureNames` case
35+
static func fromString(_ string: String?) -> CaptureName? {
36+
allCases.first { $0.rawValue == string }
37+
}
38+
39+
var alternate: CaptureName {
40+
switch self {
41+
case .type:
42+
return .typeAlternate
43+
default:
44+
return self
45+
}
46+
}
47+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
//
2+
// NSRange+InputEdit.swift
3+
//
4+
//
5+
// Created by Khan Winter on 9/12/22.
6+
//
7+
8+
import Foundation
9+
import SwiftTreeSitter
10+
11+
extension InputEdit {
12+
init?(range: NSRange, delta: Int, oldEndPoint: Point) {
13+
let newEndLocation = NSMaxRange(range) + delta
14+
15+
if newEndLocation < 0 {
16+
assertionFailure("Invalid range/delta")
17+
return nil
18+
}
19+
20+
// TODO: - Ask why Neon only uses .zero for these
21+
let startPoint: Point = .zero
22+
let newEndPoint: Point = .zero
23+
24+
self.init(startByte: UInt32(range.location * 2),
25+
oldEndByte: UInt32(NSMaxRange(range) * 2),
26+
newEndByte: UInt32(newEndLocation * 2),
27+
startPoint: startPoint,
28+
oldEndPoint: oldEndPoint,
29+
newEndPoint: newEndPoint)
30+
}
31+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
//
2+
// NSRange+NSTextRange.swift
3+
//
4+
//
5+
// Created by Khan Winter on 9/13/22.
6+
//
7+
8+
import AppKit
9+
10+
public extension NSTextRange {
11+
convenience init?(_ range: NSRange, provider: NSTextElementProvider) {
12+
let docLocation = provider.documentRange.location
13+
14+
guard let start = provider.location?(docLocation, offsetBy: range.location) else {
15+
return nil
16+
}
17+
18+
guard let end = provider.location?(start, offsetBy: range.length) else {
19+
return nil
20+
}
21+
22+
self.init(location: start, end: end)
23+
}
24+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
//
2+
// STTextView+VisibleRange.swift
3+
//
4+
//
5+
// Created by Khan Winter on 9/12/22.
6+
//
7+
8+
import Foundation
9+
import STTextView
10+
11+
extension STTextView {
12+
func textRange(for rect: CGRect) -> NSRange {
13+
let length = self.textContentStorage.textStorage?.length ?? 0
14+
15+
guard let layoutManager = self.textContainer.layoutManager else {
16+
return NSRange(0..<length)
17+
}
18+
let container = self.textContainer
19+
20+
let glyphRange = layoutManager.glyphRange(forBoundingRect: rect, in: container)
21+
22+
return layoutManager.characterRange(forGlyphRange: glyphRange, actualGlyphRange: nil)
23+
}
24+
25+
var visibleTextRange: NSRange {
26+
return textRange(for: visibleRect)
27+
}
28+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
//
2+
// HighlightRange.swift
3+
//
4+
//
5+
// Created by Khan Winter on 9/14/22.
6+
//
7+
8+
import Foundation
9+
10+
/// This class represents a range to highlight, as well as the capture name for syntax coloring.
11+
class HighlightRange {
12+
init(range: NSRange, capture: CaptureName?) {
13+
self.range = range
14+
self.capture = capture
15+
}
16+
17+
let range: NSRange
18+
let capture: CaptureName?
19+
}

0 commit comments

Comments
 (0)