Extract TextClipping to TextClipping package

This commit is contained in:
1024jp 2024-06-27 22:19:57 +09:00
parent 102f59cbf2
commit ba9f2b5ad5
7 changed files with 32 additions and 30 deletions

View File

@ -333,8 +333,6 @@
2A5E6FC52A723CEA00E33EA7 /* InfoPlist.xcstrings in Resources */ = {isa = PBXBuildFile; fileRef = 2A5E6FC32A723CE900E33EA7 /* InfoPlist.xcstrings */; };
2A5E6FC72A723F3C00E33EA7 /* ServicesMenu.xcstrings in Resources */ = {isa = PBXBuildFile; fileRef = 2A5E6FC62A723F3C00E33EA7 /* ServicesMenu.xcstrings */; };
2A5E6FC82A723F3C00E33EA7 /* ServicesMenu.xcstrings in Resources */ = {isa = PBXBuildFile; fileRef = 2A5E6FC62A723F3C00E33EA7 /* ServicesMenu.xcstrings */; };
2A5EDDBB241B649C00A07810 /* moof.textClipping in Resources */ = {isa = PBXBuildFile; fileRef = 2A5EDDBA241B649C00A07810 /* moof.textClipping */; };
2A5EDDBD241B64EB00A07810 /* TextClippingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A5EDDBC241B64EB00A07810 /* TextClippingTests.swift */; };
2A63A9D824E8C8F70017ACBB /* OutlinePicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A63A9D724E8C8F70017ACBB /* OutlinePicker.swift */; };
2A63A9D924E8C8F70017ACBB /* OutlinePicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A63A9D724E8C8F70017ACBB /* OutlinePicker.swift */; };
2A63CEC41D0B06D800ED8186 /* SyntaxTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A63CEC31D0B06D800ED8186 /* SyntaxTests.swift */; };
@ -572,8 +570,6 @@
2ABBACA21E3F1D1C00A080E7 /* NSTextStorage+ScriptingSupport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2ABBACA01E3F1D1C00A080E7 /* NSTextStorage+ScriptingSupport.swift */; };
2ABC76241909BF5200D2B592 /* Themes in Resources */ = {isa = PBXBuildFile; fileRef = 2A7846DA18FE035E006BDF00 /* Themes */; };
2ABEFB6A23DC0CA0008769F4 /* EditorCounterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2ABEFB6923DC0CA0008769F4 /* EditorCounterTests.swift */; };
2ABF49E3221A54AD00239278 /* TextClipping.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2ABF49E2221A54AD00239278 /* TextClipping.swift */; };
2ABF49E4221A54AD00239278 /* TextClipping.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2ABF49E2221A54AD00239278 /* TextClipping.swift */; };
2ABF86BD208C3C630082D52B /* AudioToolbox.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2ABF86BC208C3C630082D52B /* AudioToolbox.swift */; };
2ABF86BE208C3C630082D52B /* AudioToolbox.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2ABF86BC208C3C630082D52B /* AudioToolbox.swift */; };
2ABF9E9F2C1EC8620033D5E6 /* String+Filename.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2ABF9E9E2C1EC8590033D5E6 /* String+Filename.swift */; };
@ -982,8 +978,6 @@
2A5E6FC62A723F3C00E33EA7 /* ServicesMenu.xcstrings */ = {isa = PBXFileReference; lastKnownFileType = text.json.xcstrings; path = ServicesMenu.xcstrings; sourceTree = "<group>"; };
2A5EA1662A88F54800D16730 /* mul */ = {isa = PBXFileReference; lastKnownFileType = text.json.xcstrings; name = mul; path = mul.lproj/PrintPanelAccessory.xcstrings; sourceTree = "<group>"; };
2A5EA1672A88F70C00D16730 /* mul */ = {isa = PBXFileReference; lastKnownFileType = text.json.xcstrings; name = mul; path = mul.lproj/Main.xcstrings; sourceTree = "<group>"; };
2A5EDDBA241B649C00A07810 /* moof.textClipping */ = {isa = PBXFileReference; lastKnownFileType = file.bplist; name = moof.textClipping; path = TestFiles/moof.textClipping; sourceTree = "<group>"; };
2A5EDDBC241B64EB00A07810 /* TextClippingTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextClippingTests.swift; sourceTree = "<group>"; };
2A63A9D724E8C8F70017ACBB /* OutlinePicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OutlinePicker.swift; sourceTree = "<group>"; };
2A63CEC31D0B06D800ED8186 /* SyntaxTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SyntaxTests.swift; sourceTree = "<group>"; };
2A63CECA1D0B0E7800ED8186 /* sample.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; name = sample.html; path = TestFiles/sample.html; sourceTree = "<group>"; };
@ -1114,7 +1108,6 @@
2AB9E4C22B830902004E5BDC /* FormatSettings.xcstrings */ = {isa = PBXFileReference; lastKnownFileType = text.json.xcstrings; path = FormatSettings.xcstrings; sourceTree = "<group>"; };
2ABBACA01E3F1D1C00A080E7 /* NSTextStorage+ScriptingSupport.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSTextStorage+ScriptingSupport.swift"; sourceTree = "<group>"; };
2ABEFB6923DC0CA0008769F4 /* EditorCounterTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditorCounterTests.swift; sourceTree = "<group>"; };
2ABF49E2221A54AD00239278 /* TextClipping.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextClipping.swift; sourceTree = "<group>"; };
2ABF86BC208C3C630082D52B /* AudioToolbox.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AudioToolbox.swift; sourceTree = "<group>"; };
2ABF9E9E2C1EC8590033D5E6 /* String+Filename.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "String+Filename.swift"; sourceTree = "<group>"; };
2AC13A0824F112D800799A93 /* CommandLineToolManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CommandLineToolManager.swift; sourceTree = "<group>"; };
@ -1783,7 +1776,6 @@
2ACF23AD26302A4C002B5E10 /* Theme+Syntax.swift */,
2A1E7DD32B8C5A23004F0C07 /* Mode.swift */,
2AB857EA2B93050E0079CFA2 /* ModeOptions.swift */,
2ABF49E2221A54AD00239278 /* TextClipping.swift */,
2A1893A91FFF422D00AD244F /* LineSort.swift */,
2A341D19281EE23C00B85CB6 /* UserActivity.swift */,
2A55D5E92B7A86190092DE48 /* IssueReport.swift */,
@ -2126,7 +2118,6 @@
2AED46721E43942300751C45 /* TextFindTests.swift */,
2A1893AC1FFF6A0100AD244F /* LineSortTests.swift */,
2AC72EA1253478D5001D3CA0 /* FileDropItemTests.swift */,
2A5EDDBC241B64EB00A07810 /* TextClippingTests.swift */,
2A719F6523CD92370026F877 /* FuzzyRangeTests.swift */,
2ABEFB6923DC0CA0008769F4 /* EditorCounterTests.swift */,
2A1125C023F180FF006A1DB2 /* LineRangeCacheableTests.swift */,
@ -2144,7 +2135,6 @@
isa = PBXGroup;
children = (
2A63CECA1D0B0E7800ED8186 /* sample.html */,
2A5EDDBA241B649C00A07810 /* moof.textClipping */,
);
name = Resources;
sourceTree = "<group>";
@ -2525,7 +2515,6 @@
2A63CEC91D0B0D4600ED8186 /* Syntaxes in Resources */,
2A3DEAF21CEB23F0007B7621 /* Themes in Resources */,
2A63CECB1D0B0E7800ED8186 /* sample.html in Resources */,
2A5EDDBB241B649C00A07810 /* moof.textClipping in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -2925,7 +2914,6 @@
2A2615772977D30E008C2240 /* SyntaxOutlineEditView.swift in Sources */,
2A4714E42093A2D40093E27F /* SyntaxParser.swift in Sources */,
2A33D07F1D1C75B8005977B9 /* SyntaxValidationView.swift in Sources */,
2ABF49E4221A54AD00239278 /* TextClipping.swift in Sources */,
2AFE848722AE71130001C4ED /* TextContainer.swift in Sources */,
2AED46711E425CD200751C45 /* TextFind.swift in Sources */,
2A18560C1D47FA37008FA79E /* TextFinder.swift in Sources */,
@ -2991,7 +2979,6 @@
2AC71DE21BF0BDBC002E1434 /* StringAdvancedCountTests.swift in Sources */,
2AE12DFE1E7DB7D200681F72 /* StringFilenameTests.swift in Sources */,
2A63CEC41D0B06D800ED8186 /* SyntaxTests.swift in Sources */,
2A5EDDBD241B64EB00A07810 /* TextClippingTests.swift in Sources */,
2AED46731E43942300751C45 /* TextFindTests.swift in Sources */,
2ACC65321C98033D000574DC /* ThemeTests.swift in Sources */,
2A476CAE1D09C8C80088E37A /* URLExtensionsTests.swift in Sources */,
@ -3250,7 +3237,6 @@
2A2615782977D30E008C2240 /* SyntaxOutlineEditView.swift in Sources */,
2A4714E32093A2D40093E27F /* SyntaxParser.swift in Sources */,
2A33D07E1D1C75B8005977B9 /* SyntaxValidationView.swift in Sources */,
2ABF49E3221A54AD00239278 /* TextClipping.swift in Sources */,
2AFE848622AE71130001C4ED /* TextContainer.swift in Sources */,
2AED46701E425CD200751C45 /* TextFind.swift in Sources */,
2A18560B1D47FA37008FA79E /* TextFinder.swift in Sources */,

View File

@ -29,6 +29,7 @@ import Combine
import SwiftUI
import CharacterInfo
import Defaults
import TextClipping
final class EditorTextViewController: NSViewController, NSServicesMenuRequestor, NSTextViewDelegate {
@ -467,7 +468,7 @@ extension EditorTextViewController: EditorTextView.Delegate {
guard !fileDropItems.isEmpty else { return false }
let replacementString = urls.reduce(into: "") { (string, url) in
if url.pathExtension == "textClipping", let textClipping = try? TextClipping(contentsOf: url) {
if url.pathExtension == TextClipping.pathExtension, let textClipping = try? TextClipping(contentsOf: url) {
string += textClipping.string
return
}

View File

@ -55,7 +55,7 @@ final class HoleContentView: NSView {
self.windowOpacityObserver?.cancel()
self.windowOpacityObserver = newWindow?.publisher(for: \.isOpaque, options: .initial)
.sink { [unowned self] isOpaque in
self.holes.removeAll()
self.invalidateHoles(isOpaque: isOpaque)
self.holeViewObserver?.cancel()
self.holeViewObserver = if isOpaque {
@ -65,13 +65,7 @@ final class HoleContentView: NSView {
.map { $0.object as! NSView }
.filter { $0 is NSStackView }
.filter { $0.isDescendant(of: self) }
.eraseToVoid()
.merge(with: Just(Void()))
.sink { [unowned self] _ in
self.holes = self.descendants(type: NSStackView.self)
.map { $0.convert($0.frame, to: self) }
.filter { !$0.isEmpty }
}
.sink { [unowned self] _ in self.invalidateHoles(isOpaque: false) }
}
}
}
@ -90,6 +84,18 @@ final class HoleContentView: NSView {
hole.intersection(fillRect).fill(using: .clear)
}
}
private func invalidateHoles(isOpaque: Bool) {
if isOpaque {
self.holes.removeAll()
} else {
self.holes = self.descendants(type: NSStackView.self)
.map { $0.convert($0.frame, to: self) }
.filter { !$0.isEmpty }
}
}
}

View File

@ -18,6 +18,7 @@ let package = Package(
"Shortcut",
"StringBasics",
"Syntax",
"TextClipping",
"TextEditing",
"UnicodeNormalization",
"ValueRange",
@ -30,6 +31,7 @@ let package = Package(
.library(name: "FilePermissions", targets: ["FilePermissions"]),
.library(name: "StringBasics", targets: ["StringBasics"]),
.library(name: "Syntax", targets: ["Syntax"]),
.library(name: "TextClipping", targets: ["TextClipping"]),
.library(name: "TextEditing", targets: ["TextEditing"]),
.library(name: "UnicodeNormalization", targets: ["UnicodeNormalization"]),
@ -54,6 +56,9 @@ let package = Package(
.target(name: "Syntax", dependencies: ["StringBasics", "ValueRange"]),
.testTarget(name: "SyntaxTests", dependencies: ["Syntax"]),
.target(name: "TextClipping"),
.testTarget(name: "TextClippingTests", dependencies: ["TextClipping"], resources: [.process("Resources")]),
.target(name: "TextEditing", dependencies: ["StringBasics", "Syntax"]),
.testTarget(name: "TextEditingTests", dependencies: ["TextEditing"]),

View File

@ -1,5 +1,6 @@
//
// TextClipping.swift
// TextClipping
//
// CotEditor
// https://coteditor.com
@ -8,7 +9,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.
@ -25,9 +26,11 @@
import Foundation
struct TextClipping: Decodable {
public struct TextClipping: Equatable, Sendable, Decodable {
let string: String
public static let pathExtension = "textClipping"
public let string: String
enum CodingKeys: String, CodingKey {
@ -37,7 +40,7 @@ struct TextClipping: Decodable {
init(contentsOf url: URL) throws {
public init(contentsOf url: URL) throws {
let data = try Data(contentsOf: url)
let plist = try PropertyListDecoder().decode([String: TextClipping].self, from: data)

View File

@ -1,5 +1,6 @@
//
// TextClippingTests.swift
// TextClippingTests
//
// CotEditor
// https://coteditor.com
@ -25,13 +26,13 @@
import Foundation
import Testing
@testable import CotEditor
@testable import TextClipping
actor TextClippingTests {
struct TextClippingTests {
@Test func readTextClippingFile() throws {
let bundle = Bundle(for: type(of: self))
let bundle = Bundle.module
let url = try #require(bundle.url(forResource: "moof", withExtension: "textClipping"))
let textClipping = try TextClipping(contentsOf: url)