Skip to content

Commit b5a8ca9

Browse files
Rework Async tree-sitter Model, Fix Strong Ref Cycle (#225)
1 parent f76b48a commit b5a8ca9

24 files changed

+582
-629
lines changed

Package.resolved

Lines changed: 9 additions & 9 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Package.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ let package = Package(
2222
// tree-sitter languages
2323
.package(
2424
url: "https://github.com/CodeEditApp/CodeEditLanguages.git",
25-
exact: "0.1.17"
25+
exact: "0.1.18"
2626
),
2727
// SwiftLint
2828
.package(

Sources/CodeEditSourceEditor/CodeEditSourceEditor.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,7 @@ public struct CodeEditSourceEditor: NSViewControllerRepresentable {
212212
@MainActor
213213
public class Coordinator: NSObject {
214214
var parent: CodeEditSourceEditor
215-
var controller: TextViewController?
215+
weak var controller: TextViewController?
216216
var isUpdatingFromRepresentable: Bool = false
217217
var isUpdateFromTextView: Bool = false
218218

Sources/CodeEditSourceEditor/Controller/TextViewController+HighlightBracket.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,11 @@ extension TextViewController {
1515
for range in textView.selectionManager.textSelections.map({ $0.range }) {
1616
if range.isEmpty,
1717
range.location > 0, // Range is not the beginning of the document
18-
let preceedingCharacter = textView.textStorage.substring(
18+
let precedingCharacter = textView.textStorage.substring(
1919
from: NSRange(location: range.location - 1, length: 1) // The preceding character exists
2020
) {
2121
for pair in BracketPairs.allValues {
22-
if preceedingCharacter == pair.0 {
22+
if precedingCharacter == pair.0 {
2323
// Walk forwards
2424
if let characterIndex = findClosingPair(
2525
pair.0,
@@ -34,7 +34,7 @@ extension TextViewController {
3434
highlightCharacter(range.location - 1)
3535
}
3636
}
37-
} else if preceedingCharacter == pair.1 && range.location - 1 > 0 {
37+
} else if precedingCharacter == pair.1 && range.location - 1 > 0 {
3838
// Walk backwards
3939
if let characterIndex = findClosingPair(
4040
pair.1,

Sources/CodeEditSourceEditor/Controller/TextViewController+Highlighter.swift

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,8 @@ extension TextViewController {
3232
if let highlightProvider = highlightProvider {
3333
provider = highlightProvider
3434
} else {
35-
let textProvider: ResolvingQueryCursor.TextProvider = { [weak self] range, _ -> String? in
36-
return self?.textView.textStorage.mutableString.substring(with: range)
37-
}
38-
39-
provider = TreeSitterClient(textProvider: textProvider)
35+
self.treeSitterClient = TreeSitterClient()
36+
provider = self.treeSitterClient!
4037
}
4138

4239
if let provider = provider {

Sources/CodeEditSourceEditor/Controller/TextViewController.swift

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,12 @@ public class TextViewController: NSViewController {
149149
}
150150
}
151151

152-
internal var highlighter: Highlighter?
152+
var highlighter: Highlighter?
153+
154+
/// The tree sitter client managed by the source editor.
155+
///
156+
/// This will be `nil` if another highlighter provider is passed to the source editor.
157+
internal(set) public var treeSitterClient: TreeSitterClient?
153158

154159
private var fontCharWidth: CGFloat { (" " as NSString).size(withAttributes: [.font: font]).width }
155160

Sources/CodeEditSourceEditor/Enums/CaptureName.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
//
77

88
/// A collection of possible capture names for `tree-sitter` with their respected raw values.
9-
public enum CaptureName: String, CaseIterable {
9+
public enum CaptureName: String, CaseIterable, Sendable {
1010
case include
1111
case constructor
1212
case keyword

Sources/CodeEditSourceEditor/Extensions/NSRange+/NSRange+InputEdit.swift

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,27 +6,30 @@
66
//
77

88
import Foundation
9+
import CodeEditTextView
910
import SwiftTreeSitter
1011

1112
extension InputEdit {
12-
init?(range: NSRange, delta: Int, oldEndPoint: Point) {
13+
init?(range: NSRange, delta: Int, oldEndPoint: Point, textView: TextView) {
1314
let newEndLocation = NSMaxRange(range) + delta
1415

1516
if newEndLocation < 0 {
1617
assertionFailure("Invalid range/delta")
1718
return nil
1819
}
1920

20-
// TODO: - Ask why Neon only uses .zero for these
21-
let startPoint: Point = .zero
22-
let newEndPoint: Point = .zero
21+
let newRange = NSRange(location: range.location, length: range.length + delta)
22+
let startPoint = textView.pointForLocation(newRange.location) ?? .zero
23+
let newEndPoint = textView.pointForLocation(newEndLocation) ?? .zero
2324

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)
25+
self.init(
26+
startByte: UInt32(range.location * 2),
27+
oldEndByte: UInt32(NSMaxRange(range) * 2),
28+
newEndByte: UInt32(newEndLocation * 2),
29+
startPoint: startPoint,
30+
oldEndPoint: oldEndPoint,
31+
newEndPoint: newEndPoint
32+
)
3033
}
3134
}
3235

Sources/CodeEditSourceEditor/Extensions/Parser+createTree.swift

Lines changed: 0 additions & 20 deletions
This file was deleted.
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
//
2+
// TextView+Point.swift
3+
// CodeEditSourceEditor
4+
//
5+
// Created by Khan Winter on 1/18/24.
6+
//
7+
8+
import Foundation
9+
import CodeEditTextView
10+
import SwiftTreeSitter
11+
12+
extension TextView {
13+
func pointForLocation(_ location: Int) -> Point? {
14+
guard let linePosition = layoutManager.textLineForOffset(location) else { return nil }
15+
let column = location - linePosition.range.location
16+
return Point(row: linePosition.index, column: column)
17+
}
18+
}

0 commit comments

Comments
 (0)