-
Notifications
You must be signed in to change notification settings - Fork 85
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #59 from thecoolwinter/incremental-highlighting
Incremental Highlighting
- Loading branch information
Showing
14 changed files
with
690 additions
and
197 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
// | ||
// STTextViewController+CaptureNames.swift | ||
// CodeEditTextView | ||
// | ||
// Created by Lukas Pistrol on 16.08.22. | ||
// | ||
|
||
/// A collection of possible capture names for `tree-sitter` with their respected raw values. | ||
public enum CaptureName: String, CaseIterable { | ||
case include | ||
case constructor | ||
case keyword | ||
case boolean | ||
case `repeat` | ||
case conditional | ||
case tag | ||
case comment | ||
case variable | ||
case property | ||
case function | ||
case method | ||
case number | ||
case float | ||
case string | ||
case type | ||
case parameter | ||
case typeAlternate = "type_alternate" | ||
case variableBuiltin = "variable.builtin" | ||
case keywordReturn = "keyword.return" | ||
case keywordFunction = "keyword.function" | ||
|
||
/// Returns a specific capture name case from a given string. | ||
/// - Parameter string: A string to get the capture name from | ||
/// - Returns: A `CaptureNames` case | ||
static func fromString(_ string: String?) -> CaptureName? { | ||
allCases.first { $0.rawValue == string } | ||
} | ||
|
||
var alternate: CaptureName { | ||
switch self { | ||
case .type: | ||
return .typeAlternate | ||
default: | ||
return self | ||
} | ||
} | ||
} |
31 changes: 31 additions & 0 deletions
31
Sources/CodeEditTextView/Extensions/NSRange+/NSRange+InputEdit.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
// | ||
// NSRange+InputEdit.swift | ||
// | ||
// | ||
// Created by Khan Winter on 9/12/22. | ||
// | ||
|
||
import Foundation | ||
import SwiftTreeSitter | ||
|
||
extension InputEdit { | ||
init?(range: NSRange, delta: Int, oldEndPoint: Point) { | ||
let newEndLocation = NSMaxRange(range) + delta | ||
|
||
if newEndLocation < 0 { | ||
assertionFailure("Invalid range/delta") | ||
return nil | ||
} | ||
|
||
// TODO: - Ask why Neon only uses .zero for these | ||
let startPoint: Point = .zero | ||
let newEndPoint: Point = .zero | ||
|
||
self.init(startByte: UInt32(range.location * 2), | ||
oldEndByte: UInt32(NSMaxRange(range) * 2), | ||
newEndByte: UInt32(newEndLocation * 2), | ||
startPoint: startPoint, | ||
oldEndPoint: oldEndPoint, | ||
newEndPoint: newEndPoint) | ||
} | ||
} |
24 changes: 24 additions & 0 deletions
24
Sources/CodeEditTextView/Extensions/NSRange+/NSRange+NSTextRange.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
// | ||
// NSRange+NSTextRange.swift | ||
// | ||
// | ||
// Created by Khan Winter on 9/13/22. | ||
// | ||
|
||
import AppKit | ||
|
||
public extension NSTextRange { | ||
convenience init?(_ range: NSRange, provider: NSTextElementProvider) { | ||
let docLocation = provider.documentRange.location | ||
|
||
guard let start = provider.location?(docLocation, offsetBy: range.location) else { | ||
return nil | ||
} | ||
|
||
guard let end = provider.location?(start, offsetBy: range.length) else { | ||
return nil | ||
} | ||
|
||
self.init(location: start, end: end) | ||
} | ||
} |
File renamed without changes.
28 changes: 28 additions & 0 deletions
28
Sources/CodeEditTextView/Extensions/STTextView+/STTextView+VisibleRange.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
// | ||
// STTextView+VisibleRange.swift | ||
// | ||
// | ||
// Created by Khan Winter on 9/12/22. | ||
// | ||
|
||
import Foundation | ||
import STTextView | ||
|
||
extension STTextView { | ||
func textRange(for rect: CGRect) -> NSRange { | ||
let length = self.textContentStorage.textStorage?.length ?? 0 | ||
|
||
guard let layoutManager = self.textContainer.layoutManager else { | ||
return NSRange(0..<length) | ||
} | ||
let container = self.textContainer | ||
|
||
let glyphRange = layoutManager.glyphRange(forBoundingRect: rect, in: container) | ||
|
||
return layoutManager.characterRange(forGlyphRange: glyphRange, actualGlyphRange: nil) | ||
} | ||
|
||
var visibleTextRange: NSRange { | ||
return textRange(for: visibleRect) | ||
} | ||
} |
19 changes: 19 additions & 0 deletions
19
Sources/CodeEditTextView/Highlighting/HighlightRange.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
// | ||
// HighlightRange.swift | ||
// | ||
// | ||
// Created by Khan Winter on 9/14/22. | ||
// | ||
|
||
import Foundation | ||
|
||
/// This class represents a range to highlight, as well as the capture name for syntax coloring. | ||
class HighlightRange { | ||
init(range: NSRange, capture: CaptureName?) { | ||
self.range = range | ||
self.capture = capture | ||
} | ||
|
||
let range: NSRange | ||
let capture: CaptureName? | ||
} |
Oops, something went wrong.