Skip to content

Commit

Permalink
Extract RegexHighlighting to package
Browse files Browse the repository at this point in the history
  • Loading branch information
1024jp committed Jul 9, 2024
1 parent cbe0ff8 commit b6d5aa0
Show file tree
Hide file tree
Showing 18 changed files with 258 additions and 154 deletions.
48 changes: 6 additions & 42 deletions CotEditor.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

14 changes: 0 additions & 14 deletions CotEditor/Sources/NSImage.swift
Original file line number Diff line number Diff line change
Expand Up @@ -51,17 +51,3 @@ extension NSImage {
return image
}
}



extension NSAttributedString {

convenience init(systemSymbolName: String, configuration: NSImage.SymbolConfiguration? = nil, accessibilityDescription: String? = nil) {

let attachment = NSTextAttachment()
attachment.image = NSImage(systemSymbolName: systemSymbolName, accessibilityDescription: accessibilityDescription)?
.withSymbolConfiguration(configuration ?? .init())

self.init(attachment: attachment)
}
}
2 changes: 0 additions & 2 deletions CotEditor/Sources/PatternSortView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -245,8 +245,6 @@ struct RegularExpressionSortPatternView: View {

@Namespace private var accessibility

private let formatter = RegularExpressionFormatter()


var body: some View {

Expand Down
7 changes: 5 additions & 2 deletions CotEditor/Sources/RegexFindPanelTextView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,20 @@
//

import AppKit
import RegexHighlighting
import StringBasics

final class RegexFindPanelTextView: FindPanelTextView {

// MARK: Public Properties

var parseMode: RegularExpressionParseMode = .search { didSet { self.invalidateRegularExpression() } }
var parseMode: RegexParseMode = .search { didSet { self.invalidateRegularExpression() } }
var isRegularExpressionMode: Bool = false { didSet { self.invalidateRegularExpression() } }

private(set) var isValid = true

private let theme: RegexTheme<NSColor> = .default


// MARK: Text View Methods

Expand Down Expand Up @@ -100,6 +103,6 @@ final class RegexFindPanelTextView: FindPanelTextView {
/// Highlights the content string as a regular expression pattern.
private func invalidateRegularExpression() {

self.isValid = self.highlightAsRegularExpressionPattern(mode: self.parseMode, enabled: self.isRegularExpressionMode)
self.isValid = self.highlightAsRegularExpressionPattern(mode: self.parseMode, theme: self.theme, enabled: self.isRegularExpressionMode)
}
}
19 changes: 8 additions & 11 deletions CotEditor/Sources/RegexTextField.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@

import AppKit
import SwiftUI
import RegexHighlighting

struct RegexTextField: NSViewRepresentable {

Expand All @@ -38,9 +39,8 @@ struct RegexTextField: NSViewRepresentable {

@Binding private var text: String
private var isHighlighted: Bool = true
private let mode: RegularExpressionParseMode
private let mode: RegexParseMode
private let showsError: Bool
private let showsInvisibles: Bool

private let prompt: String?
private let onSubmit: () -> Void
Expand All @@ -49,15 +49,14 @@ struct RegexTextField: NSViewRepresentable {
private var style: Style = .automatic


init(text: Binding<String>, mode: RegularExpressionParseMode = .search, showsError: Bool = false, showsInvisible: Bool = true, prompt: String? = nil, onSubmit: @escaping () -> Void = {}) {
init(text: Binding<String>, mode: RegexParseMode = .search, showsError: Bool = false, prompt: String? = nil, onSubmit: @escaping () -> Void = {}) {

self._text = text
self.prompt = prompt
self.onSubmit = onSubmit

self.mode = mode
self.showsError = showsError
self.showsInvisibles = showsInvisible
}


Expand Down Expand Up @@ -101,7 +100,7 @@ struct RegexTextField: NSViewRepresentable {

func makeNSView(context: Context) -> NSTextField {

let textField = RegexNSTextField(string: self.text, mode: self.mode, showsError: self.showsError, showsInvisibles: self.showsInvisibles)
let textField = RegexNSTextField(string: self.text, mode: self.mode, showsError: self.showsError)
textField.delegate = context.coordinator
textField.placeholderString = self.prompt
textField.isEditable = true
Expand Down Expand Up @@ -183,18 +182,16 @@ private final class RegexNSTextField: NSTextField {

// MARK: Private Properties

private let regexFormatter: RegularExpressionFormatter
private let regexFormatter: RegexFormatter<NSColor>



// MARK: Text Field Methods

init(string: String = "", mode: RegularExpressionParseMode, showsError: Bool, showsInvisibles: Bool) {
init(string: String = "", mode: RegexParseMode, showsError: Bool) {

let formatter = RegularExpressionFormatter()
let formatter = RegexFormatter(theme: .default, showsError: showsError)
formatter.mode = mode
formatter.showsError = showsError
formatter.showsInvisibles = showsInvisibles
self.regexFormatter = formatter

super.init(frame: .zero)
Expand Down Expand Up @@ -254,7 +251,7 @@ private final class RegexNSTextField: NSTextField {

guard let editor = self.currentEditor() as? NSTextView else { return }

editor.highlightAsRegularExpressionPattern(mode: self.regexFormatter.mode, enabled: self.isRegexHighlighted)
editor.highlightAsRegularExpressionPattern(mode: self.regexFormatter.mode, theme: self.regexFormatter.theme, enabled: self.isRegexHighlighted)
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
//
// RegularExpressionSyntaxType+Color.swift
// RegexTheme.swift
//
// CotEditor
// https://coteditor.com
//
// Created by 1024jp on 2018-12-23.
// Created by 1024jp on 2024-07-09.
//
// ---------------------------------------------------------------------------
//
// © 2018-2023 1024jp
// © 2024 1024jp
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand All @@ -24,17 +24,16 @@
//

import AppKit.NSColor
import RegexHighlighting

extension RegularExpressionSyntaxType {
extension RegexTheme<NSColor> {

var color: NSColor {

switch self {
case .character: .Regex.character
case .backReference: .Regex.backReference
case .symbol: .Regex.symbol
case .quantifier: .Regex.quantifier
case .anchor: .Regex.anchor
}
}
static let `default` = RegexTheme(
character: .Regex.character,
backReference: .Regex.backReference,
symbol: .Regex.symbol,
quantifier: .Regex.quantifier,
anchor: .Regex.anchor,
invisible: .tertiaryLabelColor
)
}
8 changes: 4 additions & 4 deletions CotEditor/Sources/RegularExpressionTextField.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
//

import AppKit
import RegexHighlighting

final class RegularExpressionTextField: NSTextField {

Expand All @@ -48,7 +49,7 @@ final class RegularExpressionTextField: NSTextField {

// MARK: Private Properties

private let regexFormatter = RegularExpressionFormatter()
private let regexFormatter = RegexFormatter(theme: .default)

@IBInspectable private var isReplacement: Bool = false

Expand Down Expand Up @@ -77,7 +78,6 @@ final class RegularExpressionTextField: NSTextField {

// setup regex formatter
self.regexFormatter.mode = self.parseMode
self.regexFormatter.showsInvisibles = true
}


Expand Down Expand Up @@ -113,7 +113,7 @@ final class RegularExpressionTextField: NSTextField {

// MARK: Private Methods

private var parseMode: RegularExpressionParseMode {
private var parseMode: RegexParseMode {

self.isReplacement ? .replacement(unescapes: self.unescapesReplacement) : .search
}
Expand All @@ -124,6 +124,6 @@ final class RegularExpressionTextField: NSTextField {

guard let editor = self.currentEditor() as? NSTextView else { return }

editor.highlightAsRegularExpressionPattern(mode: self.parseMode, enabled: self.parsesRegularExpression)
editor.highlightAsRegularExpressionPattern(mode: self.parseMode, theme: self.regexFormatter.theme, enabled: self.parsesRegularExpression)
}
}
4 changes: 2 additions & 2 deletions CotEditor/Sources/SyntaxHighlightEditView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ struct SyntaxHighlightEditView: View {

TableColumn(String(localized: "Begin String", table: "SyntaxEditor", comment: "table column header"), value: \.begin) { wrappedItem in
if let item = $items[id: wrappedItem.id] {
RegexTextField(text: item.begin, showsError: true, showsInvisible: true)
RegexTextField(text: item.begin, showsError: true)
.regexHighlighted(item.isRegularExpression.wrappedValue)
.style(.table)
.focused($focusedField, equals: item.id)
Expand All @@ -89,7 +89,7 @@ struct SyntaxHighlightEditView: View {

TableColumn(String(localized: "End String", table: "SyntaxEditor", comment: "table column header"), sortUsing: KeyPathComparator(\.end)) { wrappedItem in
if let item = $items[id: wrappedItem.id] {
RegexTextField(text: item.end ?? "", showsError: true, showsInvisible: true)
RegexTextField(text: item.end ?? "", showsError: true)
.regexHighlighted(item.isRegularExpression.wrappedValue)
.style(.table)
}
Expand Down
2 changes: 1 addition & 1 deletion CotEditor/Sources/SyntaxOutlineEditView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ struct SyntaxOutlineEditView: View {
.alignment(.center)

TableColumn(String(localized: "Regular Expression Pattern", table: "SyntaxEditor", comment: "table column header")) { item in
RegexTextField(text: item.pattern, showsError: true, showsInvisible: true)
RegexTextField(text: item.pattern, showsError: true)
.style(.table)
.focused($focusedField, equals: item.id)
}
Expand Down
6 changes: 6 additions & 0 deletions Packages/MacUI/Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,23 @@ let package = Package(
products: [
.library(name: "MacUI", targets: [
"ControlUI",
"RegexHighlighting",
"Shortcut",
]),

.library(name: "RegexHighlighting", targets: ["RegexHighlighting"]),
.library(name: "Shortcut", targets: ["Shortcut"]),
],
dependencies: [
.package(path: "EditorCore"),
.package(url: "https://github.com/realm/SwiftLint", from: Version(0, 55, 0)),
],
targets: [
.target(name: "ControlUI"),

.target(name: "RegexHighlighting", dependencies: ["EditorCore"]),
.testTarget(name: "RegexHighlightingTests", dependencies: ["RegexHighlighting"]),

.target(name: "Shortcut", resources: [.process("Resources")]),
.testTarget(name: "ShortcutTests", dependencies: ["Shortcut"]),
],
Expand Down
39 changes: 39 additions & 0 deletions Packages/MacUI/Sources/RegexHighlighting/NSAttributedString.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
//
// NSAttributedString.swift
// RegexHighlighting
//
// CotEditor
// https://coteditor.com
//
// Created by 1024jp on 2024-07-09.
//
// ---------------------------------------------------------------------------
//
// © 2020-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 AppKit

extension NSAttributedString {

convenience init(systemSymbolName: String, configuration: NSImage.SymbolConfiguration? = nil, accessibilityDescription: String? = nil) {

let attachment = NSTextAttachment()
attachment.image = NSImage(systemSymbolName: systemSymbolName, accessibilityDescription: accessibilityDescription)?
.withSymbolConfiguration(configuration ?? .init())

self.init(attachment: attachment)
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
//
// NSTextSelectionDataSource.swift
// RegexHighlighting
//
// CotEditor
// https://coteditor.com
Expand All @@ -8,7 +9,7 @@
//
// ---------------------------------------------------------------------------
//
// © 2022 1024jp
// © 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.
Expand All @@ -25,8 +26,6 @@

import AppKit

// MARK: Range Conversion

extension NSTextSelectionDataSource {

/// Converts NSRange to NSTextRange.
Expand All @@ -42,17 +41,4 @@ extension NSTextSelectionDataSource {

return NSTextRange(location: location, end: end)
}


/// Converts NSTextRange to NSRange.
///
/// - Parameter textRange: The NSTextRange to convert.
/// - Returns: An NSRange.
func range(for textRange: NSTextRange) -> NSRange {

let location = self.offset(from: self.documentRange.location, to: textRange.location)
let length = self.offset(from: textRange.location, to: textRange.endLocation)

return NSRange(location: location, length: length)
}
}
Loading

0 comments on commit b6d5aa0

Please sign in to comment.