mirror of
https://github.com/coteditor/CotEditor.git
synced 2024-10-05 23:17:11 +03:00
Move Invisible to EditorCore
This commit is contained in:
parent
68800ef801
commit
a4c7261669
@ -235,8 +235,8 @@
|
||||
2A4257B71D23153B0086DAAD /* UnicodeInputView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A4257B51D23153B0086DAAD /* UnicodeInputView.swift */; };
|
||||
2A4257B91D2392A40086DAAD /* EditorTextView+ColorCode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A4257B81D2392A40086DAAD /* EditorTextView+ColorCode.swift */; };
|
||||
2A4257BA1D2392A40086DAAD /* EditorTextView+ColorCode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A4257B81D2392A40086DAAD /* EditorTextView+ColorCode.swift */; };
|
||||
2A4257BC1D239F850086DAAD /* Invisible.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A4257BB1D239F850086DAAD /* Invisible.swift */; };
|
||||
2A4257BD1D239F850086DAAD /* Invisible.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A4257BB1D239F850086DAAD /* Invisible.swift */; };
|
||||
2A4257BC1D239F850086DAAD /* Invisible+UserDefaults.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A4257BB1D239F850086DAAD /* Invisible+UserDefaults.swift */; };
|
||||
2A4257BD1D239F850086DAAD /* Invisible+UserDefaults.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A4257BB1D239F850086DAAD /* Invisible+UserDefaults.swift */; };
|
||||
2A42823A2638DAEB00D03C5C /* CharacterInspectorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A4282392638DAEB00D03C5C /* CharacterInspectorView.swift */; };
|
||||
2A42823B2638DAEB00D03C5C /* CharacterInspectorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A4282392638DAEB00D03C5C /* CharacterInspectorView.swift */; };
|
||||
2A428D442C2B03710051AD4F /* ValueRange+Identifiable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A428D432C2B03670051AD4F /* ValueRange+Identifiable.swift */; };
|
||||
@ -930,7 +930,7 @@
|
||||
2A4257AF1D22FD490086DAAD /* ColorCodePanelController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ColorCodePanelController.swift; sourceTree = "<group>"; };
|
||||
2A4257B51D23153B0086DAAD /* UnicodeInputView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UnicodeInputView.swift; sourceTree = "<group>"; };
|
||||
2A4257B81D2392A40086DAAD /* EditorTextView+ColorCode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "EditorTextView+ColorCode.swift"; sourceTree = "<group>"; };
|
||||
2A4257BB1D239F850086DAAD /* Invisible.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Invisible.swift; sourceTree = "<group>"; };
|
||||
2A4257BB1D239F850086DAAD /* Invisible+UserDefaults.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Invisible+UserDefaults.swift"; sourceTree = "<group>"; };
|
||||
2A4282392638DAEB00D03C5C /* CharacterInspectorView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CharacterInspectorView.swift; sourceTree = "<group>"; };
|
||||
2A428D432C2B03670051AD4F /* ValueRange+Identifiable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ValueRange+Identifiable.swift"; sourceTree = "<group>"; };
|
||||
2A44321B219AC1F8008A0A6B /* SettingsTabViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsTabViewController.swift; sourceTree = "<group>"; };
|
||||
@ -1790,7 +1790,6 @@
|
||||
2A78F571298C90520084B8B4 /* Snippet */,
|
||||
2AC6BFCF21D00A8500FF325C /* Regex Parser */,
|
||||
2A8C338E1D3E1C040005B0B7 /* IncompatibleCharacter.swift */,
|
||||
2A4257BB1D239F850086DAAD /* Invisible.swift */,
|
||||
2A50AA61204D513500D10A10 /* FileAttributes.swift */,
|
||||
2AF073E21D33C3AB00770BA6 /* Theme.swift */,
|
||||
2ACF23AD26302A4C002B5E10 /* Theme+Syntax.swift */,
|
||||
@ -2025,6 +2024,7 @@
|
||||
2AA7BDDA2C1B10C80075BB6C /* UnicodeNormalizationForm.swift */,
|
||||
2AA375461D40BDCB0080C27C /* LineEnding+Localization.swift */,
|
||||
2A1893A91FFF422D00AD244F /* SortPatternError+Localization.swift */,
|
||||
2A4257BB1D239F850086DAAD /* Invisible+UserDefaults.swift */,
|
||||
);
|
||||
name = Libraries;
|
||||
sourceTree = "<group>";
|
||||
@ -2819,7 +2819,7 @@
|
||||
2ACDC0A41D173250009B72D6 /* InspectorTabSegmentedControl.swift in Sources */,
|
||||
2ACDC0A71D17350A009B72D6 /* InspectorTabView.swift in Sources */,
|
||||
2AAB4C001D2444930049A68B /* InspectorViewController.swift in Sources */,
|
||||
2A4257BD1D239F850086DAAD /* Invisible.swift in Sources */,
|
||||
2A4257BD1D239F850086DAAD /* Invisible+UserDefaults.swift in Sources */,
|
||||
2A55D5EA2B7A86190092DE48 /* IssueReport.swift in Sources */,
|
||||
2A10C5F81FD19237002AB5AE /* KeyBinding.swift in Sources */,
|
||||
2A64F24C1D26615A001B229F /* KeyBindingItem.swift in Sources */,
|
||||
@ -3140,7 +3140,7 @@
|
||||
2ACDC0A31D173250009B72D6 /* InspectorTabSegmentedControl.swift in Sources */,
|
||||
2ACDC0A61D17350A009B72D6 /* InspectorTabView.swift in Sources */,
|
||||
2AAB4BFF1D2444930049A68B /* InspectorViewController.swift in Sources */,
|
||||
2A4257BC1D239F850086DAAD /* Invisible.swift in Sources */,
|
||||
2A4257BC1D239F850086DAAD /* Invisible+UserDefaults.swift in Sources */,
|
||||
2A55D5EB2B7A86190092DE48 /* IssueReport.swift in Sources */,
|
||||
2A10C5F71FD19237002AB5AE /* KeyBinding.swift in Sources */,
|
||||
2A64F24B1D26615A001B229F /* KeyBindingItem.swift in Sources */,
|
||||
|
@ -26,6 +26,7 @@
|
||||
import AppKit
|
||||
import Combine
|
||||
import Defaults
|
||||
import Invisible
|
||||
|
||||
final class FindPanelLayoutManager: NSLayoutManager, NSLayoutManagerDelegate, InvisibleDrawing {
|
||||
|
||||
|
56
CotEditor/Sources/Invisible+UserDefaults.swift
Normal file
56
CotEditor/Sources/Invisible+UserDefaults.swift
Normal file
@ -0,0 +1,56 @@
|
||||
//
|
||||
// Invisible+UserDefaults.swift
|
||||
//
|
||||
// CotEditor
|
||||
// https://coteditor.com
|
||||
//
|
||||
// Created by 1024jp on 2016-01-03.
|
||||
//
|
||||
// ---------------------------------------------------------------------------
|
||||
//
|
||||
// © 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 class Foundation.UserDefaults
|
||||
import Defaults
|
||||
import Invisible
|
||||
|
||||
extension Invisible {
|
||||
|
||||
var visibilityDefaultKey: DefaultKey<Bool> {
|
||||
|
||||
switch self {
|
||||
case .newLine: .showInvisibleNewLine
|
||||
case .tab: .showInvisibleTab
|
||||
case .space: .showInvisibleSpace
|
||||
case .noBreakSpace: .showInvisibleWhitespaces
|
||||
case .fullwidthSpace: .showInvisibleWhitespaces
|
||||
case .otherWhitespace: .showInvisibleWhitespaces
|
||||
case .otherControl: .showInvisibleControl
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
extension UserDefaults {
|
||||
|
||||
var showsInvisible: Set<Invisible> {
|
||||
|
||||
let invisibles = Invisible.allCases
|
||||
.filter { self[$0.visibilityDefaultKey] }
|
||||
|
||||
return Set(invisibles)
|
||||
}
|
||||
}
|
@ -27,6 +27,7 @@
|
||||
import AppKit
|
||||
import Combine
|
||||
import Defaults
|
||||
import Invisible
|
||||
|
||||
class LayoutManager: NSLayoutManager, InvisibleDrawing, ValidationIgnorable, LineRangeCacheable {
|
||||
|
||||
|
@ -26,6 +26,7 @@
|
||||
import AppKit
|
||||
import Combine
|
||||
import Defaults
|
||||
import Invisible
|
||||
|
||||
protocol InvisibleDrawing: NSLayoutManager {
|
||||
|
||||
|
@ -25,6 +25,7 @@
|
||||
|
||||
import Foundation
|
||||
import AppKit.NSColor
|
||||
import Invisible
|
||||
|
||||
final class RegularExpressionFormatter: Formatter {
|
||||
|
||||
|
@ -16,6 +16,7 @@ let package = Package(
|
||||
"FileEncoding",
|
||||
"FilePermissions",
|
||||
"FuzzyRange",
|
||||
"Invisible",
|
||||
"LineEnding",
|
||||
"LineSort",
|
||||
"StringBasics",
|
||||
@ -32,6 +33,7 @@ let package = Package(
|
||||
.library(name: "FileEncoding", targets: ["FileEncoding"]),
|
||||
.library(name: "FilePermissions", targets: ["FilePermissions"]),
|
||||
.library(name: "FuzzyRange", targets: ["FuzzyRange"]),
|
||||
.library(name: "Invisible", targets: ["Invisible"]),
|
||||
.library(name: "LineEnding", targets: ["LineEnding"]),
|
||||
.library(name: "LineSort", targets: ["LineSort"]),
|
||||
.library(name: "StringBasics", targets: ["StringBasics"]),
|
||||
@ -60,6 +62,8 @@ let package = Package(
|
||||
.target(name: "FuzzyRange"),
|
||||
.testTarget(name: "FuzzyRangeTests", dependencies: ["FuzzyRange"]),
|
||||
|
||||
.target(name: "Invisible"),
|
||||
|
||||
.target(name: "LineEnding", dependencies: ["ValueRange"]),
|
||||
.testTarget(name: "LineEndingTests", dependencies: ["LineEnding"]),
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
//
|
||||
// Invisible.swift
|
||||
// Invisible
|
||||
//
|
||||
// CotEditor
|
||||
// https://coteditor.com
|
||||
@ -23,10 +24,7 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import class Foundation.UserDefaults
|
||||
import Defaults
|
||||
|
||||
enum Invisible {
|
||||
public enum Invisible: Sendable, CaseIterable {
|
||||
|
||||
case newLine
|
||||
case tab
|
||||
@ -37,7 +35,7 @@ enum Invisible {
|
||||
case otherControl // Unicode Category Cc and some of Cf
|
||||
|
||||
|
||||
init?(codeUnit: UTF16.CodeUnit) {
|
||||
public init?(codeUnit: UTF16.CodeUnit) {
|
||||
|
||||
// > NSGlyphGenerator generates NSControlGlyph for all characters
|
||||
// > in the Unicode General Category C* and U200B (ZERO WIDTH SPACE).
|
||||
@ -49,20 +47,20 @@ enum Invisible {
|
||||
0x0085, // NEW LINE (Cc)
|
||||
0x2028, // LINE SEPARATOR (Zl)
|
||||
0x2029: // PARAGRAPH SEPARATOR (Zp)
|
||||
self = .newLine
|
||||
self = .newLine
|
||||
case 0x0009: // HORIZONTAL TABULATION (Cc) a.k.a. \t
|
||||
self = .tab
|
||||
self = .tab
|
||||
case 0x0020: // SPACE (Zs)
|
||||
self = .space
|
||||
self = .space
|
||||
case 0x00A0, // NO-BREAK SPACE (Zs)
|
||||
0x2007, // FIGURE SPACE (Zs)
|
||||
0x202F: // NARROW NO-BREAK SPACE (Zs)
|
||||
self = .noBreakSpace
|
||||
self = .noBreakSpace
|
||||
case 0x3000: // IDEOGRAPHIC SPACE (Zs) a.k.a. Japanese full-width space
|
||||
self = .fullwidthSpace
|
||||
self = .fullwidthSpace
|
||||
case 0x2000...0x200A, // (Zs) various width spaces, such as THREE-PER-EM SPACE
|
||||
0x205F: // MEDIUM MATHEMATICAL SPACE (Zs)
|
||||
self = .otherWhitespace
|
||||
self = .otherWhitespace
|
||||
case 0x0000...0x001F, 0x007F...0x009F, // C0 and C1 (Cc)
|
||||
0x200B, // ZERO WIDTH SPACE (Cf)
|
||||
0x200C, // ZERO WIDTH NON-JOINER (Cf)
|
||||
@ -71,14 +69,17 @@ enum Invisible {
|
||||
0x061C, 0x200E...0x200F, 0x202A...0x202E, 0x2066...0x206F, // bidi controls (Cf)
|
||||
0x2061...0x2065, // invisible operators (Cf)
|
||||
0xFFF9...0xFFFB: // interlinear annotations, controls for ruby (Cf)
|
||||
self = .otherControl
|
||||
self = .otherControl
|
||||
default:
|
||||
return nil
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var symbol: Character {
|
||||
extension Invisible {
|
||||
|
||||
public var symbol: Character {
|
||||
|
||||
switch self {
|
||||
case .newLine: "↩"
|
||||
@ -91,35 +92,3 @@ enum Invisible {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// MARK: User Defaults
|
||||
|
||||
extension Invisible: CaseIterable {
|
||||
|
||||
var visibilityDefaultKey: DefaultKey<Bool> {
|
||||
|
||||
switch self {
|
||||
case .newLine: .showInvisibleNewLine
|
||||
case .tab: .showInvisibleTab
|
||||
case .space: .showInvisibleSpace
|
||||
case .noBreakSpace: .showInvisibleWhitespaces
|
||||
case .fullwidthSpace: .showInvisibleWhitespaces
|
||||
case .otherWhitespace: .showInvisibleWhitespaces
|
||||
case .otherControl: .showInvisibleControl
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
extension UserDefaults {
|
||||
|
||||
var showsInvisible: Set<Invisible> {
|
||||
|
||||
let invisibles = Invisible.allCases
|
||||
.filter { self[$0.visibilityDefaultKey] }
|
||||
|
||||
return Set(invisibles)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user