mirror of
https://github.com/coteditor/CotEditor.git
synced 2024-09-11 19:27:30 +03:00
Extract TextFind to package
This commit is contained in:
parent
f26dc68477
commit
7577870fb1
@ -136,12 +136,8 @@
|
||||
2A2179F61A07093B002C4AB1 /* SyntaxMap.json in Resources */ = {isa = PBXBuildFile; fileRef = 2A2179F51A07093B002C4AB1 /* SyntaxMap.json */; };
|
||||
2A21E6732BB44D5E0054C8A1 /* DonationSettings.xcstrings in Resources */ = {isa = PBXBuildFile; fileRef = 2A21E6722BB44D5E0054C8A1 /* DonationSettings.xcstrings */; };
|
||||
2A21E6742BB44D5E0054C8A1 /* DonationSettings.xcstrings in Resources */ = {isa = PBXBuildFile; fileRef = 2A21E6722BB44D5E0054C8A1 /* DonationSettings.xcstrings */; };
|
||||
2A231A251E7B4EDC00C2A909 /* MultipleReplace+Codable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A231A241E7B4EDC00C2A909 /* MultipleReplace+Codable.swift */; };
|
||||
2A231A261E7B4EDC00C2A909 /* MultipleReplace+Codable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A231A241E7B4EDC00C2A909 /* MultipleReplace+Codable.swift */; };
|
||||
2A231A281E7BD82700C2A909 /* Binding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A231A271E7BD82700C2A909 /* Binding.swift */; };
|
||||
2A231A291E7BD82700C2A909 /* Binding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A231A271E7BD82700C2A909 /* Binding.swift */; };
|
||||
2A231A2D1E7BE8B700C2A909 /* FindProgress.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A231A2C1E7BE8B700C2A909 /* FindProgress.swift */; };
|
||||
2A231A2E1E7BE8B700C2A909 /* FindProgress.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A231A2C1E7BE8B700C2A909 /* FindProgress.swift */; };
|
||||
2A231A361E7C30F000C2A909 /* MultipleReplaceSplitViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A231A351E7C30F000C2A909 /* MultipleReplaceSplitViewController.swift */; };
|
||||
2A231A371E7C30F000C2A909 /* MultipleReplaceSplitViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A231A351E7C30F000C2A909 /* MultipleReplaceSplitViewController.swift */; };
|
||||
2A231A391E7C31F400C2A909 /* MultipleReplaceListViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A231A381E7C31F400C2A909 /* MultipleReplaceListViewController.swift */; };
|
||||
@ -189,8 +185,6 @@
|
||||
2A33D07F1D1C75B8005977B9 /* SyntaxValidationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A33D07D1D1C75B8005977B9 /* SyntaxValidationView.swift */; };
|
||||
2A341D1A281EE23C00B85CB6 /* UserActivity.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A341D19281EE23C00B85CB6 /* UserActivity.swift */; };
|
||||
2A341D1B281EE23C00B85CB6 /* UserActivity.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A341D19281EE23C00B85CB6 /* UserActivity.swift */; };
|
||||
2A3581981E597ECE00762AA5 /* MultipleReplace.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A3581971E597ECE00762AA5 /* MultipleReplace.swift */; };
|
||||
2A3581991E597ECE00762AA5 /* MultipleReplace.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A3581971E597ECE00762AA5 /* MultipleReplace.swift */; };
|
||||
2A359DFE1DAE93EE00FEF7AA /* NSWindow+Responder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A359DFD1DAE93EE00FEF7AA /* NSWindow+Responder.swift */; };
|
||||
2A359DFF1DAE93EE00FEF7AA /* NSWindow+Responder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A359DFD1DAE93EE00FEF7AA /* NSWindow+Responder.swift */; };
|
||||
2A3643E61E7C3D2400EA3CE8 /* ReplacementManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A3643E51E7C3D2400EA3CE8 /* ReplacementManager.swift */; };
|
||||
@ -715,9 +709,9 @@
|
||||
2AEC48341E641E4F00FB0F89 /* Snippet.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AEC48321E641E4F00FB0F89 /* Snippet.swift */; };
|
||||
2AEC69C41D41A1BE0089F96F /* EditorTextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AEC69C31D41A1BE0089F96F /* EditorTextView.swift */; };
|
||||
2AEC69C51D41A1BE0089F96F /* EditorTextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AEC69C31D41A1BE0089F96F /* EditorTextView.swift */; };
|
||||
2AED46701E425CD200751C45 /* TextFind.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AED466F1E425CD200751C45 /* TextFind.swift */; };
|
||||
2AED46711E425CD200751C45 /* TextFind.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AED466F1E425CD200751C45 /* TextFind.swift */; };
|
||||
2AED46731E43942300751C45 /* TextFindTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AED46721E43942300751C45 /* TextFindTests.swift */; };
|
||||
2AED46701E425CD200751C45 /* TextFind.Error+Localization.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AED466F1E425CD200751C45 /* TextFind.Error+Localization.swift */; };
|
||||
2AED46711E425CD200751C45 /* TextFind.Error+Localization.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AED466F1E425CD200751C45 /* TextFind.Error+Localization.swift */; };
|
||||
2AED46731E43942300751C45 /* TextFinderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AED46721E43942300751C45 /* TextFinderTests.swift */; };
|
||||
2AED70EE1D2E36EF006FFBCE /* DocumentViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AED70ED1D2E36EF006FFBCE /* DocumentViewController.swift */; };
|
||||
2AED70EF1D2E36EF006FFBCE /* DocumentViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AED70ED1D2E36EF006FFBCE /* DocumentViewController.swift */; };
|
||||
2AEE84B21E8158D700BA7982 /* WriteToConsoleCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AEE84B11E8158D700BA7982 /* WriteToConsoleCommand.swift */; };
|
||||
@ -866,9 +860,7 @@
|
||||
2A1FAD5720A74D0A00566D7C /* MutableCopying.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MutableCopying.swift; sourceTree = "<group>"; };
|
||||
2A2179F51A07093B002C4AB1 /* SyntaxMap.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = SyntaxMap.json; sourceTree = "<group>"; };
|
||||
2A21E6722BB44D5E0054C8A1 /* DonationSettings.xcstrings */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json.xcstrings; path = DonationSettings.xcstrings; sourceTree = "<group>"; };
|
||||
2A231A241E7B4EDC00C2A909 /* MultipleReplace+Codable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "MultipleReplace+Codable.swift"; sourceTree = "<group>"; };
|
||||
2A231A271E7BD82700C2A909 /* Binding.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Binding.swift; sourceTree = "<group>"; };
|
||||
2A231A2C1E7BE8B700C2A909 /* FindProgress.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FindProgress.swift; sourceTree = "<group>"; };
|
||||
2A231A351E7C30F000C2A909 /* MultipleReplaceSplitViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MultipleReplaceSplitViewController.swift; sourceTree = "<group>"; };
|
||||
2A231A381E7C31F400C2A909 /* MultipleReplaceListViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MultipleReplaceListViewController.swift; sourceTree = "<group>"; };
|
||||
2A24F90F2BEDDFEF00CB6CCF /* WhatsNewView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WhatsNewView.swift; sourceTree = "<group>"; };
|
||||
@ -893,7 +885,6 @@
|
||||
2A30C7DA2B1380BE002F6381 /* ShortcutView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShortcutView.swift; sourceTree = "<group>"; };
|
||||
2A33D07D1D1C75B8005977B9 /* SyntaxValidationView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SyntaxValidationView.swift; sourceTree = "<group>"; };
|
||||
2A341D19281EE23C00B85CB6 /* UserActivity.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserActivity.swift; sourceTree = "<group>"; };
|
||||
2A3581971E597ECE00762AA5 /* MultipleReplace.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MultipleReplace.swift; sourceTree = "<group>"; };
|
||||
2A359DFD1DAE93EE00FEF7AA /* NSWindow+Responder.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSWindow+Responder.swift"; sourceTree = "<group>"; };
|
||||
2A3643E51E7C3D2400EA3CE8 /* ReplacementManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReplacementManager.swift; sourceTree = "<group>"; };
|
||||
2A36CE7B1FF654C000020702 /* NSTextView+Snippet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSTextView+Snippet.swift"; sourceTree = "<group>"; };
|
||||
@ -1175,8 +1166,8 @@
|
||||
2AEBD259246BB4C200EC97A3 /* NSAttributedStringTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSAttributedStringTests.swift; sourceTree = "<group>"; };
|
||||
2AEC48321E641E4F00FB0F89 /* Snippet.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Snippet.swift; sourceTree = "<group>"; };
|
||||
2AEC69C31D41A1BE0089F96F /* EditorTextView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EditorTextView.swift; sourceTree = "<group>"; };
|
||||
2AED466F1E425CD200751C45 /* TextFind.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TextFind.swift; sourceTree = "<group>"; };
|
||||
2AED46721E43942300751C45 /* TextFindTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TextFindTests.swift; sourceTree = "<group>"; };
|
||||
2AED466F1E425CD200751C45 /* TextFind.Error+Localization.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "TextFind.Error+Localization.swift"; sourceTree = "<group>"; };
|
||||
2AED46721E43942300751C45 /* TextFinderTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TextFinderTests.swift; sourceTree = "<group>"; };
|
||||
2AED70ED1D2E36EF006FFBCE /* DocumentViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DocumentViewController.swift; sourceTree = "<group>"; };
|
||||
2AEE84B11E8158D700BA7982 /* WriteToConsoleCommand.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WriteToConsoleCommand.swift; sourceTree = "<group>"; };
|
||||
2AF073E21D33C3AB00770BA6 /* Theme.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Theme.swift; sourceTree = "<group>"; };
|
||||
@ -1479,8 +1470,6 @@
|
||||
2A231A2A1E7BD92F00C2A909 /* Models */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
2A3581971E597ECE00762AA5 /* MultipleReplace.swift */,
|
||||
2A231A241E7B4EDC00C2A909 /* MultipleReplace+Codable.swift */,
|
||||
2A3A19DE2068A76600516DE4 /* NSTextView+MultipleReplace.swift */,
|
||||
);
|
||||
name = Models;
|
||||
@ -1849,8 +1838,7 @@
|
||||
children = (
|
||||
2A18560A1D47FA37008FA79E /* TextFinder.swift */,
|
||||
2A6876A72963DE38006257A6 /* TextFinderSettings.swift */,
|
||||
2AED466F1E425CD200751C45 /* TextFind.swift */,
|
||||
2A231A2C1E7BE8B700C2A909 /* FindProgress.swift */,
|
||||
2AED466F1E425CD200751C45 /* TextFind.Error+Localization.swift */,
|
||||
2AB1BD21287D752300C6FEAF /* Views */,
|
||||
2A009ADB1A5AB96F00C3D542 /* Text View */,
|
||||
2A3581931E597AFE00762AA5 /* Multiple Replace */,
|
||||
@ -2107,7 +2095,7 @@
|
||||
2ACC65311C98033D000574DC /* ThemeTests.swift */,
|
||||
2A9C07551CF9F982006D672D /* IncompatibleCharacterTests.swift */,
|
||||
2A54BE2B1D40EB24000816B0 /* LineEndingTests.swift */,
|
||||
2AED46721E43942300751C45 /* TextFindTests.swift */,
|
||||
2AED46721E43942300751C45 /* TextFinderTests.swift */,
|
||||
2AC72EA1253478D5001D3CA0 /* FileDropItemTests.swift */,
|
||||
2ABEFB6923DC0CA0008769F4 /* EditorCounterTests.swift */,
|
||||
2A1125C023F180FF006A1DB2 /* LineRangeCacheableTests.swift */,
|
||||
@ -2745,7 +2733,6 @@
|
||||
2AE52F291D176B8500D60A32 /* FindPanelSplitView.swift in Sources */,
|
||||
2A5D13361D1FC87900D38E6A /* FindPanelTextClipView.swift in Sources */,
|
||||
2A5D13331D1FB90300D38E6A /* FindPanelTextView.swift in Sources */,
|
||||
2A231A2E1E7BE8B700C2A909 /* FindProgress.swift in Sources */,
|
||||
2A5D13111D1EE66500D38E6A /* FindProgressView.swift in Sources */,
|
||||
2AF98CAB294B9488009AD47F /* FindSettingsView.swift in Sources */,
|
||||
2A65EC262B80C01B008096C5 /* FontPicker.swift in Sources */,
|
||||
@ -2786,8 +2773,6 @@
|
||||
2AB857E82B922D7D0079CFA2 /* ModeManager.swift in Sources */,
|
||||
2AB857EB2B93050E0079CFA2 /* ModeOptions.swift in Sources */,
|
||||
2A836D9F2AB1528700B4D458 /* ModeSettingsView.swift in Sources */,
|
||||
2A3581991E597ECE00762AA5 /* MultipleReplace.swift in Sources */,
|
||||
2A231A261E7B4EDC00C2A909 /* MultipleReplace+Codable.swift in Sources */,
|
||||
2A231A3A1E7C31F400C2A909 /* MultipleReplaceListViewController.swift in Sources */,
|
||||
2A6876AB29641547006257A6 /* MultipleReplacePanelController.swift in Sources */,
|
||||
2AF98CAF294C0670009AD47F /* MultipleReplaceSettingsView.swift in Sources */,
|
||||
@ -2904,7 +2889,7 @@
|
||||
2A4714E42093A2D40093E27F /* SyntaxParser.swift in Sources */,
|
||||
2A33D07F1D1C75B8005977B9 /* SyntaxValidationView.swift in Sources */,
|
||||
2AFE848722AE71130001C4ED /* TextContainer.swift in Sources */,
|
||||
2AED46711E425CD200751C45 /* TextFind.swift in Sources */,
|
||||
2AED46711E425CD200751C45 /* TextFind.Error+Localization.swift in Sources */,
|
||||
2A18560C1D47FA37008FA79E /* TextFinder.swift in Sources */,
|
||||
2A6876A82963DE38006257A6 /* TextFinderSettings.swift in Sources */,
|
||||
2AD69B861D3E42F700FBD998 /* TextSelection.swift in Sources */,
|
||||
@ -2966,7 +2951,7 @@
|
||||
2AC71DE21BF0BDBC002E1434 /* StringAdvancedCountTests.swift in Sources */,
|
||||
2AE12DFE1E7DB7D200681F72 /* StringFilenameTests.swift in Sources */,
|
||||
2A63CEC41D0B06D800ED8186 /* SyntaxTests.swift in Sources */,
|
||||
2AED46731E43942300751C45 /* TextFindTests.swift in Sources */,
|
||||
2AED46731E43942300751C45 /* TextFinderTests.swift in Sources */,
|
||||
2ACC65321C98033D000574DC /* ThemeTests.swift in Sources */,
|
||||
2A476CAE1D09C8C80088E37A /* URLExtensionsTests.swift in Sources */,
|
||||
2AFD218D27E0442B00E83E88 /* UTTypeExtensionTests.swift in Sources */,
|
||||
@ -3065,7 +3050,6 @@
|
||||
2AE52F281D176B8500D60A32 /* FindPanelSplitView.swift in Sources */,
|
||||
2A5D13351D1FC87900D38E6A /* FindPanelTextClipView.swift in Sources */,
|
||||
2A5D13321D1FB90300D38E6A /* FindPanelTextView.swift in Sources */,
|
||||
2A231A2D1E7BE8B700C2A909 /* FindProgress.swift in Sources */,
|
||||
2A5D13101D1EE66500D38E6A /* FindProgressView.swift in Sources */,
|
||||
2AF98CAC294B9488009AD47F /* FindSettingsView.swift in Sources */,
|
||||
2A65EC272B80C01B008096C5 /* FontPicker.swift in Sources */,
|
||||
@ -3106,8 +3090,6 @@
|
||||
2AB857E92B922D7D0079CFA2 /* ModeManager.swift in Sources */,
|
||||
2AB857EC2B93050E0079CFA2 /* ModeOptions.swift in Sources */,
|
||||
2A836DA02AB1528700B4D458 /* ModeSettingsView.swift in Sources */,
|
||||
2A3581981E597ECE00762AA5 /* MultipleReplace.swift in Sources */,
|
||||
2A231A251E7B4EDC00C2A909 /* MultipleReplace+Codable.swift in Sources */,
|
||||
2A231A391E7C31F400C2A909 /* MultipleReplaceListViewController.swift in Sources */,
|
||||
2A6876AC29641547006257A6 /* MultipleReplacePanelController.swift in Sources */,
|
||||
2AF98CB0294C0670009AD47F /* MultipleReplaceSettingsView.swift in Sources */,
|
||||
@ -3224,7 +3206,7 @@
|
||||
2A4714E32093A2D40093E27F /* SyntaxParser.swift in Sources */,
|
||||
2A33D07E1D1C75B8005977B9 /* SyntaxValidationView.swift in Sources */,
|
||||
2AFE848622AE71130001C4ED /* TextContainer.swift in Sources */,
|
||||
2AED46701E425CD200751C45 /* TextFind.swift in Sources */,
|
||||
2AED46701E425CD200751C45 /* TextFind.Error+Localization.swift in Sources */,
|
||||
2A18560B1D47FA37008FA79E /* TextFinder.swift in Sources */,
|
||||
2A6876A92963DE38006257A6 /* TextFinderSettings.swift in Sources */,
|
||||
2AD69B851D3E42F700FBD998 /* TextSelection.swift in Sources */,
|
||||
|
@ -24,6 +24,7 @@
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
import TextFind
|
||||
|
||||
struct FindProgressView: View {
|
||||
|
||||
|
@ -29,6 +29,7 @@ import Combine
|
||||
import UniformTypeIdentifiers
|
||||
import OSLog
|
||||
import Defaults
|
||||
import TextFind
|
||||
|
||||
final class MultipleReplaceListViewController: NSViewController, NSMenuItemValidation {
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
//
|
||||
// ---------------------------------------------------------------------------
|
||||
//
|
||||
// © 2022-2023 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.
|
||||
@ -24,6 +24,7 @@
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
import TextFind
|
||||
|
||||
struct MultipleReplaceSettingsView: View {
|
||||
|
||||
|
@ -27,6 +27,7 @@ import AppKit
|
||||
import Combine
|
||||
import SwiftUI
|
||||
import Defaults
|
||||
import TextFind
|
||||
|
||||
final class MultipleReplaceViewController: NSViewController {
|
||||
|
||||
|
@ -25,6 +25,7 @@
|
||||
|
||||
import AppKit
|
||||
import SwiftUI
|
||||
import TextFind
|
||||
|
||||
extension NSTextView {
|
||||
|
||||
|
@ -25,6 +25,7 @@
|
||||
|
||||
import Foundation
|
||||
import Observation
|
||||
import TextFind
|
||||
import UniformTypeIdentifiers
|
||||
|
||||
@Observable final class ReplacementManager: SettingFileManaging {
|
||||
|
65
CotEditor/Sources/TextFind.Error+Localization.swift
Normal file
65
CotEditor/Sources/TextFind.Error+Localization.swift
Normal file
@ -0,0 +1,65 @@
|
||||
//
|
||||
// TextFind.Error+Localization.swift
|
||||
//
|
||||
// CotEditor
|
||||
// https://coteditor.com
|
||||
//
|
||||
// Created by 1024jp on 2017-02-02.
|
||||
//
|
||||
// ---------------------------------------------------------------------------
|
||||
//
|
||||
// © 2015-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 TextFind
|
||||
|
||||
extension TextFind.Error: @retroactive LocalizedError {
|
||||
|
||||
public var errorDescription: String? {
|
||||
|
||||
switch self {
|
||||
case .regularExpression:
|
||||
String(localized: "TextFind.Error.regularExpression.errorDescription",
|
||||
defaultValue: "Invalid regular expression",
|
||||
table: "TextFind")
|
||||
case .emptyFindString:
|
||||
String(localized: "TextFind.Error.emptyFindString.errorDescription",
|
||||
defaultValue: "Empty find string",
|
||||
table: "TextFind")
|
||||
case .emptyInSelectionSearch:
|
||||
String(localized: "TextFind.Error.emptyInSelectionSearch.errorDescription",
|
||||
defaultValue: "The option “in selection” is selected, although nothing is selected.",
|
||||
table: "TextFind")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public var recoverySuggestion: String? {
|
||||
|
||||
switch self {
|
||||
case .regularExpression(let reason):
|
||||
reason
|
||||
case .emptyFindString:
|
||||
String(localized: "TextFind.Error.emptyFindString.recoverySuggestion",
|
||||
defaultValue: "Input text to find.",
|
||||
table: "TextFind")
|
||||
case .emptyInSelectionSearch:
|
||||
String(localized: "TextFind.Error.emptyInSelectionSearch.recoverySuggestion",
|
||||
defaultValue: "Select the search scope in the document or turn off the “in selection” option.",
|
||||
table: "TextFind")
|
||||
}
|
||||
}
|
||||
}
|
@ -25,6 +25,7 @@
|
||||
|
||||
import AppKit
|
||||
import SwiftUI
|
||||
import TextFind
|
||||
import ValueRange
|
||||
|
||||
extension NSAttributedString: @retroactive @unchecked Sendable { }
|
||||
|
@ -23,8 +23,10 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import AppKit
|
||||
import Foundation
|
||||
import AppKit.NSPasteboard
|
||||
import Defaults
|
||||
import TextFind
|
||||
|
||||
@MainActor final class TextFinderSettings: NSObject {
|
||||
|
||||
|
@ -22,6 +22,7 @@ let package = Package(
|
||||
"Syntax",
|
||||
"TextClipping",
|
||||
"TextEditing",
|
||||
"TextFind",
|
||||
"UnicodeNormalization",
|
||||
"ValueRange",
|
||||
"Shortcut",
|
||||
@ -37,6 +38,7 @@ let package = Package(
|
||||
.library(name: "Syntax", targets: ["Syntax"]),
|
||||
.library(name: "TextClipping", targets: ["TextClipping"]),
|
||||
.library(name: "TextEditing", targets: ["TextEditing"]),
|
||||
.library(name: "TextFind", targets: ["TextFind"]),
|
||||
.library(name: "UnicodeNormalization", targets: ["UnicodeNormalization"]),
|
||||
|
||||
.library(name: "Shortcut", targets: ["Shortcut"]),
|
||||
@ -72,6 +74,9 @@ let package = Package(
|
||||
.target(name: "TextEditing", dependencies: ["StringBasics", "Syntax"]),
|
||||
.testTarget(name: "TextEditingTests", dependencies: ["TextEditing"]),
|
||||
|
||||
.target(name: "TextFind", dependencies: ["StringBasics", "ValueRange"]),
|
||||
.testTarget(name: "TextFindTests", dependencies: ["TextFind"]),
|
||||
|
||||
.target(name: "UnicodeNormalization"),
|
||||
.testTarget(name: "UnicodeNormalizationTests", dependencies: ["UnicodeNormalization"]),
|
||||
|
||||
|
@ -24,7 +24,7 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
extension Sequence where Element: Equatable {
|
||||
public extension Sequence where Element: Equatable {
|
||||
|
||||
/// An array consists of unique elements of receiver by keeping ordering.
|
||||
var uniqued: [Element] {
|
||||
@ -36,3 +36,14 @@ extension Sequence where Element: Equatable {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public extension Array where Element: Equatable {
|
||||
|
||||
/// Removes duplicated elements by keeping ordering.
|
||||
mutating func unique() {
|
||||
|
||||
self = self.uniqued
|
||||
}
|
||||
}
|
||||
|
@ -24,24 +24,6 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
// MARK: - Unique
|
||||
|
||||
extension Sequence where Element: Equatable {
|
||||
|
||||
/// An array consists of unique elements of receiver by keeping ordering.
|
||||
var uniqued: [Element] {
|
||||
|
||||
self.reduce(into: []) { (unique, element) in
|
||||
guard !unique.contains(element) else { return }
|
||||
|
||||
unique.append(element)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// MARK: - Sort
|
||||
|
||||
extension Sequence {
|
||||
|
||||
/// Returns the elements of the sequence, sorted using the value that the given key path refers as the comparison between elements.
|
||||
|
@ -8,7 +8,7 @@
|
||||
//
|
||||
// ---------------------------------------------------------------------------
|
||||
//
|
||||
// © 2022-2023 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.
|
||||
@ -26,13 +26,13 @@
|
||||
import Foundation
|
||||
import Observation
|
||||
|
||||
@Observable final class FindProgress: @unchecked Sendable {
|
||||
@Observable public final class FindProgress: @unchecked Sendable {
|
||||
|
||||
@ObservationIgnored private(set) var count = 0
|
||||
@ObservationIgnored var completedUnit = 0
|
||||
@ObservationIgnored public private(set) var count = 0
|
||||
@ObservationIgnored public var completedUnit = 0
|
||||
|
||||
private(set) var isCancelled = false
|
||||
private(set) var isFinished = false
|
||||
public private(set) var isCancelled = false
|
||||
public private(set) var isFinished = false
|
||||
|
||||
private let scope: Range<Int>
|
||||
|
||||
@ -40,14 +40,14 @@ import Observation
|
||||
/// Instantiates a progress.
|
||||
///
|
||||
/// - Parameter scope: The range of progress unit to work with.
|
||||
init(scope: Range<Int>) {
|
||||
public init(scope: Range<Int>) {
|
||||
|
||||
self.scope = scope
|
||||
}
|
||||
|
||||
|
||||
/// The fraction of task completed in between 0...1.0.
|
||||
var fractionCompleted: Double {
|
||||
public var fractionCompleted: Double {
|
||||
|
||||
if self.isFinished || self.scope.isEmpty {
|
||||
return 1
|
||||
@ -60,21 +60,21 @@ import Observation
|
||||
/// Increments count.
|
||||
///
|
||||
/// - Parameter count: The amount to increment.
|
||||
func increment(by count: Int = 1) {
|
||||
public func increment(by count: Int = 1) {
|
||||
|
||||
self.count += count
|
||||
}
|
||||
|
||||
|
||||
/// Raise `isCancelled` flag.
|
||||
func cancel() {
|
||||
public func cancel() {
|
||||
|
||||
self.isCancelled = true
|
||||
}
|
||||
|
||||
|
||||
/// Raise `isFinished` flag.
|
||||
func finish() {
|
||||
public func finish() {
|
||||
|
||||
self.isFinished = true
|
||||
}
|
@ -8,7 +8,7 @@
|
||||
//
|
||||
// ---------------------------------------------------------------------------
|
||||
//
|
||||
// © 2017-2023 1024jp
|
||||
// © 2017-2024 1024jp
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
@ -38,7 +38,7 @@ extension MultipleReplace.Replacement: Codable {
|
||||
}
|
||||
|
||||
|
||||
init(from decoder: any Decoder) throws {
|
||||
public init(from decoder: any Decoder) throws {
|
||||
|
||||
let container = try decoder.container(keyedBy: CodingKeys.self)
|
||||
|
||||
@ -51,7 +51,7 @@ extension MultipleReplace.Replacement: Codable {
|
||||
}
|
||||
|
||||
|
||||
func encode(to encoder: any Encoder) throws {
|
||||
public func encode(to encoder: any Encoder) throws {
|
||||
|
||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||
|
||||
@ -86,7 +86,7 @@ extension MultipleReplace.Settings: Codable {
|
||||
}
|
||||
|
||||
|
||||
init(from decoder: any Decoder) throws {
|
||||
public init(from decoder: any Decoder) throws {
|
||||
|
||||
let container = try decoder.container(keyedBy: CodingKeys.self)
|
||||
|
||||
@ -102,7 +102,7 @@ extension MultipleReplace.Settings: Codable {
|
||||
}
|
||||
|
||||
|
||||
func encode(to encoder: any Encoder) throws {
|
||||
public func encode(to encoder: any Encoder) throws {
|
||||
|
||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||
|
@ -25,30 +25,57 @@
|
||||
|
||||
import Foundation
|
||||
|
||||
struct MultipleReplace: Codable {
|
||||
public struct MultipleReplace: Equatable, Sendable, Codable {
|
||||
|
||||
struct Replacement: Equatable {
|
||||
public struct Replacement: Equatable, Sendable {
|
||||
|
||||
var findString: String = ""
|
||||
var replacementString: String = ""
|
||||
var usesRegularExpression: Bool = false
|
||||
var ignoresCase: Bool = false
|
||||
var description: String?
|
||||
var isEnabled = true
|
||||
public var findString: String
|
||||
public var replacementString: String
|
||||
public var usesRegularExpression: Bool
|
||||
public var ignoresCase: Bool
|
||||
public var description: String?
|
||||
public var isEnabled: Bool
|
||||
|
||||
|
||||
public init(findString: String = "", replacementString: String = "", usesRegularExpression: Bool = false, ignoresCase: Bool = false, description: String? = nil, isEnabled: Bool = true) {
|
||||
|
||||
self.findString = findString
|
||||
self.replacementString = replacementString
|
||||
self.usesRegularExpression = usesRegularExpression
|
||||
self.ignoresCase = ignoresCase
|
||||
self.description = description
|
||||
self.isEnabled = isEnabled
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
struct Settings: Equatable {
|
||||
public struct Settings: Equatable, Sendable {
|
||||
|
||||
var textualOptions: String.CompareOptions = []
|
||||
var regexOptions: NSRegularExpression.Options = [.anchorsMatchLines]
|
||||
var matchesFullWord: Bool = false
|
||||
var unescapesReplacementString: Bool = true
|
||||
public var textualOptions: String.CompareOptions
|
||||
public var regexOptions: NSRegularExpression.Options
|
||||
public var matchesFullWord: Bool
|
||||
public var unescapesReplacementString: Bool
|
||||
|
||||
|
||||
public init(textualOptions: String.CompareOptions = [], regexOptions: NSRegularExpression.Options = [.anchorsMatchLines], matchesFullWord: Bool = false, unescapesReplacementString: Bool = true) {
|
||||
|
||||
self.textualOptions = textualOptions
|
||||
self.regexOptions = regexOptions
|
||||
self.matchesFullWord = matchesFullWord
|
||||
self.unescapesReplacementString = unescapesReplacementString
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var replacements: [Replacement] = []
|
||||
var settings: Settings = .init()
|
||||
public var replacements: [Replacement]
|
||||
public var settings: Settings
|
||||
|
||||
|
||||
public init(replacements: [Replacement] = [], settings: Settings = .init()) {
|
||||
|
||||
self.replacements = replacements
|
||||
self.settings = settings
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -57,14 +84,14 @@ struct MultipleReplace: Codable {
|
||||
|
||||
extension MultipleReplace {
|
||||
|
||||
struct Result {
|
||||
public struct Result: Equatable, Sendable {
|
||||
|
||||
var string: String
|
||||
var selectedRanges: [NSRange]?
|
||||
public var string: String
|
||||
public var selectedRanges: [NSRange]?
|
||||
}
|
||||
|
||||
|
||||
enum Status {
|
||||
public enum Status: Equatable, Sendable {
|
||||
|
||||
case processed
|
||||
case unitChanged
|
||||
@ -81,7 +108,7 @@ extension MultipleReplace {
|
||||
/// - inSelection: Whether find only in selection.
|
||||
/// - progress: The progress object to observe cancellation by the user and notify the find progress.
|
||||
/// - Returns: The found ranges. This method will return first all search finished.
|
||||
func find(string: String, ranges: [NSRange], inSelection: Bool, progress: FindProgress? = nil) throws(CancellationError) -> [NSRange] {
|
||||
public func find(string: String, ranges: [NSRange], inSelection: Bool, progress: FindProgress? = nil) throws(CancellationError) -> [NSRange] {
|
||||
|
||||
var result: [NSRange] = []
|
||||
|
||||
@ -121,7 +148,7 @@ extension MultipleReplace {
|
||||
/// - inSelection: Whether replace only in selection.
|
||||
/// - progress: The progress object to observe cancellation by the user and notify the replacement progress.
|
||||
/// - Returns: The result of the replacement. This method will return first all replacement finished.
|
||||
func replace(string: String, ranges: [NSRange], inSelection: Bool, progress: FindProgress? = nil) throws(CancellationError) -> Result {
|
||||
public func replace(string: String, ranges: [NSRange], inSelection: Bool, progress: FindProgress? = nil) throws(CancellationError) -> Result {
|
||||
|
||||
var result = Result(string: string, selectedRanges: ranges)
|
||||
|
||||
@ -190,7 +217,7 @@ private extension MultipleReplace.Replacement {
|
||||
extension MultipleReplace.Replacement {
|
||||
|
||||
/// Checks if replacement rule is valid.
|
||||
func validate(regexOptions: NSRegularExpression.Options = []) throws(TextFind.Error) {
|
||||
public func validate(regexOptions: NSRegularExpression.Options = []) throws(TextFind.Error) {
|
||||
|
||||
guard !self.findString.isEmpty else {
|
||||
throw TextFind.Error.emptyFindString
|
@ -27,71 +27,35 @@ import Foundation
|
||||
import StringBasics
|
||||
import ValueRange
|
||||
|
||||
struct TextFind {
|
||||
public struct TextFind: Equatable, Sendable {
|
||||
|
||||
typealias ReplacementItem = ValueRange<String>
|
||||
public typealias ReplacementItem = ValueRange<String>
|
||||
|
||||
|
||||
enum Mode: Equatable {
|
||||
public enum Mode: Equatable, Sendable {
|
||||
|
||||
case textual(options: String.CompareOptions, fullWord: Bool) // don't include .backwards to options
|
||||
case regularExpression(options: NSRegularExpression.Options, unescapesReplacement: Bool)
|
||||
}
|
||||
|
||||
|
||||
enum `Error`: LocalizedError {
|
||||
public enum `Error`: Swift.Error, Sendable {
|
||||
|
||||
case regularExpression(reason: String)
|
||||
case emptyFindString
|
||||
case emptyInSelectionSearch
|
||||
|
||||
|
||||
var errorDescription: String? {
|
||||
|
||||
switch self {
|
||||
case .regularExpression:
|
||||
String(localized: "TextFind.Error.regularExpression.errorDescription",
|
||||
defaultValue: "Invalid regular expression",
|
||||
table: "TextFind")
|
||||
case .emptyFindString:
|
||||
String(localized: "TextFind.Error.emptyFindString.errorDescription",
|
||||
defaultValue: "Empty find string",
|
||||
table: "TextFind")
|
||||
case .emptyInSelectionSearch:
|
||||
String(localized: "TextFind.Error.emptyInSelectionSearch.errorDescription",
|
||||
defaultValue: "The option “in selection” is selected, although nothing is selected.",
|
||||
table: "TextFind")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var recoverySuggestion: String? {
|
||||
|
||||
switch self {
|
||||
case .regularExpression(let reason):
|
||||
reason
|
||||
case .emptyFindString:
|
||||
String(localized: "TextFind.Error.emptyFindString.recoverySuggestion",
|
||||
defaultValue: "Input text to find.",
|
||||
table: "TextFind")
|
||||
case .emptyInSelectionSearch:
|
||||
String(localized: "TextFind.Error.emptyInSelectionSearch.recoverySuggestion",
|
||||
defaultValue: "Select the search scope in the document or turn off the “in selection” option.",
|
||||
table: "TextFind")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// MARK: Public Properties
|
||||
|
||||
let findString: String
|
||||
let mode: TextFind.Mode
|
||||
let inSelection: Bool
|
||||
public let findString: String
|
||||
public let mode: TextFind.Mode
|
||||
public let inSelection: Bool
|
||||
|
||||
let string: String
|
||||
let selectedRanges: [NSRange]
|
||||
public let string: String
|
||||
public let selectedRanges: [NSRange]
|
||||
|
||||
|
||||
// MARK: Private Properties
|
||||
@ -112,7 +76,7 @@ struct TextFind {
|
||||
/// - mode: The settable options for the text search.
|
||||
/// - inSelection: Whether find string only in selectedRanges.
|
||||
/// - selectedRanges: The selected ranges in the text view.
|
||||
init(for string: String, findString: String, mode: TextFind.Mode, inSelection: Bool = false, selectedRanges: [NSRange] = [NSRange()]) throws(TextFind.Error) {
|
||||
public init(for string: String, findString: String, mode: TextFind.Mode, inSelection: Bool = false, selectedRanges: [NSRange] = [NSRange()]) throws(TextFind.Error) {
|
||||
|
||||
assert(!selectedRanges.isEmpty)
|
||||
|
||||
@ -151,14 +115,14 @@ struct TextFind {
|
||||
// MARK: Public Methods
|
||||
|
||||
/// The number of capture groups in the regular expression.
|
||||
var numberOfCaptureGroups: Int {
|
||||
public var numberOfCaptureGroups: Int {
|
||||
|
||||
self.regex?.numberOfCaptureGroups ?? 0
|
||||
}
|
||||
|
||||
|
||||
/// The range large enough to contain all scope ranges.
|
||||
var scopeRange: Range<Int> {
|
||||
public var scopeRange: Range<Int> {
|
||||
|
||||
self.scopeRanges.map(\.lowerBound).min()!..<self.scopeRanges.map(\.upperBound).max()!
|
||||
}
|
||||
@ -167,7 +131,7 @@ struct TextFind {
|
||||
/// All matched ranges.
|
||||
///
|
||||
/// - Throws: `CancellationError`
|
||||
var matches: [NSRange] {
|
||||
public var matches: [NSRange] {
|
||||
|
||||
get throws {
|
||||
var ranges: [NSRange] = []
|
||||
@ -193,7 +157,7 @@ struct TextFind {
|
||||
/// - includingCurrentSelection: Whether includes the current selection to search.
|
||||
/// - wraps: Whether the search wraps around.
|
||||
/// - Returns: A character range and flag whether the search wrapped; or `nil` when not found.
|
||||
func find(in matches: [NSRange], forward: Bool, includingSelection: Bool = false, wraps: Bool) -> (range: NSRange, wrapped: Bool)? {
|
||||
public func find(in matches: [NSRange], forward: Bool, includingSelection: Bool = false, wraps: Bool) -> (range: NSRange, wrapped: Bool)? {
|
||||
|
||||
assert(forward || !includingSelection)
|
||||
|
||||
@ -231,7 +195,7 @@ struct TextFind {
|
||||
/// - Parameters:
|
||||
/// - replacementString: The string with which to replace.
|
||||
/// - Returns: The struct of a string to replace with and a range to replace if found. Otherwise, nil.
|
||||
func replace(with replacementString: String) -> ReplacementItem? {
|
||||
public func replace(with replacementString: String) -> ReplacementItem? {
|
||||
|
||||
let string = self.string
|
||||
let selectedRange = self.selectedRanges.first!
|
||||
@ -262,7 +226,7 @@ struct TextFind {
|
||||
/// - block: The block enumerates the matches.
|
||||
/// - matches: The array of matches including group matches.
|
||||
/// - stop: The `block` can set the value to true to stop further processing.
|
||||
func findAll(using block: (_ matches: [NSRange], _ stop: inout Bool) -> Void) {
|
||||
public func findAll(using block: (_ matches: [NSRange], _ stop: inout Bool) -> Void) {
|
||||
|
||||
for range in self.scopeRanges {
|
||||
self.enumerateMatches(in: range) { (matchedRange, match, stop) in
|
||||
@ -288,7 +252,7 @@ struct TextFind {
|
||||
/// - Returns:
|
||||
/// - replacementItems: ReplacementItem per selectedRange.
|
||||
/// - selectedRanges: New selections for textView only if the replacement is performed within selection. Otherwise, `nil`.
|
||||
func replaceAll(with replacementString: String, using block: @escaping (_ range: NSRange, _ count: Int, _ stop: inout Bool) -> Void) -> (replacementItems: [ReplacementItem], selectedRanges: [NSRange]?) {
|
||||
public func replaceAll(with replacementString: String, using block: @escaping (_ range: NSRange, _ count: Int, _ stop: inout Bool) -> Void) -> (replacementItems: [ReplacementItem], selectedRanges: [NSRange]?) {
|
||||
|
||||
let replacementString = self.replacementString(from: replacementString)
|
||||
var replacementItems: [ReplacementItem] = []
|
@ -24,31 +24,12 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import AppKit
|
||||
import Foundation
|
||||
import Testing
|
||||
@testable import CotEditor
|
||||
@testable import TextFind
|
||||
|
||||
struct TextFindTests {
|
||||
|
||||
@Test func finderActions() {
|
||||
|
||||
#expect(TextFinder.Action.showFindInterface.rawValue == NSTextFinder.Action.showFindInterface.rawValue)
|
||||
#expect(TextFinder.Action.nextMatch.rawValue == NSTextFinder.Action.nextMatch.rawValue)
|
||||
#expect(TextFinder.Action.previousMatch.rawValue == NSTextFinder.Action.previousMatch.rawValue)
|
||||
#expect(TextFinder.Action.replaceAll.rawValue == NSTextFinder.Action.replaceAll.rawValue)
|
||||
#expect(TextFinder.Action.replace.rawValue == NSTextFinder.Action.replace.rawValue)
|
||||
#expect(TextFinder.Action.replaceAndFind.rawValue == NSTextFinder.Action.replaceAndFind.rawValue)
|
||||
#expect(TextFinder.Action.setSearchString.rawValue == NSTextFinder.Action.setSearchString.rawValue)
|
||||
#expect(TextFinder.Action.replaceAllInSelection.rawValue == NSTextFinder.Action.replaceAllInSelection.rawValue)
|
||||
#expect(TextFinder.Action.selectAll.rawValue == NSTextFinder.Action.selectAll.rawValue)
|
||||
#expect(TextFinder.Action.selectAllInSelection.rawValue == NSTextFinder.Action.selectAllInSelection.rawValue)
|
||||
#expect(TextFinder.Action.hideFindInterface.rawValue == NSTextFinder.Action.hideFindInterface.rawValue)
|
||||
#expect(TextFinder.Action.showReplaceInterface.rawValue == NSTextFinder.Action.showReplaceInterface.rawValue)
|
||||
#expect(TextFinder.Action.showReplaceInterface.rawValue == NSTextFinder.Action.showReplaceInterface.rawValue)
|
||||
#expect(TextFinder.Action.hideReplaceInterface.rawValue == NSTextFinder.Action.hideReplaceInterface.rawValue)
|
||||
}
|
||||
|
||||
|
||||
@Test func countCaptureGroup() throws {
|
||||
|
||||
var mode: TextFind.Mode
|
50
Tests/TextFinderTests.swift
Normal file
50
Tests/TextFinderTests.swift
Normal file
@ -0,0 +1,50 @@
|
||||
//
|
||||
// TextFinderTests.swift
|
||||
// Tests
|
||||
//
|
||||
// CotEditor
|
||||
// https://coteditor.com
|
||||
//
|
||||
// Created by 1024jp on 2017-02-03.
|
||||
//
|
||||
// ---------------------------------------------------------------------------
|
||||
//
|
||||
// © 2017-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
|
||||
import Testing
|
||||
@testable import CotEditor
|
||||
|
||||
struct TextFinderTests {
|
||||
|
||||
@Test func finderActions() {
|
||||
|
||||
#expect(TextFinder.Action.showFindInterface.rawValue == NSTextFinder.Action.showFindInterface.rawValue)
|
||||
#expect(TextFinder.Action.nextMatch.rawValue == NSTextFinder.Action.nextMatch.rawValue)
|
||||
#expect(TextFinder.Action.previousMatch.rawValue == NSTextFinder.Action.previousMatch.rawValue)
|
||||
#expect(TextFinder.Action.replaceAll.rawValue == NSTextFinder.Action.replaceAll.rawValue)
|
||||
#expect(TextFinder.Action.replace.rawValue == NSTextFinder.Action.replace.rawValue)
|
||||
#expect(TextFinder.Action.replaceAndFind.rawValue == NSTextFinder.Action.replaceAndFind.rawValue)
|
||||
#expect(TextFinder.Action.setSearchString.rawValue == NSTextFinder.Action.setSearchString.rawValue)
|
||||
#expect(TextFinder.Action.replaceAllInSelection.rawValue == NSTextFinder.Action.replaceAllInSelection.rawValue)
|
||||
#expect(TextFinder.Action.selectAll.rawValue == NSTextFinder.Action.selectAll.rawValue)
|
||||
#expect(TextFinder.Action.selectAllInSelection.rawValue == NSTextFinder.Action.selectAllInSelection.rawValue)
|
||||
#expect(TextFinder.Action.hideFindInterface.rawValue == NSTextFinder.Action.hideFindInterface.rawValue)
|
||||
#expect(TextFinder.Action.showReplaceInterface.rawValue == NSTextFinder.Action.showReplaceInterface.rawValue)
|
||||
#expect(TextFinder.Action.showReplaceInterface.rawValue == NSTextFinder.Action.showReplaceInterface.rawValue)
|
||||
#expect(TextFinder.Action.hideReplaceInterface.rawValue == NSTextFinder.Action.hideReplaceInterface.rawValue)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user