Skip to content

Commit

Permalink
Refactor Syntax library
Browse files Browse the repository at this point in the history
  • Loading branch information
1024jp committed Jul 11, 2024
1 parent eafe3d1 commit c3d8c73
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 29 deletions.
59 changes: 59 additions & 0 deletions Packages/EditorCore/Sources/Syntax/Highlight.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
//
// Highlight.swift
// Syntax
//
// CotEditor
// https://coteditor.com
//
// Created by 1024jp on 2024-07-11.
//
// ---------------------------------------------------------------------------
//
// © 2022-2024 1024jp
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

import Foundation
import ValueRange

public typealias Highlight = ValueRange<SyntaxType>


extension Highlight {

/// Converts a syntax highlight dictionary to sorted Highlights.
///
/// - Note:
/// This sanitization reduces the performance time of `LayoutManager.apply(highlights:theme:range:)` significantly.
///
/// - Parameter dictionary: The syntax highlight dictionary.
/// - Returns: An array of sorted Highlight structs.
/// - Throws: CancellationError
static func highlights(dictionary: [SyntaxType: [NSRange]]) throws -> [Highlight] {

try SyntaxType.allCases.reversed()
.reduce(into: [SyntaxType: IndexSet]()) { (dict, type) in
guard let ranges = dictionary[type] else { return }

try Task.checkCancellation()

let indexes = IndexSet(integersIn: ranges)

dict[type] = dict.values.reduce(into: indexes) { $0.subtract($1) }
}
.mapValues { $0.rangeView.map(NSRange.init) }
.flatMap { (type, ranges) in ranges.map { ValueRange(value: type, range: $0) } }
.sorted { $0.range.location < $1.range.location }
}
}
30 changes: 1 addition & 29 deletions Packages/EditorCore/Sources/Syntax/HighlightParser.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,6 @@ import Foundation
import StringBasics
import ValueRange

public typealias Highlight = ValueRange<SyntaxType>


public enum NestableToken: Equatable, Hashable, Sendable {

Expand Down Expand Up @@ -98,7 +96,7 @@ public struct HighlightParser: Sendable {
$0.merge($1, uniquingKeysWith: +)
}

return try Self.sanitize(dictionary)
return try Highlight.highlights(dictionary: dictionary)
}
}

Expand Down Expand Up @@ -185,30 +183,4 @@ public struct HighlightParser: Sendable {

return highlights
}


/// Removes overlapped ranges and converts to sorted Highlights.
///
/// - Note:
/// This sanitization reduces the performance time of `SyntaxParser.apply(highlights:range:)` significantly.
///
/// - Parameter dictionary: The syntax highlight dictionary.
/// - Returns: An array of sorted Highlight structs.
/// - Throws: CancellationError
private static func sanitize(_ dictionary: [SyntaxType: [NSRange]]) throws -> [Highlight] {

try SyntaxType.allCases.reversed()
.reduce(into: [SyntaxType: IndexSet]()) { (dict, type) in
guard let ranges = dictionary[type] else { return }

try Task.checkCancellation()

let indexes = IndexSet(integersIn: ranges)

dict[type] = dict.values.reduce(into: indexes) { $0.subtract($1) }
}
.mapValues { $0.rangeView.map(NSRange.init) }
.flatMap { (type, ranges) in ranges.map { ValueRange(value: type, range: $0) } }
.sorted { $0.range.location < $1.range.location }
}
}

0 comments on commit c3d8c73

Please sign in to comment.