mirror of
https://github.com/coteditor/CotEditor.git
synced 2024-10-05 15:08:16 +03:00
Extract LineEnding to package
This commit is contained in:
parent
356186cf0f
commit
565d043074
@ -266,7 +266,6 @@
|
||||
2A50AA63204D513500D10A10 /* FileAttributes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A50AA61204D513500D10A10 /* FileAttributes.swift */; };
|
||||
2A53F56727585A0E00ED16DF /* RegularExpressionReferenceView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A53F56627585A0E00ED16DF /* RegularExpressionReferenceView.swift */; };
|
||||
2A53F56827585A0E00ED16DF /* RegularExpressionReferenceView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A53F56627585A0E00ED16DF /* RegularExpressionReferenceView.swift */; };
|
||||
2A54BE2C1D40EB24000816B0 /* LineEndingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A54BE2B1D40EB24000816B0 /* LineEndingTests.swift */; };
|
||||
2A55D5D82B7A728A0092DE48 /* AdvancedCharacterCount.xcstrings in Resources */ = {isa = PBXBuildFile; fileRef = 2A55D5D72B7A728A0092DE48 /* AdvancedCharacterCount.xcstrings */; };
|
||||
2A55D5D92B7A728A0092DE48 /* AdvancedCharacterCount.xcstrings in Resources */ = {isa = PBXBuildFile; fileRef = 2A55D5D72B7A728A0092DE48 /* AdvancedCharacterCount.xcstrings */; };
|
||||
2A55D5EA2B7A86190092DE48 /* IssueReport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A55D5E92B7A86190092DE48 /* IssueReport.swift */; };
|
||||
@ -482,8 +481,8 @@
|
||||
2AA175FB2AC5634500F6462C /* PopoverHolderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AA175F92AC5634500F6462C /* PopoverHolderView.swift */; };
|
||||
2AA2C6FC24399A920017D1EC /* Yams in Frameworks */ = {isa = PBXBuildFile; productRef = 2AA2C6FB24399A920017D1EC /* Yams */; };
|
||||
2AA2C6FE24399AA20017D1EC /* Yams in Frameworks */ = {isa = PBXBuildFile; productRef = 2AA2C6FD24399AA20017D1EC /* Yams */; };
|
||||
2AA375471D40BDCB0080C27C /* LineEnding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AA375461D40BDCB0080C27C /* LineEnding.swift */; };
|
||||
2AA375481D40BDCB0080C27C /* LineEnding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AA375461D40BDCB0080C27C /* LineEnding.swift */; };
|
||||
2AA375471D40BDCB0080C27C /* LineEnding+Localization.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AA375461D40BDCB0080C27C /* LineEnding+Localization.swift */; };
|
||||
2AA375481D40BDCB0080C27C /* LineEnding+Localization.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AA375461D40BDCB0080C27C /* LineEnding+Localization.swift */; };
|
||||
2AA45A4B1D2E871900A1A401 /* EditorViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AA45A4A1D2E871900A1A401 /* EditorViewController.swift */; };
|
||||
2AA45A4C1D2E871900A1A401 /* EditorViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AA45A4A1D2E871900A1A401 /* EditorViewController.swift */; };
|
||||
2AA45A511D2E938500A1A401 /* NavigationBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AA45A501D2E938500A1A401 /* NavigationBar.swift */; };
|
||||
@ -938,7 +937,6 @@
|
||||
2A4E637F20ADC45F0033CE63 /* NSBezierPath.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSBezierPath.swift; sourceTree = "<group>"; };
|
||||
2A50AA61204D513500D10A10 /* FileAttributes.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileAttributes.swift; sourceTree = "<group>"; };
|
||||
2A53F56627585A0E00ED16DF /* RegularExpressionReferenceView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RegularExpressionReferenceView.swift; sourceTree = "<group>"; };
|
||||
2A54BE2B1D40EB24000816B0 /* LineEndingTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LineEndingTests.swift; sourceTree = "<group>"; };
|
||||
2A55D5D72B7A728A0092DE48 /* AdvancedCharacterCount.xcstrings */ = {isa = PBXFileReference; lastKnownFileType = text.json.xcstrings; path = AdvancedCharacterCount.xcstrings; sourceTree = "<group>"; };
|
||||
2A55D5E92B7A86190092DE48 /* IssueReport.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IssueReport.swift; sourceTree = "<group>"; };
|
||||
2A57B98E294ED75900771696 /* RangedIntegerFormatStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RangedIntegerFormatStyle.swift; sourceTree = "<group>"; };
|
||||
@ -1013,8 +1011,8 @@
|
||||
2A78BFB21D1B240900A583D2 /* UpdaterManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UpdaterManager.swift; sourceTree = "<group>"; };
|
||||
2A78BFBB1D1B376000A583D2 /* ServicesProvider.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ServicesProvider.swift; sourceTree = "<group>"; };
|
||||
2A7C92FB29FD64A8008343C8 /* DefaultKey+FontType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "DefaultKey+FontType.swift"; sourceTree = "<group>"; };
|
||||
2A7E06E52C1A711B00E5396D /* EditorKit */ = {isa = PBXFileReference; lastKnownFileType = wrapper; path = EditorKit; sourceTree = "<group>"; };
|
||||
2A7DFA492BE96C06001D5BDD /* DirectoryDocument+Actions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "DirectoryDocument+Actions.swift"; sourceTree = "<group>"; };
|
||||
2A7E06E52C1A711B00E5396D /* EditorKit */ = {isa = PBXFileReference; lastKnownFileType = wrapper; path = EditorKit; sourceTree = "<group>"; };
|
||||
2A7F4E012871F46D0029CE66 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/PrintPanelAccessory.storyboard; sourceTree = "<group>"; };
|
||||
2A7FEF0A2B90B05C0042BEFF /* FilterField.xcstrings */ = {isa = PBXFileReference; lastKnownFileType = text.json.xcstrings; path = FilterField.xcstrings; sourceTree = "<group>"; };
|
||||
2A80BE8C27FFA61700D2F7FF /* LineEndingScanner.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LineEndingScanner.swift; sourceTree = "<group>"; };
|
||||
@ -1057,7 +1055,7 @@
|
||||
2AA14CFE1FA498E900EAF586 /* UnixScript.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UnixScript.swift; sourceTree = "<group>"; };
|
||||
2AA14D011FA4999200EAF586 /* PersistentOSAScript.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PersistentOSAScript.swift; sourceTree = "<group>"; };
|
||||
2AA175F92AC5634500F6462C /* PopoverHolderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PopoverHolderView.swift; sourceTree = "<group>"; };
|
||||
2AA375461D40BDCB0080C27C /* LineEnding.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LineEnding.swift; sourceTree = "<group>"; };
|
||||
2AA375461D40BDCB0080C27C /* LineEnding+Localization.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "LineEnding+Localization.swift"; sourceTree = "<group>"; };
|
||||
2AA45A4A1D2E871900A1A401 /* EditorViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EditorViewController.swift; sourceTree = "<group>"; };
|
||||
2AA45A501D2E938500A1A401 /* NavigationBar.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NavigationBar.swift; sourceTree = "<group>"; };
|
||||
2AA45A531D2F22C600A1A401 /* NSFont+Size.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSFont+Size.swift"; sourceTree = "<group>"; };
|
||||
@ -1766,7 +1764,6 @@
|
||||
2A505C07298952E5002080AA /* KeyBinding */,
|
||||
2A78F571298C90520084B8B4 /* Snippet */,
|
||||
2AC6BFCF21D00A8500FF325C /* Regex Parser */,
|
||||
2AA375461D40BDCB0080C27C /* LineEnding.swift */,
|
||||
2A8C338E1D3E1C040005B0B7 /* IncompatibleCharacter.swift */,
|
||||
2A4257BB1D239F850086DAAD /* Invisible.swift */,
|
||||
2A50AA61204D513500D10A10 /* FileAttributes.swift */,
|
||||
@ -2000,6 +1997,7 @@
|
||||
children = (
|
||||
2A428D432C2B03670051AD4F /* ValueRange+Identifiable.swift */,
|
||||
2AA7BDDA2C1B10C80075BB6C /* UnicodeNormalizationForm.swift */,
|
||||
2AA375461D40BDCB0080C27C /* LineEnding+Localization.swift */,
|
||||
2A1893A91FFF422D00AD244F /* SortPatternError+Localization.swift */,
|
||||
);
|
||||
name = Libraries;
|
||||
@ -2111,7 +2109,6 @@
|
||||
2A63CEC31D0B06D800ED8186 /* SyntaxTests.swift */,
|
||||
2ACC65311C98033D000574DC /* ThemeTests.swift */,
|
||||
2A9C07551CF9F982006D672D /* IncompatibleCharacterTests.swift */,
|
||||
2A54BE2B1D40EB24000816B0 /* LineEndingTests.swift */,
|
||||
2AED46721E43942300751C45 /* TextFinderTests.swift */,
|
||||
2AC72EA1253478D5001D3CA0 /* FileDropItemTests.swift */,
|
||||
2ABEFB6923DC0CA0008769F4 /* EditorCounterTests.swift */,
|
||||
@ -2781,7 +2778,7 @@
|
||||
2A64F2431D256FCB001B229F /* KeyBindingManager.swift in Sources */,
|
||||
2AA4D3751D1AA0AC001D261D /* KeyBindingsSettingsView.swift in Sources */,
|
||||
2A6FD9E81D394F5900A59784 /* LayoutManager.swift in Sources */,
|
||||
2AA375481D40BDCB0080C27C /* LineEnding.swift in Sources */,
|
||||
2AA375481D40BDCB0080C27C /* LineEnding+Localization.swift in Sources */,
|
||||
2A80BE8D27FFA61700D2F7FF /* LineEndingScanner.swift in Sources */,
|
||||
2A6416A41D2F9F7200FA9E1A /* LineNumberView.swift in Sources */,
|
||||
2A1125C423F1A86B006A1DB2 /* LineRangeCacheable.swift in Sources */,
|
||||
@ -2961,7 +2958,6 @@
|
||||
2A9082EF1D325ED900228F50 /* GeometryTests.swift in Sources */,
|
||||
2A9C07561CF9F982006D672D /* IncompatibleCharacterTests.swift in Sources */,
|
||||
2A80BE9227FFFA8900D2F7FF /* LineEndingScannerTests.swift in Sources */,
|
||||
2A54BE2C1D40EB24000816B0 /* LineEndingTests.swift in Sources */,
|
||||
2A1125C123F180FF006A1DB2 /* LineRangeCacheableTests.swift in Sources */,
|
||||
2AEBD25A246BB4C200EC97A3 /* NSAttributedStringTests.swift in Sources */,
|
||||
2A89160C2394B87100AC13EE /* NSLayoutManagerTests.swift in Sources */,
|
||||
@ -3102,7 +3098,7 @@
|
||||
2A64F2421D256FCB001B229F /* KeyBindingManager.swift in Sources */,
|
||||
2AA4D3741D1AA0AC001D261D /* KeyBindingsSettingsView.swift in Sources */,
|
||||
2A6FD9E71D394F5900A59784 /* LayoutManager.swift in Sources */,
|
||||
2AA375471D40BDCB0080C27C /* LineEnding.swift in Sources */,
|
||||
2AA375471D40BDCB0080C27C /* LineEnding+Localization.swift in Sources */,
|
||||
2A80BE8E27FFA61700D2F7FF /* LineEndingScanner.swift in Sources */,
|
||||
2A6416A31D2F9F7200FA9E1A /* LineNumberView.swift in Sources */,
|
||||
2A1125C323F1A86B006A1DB2 /* LineRangeCacheable.swift in Sources */,
|
||||
|
@ -31,6 +31,7 @@ import UniformTypeIdentifiers
|
||||
import OSLog
|
||||
import Defaults
|
||||
import FileEncoding
|
||||
import LineEnding
|
||||
import UnicodeNormalization
|
||||
|
||||
extension KeyPath: @retroactive @unchecked Sendable { }
|
||||
|
@ -27,6 +27,7 @@
|
||||
import AppKit
|
||||
import FileEncoding
|
||||
import FuzzyRange
|
||||
import LineEnding
|
||||
|
||||
private enum OSALineEnding: FourCharCode {
|
||||
|
||||
|
@ -33,6 +33,7 @@ import OSLog
|
||||
import Defaults
|
||||
import FileEncoding
|
||||
import FilePermissions
|
||||
import LineEnding
|
||||
import Syntax
|
||||
|
||||
extension Document: EditorSource {
|
||||
|
@ -28,6 +28,7 @@ import Observation
|
||||
import Combine
|
||||
import FileEncoding
|
||||
import FilePermissions
|
||||
import LineEnding
|
||||
import Syntax
|
||||
|
||||
final class DocumentInspectorViewController: NSHostingController<DocumentInspectorView>, DocumentOwner {
|
||||
|
@ -8,7 +8,7 @@
|
||||
//
|
||||
// ---------------------------------------------------------------------------
|
||||
//
|
||||
// © 2019-2023 1024jp
|
||||
// © 2019-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 AppKit
|
||||
import LineEnding
|
||||
|
||||
extension EditorTextView {
|
||||
|
||||
|
@ -27,6 +27,7 @@
|
||||
import AppKit
|
||||
import Combine
|
||||
import Defaults
|
||||
import LineEnding
|
||||
import Shortcut
|
||||
import Syntax
|
||||
import StringBasics
|
||||
|
@ -26,6 +26,7 @@
|
||||
import SwiftUI
|
||||
import Defaults
|
||||
import FileEncoding
|
||||
import LineEnding
|
||||
|
||||
struct FormatSettingsView: View {
|
||||
|
||||
|
@ -25,6 +25,7 @@
|
||||
|
||||
import SwiftUI
|
||||
import Observation
|
||||
import LineEnding
|
||||
import ValueRange
|
||||
|
||||
struct InconsistentLineEndingsView: View {
|
||||
|
61
CotEditor/Sources/LineEnding+Localization.swift
Normal file
61
CotEditor/Sources/LineEnding+Localization.swift
Normal file
@ -0,0 +1,61 @@
|
||||
//
|
||||
// LineEnding+Localization.swift
|
||||
//
|
||||
// CotEditor
|
||||
// https://coteditor.com
|
||||
//
|
||||
// Created by 1024jp on 2014-11-30.
|
||||
//
|
||||
// ---------------------------------------------------------------------------
|
||||
//
|
||||
// © 2014-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 LineEnding
|
||||
|
||||
extension LineEnding {
|
||||
|
||||
var description: String {
|
||||
|
||||
switch self {
|
||||
case .lf:
|
||||
String(localized: "LineEnding.lf.description",
|
||||
defaultValue: "macOS / Unix",
|
||||
table: "LineEnding")
|
||||
case .cr:
|
||||
String(localized: "LineEnding.cr.description",
|
||||
defaultValue: "Classic Mac OS",
|
||||
table: "LineEnding")
|
||||
case .crlf:
|
||||
String(localized: "LineEnding.crlf.description",
|
||||
defaultValue: "Windows", table: "LineEnding")
|
||||
case .nel:
|
||||
String(localized: "LineEnding.nel.description",
|
||||
defaultValue: "Unix Next Line",
|
||||
table: "LineEnding",
|
||||
comment: "Since this is a technical term, it should be left as-is.")
|
||||
case .lineSeparator:
|
||||
String(localized: "LineEnding.lineSeparator.description",
|
||||
defaultValue: "Unix Line Separator",
|
||||
table: "LineEnding",
|
||||
comment: "Since this is a technical term, it should be left as-is.")
|
||||
case .paragraphSeparator:
|
||||
String(localized: "LineEnding.paragraphSeparator.description",
|
||||
defaultValue: "Unix Paragraph Separator",
|
||||
table: "LineEnding",
|
||||
comment: "Since this is a technical term, it should be left as-is.")
|
||||
}
|
||||
}
|
||||
}
|
@ -26,7 +26,8 @@
|
||||
import Combine
|
||||
import Foundation
|
||||
import Observation
|
||||
import class AppKit.NSTextStorage
|
||||
import AppKit.NSTextStorage
|
||||
import LineEnding
|
||||
import ValueRange
|
||||
|
||||
@Observable final class LineEndingScanner {
|
||||
|
@ -28,6 +28,7 @@ import Observation
|
||||
import Combine
|
||||
import Defaults
|
||||
import FileEncoding
|
||||
import LineEnding
|
||||
|
||||
final class StatusBarController: NSHostingController<StatusBar> {
|
||||
|
||||
|
@ -25,6 +25,7 @@
|
||||
|
||||
import AppKit
|
||||
import SwiftUI
|
||||
import LineEnding
|
||||
import TextFind
|
||||
import ValueRange
|
||||
|
||||
|
@ -16,6 +16,7 @@ let package = Package(
|
||||
"FileEncoding",
|
||||
"FilePermissions",
|
||||
"FuzzyRange",
|
||||
"LineEnding",
|
||||
"LineSort",
|
||||
"Shortcut",
|
||||
"StringBasics",
|
||||
@ -33,6 +34,7 @@ let package = Package(
|
||||
.library(name: "FileEncoding", targets: ["FileEncoding"]),
|
||||
.library(name: "FilePermissions", targets: ["FilePermissions"]),
|
||||
.library(name: "FuzzyRange", targets: ["FuzzyRange"]),
|
||||
.library(name: "LineEnding", targets: ["LineEnding"]),
|
||||
.library(name: "LineSort", targets: ["LineSort"]),
|
||||
.library(name: "StringBasics", targets: ["StringBasics"]),
|
||||
.library(name: "Syntax", targets: ["Syntax"]),
|
||||
@ -62,6 +64,9 @@ let package = Package(
|
||||
.target(name: "FuzzyRange"),
|
||||
.testTarget(name: "FuzzyRangeTests", dependencies: ["FuzzyRange"]),
|
||||
|
||||
.target(name: "LineEnding", dependencies: ["ValueRange"]),
|
||||
.testTarget(name: "LineEndingTests", dependencies: ["LineEnding"]),
|
||||
|
||||
.target(name: "LineSort", dependencies: ["StringBasics"]),
|
||||
.testTarget(name: "LineSortTests", dependencies: ["LineSort"]),
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
//
|
||||
// LineEnding.swift
|
||||
// LineEnding
|
||||
//
|
||||
// CotEditor
|
||||
// https://coteditor.com
|
||||
@ -26,7 +27,7 @@
|
||||
import Foundation
|
||||
import ValueRange
|
||||
|
||||
enum LineEnding: Character, CaseIterable {
|
||||
public enum LineEnding: Character, Sendable, CaseIterable {
|
||||
|
||||
case lf = "\n"
|
||||
case cr = "\r"
|
||||
@ -36,25 +37,25 @@ enum LineEnding: Character, CaseIterable {
|
||||
case paragraphSeparator = "\u{2029}"
|
||||
|
||||
|
||||
var string: String {
|
||||
public var string: String {
|
||||
|
||||
String(self.rawValue)
|
||||
}
|
||||
|
||||
|
||||
var length: Int {
|
||||
public var length: Int {
|
||||
|
||||
self.rawValue.unicodeScalars.count
|
||||
}
|
||||
|
||||
|
||||
var index: Int {
|
||||
public var index: Int {
|
||||
|
||||
Self.allCases.firstIndex(of: self)!
|
||||
}
|
||||
|
||||
|
||||
var isBasic: Bool {
|
||||
public var isBasic: Bool {
|
||||
|
||||
switch self {
|
||||
case .lf, .cr, .crlf: true
|
||||
@ -63,7 +64,7 @@ enum LineEnding: Character, CaseIterable {
|
||||
}
|
||||
|
||||
|
||||
var label: String {
|
||||
public var label: String {
|
||||
|
||||
switch self {
|
||||
case .lf: "LF"
|
||||
@ -74,46 +75,13 @@ enum LineEnding: Character, CaseIterable {
|
||||
case .paragraphSeparator: "PS"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var description: String {
|
||||
|
||||
switch self {
|
||||
case .lf:
|
||||
String(localized: "LineEnding.lf.description",
|
||||
defaultValue: "macOS / Unix",
|
||||
table: "LineEnding")
|
||||
case .cr:
|
||||
String(localized: "LineEnding.cr.description",
|
||||
defaultValue: "Classic Mac OS",
|
||||
table: "LineEnding")
|
||||
case .crlf:
|
||||
String(localized: "LineEnding.crlf.description",
|
||||
defaultValue: "Windows", table: "LineEnding")
|
||||
case .nel:
|
||||
String(localized: "LineEnding.nel.description",
|
||||
defaultValue: "Unix Next Line",
|
||||
table: "LineEnding",
|
||||
comment: "Since this is a technical term, it should be left as-is.")
|
||||
case .lineSeparator:
|
||||
String(localized: "LineEnding.lineSeparator.description",
|
||||
defaultValue: "Unix Line Separator",
|
||||
table: "LineEnding",
|
||||
comment: "Since this is a technical term, it should be left as-is.")
|
||||
case .paragraphSeparator:
|
||||
String(localized: "LineEnding.paragraphSeparator.description",
|
||||
defaultValue: "Unix Paragraph Separator",
|
||||
table: "LineEnding",
|
||||
comment: "Since this is a technical term, it should be left as-is.")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// MARK: -
|
||||
|
||||
extension String {
|
||||
public extension String {
|
||||
|
||||
/// Collects ranges of all line endings per line ending type from the beginning.
|
||||
///
|
||||
@ -126,14 +94,15 @@ extension String {
|
||||
|
||||
var lineEndingRanges: [ValueRange<LineEnding>] = []
|
||||
let string = self as NSString
|
||||
let range = range ?? NSRange(..<self.utf16.count)
|
||||
|
||||
string.enumerateSubstrings(in: range ?? string.range, options: [.byLines, .substringNotRequired]) { (_, substringRange, enclosingRange, _) in
|
||||
guard !enclosingRange.isEmpty else { return }
|
||||
string.enumerateSubstrings(in: range, options: [.byLines, .substringNotRequired]) { (_, substringRange, enclosingRange, _) in
|
||||
guard enclosingRange.length > 0 else { return }
|
||||
|
||||
let lineEndingRange = NSRange(substringRange.upperBound..<enclosingRange.upperBound)
|
||||
|
||||
guard
|
||||
!lineEndingRange.isEmpty,
|
||||
lineEndingRange.length > 0,
|
||||
let lastCharacter = string.substring(with: lineEndingRange).first, // line ending must be a single character
|
||||
let lineEnding = LineEnding(rawValue: lastCharacter)
|
||||
else { return }
|
||||
@ -146,7 +115,7 @@ extension String {
|
||||
}
|
||||
|
||||
|
||||
extension StringProtocol {
|
||||
public extension StringProtocol {
|
||||
|
||||
/// Returns a new string in which all line endings in the receiver are replaced with the given line endings.
|
||||
///
|
||||
@ -160,7 +129,7 @@ extension StringProtocol {
|
||||
}
|
||||
|
||||
|
||||
extension NSMutableAttributedString {
|
||||
public extension NSMutableAttributedString {
|
||||
|
||||
/// Replaces all line endings in the receiver with given line endings.
|
||||
///
|
||||
@ -171,7 +140,7 @@ extension NSMutableAttributedString {
|
||||
// -> Intentionally avoid replacing characters in the mutableString directly,
|
||||
// because it pots a quantity of small edited notifications,
|
||||
// which costs high. (2023-11, macOS 14)
|
||||
self.replaceCharacters(in: self.range, with: self.string.replacingLineEndings(with: lineEnding))
|
||||
self.replaceCharacters(in: NSRange(..<self.length), with: self.string.replacingLineEndings(with: lineEnding))
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// LineEndingTests.swift
|
||||
// Tests
|
||||
// LineEndingTests
|
||||
//
|
||||
// CotEditor
|
||||
// https://coteditor.com
|
||||
@ -27,7 +27,7 @@
|
||||
import Foundation
|
||||
import Testing
|
||||
import ValueRange
|
||||
@testable import CotEditor
|
||||
@testable import LineEnding
|
||||
|
||||
struct LineEndingTests {
|
||||
|
||||
@ -75,7 +75,6 @@ struct LineEndingTests {
|
||||
}
|
||||
|
||||
|
||||
|
||||
private extension ValueRange where Value == LineEnding {
|
||||
|
||||
init(value: LineEnding, location: Int) {
|
Loading…
Reference in New Issue
Block a user