Move Invisible to EditorCore

This commit is contained in:
1024jp 2024-07-05 22:56:32 +09:00
parent 68800ef801
commit a4c7261669
8 changed files with 86 additions and 53 deletions

View File

@ -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 */,

View File

@ -26,6 +26,7 @@
import AppKit
import Combine
import Defaults
import Invisible
final class FindPanelLayoutManager: NSLayoutManager, NSLayoutManagerDelegate, InvisibleDrawing {

View 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)
}
}

View File

@ -27,6 +27,7 @@
import AppKit
import Combine
import Defaults
import Invisible
class LayoutManager: NSLayoutManager, InvisibleDrawing, ValidationIgnorable, LineRangeCacheable {

View File

@ -26,6 +26,7 @@
import AppKit
import Combine
import Defaults
import Invisible
protocol InvisibleDrawing: NSLayoutManager {

View File

@ -25,6 +25,7 @@
import Foundation
import AppKit.NSColor
import Invisible
final class RegularExpressionFormatter: Formatter {

View File

@ -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"]),

View File

@ -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
}
}
}
extension Invisible {
var symbol: Character {
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)
}
}