From a10b1b0c91c423aada53a6f6b09f875c6849ef1f Mon Sep 17 00:00:00 2001 From: Wouter01 Date: Fri, 30 Dec 2022 17:12:17 +0100 Subject: [PATCH 01/30] First version of CodeEditExtension API Signed-off-by: Wouter01 --- Package.swift | 18 ++++- .../CodeEditKit/CEToolbarItemPlacement.swift | 22 ++++++ Sources/CodeEditKit/CodableWrappers.swift | 52 +++++++++++++ Sources/CodeEditKit/CodeEditExtension.swift | 74 +++++++++++++++++++ Sources/CodeEditKit/Entitlements.swift | 22 ++++++ Sources/CodeEditKit/ExtensionKind.swift | 18 +++++ Sources/CodeEditKit/File.swift | 39 ++++++++++ Sources/CodeEditKit/Nameable.swift | 19 +++++ .../Actions/ActionExtension.swift | 16 ++++ .../NonUIExtensions/Actions/ActionKind.swift | 13 ++++ .../Actions/CEAction+Either.swift | 20 +++++ .../NonUIExtensions/Actions/CEAction.swift | 16 ++++ .../Actions/ShortcutAction.swift | 22 ++++++ .../Actions/ToolbarAction.swift | 22 ++++++ .../Theme/ThemeExtension.swift | 43 +++++++++++ .../Theme/ThemeItem+Either.swift | 16 ++++ .../NonUIExtensions/Theme/ThemeItem.swift | 14 ++++ .../Environment/CEEnvironment.swift | 59 +++++++++++++++ .../Environment/CEEnvironmentKey.swift | 26 +++++++ .../EnvironmentObjcPublisher.swift | 26 +++++++ .../Settings/GeneralSettingsScene.swift | 40 ++++++++++ .../Settings/GeneralSettingsView.swift | 20 +++++ .../Settings/SettingsExtension.swift | 25 +++++++ .../UIExtensions/Sidebar/Examples.swift | 25 +++++++ .../Sidebar/SidebarExtension.swift | 33 +++++++++ .../Sidebar/SidebarItem+Either.swift | 16 ++++ .../UIExtensions/Sidebar/SidebarItem.swift | 14 ++++ .../ToolbarItem/CEToolbarItem+Either.swift | 16 ++++ .../ToolbarItem/CEToolbarItem.swift | 22 ++++++ .../ToolbarItem/ToolbarItemExtension.swift | 32 ++++++++ Sources/CodeEditKit/XPCWrapper.swift | 65 ++++++++++++++++ .../Documentation.docc/Documentation.md | 0 .../ExtensionAPI.swift | 0 .../ExtensionInterface.swift | 0 .../ExtensionManifest.swift | 0 .../Targets/Target.swift | 0 .../TargetsAPI.swift | 0 .../Example/ExampleSidebar.swift | 17 +++++ .../Example/ExampleToolbarItem.swift | 19 +++++ .../Example/FirstExtension.swift | 66 +++++++++++++++++ 40 files changed, 963 insertions(+), 4 deletions(-) create mode 100644 Sources/CodeEditKit/CEToolbarItemPlacement.swift create mode 100644 Sources/CodeEditKit/CodableWrappers.swift create mode 100644 Sources/CodeEditKit/CodeEditExtension.swift create mode 100644 Sources/CodeEditKit/Entitlements.swift create mode 100644 Sources/CodeEditKit/ExtensionKind.swift create mode 100644 Sources/CodeEditKit/File.swift create mode 100644 Sources/CodeEditKit/Nameable.swift create mode 100644 Sources/CodeEditKit/NonUIExtensions/Actions/ActionExtension.swift create mode 100644 Sources/CodeEditKit/NonUIExtensions/Actions/ActionKind.swift create mode 100644 Sources/CodeEditKit/NonUIExtensions/Actions/CEAction+Either.swift create mode 100644 Sources/CodeEditKit/NonUIExtensions/Actions/CEAction.swift create mode 100644 Sources/CodeEditKit/NonUIExtensions/Actions/ShortcutAction.swift create mode 100644 Sources/CodeEditKit/NonUIExtensions/Actions/ToolbarAction.swift create mode 100644 Sources/CodeEditKit/NonUIExtensions/Theme/ThemeExtension.swift create mode 100644 Sources/CodeEditKit/NonUIExtensions/Theme/ThemeItem+Either.swift create mode 100644 Sources/CodeEditKit/NonUIExtensions/Theme/ThemeItem.swift create mode 100644 Sources/CodeEditKit/UIExtensions/Environment/CEEnvironment.swift create mode 100644 Sources/CodeEditKit/UIExtensions/Environment/CEEnvironmentKey.swift create mode 100644 Sources/CodeEditKit/UIExtensions/Environment/EnvironmentObjcPublisher.swift create mode 100644 Sources/CodeEditKit/UIExtensions/Settings/GeneralSettingsScene.swift create mode 100644 Sources/CodeEditKit/UIExtensions/Settings/GeneralSettingsView.swift create mode 100644 Sources/CodeEditKit/UIExtensions/Settings/SettingsExtension.swift create mode 100644 Sources/CodeEditKit/UIExtensions/Sidebar/Examples.swift create mode 100644 Sources/CodeEditKit/UIExtensions/Sidebar/SidebarExtension.swift create mode 100644 Sources/CodeEditKit/UIExtensions/Sidebar/SidebarItem+Either.swift create mode 100644 Sources/CodeEditKit/UIExtensions/Sidebar/SidebarItem.swift create mode 100644 Sources/CodeEditKit/UIExtensions/ToolbarItem/CEToolbarItem+Either.swift create mode 100644 Sources/CodeEditKit/UIExtensions/ToolbarItem/CEToolbarItem.swift create mode 100644 Sources/CodeEditKit/UIExtensions/ToolbarItem/ToolbarItemExtension.swift create mode 100644 Sources/CodeEditKit/XPCWrapper.swift rename Sources/{CodeEditKit => CodeEditKitOld}/Documentation.docc/Documentation.md (100%) rename Sources/{CodeEditKit => CodeEditKitOld}/ExtensionAPI.swift (100%) rename Sources/{CodeEditKit => CodeEditKitOld}/ExtensionInterface.swift (100%) rename Sources/{CodeEditKit => CodeEditKitOld}/ExtensionManifest.swift (100%) rename Sources/{CodeEditKit => CodeEditKitOld}/Targets/Target.swift (100%) rename Sources/{CodeEditKit => CodeEditKitOld}/TargetsAPI.swift (100%) create mode 100644 Tests/CodeEditKitTests/Example/ExampleSidebar.swift create mode 100644 Tests/CodeEditKitTests/Example/ExampleToolbarItem.swift create mode 100644 Tests/CodeEditKitTests/Example/FirstExtension.swift diff --git a/Package.swift b/Package.swift index 499ad18..56aeda7 100644 --- a/Package.swift +++ b/Package.swift @@ -1,20 +1,30 @@ -// swift-tools-version:5.6 +// swift-tools-version:5.7 import PackageDescription let package = Package( name: "CodeEditKit", + platforms: [ + .macOS(.v13) + ], products: [ .library( name: "CodeEditKit", type: .dynamic, - targets: ["CodeEditKit"]), + targets: ["CodeEditKit", "CodeEditKitOld"]), + ], + dependencies: [ + .package(url: "https://github.com/andtie/SequenceBuilder", branch: "main"), + .package( + url: "https://github.com/Flight-School/AnyCodable", + from: "0.6.0" + ), ], - dependencies: [], targets: [ .target( name: "CodeEditKit", - dependencies: []), + dependencies: ["SequenceBuilder", "AnyCodable"]), + .target(name: "CodeEditKitOld"), .testTarget( name: "CodeEditKitTests", dependencies: ["CodeEditKit"]), diff --git a/Sources/CodeEditKit/CEToolbarItemPlacement.swift b/Sources/CodeEditKit/CEToolbarItemPlacement.swift new file mode 100644 index 0000000..60c9d05 --- /dev/null +++ b/Sources/CodeEditKit/CEToolbarItemPlacement.swift @@ -0,0 +1,22 @@ +// +// File.swift +// +// +// Created by Wouter Hennen on 30/12/2022. +// + +import SwiftUI + +public enum CEToolbarItemPlacement: Codable { + case automatic + case principal + + public var toolbarItemPlacement: ToolbarItemPlacement { + switch self { + case .automatic: + return .automatic + case .principal: + return .principal + } + } +} diff --git a/Sources/CodeEditKit/CodableWrappers.swift b/Sources/CodeEditKit/CodableWrappers.swift new file mode 100644 index 0000000..fab11f2 --- /dev/null +++ b/Sources/CodeEditKit/CodableWrappers.swift @@ -0,0 +1,52 @@ +// +// File 2.swift +// +// +// Created by Wouter Hennen on 06/12/2022. +// + +import Foundation + +@propertyWrapper +public struct Encoded { + public var wrappedValue: T + + public init(wrappedValue: T) { + self.wrappedValue = wrappedValue + } + + public var errorDescription: String? { + do { + _ = try JSONEncoder().encode(wrappedValue) + return nil + } catch { + return error.localizedDescription + } + } + + public var projectedValue: Data? { + try? JSONEncoder().encode(wrappedValue) + } +} + +@propertyWrapper +public struct Decoded { + public var wrappedValue: Data + + public init(wrappedValue: Data) { + self.wrappedValue = wrappedValue + } + + public var errorDescription: String? { + do { + _ = try JSONDecoder().decode(T.self, from: wrappedValue) + return nil + } catch { + return error.localizedDescription + } + } + + public var projectedValue: T? { + try? JSONDecoder().decode(T.self, from: wrappedValue) + } +} diff --git a/Sources/CodeEditKit/CodeEditExtension.swift b/Sources/CodeEditKit/CodeEditExtension.swift new file mode 100644 index 0000000..b7e69fe --- /dev/null +++ b/Sources/CodeEditKit/CodeEditExtension.swift @@ -0,0 +1,74 @@ +// +// File.swift +// +// +// Created by Wouter Hennen on 30/12/2022. +// + +import Foundation +import ExtensionKit +import ExtensionFoundation +import SwiftUI + +public protocol CodeEditExtension: AppExtension { + + associatedtype Body: AppExtensionScene + associatedtype Configuration = AppExtensionSceneConfiguration + + var description: String { get } + var entitlements: [Entitlement] { get } + + + @AppExtensionSceneBuilder + var body: Body { get } +} + +extension CodeEditExtension { + func gatherAvailableExtensions() -> [ExtensionKind] { + var extensions: [ExtensionKind] = [] + + if self is any SettingsExtension { + extensions.append(.settings) + } + + if let self = self as? any ThemeExtension { + extensions.append(contentsOf: self.availableExtensions) + } + + if let self = self as? any SidebarExtension { + extensions.append(contentsOf: self.availableExtensions) + } + + if let self = self as? any ToolbarItemExtension { + extensions.append(contentsOf: self.availableExtensions) + } + return extensions + } +} + +public extension CodeEditExtension{ + var configuration: AppExtensionSceneConfiguration { + AppExtensionSceneConfiguration(self.body, configuration: SettingsExtensionConfiguration(self)) + } +} + +public struct SettingsExtensionConfiguration: AppExtensionConfiguration { + public func accept(connection: NSXPCConnection) -> Bool { + connection.exportedInterface = .init(with: XPCWrappable.self) + connection.exportedObject = XPCWrapper(appExtension) + connection.resume() + + return true + } + + let appExtension: E + + /// Creates a default configuration for the given extension. + /// - Parameter appExtension: An instance of your custom extension that conforms to the ``TextTransformExtension`` protocol. + public init(_ appExtension: E) { + self.appExtension = appExtension + } +} + + + diff --git a/Sources/CodeEditKit/Entitlements.swift b/Sources/CodeEditKit/Entitlements.swift new file mode 100644 index 0000000..8505e3c --- /dev/null +++ b/Sources/CodeEditKit/Entitlements.swift @@ -0,0 +1,22 @@ +// +// File.swift +// +// +// Created by Wouter Hennen on 30/12/2022. +// + +import Foundation + +public enum Entitlement: CustomStringConvertible, Codable, CaseIterable { + case workspace + case currentfile + + public var description: String { + switch self { + case .workspace: + return "Workspace" + case .currentfile: + return "Current File" + } + } +} diff --git a/Sources/CodeEditKit/ExtensionKind.swift b/Sources/CodeEditKit/ExtensionKind.swift new file mode 100644 index 0000000..a8cb3dc --- /dev/null +++ b/Sources/CodeEditKit/ExtensionKind.swift @@ -0,0 +1,18 @@ +// +// File.swift +// +// +// Created by Wouter Hennen on 30/12/2022. +// + +import SwiftUI + +public enum ExtensionKind: Codable { + case sidebarItem(sceneID: String) + case toolbarItem(sceneID: String, placement: CEToolbarItemPlacement) + case action(actionID: String) + case theme(themeID: String) + case settings +} + + diff --git a/Sources/CodeEditKit/File.swift b/Sources/CodeEditKit/File.swift new file mode 100644 index 0000000..5b8d12b --- /dev/null +++ b/Sources/CodeEditKit/File.swift @@ -0,0 +1,39 @@ +// +// File.swift +// +// +// Created by Wouter Hennen on 30/12/2022. +// + +import Foundation +import AppKit + +@propertyWrapper +public struct CodableColorArray { + public var wrappedValue: [NSColor] + + public init(wrappedValue: [NSColor]) { + self.wrappedValue = wrappedValue + } +} + +extension CodableColorArray: Codable { + public init(from decoder: Decoder) throws { + let container = try decoder.singleValueContainer() + let data = try container.decode(Data.self) + + guard let color = try NSKeyedUnarchiver.unarchivedArrayOfObjects(ofClass: NSColor.self, from: data) else { + throw DecodingError.dataCorruptedError( + in: container, + debugDescription: "Invalid color" + ) + } + wrappedValue = color + } + + public func encode(to encoder: Encoder) throws { + var container = encoder.singleValueContainer() + let data = try NSKeyedArchiver.archivedData(withRootObject: wrappedValue, requiringSecureCoding: true) + try container.encode(data) + } +} diff --git a/Sources/CodeEditKit/Nameable.swift b/Sources/CodeEditKit/Nameable.swift new file mode 100644 index 0000000..00ff195 --- /dev/null +++ b/Sources/CodeEditKit/Nameable.swift @@ -0,0 +1,19 @@ +// +// File.swift +// +// +// Created by Wouter Hennen on 30/12/2022. +// + +import Foundation +import SequenceBuilder + +public protocol Nameable { + var name: String { get } +} + +extension Either: Nameable where Left: Nameable, Right: Nameable { + public var name: String { + fold(left: \.name, right: \.name) + } +} diff --git a/Sources/CodeEditKit/NonUIExtensions/Actions/ActionExtension.swift b/Sources/CodeEditKit/NonUIExtensions/Actions/ActionExtension.swift new file mode 100644 index 0000000..deed0b7 --- /dev/null +++ b/Sources/CodeEditKit/NonUIExtensions/Actions/ActionExtension.swift @@ -0,0 +1,16 @@ +// +// File.swift +// +// +// Created by Wouter Hennen on 30/12/2022. +// + +import Foundation +import SequenceBuilder + +public protocol ActionExtension { + associatedtype ActionsBody: Sequence where ActionsBody.Element: CEAction + + @SequenceBuilder + var actions: ActionsBody { get } +} diff --git a/Sources/CodeEditKit/NonUIExtensions/Actions/ActionKind.swift b/Sources/CodeEditKit/NonUIExtensions/Actions/ActionKind.swift new file mode 100644 index 0000000..51d309e --- /dev/null +++ b/Sources/CodeEditKit/NonUIExtensions/Actions/ActionKind.swift @@ -0,0 +1,13 @@ +// +// File.swift +// +// +// Created by Wouter Hennen on 30/12/2022. +// + +import Foundation + +public enum ActionKind { + case shortcut + case toolbar +} diff --git a/Sources/CodeEditKit/NonUIExtensions/Actions/CEAction+Either.swift b/Sources/CodeEditKit/NonUIExtensions/Actions/CEAction+Either.swift new file mode 100644 index 0000000..666db78 --- /dev/null +++ b/Sources/CodeEditKit/NonUIExtensions/Actions/CEAction+Either.swift @@ -0,0 +1,20 @@ +// +// File.swift +// +// +// Created by Wouter Hennen on 30/12/2022. +// + +import Foundation +import SequenceBuilder + +extension Either: CEAction where Left: CEAction, Right: CEAction { + + public var kind: ActionKind { + fold(left: \.kind, right: \.kind) + } + + public var action: () -> Void { + fold(left: \.action, right: \.action) + } +} diff --git a/Sources/CodeEditKit/NonUIExtensions/Actions/CEAction.swift b/Sources/CodeEditKit/NonUIExtensions/Actions/CEAction.swift new file mode 100644 index 0000000..b9bd767 --- /dev/null +++ b/Sources/CodeEditKit/NonUIExtensions/Actions/CEAction.swift @@ -0,0 +1,16 @@ +// +// File.swift +// +// +// Created by Wouter Hennen on 30/12/2022. +// + +import Foundation + +public protocol CEAction: Identifiable, Nameable where ID == String { + + var id: ID { get } + var name: String { get } + var kind: ActionKind { get } + var action: () -> Void { get } +} diff --git a/Sources/CodeEditKit/NonUIExtensions/Actions/ShortcutAction.swift b/Sources/CodeEditKit/NonUIExtensions/Actions/ShortcutAction.swift new file mode 100644 index 0000000..6acafaf --- /dev/null +++ b/Sources/CodeEditKit/NonUIExtensions/Actions/ShortcutAction.swift @@ -0,0 +1,22 @@ +// +// File.swift +// +// +// Created by Wouter Hennen on 30/12/2022. +// + +import Foundation + +public struct ShortcutAction: CEAction { + public var kind: ActionKind = .shortcut + + public var name: String + public var id: String { "shortcut\(name)"} + + public var action: () -> Void + + public init(name: String, action: @escaping () -> Void) { + self.name = name + self.action = action + } +} diff --git a/Sources/CodeEditKit/NonUIExtensions/Actions/ToolbarAction.swift b/Sources/CodeEditKit/NonUIExtensions/Actions/ToolbarAction.swift new file mode 100644 index 0000000..9f773a7 --- /dev/null +++ b/Sources/CodeEditKit/NonUIExtensions/Actions/ToolbarAction.swift @@ -0,0 +1,22 @@ +// +// File.swift +// +// +// Created by Wouter Hennen on 30/12/2022. +// + +import Foundation + +public struct ToolbarAction: CEAction { + public var kind: ActionKind = .toolbar + + public var name: String + public var id: String { "toolbar\(name)"} + + public var action: () -> Void + + public init(name: String, action: @escaping () -> Void) { + self.name = name + self.action = action + } +} diff --git a/Sources/CodeEditKit/NonUIExtensions/Theme/ThemeExtension.swift b/Sources/CodeEditKit/NonUIExtensions/Theme/ThemeExtension.swift new file mode 100644 index 0000000..24e7362 --- /dev/null +++ b/Sources/CodeEditKit/NonUIExtensions/Theme/ThemeExtension.swift @@ -0,0 +1,43 @@ +// +// File.swift +// +// +// Created by Wouter Hennen on 30/12/2022. +// + +import SwiftUI +import SequenceBuilder + +public protocol ThemeExtension { + associatedtype ThemesBody: Sequence where ThemesBody.Element: ThemeItem + + @SequenceBuilder + var themes: ThemesBody { get } +} + +extension ThemeExtension { + var availableExtensions: [ExtensionKind] { + themes.map { ExtensionKind.theme(themeID: $0.id) } + } + + func getTheme(with id: String) -> GeneralThemeItem? { + guard let theme = themes.first(where: { $0.id == id }) else { return nil } + return GeneralThemeItem(theme) + } +} + +public struct GeneralThemeItem: ThemeItem, Codable { + public var id: String + public var name: String + @CodableColorArray public var colors: [NSColor] + + public init(id: String, name: String, colors: [NSColor]) { + self.id = id + self.name = name + self.colors = colors + } + + init(_ theme: any ThemeItem) { + self.init(id: theme.id, name: theme.name, colors: theme.colors) + } +} diff --git a/Sources/CodeEditKit/NonUIExtensions/Theme/ThemeItem+Either.swift b/Sources/CodeEditKit/NonUIExtensions/Theme/ThemeItem+Either.swift new file mode 100644 index 0000000..9870c64 --- /dev/null +++ b/Sources/CodeEditKit/NonUIExtensions/Theme/ThemeItem+Either.swift @@ -0,0 +1,16 @@ +// +// File.swift +// +// +// Created by Wouter Hennen on 30/12/2022. +// + +import SwiftUI +import SequenceBuilder + +extension Either: ThemeItem where Left: ThemeItem, Right: ThemeItem { + + public var colors: [NSColor] { + fold(left: \.colors, right: \.colors) + } +} diff --git a/Sources/CodeEditKit/NonUIExtensions/Theme/ThemeItem.swift b/Sources/CodeEditKit/NonUIExtensions/Theme/ThemeItem.swift new file mode 100644 index 0000000..4d631fb --- /dev/null +++ b/Sources/CodeEditKit/NonUIExtensions/Theme/ThemeItem.swift @@ -0,0 +1,14 @@ +// +// File.swift +// +// +// Created by Wouter Hennen on 30/12/2022. +// + +import SwiftUI + +public protocol ThemeItem: Identifiable, Nameable where ID == String { + var id: ID { get } + var name: String { get } + var colors: [NSColor] { get } +} diff --git a/Sources/CodeEditKit/UIExtensions/Environment/CEEnvironment.swift b/Sources/CodeEditKit/UIExtensions/Environment/CEEnvironment.swift new file mode 100644 index 0000000..e60a0dc --- /dev/null +++ b/Sources/CodeEditKit/UIExtensions/Environment/CEEnvironment.swift @@ -0,0 +1,59 @@ +// +// File.swift +// +// +// Created by Wouter Hennen on 30/12/2022. +// + +import Foundation +import AnyCodable +import SwiftUI + +public struct _CEEnvironment: Codable, Equatable { + public var test = false + public var complexValue: Array = [] + + var otherKeys: [String: AnyCodable] = [:] + + mutating func update(_ keyPath: WritableKeyPath, _ value: Value) { + self[keyPath: keyPath] = value + } + + public subscript(key: K.Type) -> K.Value where K : CEEnvironmentKey { + get { + guard let data = otherKeys[key.identifier] else { return key.defaultValue } + return data.value as! K.Value + } + set { otherKeys[key.identifier] = AnyCodable(newValue) } + } +} + +@propertyWrapper +public struct CEEnvironment : DynamicProperty { + @Environment(\._ceEnvironment) var environment + + public init(_ keyPath: KeyPath<_CEEnvironment, Value>) { + self.keyPath = keyPath + } + + let keyPath: KeyPath<_CEEnvironment, Value> + + public var wrappedValue: Value { + environment[keyPath: keyPath] + } +} + +public struct _CEEnvironmentKey: EnvironmentKey { + public static let defaultValue = _CEEnvironment() +} + +public extension EnvironmentValues { + var _ceEnvironment: _CEEnvironmentKey.Value { + get { + return self[_CEEnvironmentKey.self] + } + set { + self[_CEEnvironmentKey.self] = newValue + } + } +} diff --git a/Sources/CodeEditKit/UIExtensions/Environment/CEEnvironmentKey.swift b/Sources/CodeEditKit/UIExtensions/Environment/CEEnvironmentKey.swift new file mode 100644 index 0000000..3aefc2e --- /dev/null +++ b/Sources/CodeEditKit/UIExtensions/Environment/CEEnvironmentKey.swift @@ -0,0 +1,26 @@ +// +// File.swift +// +// +// Created by Wouter Hennen on 30/12/2022. +// + +import Foundation + +public protocol CEEnvironmentKey { + + /// The associated type representing the type of the environment key's + /// value. + associatedtype Value: Codable + + static var identifier: String { get } + + /// The default value for the environment key. + static var defaultValue: Self.Value { get } +} + +public extension CEEnvironmentKey { + static var identifier: String { + String(describing: Self.self) + } +} diff --git a/Sources/CodeEditKit/UIExtensions/Environment/EnvironmentObjcPublisher.swift b/Sources/CodeEditKit/UIExtensions/Environment/EnvironmentObjcPublisher.swift new file mode 100644 index 0000000..df01f30 --- /dev/null +++ b/Sources/CodeEditKit/UIExtensions/Environment/EnvironmentObjcPublisher.swift @@ -0,0 +1,26 @@ +// +// File.swift +// +// +// Created by Wouter Hennen on 30/12/2022. +// + +import Foundation + +@objc public protocol EnvironmentPublisherObjc { + func publishEnvironment(data: Data) +} + + +public class EnvironmentPublisher: ObservableObject, EnvironmentPublisherObjc { + + @Published var environment = _CEEnvironment() + + public init() {} + + public func publishEnvironment(@Decoded<_CEEnvironment> data: Data) { + guard let $data else { return } + environment = $data + print("update: received data \($data)") + } +} diff --git a/Sources/CodeEditKit/UIExtensions/Settings/GeneralSettingsScene.swift b/Sources/CodeEditKit/UIExtensions/Settings/GeneralSettingsScene.swift new file mode 100644 index 0000000..a4f00f0 --- /dev/null +++ b/Sources/CodeEditKit/UIExtensions/Settings/GeneralSettingsScene.swift @@ -0,0 +1,40 @@ +// +// File.swift +// +// +// Created by Wouter Hennen on 30/12/2022. +// + +import Foundation +import SwiftUI +import ExtensionKit + +struct GeneralSettingsScene: AppExtensionScene { + + @ViewBuilder + let content: () -> Content + + init(content: @escaping () -> Content) { + self.content = content + } + + var connection: NSXPCConnection? + var environmentWrapper = EnvironmentPublisher() + + var body: some AppExtensionScene { + PrimitiveAppExtensionScene(id: "Settings") { + GeneralSettingsView(environmentWrapper: environmentWrapper) { + Form { + content() + } + .formStyle(.grouped) + } + } onConnection: { connection in + connection.exportedInterface = .init(with: EnvironmentPublisherObjc.self) + connection.exportedObject = environmentWrapper + connection.resume() + + return true + } + } +} diff --git a/Sources/CodeEditKit/UIExtensions/Settings/GeneralSettingsView.swift b/Sources/CodeEditKit/UIExtensions/Settings/GeneralSettingsView.swift new file mode 100644 index 0000000..4076f64 --- /dev/null +++ b/Sources/CodeEditKit/UIExtensions/Settings/GeneralSettingsView.swift @@ -0,0 +1,20 @@ +// +// File.swift +// +// +// Created by Wouter Hennen on 30/12/2022. +// + +import Foundation +import SwiftUI + +struct GeneralSettingsView: View { + + @StateObject var environmentWrapper: EnvironmentPublisher + @ViewBuilder var content: Content + + var body: some View { + content + .environment(\._ceEnvironment, environmentWrapper.environment) + } +} diff --git a/Sources/CodeEditKit/UIExtensions/Settings/SettingsExtension.swift b/Sources/CodeEditKit/UIExtensions/Settings/SettingsExtension.swift new file mode 100644 index 0000000..29ab670 --- /dev/null +++ b/Sources/CodeEditKit/UIExtensions/Settings/SettingsExtension.swift @@ -0,0 +1,25 @@ +// +// File.swift +// +// +// Created by Wouter Hennen on 30/12/2022. +// + +import Foundation +import SwiftUI +import ExtensionKit + +protocol SettingsExtension { + associatedtype SettingsBody: View + + @ViewBuilder + var settings: SettingsBody { get } +} + +extension SettingsExtension { + var settingsScene: some AppExtensionScene { + GeneralSettingsScene { + self.settings + } + } +} diff --git a/Sources/CodeEditKit/UIExtensions/Sidebar/Examples.swift b/Sources/CodeEditKit/UIExtensions/Sidebar/Examples.swift new file mode 100644 index 0000000..669e7f9 --- /dev/null +++ b/Sources/CodeEditKit/UIExtensions/Sidebar/Examples.swift @@ -0,0 +1,25 @@ +// +// File.swift +// +// +// Created by Wouter Hennen on 30/12/2022. +// + +import Foundation +import SwiftUI + +struct DefaultNavigator: SidebarItem { + var id: String = "TestTest" + var icon: String = "Test" + var body: some View { + Text("Piep") + } +} + +struct DefaultNavigator2: SidebarItem { + var id: String = "Hello" + var icon: String = "Test" + var body: some View { + Text("Piep2") + } +} diff --git a/Sources/CodeEditKit/UIExtensions/Sidebar/SidebarExtension.swift b/Sources/CodeEditKit/UIExtensions/Sidebar/SidebarExtension.swift new file mode 100644 index 0000000..5e37fe7 --- /dev/null +++ b/Sources/CodeEditKit/UIExtensions/Sidebar/SidebarExtension.swift @@ -0,0 +1,33 @@ +// +// File.swift +// +// +// Created by Wouter Hennen on 30/12/2022. +// + +import Foundation +import SequenceBuilder +import ExtensionKit + +public protocol SidebarExtension { + + associatedtype SidebarBody: Sequence where SidebarBody.Element: SidebarItem + + @SequenceBuilder + var sidebars: SidebarBody { get } +} + +public extension SidebarExtension { + var sidebarScenes: some AppExtensionScene { + + sidebars.map { item in + PrimitiveAppExtensionScene(id: item.id) { + item.body + } + } + } + + var availableExtensions: [ExtensionKind] { + sidebars.map { ExtensionKind.sidebarItem(sceneID: $0.id) } + } +} diff --git a/Sources/CodeEditKit/UIExtensions/Sidebar/SidebarItem+Either.swift b/Sources/CodeEditKit/UIExtensions/Sidebar/SidebarItem+Either.swift new file mode 100644 index 0000000..9991eb1 --- /dev/null +++ b/Sources/CodeEditKit/UIExtensions/Sidebar/SidebarItem+Either.swift @@ -0,0 +1,16 @@ +// +// File.swift +// +// +// Created by Wouter Hennen on 30/12/2022. +// + +import Foundation +import SequenceBuilder + +extension Either: SidebarItem where Left: SidebarItem, Right: SidebarItem { + + public var icon: String { + fold(left: \.icon, right: \.icon) + } +} diff --git a/Sources/CodeEditKit/UIExtensions/Sidebar/SidebarItem.swift b/Sources/CodeEditKit/UIExtensions/Sidebar/SidebarItem.swift new file mode 100644 index 0000000..6713ab0 --- /dev/null +++ b/Sources/CodeEditKit/UIExtensions/Sidebar/SidebarItem.swift @@ -0,0 +1,14 @@ +// +// File.swift +// +// +// Created by Wouter Hennen on 30/12/2022. +// + +import Foundation +import SwiftUI + +public protocol SidebarItem: View, Identifiable where ID == String { + var id: ID { get } + var icon: String { get } +} diff --git a/Sources/CodeEditKit/UIExtensions/ToolbarItem/CEToolbarItem+Either.swift b/Sources/CodeEditKit/UIExtensions/ToolbarItem/CEToolbarItem+Either.swift new file mode 100644 index 0000000..b74c834 --- /dev/null +++ b/Sources/CodeEditKit/UIExtensions/ToolbarItem/CEToolbarItem+Either.swift @@ -0,0 +1,16 @@ +// +// File.swift +// +// +// Created by Wouter Hennen on 30/12/2022. +// + +import SwiftUI +import SequenceBuilder + +extension Either: CEToolbarItem where Left: CEToolbarItem, Right: CEToolbarItem { + + public var placement: CEToolbarItemPlacement { + fold(left: \.placement, right: \.placement) + } +} diff --git a/Sources/CodeEditKit/UIExtensions/ToolbarItem/CEToolbarItem.swift b/Sources/CodeEditKit/UIExtensions/ToolbarItem/CEToolbarItem.swift new file mode 100644 index 0000000..bfae158 --- /dev/null +++ b/Sources/CodeEditKit/UIExtensions/ToolbarItem/CEToolbarItem.swift @@ -0,0 +1,22 @@ +// +// File.swift +// +// +// Created by Wouter Hennen on 30/12/2022. +// + +import Foundation +import SwiftUI + +public protocol CEToolbarItem: View, Identifiable where ID == String { + var id: ID { get } + var placement: CEToolbarItemPlacement { get } +} + +extension CEToolbarItem { + var mappedID: String { + "CEToolbarItem_\(id)" + } + + public var placement: CEToolbarItemPlacement { .automatic } +} diff --git a/Sources/CodeEditKit/UIExtensions/ToolbarItem/ToolbarItemExtension.swift b/Sources/CodeEditKit/UIExtensions/ToolbarItem/ToolbarItemExtension.swift new file mode 100644 index 0000000..cb2118e --- /dev/null +++ b/Sources/CodeEditKit/UIExtensions/ToolbarItem/ToolbarItemExtension.swift @@ -0,0 +1,32 @@ +// +// File.swift +// +// +// Created by Wouter Hennen on 30/12/2022. +// + +import Foundation +import SequenceBuilder +import ExtensionKit + +public protocol ToolbarItemExtension { + + associatedtype ToolbarItemBody: Sequence where ToolbarItemBody.Element: CEToolbarItem + + @SequenceBuilder + var toolbaritems: ToolbarItemBody { get } +} + +extension ToolbarItemExtension { + public var toolbarItemScenes: some AppExtensionScene { + toolbaritems.map { nav in + PrimitiveAppExtensionScene(id: nav.mappedID) { + nav.body + } + } + } + + var availableExtensions: [ExtensionKind] { + toolbaritems.map { ExtensionKind.toolbarItem(sceneID: $0.id, placement: $0.placement) } + } +} diff --git a/Sources/CodeEditKit/XPCWrapper.swift b/Sources/CodeEditKit/XPCWrapper.swift new file mode 100644 index 0000000..b8be739 --- /dev/null +++ b/Sources/CodeEditKit/XPCWrapper.swift @@ -0,0 +1,65 @@ +// +// File.swift +// +// +// Created by Wouter Hennen on 30/12/2022. +// + +import Foundation + +public typealias XPCReply = (Data?, Error?) -> Void + +public enum XPCError: Error { + case extensionDoesNotExist(description: String) + case identifierDoesNotExist(description: String) +} + +@objc +public protocol XPCWrappable { + func getExtensionKinds(reply: @escaping XPCReply) + + func getTheme(reply: @escaping XPCReply) + + func doAction(with identifier: String, reply: @escaping XPCReply) +} + + +class XPCWrapper: XPCWrappable { + + var ext: any CodeEditExtension + + init(_ ext: any CodeEditExtension) { + self.ext = ext + } + + func getExtensionKinds(reply: @escaping XPCReply) { + do { + let encoded = try JSONEncoder().encode(ext.gatherAvailableExtensions()) + reply(encoded, nil) + } catch { + reply(nil, error) + } + } + + func getTheme(reply: @escaping XPCReply) { + guard let ext = ext as? any ThemeExtension else { + reply(nil, XPCError.extensionDoesNotExist(description: String(describing: (any ThemeExtension).self))) + return + } + let id = "XcodeLightTheme" + guard let theme = ext.getTheme(with: id) else { + reply(nil, XPCError.identifierDoesNotExist(description: id)) + return + } + do { + let encoded = try JSONEncoder().encode(theme) + reply(encoded, nil) + } catch { + reply(nil, error) + } + } + + func doAction(with identifier: String, reply: @escaping XPCReply) { + + } +} diff --git a/Sources/CodeEditKit/Documentation.docc/Documentation.md b/Sources/CodeEditKitOld/Documentation.docc/Documentation.md similarity index 100% rename from Sources/CodeEditKit/Documentation.docc/Documentation.md rename to Sources/CodeEditKitOld/Documentation.docc/Documentation.md diff --git a/Sources/CodeEditKit/ExtensionAPI.swift b/Sources/CodeEditKitOld/ExtensionAPI.swift similarity index 100% rename from Sources/CodeEditKit/ExtensionAPI.swift rename to Sources/CodeEditKitOld/ExtensionAPI.swift diff --git a/Sources/CodeEditKit/ExtensionInterface.swift b/Sources/CodeEditKitOld/ExtensionInterface.swift similarity index 100% rename from Sources/CodeEditKit/ExtensionInterface.swift rename to Sources/CodeEditKitOld/ExtensionInterface.swift diff --git a/Sources/CodeEditKit/ExtensionManifest.swift b/Sources/CodeEditKitOld/ExtensionManifest.swift similarity index 100% rename from Sources/CodeEditKit/ExtensionManifest.swift rename to Sources/CodeEditKitOld/ExtensionManifest.swift diff --git a/Sources/CodeEditKit/Targets/Target.swift b/Sources/CodeEditKitOld/Targets/Target.swift similarity index 100% rename from Sources/CodeEditKit/Targets/Target.swift rename to Sources/CodeEditKitOld/Targets/Target.swift diff --git a/Sources/CodeEditKit/TargetsAPI.swift b/Sources/CodeEditKitOld/TargetsAPI.swift similarity index 100% rename from Sources/CodeEditKit/TargetsAPI.swift rename to Sources/CodeEditKitOld/TargetsAPI.swift diff --git a/Tests/CodeEditKitTests/Example/ExampleSidebar.swift b/Tests/CodeEditKitTests/Example/ExampleSidebar.swift new file mode 100644 index 0000000..d10c243 --- /dev/null +++ b/Tests/CodeEditKitTests/Example/ExampleSidebar.swift @@ -0,0 +1,17 @@ +// +// File.swift +// +// +// Created by Wouter Hennen on 30/12/2022. +// + +import SwiftUI +import CodeEditKit + +struct ExampleSidebar: SidebarItem { + var id: String = "TestTest" + var icon: String = "Test" + var body: some View { + Text("Piep") + } +} diff --git a/Tests/CodeEditKitTests/Example/ExampleToolbarItem.swift b/Tests/CodeEditKitTests/Example/ExampleToolbarItem.swift new file mode 100644 index 0000000..138bedd --- /dev/null +++ b/Tests/CodeEditKitTests/Example/ExampleToolbarItem.swift @@ -0,0 +1,19 @@ +// +// File.swift +// +// +// Created by Wouter Hennen on 30/12/2022. +// + +import SwiftUI +import CodeEditKit + +struct ExampleToolbarItem: CEToolbarItem { + var id: String = "PlayItem" + var placement: ToolbarItemPlacement = .principal + var body: some View { + Button("Test") { + + } + } +} diff --git a/Tests/CodeEditKitTests/Example/FirstExtension.swift b/Tests/CodeEditKitTests/Example/FirstExtension.swift new file mode 100644 index 0000000..deda8b3 --- /dev/null +++ b/Tests/CodeEditKitTests/Example/FirstExtension.swift @@ -0,0 +1,66 @@ +// +// File.swift +// +// +// Created by Wouter Hennen on 30/12/2022. +// + +import SwiftUI +import ExtensionKit +import CodeEditKit + +//@main +struct ExampleExtension: CodeEditExtension { + var description: String = "test" + + var entitlements: [Entitlement] = [.currentfile] + + var body: some AppExtensionScene { + sidebarScenes + toolbarItemScenes + } +} + +extension ExampleExtension: SidebarExtension { + var sidebars: [some SidebarItem] { + ExampleSidebar() + } +} + +extension ExampleExtension: ActionExtension { + var actions: [some CEAction] { + ShortcutAction(name: "Test") { + print("Blablabla") + } + + ShortcutAction(name: "Test2") { + print("Blablabla") + } + + ToolbarAction(name: "Test") { + print("Hello") + } + } +} + +extension ExampleExtension: ToolbarItemExtension { + var toolbaritems: [some CEToolbarItem] { + ExampleToolbarItem() + } +} + +extension ExampleExtension: ThemeExtension { + var themes: [some ThemeItem] { + XcodeLightTheme() + } +} + +struct XcodeLightTheme: ThemeItem { + var id: String = "XcodeLightTheme" + var name: String = "Xcode Light Theme" + var colors: [Color] = [.blue] +} + + + + From 8ced3f7d435c79a2287b7859a6c4ba8ec265df25 Mon Sep 17 00:00:00 2001 From: Wouter01 Date: Mon, 2 Jan 2023 01:58:10 +0100 Subject: [PATCH 02/30] Extension Settings Window + (temporary) move to SwiftUI App Lifecycle --- Sources/CodeEditKit/CEWorkspace.swift | 15 +++++++++++++++ .../{File.swift => CodableColorArray.swift} | 0 Sources/CodeEditKit/ExtensionKind.swift | 17 ++++++++++++++++- .../Settings/SettingsExtension.swift | 4 ++-- 4 files changed, 33 insertions(+), 3 deletions(-) create mode 100644 Sources/CodeEditKit/CEWorkspace.swift rename Sources/CodeEditKit/{File.swift => CodableColorArray.swift} (100%) diff --git a/Sources/CodeEditKit/CEWorkspace.swift b/Sources/CodeEditKit/CEWorkspace.swift new file mode 100644 index 0000000..00bf80e --- /dev/null +++ b/Sources/CodeEditKit/CEWorkspace.swift @@ -0,0 +1,15 @@ +// +// File.swift +// +// +// Created by Wouter Hennen on 30/12/2022. +// + +import Foundation + +@objc +protocol CEWorkSpaceObjc { + func didOpen() + + func willClose() +} diff --git a/Sources/CodeEditKit/File.swift b/Sources/CodeEditKit/CodableColorArray.swift similarity index 100% rename from Sources/CodeEditKit/File.swift rename to Sources/CodeEditKit/CodableColorArray.swift diff --git a/Sources/CodeEditKit/ExtensionKind.swift b/Sources/CodeEditKit/ExtensionKind.swift index a8cb3dc..09f98a9 100644 --- a/Sources/CodeEditKit/ExtensionKind.swift +++ b/Sources/CodeEditKit/ExtensionKind.swift @@ -7,12 +7,27 @@ import SwiftUI -public enum ExtensionKind: Codable { +public enum ExtensionKind: Codable, Hashable, CustomStringConvertible { case sidebarItem(sceneID: String) case toolbarItem(sceneID: String, placement: CEToolbarItemPlacement) case action(actionID: String) case theme(themeID: String) case settings + + public var description: String { + switch self { + case .sidebarItem(let sceneID): + return "Sidebar with ID \(sceneID)" + case .toolbarItem(let sceneID, let placement): + return "Toolbar Item with ID \(sceneID)" + case .action(let actionID): + return "Action with ID \(actionID)" + case .theme(let themeID): + return "Theme with ID \(themeID)" + case .settings: + return "Settings" + } + } } diff --git a/Sources/CodeEditKit/UIExtensions/Settings/SettingsExtension.swift b/Sources/CodeEditKit/UIExtensions/Settings/SettingsExtension.swift index 29ab670..713880b 100644 --- a/Sources/CodeEditKit/UIExtensions/Settings/SettingsExtension.swift +++ b/Sources/CodeEditKit/UIExtensions/Settings/SettingsExtension.swift @@ -9,14 +9,14 @@ import Foundation import SwiftUI import ExtensionKit -protocol SettingsExtension { +public protocol SettingsExtension { associatedtype SettingsBody: View @ViewBuilder var settings: SettingsBody { get } } -extension SettingsExtension { +public extension SettingsExtension { var settingsScene: some AppExtensionScene { GeneralSettingsScene { self.settings From b5180a918cd19f827dfc868b4bf2872f1dfc44f1 Mon Sep 17 00:00:00 2001 From: Wouter01 Date: Mon, 2 Jan 2023 15:13:54 +0100 Subject: [PATCH 03/30] - Fixed environment - Added extension Navigators to CodeEdit Window --- Sources/CodeEditKit/ExtensionKind.swift | 4 +-- .../GenericExtension/GenericExtension.swift | 25 +++++++++++++ Sources/CodeEditKit/GenericScene.swift | 35 +++++++++++++++++++ Sources/CodeEditKit/Nameable.swift | 19 ---------- .../NonUIExtensions/Actions/CEAction.swift | 4 +-- .../Actions/ShortcutAction.swift | 11 +++--- .../Actions/ToolbarAction.swift | 10 +++--- .../Theme/ThemeExtension.swift | 10 +++--- .../NonUIExtensions/Theme/ThemeItem.swift | 4 +-- .../Environment/CEEnvironmentModifier.swift | 26 ++++++++++++++ .../Settings/GeneralSettingsScene.swift | 1 + .../Settings/SettingsExtension.swift | 7 ++-- .../UIExtensions/Sidebar/Examples.swift | 8 +++-- .../Sidebar/SidebarExtension.swift | 12 +++---- .../UIExtensions/Sidebar/SidebarItem.swift | 16 +++++++-- .../ToolbarItem/CEToolbarItem.swift | 7 +--- .../ToolbarItem/ToolbarItemExtension.swift | 2 +- 17 files changed, 142 insertions(+), 59 deletions(-) create mode 100644 Sources/CodeEditKit/GenericExtension/GenericExtension.swift create mode 100644 Sources/CodeEditKit/GenericScene.swift delete mode 100644 Sources/CodeEditKit/Nameable.swift create mode 100644 Sources/CodeEditKit/UIExtensions/Environment/CEEnvironmentModifier.swift diff --git a/Sources/CodeEditKit/ExtensionKind.swift b/Sources/CodeEditKit/ExtensionKind.swift index 09f98a9..2a650cf 100644 --- a/Sources/CodeEditKit/ExtensionKind.swift +++ b/Sources/CodeEditKit/ExtensionKind.swift @@ -8,7 +8,7 @@ import SwiftUI public enum ExtensionKind: Codable, Hashable, CustomStringConvertible { - case sidebarItem(sceneID: String) + case sidebarItem(sceneID: String, icon: String) case toolbarItem(sceneID: String, placement: CEToolbarItemPlacement) case action(actionID: String) case theme(themeID: String) @@ -16,7 +16,7 @@ public enum ExtensionKind: Codable, Hashable, CustomStringConvertible { public var description: String { switch self { - case .sidebarItem(let sceneID): + case .sidebarItem(let sceneID, _): return "Sidebar with ID \(sceneID)" case .toolbarItem(let sceneID, let placement): return "Toolbar Item with ID \(sceneID)" diff --git a/Sources/CodeEditKit/GenericExtension/GenericExtension.swift b/Sources/CodeEditKit/GenericExtension/GenericExtension.swift new file mode 100644 index 0000000..0b24a5c --- /dev/null +++ b/Sources/CodeEditKit/GenericExtension/GenericExtension.swift @@ -0,0 +1,25 @@ +// +// File.swift +// +// +// Created by Wouter Hennen on 02/01/2023. +// + +import Foundation +import SequenceBuilder + +public protocol GenericExtension: Identifiable, CustomStringConvertible where ID == String { + var label: String { get } +} + +public extension GenericExtension { + var id: String { + String(describing: Self.self) + } +} + +extension Either: GenericExtension where Left: GenericExtension, Right: GenericExtension { + public var label: String { + fold(left: \.label, right: \.label) + } +} diff --git a/Sources/CodeEditKit/GenericScene.swift b/Sources/CodeEditKit/GenericScene.swift new file mode 100644 index 0000000..d15621a --- /dev/null +++ b/Sources/CodeEditKit/GenericScene.swift @@ -0,0 +1,35 @@ +// +// File.swift +// +// +// Created by Wouter Hennen on 02/01/2023. +// + +import SwiftUI +import ExtensionKit + +struct GenericScene: AppExtensionScene { + + var sceneID: String + + @ViewBuilder + var content: Content + + var environmentWrapper = EnvironmentPublisher() + + var body: some AppExtensionScene { + PrimitiveAppExtensionScene(id: sceneID) { + GeneralSettingsView(environmentWrapper: environmentWrapper) { + content + } + } onConnection: { connection in + connection.exportedInterface = .init(with: EnvironmentPublisherObjc.self) + connection.exportedObject = environmentWrapper + + connection.resume() + + return true + } + } +} + diff --git a/Sources/CodeEditKit/Nameable.swift b/Sources/CodeEditKit/Nameable.swift deleted file mode 100644 index 00ff195..0000000 --- a/Sources/CodeEditKit/Nameable.swift +++ /dev/null @@ -1,19 +0,0 @@ -// -// File.swift -// -// -// Created by Wouter Hennen on 30/12/2022. -// - -import Foundation -import SequenceBuilder - -public protocol Nameable { - var name: String { get } -} - -extension Either: Nameable where Left: Nameable, Right: Nameable { - public var name: String { - fold(left: \.name, right: \.name) - } -} diff --git a/Sources/CodeEditKit/NonUIExtensions/Actions/CEAction.swift b/Sources/CodeEditKit/NonUIExtensions/Actions/CEAction.swift index b9bd767..61c9b99 100644 --- a/Sources/CodeEditKit/NonUIExtensions/Actions/CEAction.swift +++ b/Sources/CodeEditKit/NonUIExtensions/Actions/CEAction.swift @@ -7,10 +7,8 @@ import Foundation -public protocol CEAction: Identifiable, Nameable where ID == String { +public protocol CEAction: GenericExtension { - var id: ID { get } - var name: String { get } var kind: ActionKind { get } var action: () -> Void { get } } diff --git a/Sources/CodeEditKit/NonUIExtensions/Actions/ShortcutAction.swift b/Sources/CodeEditKit/NonUIExtensions/Actions/ShortcutAction.swift index 6acafaf..d4c5d07 100644 --- a/Sources/CodeEditKit/NonUIExtensions/Actions/ShortcutAction.swift +++ b/Sources/CodeEditKit/NonUIExtensions/Actions/ShortcutAction.swift @@ -10,13 +10,16 @@ import Foundation public struct ShortcutAction: CEAction { public var kind: ActionKind = .shortcut - public var name: String - public var id: String { "shortcut\(name)"} + public var label: String + public var id: String { "shortcut\(label)"} + + public var description: String public var action: () -> Void - public init(name: String, action: @escaping () -> Void) { - self.name = name + public init(_ label: String, description: String = "Short description", action: @escaping () -> Void) { + self.label = label + self.description = description self.action = action } } diff --git a/Sources/CodeEditKit/NonUIExtensions/Actions/ToolbarAction.swift b/Sources/CodeEditKit/NonUIExtensions/Actions/ToolbarAction.swift index 9f773a7..84988e6 100644 --- a/Sources/CodeEditKit/NonUIExtensions/Actions/ToolbarAction.swift +++ b/Sources/CodeEditKit/NonUIExtensions/Actions/ToolbarAction.swift @@ -10,13 +10,15 @@ import Foundation public struct ToolbarAction: CEAction { public var kind: ActionKind = .toolbar - public var name: String - public var id: String { "toolbar\(name)"} + public var label: String + public var id: String { "toolbar\(label)"} + public var description: String public var action: () -> Void - public init(name: String, action: @escaping () -> Void) { - self.name = name + public init(_ label: String, description: String = "Toolbar action", action: @escaping () -> Void) { + self.label = label + self.description = description self.action = action } } diff --git a/Sources/CodeEditKit/NonUIExtensions/Theme/ThemeExtension.swift b/Sources/CodeEditKit/NonUIExtensions/Theme/ThemeExtension.swift index 24e7362..efa6ea9 100644 --- a/Sources/CodeEditKit/NonUIExtensions/Theme/ThemeExtension.swift +++ b/Sources/CodeEditKit/NonUIExtensions/Theme/ThemeExtension.swift @@ -28,16 +28,18 @@ extension ThemeExtension { public struct GeneralThemeItem: ThemeItem, Codable { public var id: String - public var name: String + public var label: String + public var description: String @CodableColorArray public var colors: [NSColor] - public init(id: String, name: String, colors: [NSColor]) { + public init(id: String, label: String, description: String = "Generic Theme", colors: [NSColor]) { self.id = id - self.name = name + self.label = label + self.description = description self.colors = colors } init(_ theme: any ThemeItem) { - self.init(id: theme.id, name: theme.name, colors: theme.colors) + self.init(id: theme.id, label: theme.label, description: theme.description, colors: theme.colors) } } diff --git a/Sources/CodeEditKit/NonUIExtensions/Theme/ThemeItem.swift b/Sources/CodeEditKit/NonUIExtensions/Theme/ThemeItem.swift index 4d631fb..bceea84 100644 --- a/Sources/CodeEditKit/NonUIExtensions/Theme/ThemeItem.swift +++ b/Sources/CodeEditKit/NonUIExtensions/Theme/ThemeItem.swift @@ -7,8 +7,6 @@ import SwiftUI -public protocol ThemeItem: Identifiable, Nameable where ID == String { - var id: ID { get } - var name: String { get } +public protocol ThemeItem: GenericExtension { var colors: [NSColor] { get } } diff --git a/Sources/CodeEditKit/UIExtensions/Environment/CEEnvironmentModifier.swift b/Sources/CodeEditKit/UIExtensions/Environment/CEEnvironmentModifier.swift new file mode 100644 index 0000000..dc117e2 --- /dev/null +++ b/Sources/CodeEditKit/UIExtensions/Environment/CEEnvironmentModifier.swift @@ -0,0 +1,26 @@ +// +// File.swift +// +// +// Created by Wouter Hennen on 02/01/2023. +// + +import SwiftUI + +public struct CEEnvironmentModifier: ViewModifier { + var keyPath: WritableKeyPath<_CEEnvironment, Value> + var value: Value + + public func body(content: Content) -> some View { + content + .transformEnvironment(\._ceEnvironment) { env in + env.update(keyPath, value) + } + } +} + +public extension View { + func ceEnvironment(_ keyPath: WritableKeyPath<_CEEnvironment, Value>, _ value: Value) -> some View { + return modifier(CEEnvironmentModifier(keyPath: keyPath, value: value)) + } +} diff --git a/Sources/CodeEditKit/UIExtensions/Settings/GeneralSettingsScene.swift b/Sources/CodeEditKit/UIExtensions/Settings/GeneralSettingsScene.swift index a4f00f0..075d2a9 100644 --- a/Sources/CodeEditKit/UIExtensions/Settings/GeneralSettingsScene.swift +++ b/Sources/CodeEditKit/UIExtensions/Settings/GeneralSettingsScene.swift @@ -9,6 +9,7 @@ import Foundation import SwiftUI import ExtensionKit + struct GeneralSettingsScene: AppExtensionScene { @ViewBuilder diff --git a/Sources/CodeEditKit/UIExtensions/Settings/SettingsExtension.swift b/Sources/CodeEditKit/UIExtensions/Settings/SettingsExtension.swift index 713880b..1ca33d2 100644 --- a/Sources/CodeEditKit/UIExtensions/Settings/SettingsExtension.swift +++ b/Sources/CodeEditKit/UIExtensions/Settings/SettingsExtension.swift @@ -18,8 +18,11 @@ public protocol SettingsExtension { public extension SettingsExtension { var settingsScene: some AppExtensionScene { - GeneralSettingsScene { - self.settings + GenericScene(sceneID: "Settings") { + Form { + self.settings + } + .formStyle(.grouped) } } } diff --git a/Sources/CodeEditKit/UIExtensions/Sidebar/Examples.swift b/Sources/CodeEditKit/UIExtensions/Sidebar/Examples.swift index 669e7f9..d09e2b2 100644 --- a/Sources/CodeEditKit/UIExtensions/Sidebar/Examples.swift +++ b/Sources/CodeEditKit/UIExtensions/Sidebar/Examples.swift @@ -9,16 +9,20 @@ import Foundation import SwiftUI struct DefaultNavigator: SidebarItem { - var id: String = "TestTest" var icon: String = "Test" + + var label: String = "Test" + + var description: String = "Short description" var body: some View { Text("Piep") } } struct DefaultNavigator2: SidebarItem { - var id: String = "Hello" var icon: String = "Test" + var label: String = "Default Navigator 2" + var description: String = "blablabla" var body: some View { Text("Piep2") } diff --git a/Sources/CodeEditKit/UIExtensions/Sidebar/SidebarExtension.swift b/Sources/CodeEditKit/UIExtensions/Sidebar/SidebarExtension.swift index 5e37fe7..426ac06 100644 --- a/Sources/CodeEditKit/UIExtensions/Sidebar/SidebarExtension.swift +++ b/Sources/CodeEditKit/UIExtensions/Sidebar/SidebarExtension.swift @@ -8,6 +8,7 @@ import Foundation import SequenceBuilder import ExtensionKit +import SwiftUI public protocol SidebarExtension { @@ -17,17 +18,14 @@ public protocol SidebarExtension { var sidebars: SidebarBody { get } } + + public extension SidebarExtension { var sidebarScenes: some AppExtensionScene { - - sidebars.map { item in - PrimitiveAppExtensionScene(id: item.id) { - item.body - } - } + sidebars.map(\.scene) } var availableExtensions: [ExtensionKind] { - sidebars.map { ExtensionKind.sidebarItem(sceneID: $0.id) } + sidebars.map { ExtensionKind.sidebarItem(sceneID: $0.id, icon: $0.icon) } } } diff --git a/Sources/CodeEditKit/UIExtensions/Sidebar/SidebarItem.swift b/Sources/CodeEditKit/UIExtensions/Sidebar/SidebarItem.swift index 6713ab0..7df92af 100644 --- a/Sources/CodeEditKit/UIExtensions/Sidebar/SidebarItem.swift +++ b/Sources/CodeEditKit/UIExtensions/Sidebar/SidebarItem.swift @@ -7,8 +7,20 @@ import Foundation import SwiftUI +import ExtensionKit -public protocol SidebarItem: View, Identifiable where ID == String { - var id: ID { get } +public protocol SidebarItem: View, GenericExtension { var icon: String { get } } + +extension SidebarItem { + var scene: some AppExtensionScene { + PrimitiveAppExtensionScene(id: id) { + VStack(alignment: .leading) { + self + .scrollContentBackground(.hidden) + } + .frame(maxWidth: .infinity, maxHeight: .infinity) + } + } +} diff --git a/Sources/CodeEditKit/UIExtensions/ToolbarItem/CEToolbarItem.swift b/Sources/CodeEditKit/UIExtensions/ToolbarItem/CEToolbarItem.swift index bfae158..7ae5803 100644 --- a/Sources/CodeEditKit/UIExtensions/ToolbarItem/CEToolbarItem.swift +++ b/Sources/CodeEditKit/UIExtensions/ToolbarItem/CEToolbarItem.swift @@ -8,15 +8,10 @@ import Foundation import SwiftUI -public protocol CEToolbarItem: View, Identifiable where ID == String { - var id: ID { get } +public protocol CEToolbarItem: View, GenericExtension { var placement: CEToolbarItemPlacement { get } } extension CEToolbarItem { - var mappedID: String { - "CEToolbarItem_\(id)" - } - public var placement: CEToolbarItemPlacement { .automatic } } diff --git a/Sources/CodeEditKit/UIExtensions/ToolbarItem/ToolbarItemExtension.swift b/Sources/CodeEditKit/UIExtensions/ToolbarItem/ToolbarItemExtension.swift index cb2118e..21da061 100644 --- a/Sources/CodeEditKit/UIExtensions/ToolbarItem/ToolbarItemExtension.swift +++ b/Sources/CodeEditKit/UIExtensions/ToolbarItem/ToolbarItemExtension.swift @@ -20,7 +20,7 @@ public protocol ToolbarItemExtension { extension ToolbarItemExtension { public var toolbarItemScenes: some AppExtensionScene { toolbaritems.map { nav in - PrimitiveAppExtensionScene(id: nav.mappedID) { + PrimitiveAppExtensionScene(id: nav.id) { nav.body } } From 96750ceb143d71ff0cec8b2876db01a77134b5c5 Mon Sep 17 00:00:00 2001 From: Wouter01 Date: Tue, 3 Jan 2023 01:59:20 +0100 Subject: [PATCH 04/30] Added openWindow environment value for extensions Signed-off-by: Wouter01 --- Package.swift | 3 ++- Sources/CodeEditKit/GenericScene.swift | 12 ++++++++++- .../Environment/CEEnvironment.swift | 1 + .../EnvironmentObjcPublisher.swift | 14 +++++++++++-- .../UIExtensions/Environment/File.swift | 20 +++++++++++++++++++ .../UIExtensions/Sidebar/SidebarItem.swift | 1 + 6 files changed, 47 insertions(+), 4 deletions(-) create mode 100644 Sources/CodeEditKit/UIExtensions/Environment/File.swift diff --git a/Package.swift b/Package.swift index 56aeda7..c053847 100644 --- a/Package.swift +++ b/Package.swift @@ -15,6 +15,7 @@ let package = Package( ], dependencies: [ .package(url: "https://github.com/andtie/SequenceBuilder", branch: "main"), + .package(url: "https://github.com/ChimeHQ/ConcurrencyPlus", branch: "main"), .package( url: "https://github.com/Flight-School/AnyCodable", from: "0.6.0" @@ -23,7 +24,7 @@ let package = Package( targets: [ .target( name: "CodeEditKit", - dependencies: ["SequenceBuilder", "AnyCodable"]), + dependencies: ["SequenceBuilder", "AnyCodable", "ConcurrencyPlus"]), .target(name: "CodeEditKitOld"), .testTarget( name: "CodeEditKitTests", diff --git a/Sources/CodeEditKit/GenericScene.swift b/Sources/CodeEditKit/GenericScene.swift index d15621a..e50cc22 100644 --- a/Sources/CodeEditKit/GenericScene.swift +++ b/Sources/CodeEditKit/GenericScene.swift @@ -8,6 +8,10 @@ import SwiftUI import ExtensionKit +public enum Callbacks: Codable { + case openWindow(id: String) +} + struct GenericScene: AppExtensionScene { var sceneID: String @@ -17,15 +21,21 @@ struct GenericScene: AppExtensionScene { var environmentWrapper = EnvironmentPublisher() + var connection: NSXPCConnection? + var body: some AppExtensionScene { PrimitiveAppExtensionScene(id: sceneID) { GeneralSettingsView(environmentWrapper: environmentWrapper) { content + .environment(\.ceOpenWindow) { id in + try await environmentWrapper.update(callback: .openWindow(id: id)) + } } } onConnection: { connection in connection.exportedInterface = .init(with: EnvironmentPublisherObjc.self) + connection.remoteObjectInterface = .init(with: EnvironmentPublisherObjc.self) connection.exportedObject = environmentWrapper - + environmentWrapper.connection = connection connection.resume() return true diff --git a/Sources/CodeEditKit/UIExtensions/Environment/CEEnvironment.swift b/Sources/CodeEditKit/UIExtensions/Environment/CEEnvironment.swift index e60a0dc..552d3b0 100644 --- a/Sources/CodeEditKit/UIExtensions/Environment/CEEnvironment.swift +++ b/Sources/CodeEditKit/UIExtensions/Environment/CEEnvironment.swift @@ -10,6 +10,7 @@ import AnyCodable import SwiftUI public struct _CEEnvironment: Codable, Equatable { + public var test = false public var complexValue: Array = [] diff --git a/Sources/CodeEditKit/UIExtensions/Environment/EnvironmentObjcPublisher.swift b/Sources/CodeEditKit/UIExtensions/Environment/EnvironmentObjcPublisher.swift index df01f30..2a0ae24 100644 --- a/Sources/CodeEditKit/UIExtensions/Environment/EnvironmentObjcPublisher.swift +++ b/Sources/CodeEditKit/UIExtensions/Environment/EnvironmentObjcPublisher.swift @@ -6,21 +6,31 @@ // import Foundation +import ConcurrencyPlus @objc public protocol EnvironmentPublisherObjc { func publishEnvironment(data: Data) } - public class EnvironmentPublisher: ObservableObject, EnvironmentPublisherObjc { @Published var environment = _CEEnvironment() - public init() {} + var connection: NSXPCConnection? + + /// Send callbacks from functions + func update(@Encoded callback: Callbacks) async throws { + guard let $callback else { return } + try await connection!.withService { (service: EnvironmentPublisherObjc) in + service.publishEnvironment(data: $callback) + } + } public func publishEnvironment(@Decoded<_CEEnvironment> data: Data) { guard let $data else { return } environment = $data + print("update: received data \($data)") } } + diff --git a/Sources/CodeEditKit/UIExtensions/Environment/File.swift b/Sources/CodeEditKit/UIExtensions/Environment/File.swift new file mode 100644 index 0000000..ae06adf --- /dev/null +++ b/Sources/CodeEditKit/UIExtensions/Environment/File.swift @@ -0,0 +1,20 @@ +// +// File.swift +// +// +// Created by Wouter Hennen on 02/01/2023. +// + +import Foundation +import SwiftUI + +public struct CEOpenWindowEnvKey: EnvironmentKey { + public static var defaultValue: (String) async throws -> Void = { _ in } +} + +public extension EnvironmentValues { + var ceOpenWindow: CEOpenWindowEnvKey.Value { + get { self[CEOpenWindowEnvKey.self] } + set { self[CEOpenWindowEnvKey.self] = newValue } + } +} diff --git a/Sources/CodeEditKit/UIExtensions/Sidebar/SidebarItem.swift b/Sources/CodeEditKit/UIExtensions/Sidebar/SidebarItem.swift index 7df92af..0d607d5 100644 --- a/Sources/CodeEditKit/UIExtensions/Sidebar/SidebarItem.swift +++ b/Sources/CodeEditKit/UIExtensions/Sidebar/SidebarItem.swift @@ -16,6 +16,7 @@ public protocol SidebarItem: View, GenericExtension { extension SidebarItem { var scene: some AppExtensionScene { PrimitiveAppExtensionScene(id: id) { + VStack(alignment: .leading) { self .scrollContentBackground(.hidden) From 218de3f01e33b31fc71d33d4ea42e76ed8391e2a Mon Sep 17 00:00:00 2001 From: Wouter01 Date: Tue, 3 Jan 2023 02:27:39 +0100 Subject: [PATCH 05/30] Fixed examples Signed-off-by: Wouter01 --- .../CodeEditKit/Documentation.docc/Commands.md | 13 +++++++++++++ .../Documentation.docc/Documentation.md | 0 .../Example/ExampleSidebar.swift | 5 +++-- .../Example/ExampleToolbarItem.swift | 5 ++++- .../Example/FirstExtension.swift | 16 ++++++++++------ 5 files changed, 30 insertions(+), 9 deletions(-) create mode 100644 Sources/CodeEditKit/Documentation.docc/Commands.md rename Sources/{CodeEditKitOld => CodeEditKit}/Documentation.docc/Documentation.md (100%) diff --git a/Sources/CodeEditKit/Documentation.docc/Commands.md b/Sources/CodeEditKit/Documentation.docc/Commands.md new file mode 100644 index 0000000..f6120d2 --- /dev/null +++ b/Sources/CodeEditKit/Documentation.docc/Commands.md @@ -0,0 +1,13 @@ +# Commands + +Summary + +## Overview + +Text + +## Topics + +### Group + +- ``Symbol`` diff --git a/Sources/CodeEditKitOld/Documentation.docc/Documentation.md b/Sources/CodeEditKit/Documentation.docc/Documentation.md similarity index 100% rename from Sources/CodeEditKitOld/Documentation.docc/Documentation.md rename to Sources/CodeEditKit/Documentation.docc/Documentation.md diff --git a/Tests/CodeEditKitTests/Example/ExampleSidebar.swift b/Tests/CodeEditKitTests/Example/ExampleSidebar.swift index d10c243..fcf63f9 100644 --- a/Tests/CodeEditKitTests/Example/ExampleSidebar.swift +++ b/Tests/CodeEditKitTests/Example/ExampleSidebar.swift @@ -9,8 +9,9 @@ import SwiftUI import CodeEditKit struct ExampleSidebar: SidebarItem { - var id: String = "TestTest" - var icon: String = "Test" + var icon: String = "star" + var label: String = "Example Sidebar" + var description: String = "This is a description of the sidebar" var body: some View { Text("Piep") } diff --git a/Tests/CodeEditKitTests/Example/ExampleToolbarItem.swift b/Tests/CodeEditKitTests/Example/ExampleToolbarItem.swift index 138bedd..b2a93ee 100644 --- a/Tests/CodeEditKitTests/Example/ExampleToolbarItem.swift +++ b/Tests/CodeEditKitTests/Example/ExampleToolbarItem.swift @@ -9,7 +9,10 @@ import SwiftUI import CodeEditKit struct ExampleToolbarItem: CEToolbarItem { - var id: String = "PlayItem" + var label: String = "Example Toolbar" + + var description: String = "This is the description" + var placement: ToolbarItemPlacement = .principal var body: some View { Button("Test") { diff --git a/Tests/CodeEditKitTests/Example/FirstExtension.swift b/Tests/CodeEditKitTests/Example/FirstExtension.swift index deda8b3..3c8e0fb 100644 --- a/Tests/CodeEditKitTests/Example/FirstExtension.swift +++ b/Tests/CodeEditKitTests/Example/FirstExtension.swift @@ -29,15 +29,16 @@ extension ExampleExtension: SidebarExtension { extension ExampleExtension: ActionExtension { var actions: [some CEAction] { - ShortcutAction(name: "Test") { + + ShortcutAction("Test") { print("Blablabla") } - ShortcutAction(name: "Test2") { + ShortcutAction("Test2") { print("Blablabla") } - ToolbarAction(name: "Test") { + ToolbarAction("Test") { print("Hello") } } @@ -56,9 +57,12 @@ extension ExampleExtension: ThemeExtension { } struct XcodeLightTheme: ThemeItem { - var id: String = "XcodeLightTheme" - var name: String = "Xcode Light Theme" - var colors: [Color] = [.blue] + + var label: String = "Xcode Light Theme" + + var description: String = "This is the Xcode light theme" + + var colors: [NSColor] = [.blue] } From f57fbfff35f09ff1e7f4fe3b7992355398f92e49 Mon Sep 17 00:00:00 2001 From: Wouter01 Date: Tue, 3 Jan 2023 02:27:49 +0100 Subject: [PATCH 06/30] added some documentation Signed-off-by: Wouter01 --- Package.resolved | 32 +++++++++++++++++++ .../Documentation.docc/Commands.md | 4 +-- .../Documentation.docc/Documentation.md | 11 +++++-- 3 files changed, 43 insertions(+), 4 deletions(-) create mode 100644 Package.resolved diff --git a/Package.resolved b/Package.resolved new file mode 100644 index 0000000..018481d --- /dev/null +++ b/Package.resolved @@ -0,0 +1,32 @@ +{ + "pins" : [ + { + "identity" : "anycodable", + "kind" : "remoteSourceControl", + "location" : "https://github.com/Flight-School/AnyCodable", + "state" : { + "revision" : "862808b2070cd908cb04f9aafe7de83d35f81b05", + "version" : "0.6.7" + } + }, + { + "identity" : "concurrencyplus", + "kind" : "remoteSourceControl", + "location" : "https://github.com/ChimeHQ/ConcurrencyPlus", + "state" : { + "branch" : "main", + "revision" : "b5ba8d5ea6bfe9e43ccc44aa63f9b458057fa0f4" + } + }, + { + "identity" : "sequencebuilder", + "kind" : "remoteSourceControl", + "location" : "https://github.com/andtie/SequenceBuilder", + "state" : { + "branch" : "main", + "revision" : "54d3d1eff31a7e35122f616840fff11899ea85b4" + } + } + ], + "version" : 2 +} diff --git a/Sources/CodeEditKit/Documentation.docc/Commands.md b/Sources/CodeEditKit/Documentation.docc/Commands.md index f6120d2..1652e2b 100644 --- a/Sources/CodeEditKit/Documentation.docc/Commands.md +++ b/Sources/CodeEditKit/Documentation.docc/Commands.md @@ -1,10 +1,10 @@ # Commands -Summary +Quick actions ## Overview -Text +Blablabla ## Topics diff --git a/Sources/CodeEditKit/Documentation.docc/Documentation.md b/Sources/CodeEditKit/Documentation.docc/Documentation.md index 36bb499..1cc176e 100644 --- a/Sources/CodeEditKit/Documentation.docc/Documentation.md +++ b/Sources/CodeEditKit/Documentation.docc/Documentation.md @@ -4,6 +4,13 @@ CodeEditKit is a dynamic library which is shared between CodeEdit and it's exten ## Overview -This is still work in progress. +Extensions are an essential part of CodeEdit. They can extend the languages CodeEdit supports, add custom actions and behaviors, and even provide custom views of certain data. + +### Extension Types + +There are lots of extension types you can use to extend the functionality of CodeEdit. + +- +- Sidebars +- Test -> See [this thread](https://github.com/orgs/CodeEditApp/discussions/792) for more information. From 54dbb48a7c190b2d606ac1a3524607884783d910 Mon Sep 17 00:00:00 2001 From: Wouter01 Date: Tue, 3 Jan 2023 02:30:23 +0100 Subject: [PATCH 07/30] removed old target Signed-off-by: Wouter01 --- Package.swift | 3 +- Sources/CodeEditKitOld/ExtensionAPI.swift | 19 ------- .../CodeEditKitOld/ExtensionInterface.swift | 24 --------- .../CodeEditKitOld/ExtensionManifest.swift | 16 ------ Sources/CodeEditKitOld/Targets/Target.swift | 54 ------------------- Sources/CodeEditKitOld/TargetsAPI.swift | 24 --------- 6 files changed, 1 insertion(+), 139 deletions(-) delete mode 100644 Sources/CodeEditKitOld/ExtensionAPI.swift delete mode 100644 Sources/CodeEditKitOld/ExtensionInterface.swift delete mode 100644 Sources/CodeEditKitOld/ExtensionManifest.swift delete mode 100644 Sources/CodeEditKitOld/Targets/Target.swift delete mode 100644 Sources/CodeEditKitOld/TargetsAPI.swift diff --git a/Package.swift b/Package.swift index c053847..017b33b 100644 --- a/Package.swift +++ b/Package.swift @@ -11,7 +11,7 @@ let package = Package( .library( name: "CodeEditKit", type: .dynamic, - targets: ["CodeEditKit", "CodeEditKitOld"]), + targets: ["CodeEditKit"]), ], dependencies: [ .package(url: "https://github.com/andtie/SequenceBuilder", branch: "main"), @@ -25,7 +25,6 @@ let package = Package( .target( name: "CodeEditKit", dependencies: ["SequenceBuilder", "AnyCodable", "ConcurrencyPlus"]), - .target(name: "CodeEditKitOld"), .testTarget( name: "CodeEditKitTests", dependencies: ["CodeEditKit"]), diff --git a/Sources/CodeEditKitOld/ExtensionAPI.swift b/Sources/CodeEditKitOld/ExtensionAPI.swift deleted file mode 100644 index 12ab798..0000000 --- a/Sources/CodeEditKitOld/ExtensionAPI.swift +++ /dev/null @@ -1,19 +0,0 @@ -// -// ExtensionAPI.swift -// -// -// Created by Pavel Kasila on 27.03.22. -// - -import Foundation - -/// A protocol to conform to for Extension API instance assigned to ``extensionId`` -public protocol ExtensionAPI { - - var extensionId: String { get } - var workspaceURL: URL { get } - - /// API to work with targets - var targets: TargetsAPI { get } - -} diff --git a/Sources/CodeEditKitOld/ExtensionInterface.swift b/Sources/CodeEditKitOld/ExtensionInterface.swift deleted file mode 100644 index 2584a28..0000000 --- a/Sources/CodeEditKitOld/ExtensionInterface.swift +++ /dev/null @@ -1,24 +0,0 @@ -// -// ExtensionInterface.swift -// -// -// Created by Pavel Kasila on 27.03.22. -// - -import Foundation - -/// A protocol for extensions to conform to -public protocol ExtensionInterface { -} - -open class ExtensionBuilder: NSObject { - required public override init() { - super.init() - } - - /// Builds extension with API - /// - Parameter withAPI: the API implementation itself - open func build(withAPI api: ExtensionAPI) -> ExtensionInterface { - fatalError("You should override ExtensionBuilder.build") - } -} diff --git a/Sources/CodeEditKitOld/ExtensionManifest.swift b/Sources/CodeEditKitOld/ExtensionManifest.swift deleted file mode 100644 index a87c84f..0000000 --- a/Sources/CodeEditKitOld/ExtensionManifest.swift +++ /dev/null @@ -1,16 +0,0 @@ -// -// ExtensionManifest.swift -// -// -// Created by Pavel Kasila on 27.03.22. -// - -import Foundation - -public struct ExtensionManifest: Codable, Hashable { - public var name: String - public var displayName: String - public var homepage: URL? - public var repository: URL? - public var issues: URL? -} diff --git a/Sources/CodeEditKitOld/Targets/Target.swift b/Sources/CodeEditKitOld/Targets/Target.swift deleted file mode 100644 index c41aebf..0000000 --- a/Sources/CodeEditKitOld/Targets/Target.swift +++ /dev/null @@ -1,54 +0,0 @@ -// -// Target.swift -// -// -// Created by Pavel Kasila on 27.03.22. -// - -import Foundation - -/// This structure stores information about the target to be available in CodeEdit for running -public struct Target: Identifiable { - - /** - * Initializes a target with parameters - * - Parameter id: The unique identifier of the target set by the extension - * - Parameter displayName: The name of the target to be displayed in the UI - * - Parameter executable: The executable to launch inside the pseudo terminal - * - Parameter args: an array of strings that is passed as the arguments to the underlying process - * - Parameter environment: an array of environment variables to pass to the child process. - * - Parameter execName: If provided, this is used as the Unix argv[0] parameter, otherwise, - * the executable is used as the args [0], this is used when the intent is to set a different process name - * than the file that backs it. - */ - public init(id: String, displayName: String, - executable: String, args: [String] = [], - environment: [String]? = nil, execName: String? = nil) { - self.id = id - self.displayName = displayName - self.executable = executable - self.args = args - self.environment = environment - self.execName = execName - } - - /// `id` is a unique identifier of the target set by the extension - public var id: String - - /// `displayName` is a name to be displayed in the UI to represent target - public var displayName: String - - /// `executable` is the executable to launch inside the pseudo terminal - public var executable: String - - /// `args` is an array of strings that is passed as the arguments to the underlying process - public var args: [String] = [] - - /// `environment` is an array of environment variables to pass to the child process. - public var environment: [String]? - - /// `execName` If provided, this is used as the Unix argv[0] parameter, otherwise, - /// the executable is used as the args [0], this is used when the intent is to set a different - /// process name than the file that backs it. - public var execName: String? -} diff --git a/Sources/CodeEditKitOld/TargetsAPI.swift b/Sources/CodeEditKitOld/TargetsAPI.swift deleted file mode 100644 index 4de0897..0000000 --- a/Sources/CodeEditKitOld/TargetsAPI.swift +++ /dev/null @@ -1,24 +0,0 @@ -// -// TargetsAPI.swift -// -// -// Created by Pavel Kasila on 27.03.22. -// - -import Foundation - -/// API for targets -public protocol TargetsAPI { - - /// Adds new target to the list - /// - Parameter target: the target to be added to the list - func add(target: Target) - - /// Deletes a target from the list - /// - Parameter target: the target to be removed from the list - func delete(target: Target) - - /// Clears all targets from the list - func clear() - -} From a8cbc5b8d2e908197dce18c911ad6cb1b2c45dfc Mon Sep 17 00:00:00 2001 From: Wouter01 Date: Tue, 3 Jan 2023 05:49:06 +0100 Subject: [PATCH 08/30] CodeEditExtension protocol changes - Added default body implementation - Added ObservableObject requirement - Moved from @main struct to @main final class Signed-off-by: Wouter01 --- .../CodeEditKit/CodeEditExtension+Body.swift | 61 +++++++++++++++++++ Sources/CodeEditKit/CodeEditExtension.swift | 25 +++++++- .../Settings/SettingsExtension.swift | 3 +- .../Sidebar/SidebarExtension.swift | 4 +- .../UIExtensions/Sidebar/SidebarItem.swift | 4 +- .../ToolbarItem/ToolbarItemExtension.swift | 3 +- .../Example/FirstExtension.swift | 22 ++++--- 7 files changed, 106 insertions(+), 16 deletions(-) create mode 100644 Sources/CodeEditKit/CodeEditExtension+Body.swift diff --git a/Sources/CodeEditKit/CodeEditExtension+Body.swift b/Sources/CodeEditKit/CodeEditExtension+Body.swift new file mode 100644 index 0000000..04cf7b1 --- /dev/null +++ b/Sources/CodeEditKit/CodeEditExtension+Body.swift @@ -0,0 +1,61 @@ +// +// File.swift +// +// +// Created by Wouter Hennen on 03/01/2023. +// + +import Foundation +import SequenceBuilder +import ExtensionKit + +public extension CodeEditExtension where Self: SettingsExtension { + var body: some AppExtensionScene { + settingsScene + } +} + +public extension CodeEditExtension where Self: SidebarExtension { + var body: some AppExtensionScene { + sidebarScenes + } +} + +public extension CodeEditExtension where Self: ToolbarItemExtension { + var body: some AppExtensionScene { + toolbarItemScenes + } +} + +public extension CodeEditExtension where Self: SettingsExtension & SidebarExtension { + @AppExtensionSceneBuilder + var body: some AppExtensionScene { + settingsScene + sidebarScenes + } +} + +public extension CodeEditExtension where Self: SettingsExtension & ToolbarItemExtension { + @AppExtensionSceneBuilder + var body: some AppExtensionScene { + settingsScene + toolbarItemScenes + } +} + +public extension CodeEditExtension where Self: SidebarExtension & ToolbarItemExtension { + @AppExtensionSceneBuilder + var body: some AppExtensionScene { + sidebarScenes + toolbarItemScenes + } +} + +public extension CodeEditExtension where Self: SettingsExtension & SidebarExtension & ToolbarItemExtension { + @AppExtensionSceneBuilder + var body: some AppExtensionScene { + settingsScene + sidebarScenes + toolbarItemScenes + } +} diff --git a/Sources/CodeEditKit/CodeEditExtension.swift b/Sources/CodeEditKit/CodeEditExtension.swift index b7e69fe..7b4cc4e 100644 --- a/Sources/CodeEditKit/CodeEditExtension.swift +++ b/Sources/CodeEditKit/CodeEditExtension.swift @@ -9,21 +9,37 @@ import Foundation import ExtensionKit import ExtensionFoundation import SwiftUI +import SequenceBuilder public protocol CodeEditExtension: AppExtension { + /// The shared instance of ``CodeEditExtension``. + /// Can be used to access shared state. + static var shared: Self { get } + /// UI scenes of the extension. associatedtype Body: AppExtensionScene + + /// Extension Configuration. associatedtype Configuration = AppExtensionSceneConfiguration + /// A brief description of the extension. Should be max a few words. var description: String { get } - var entitlements: [Entitlement] { get } + /// A list of Entitlements the app needs, e.g. Network Access. + var entitlements: [Entitlement] { get } + /// UI scenes of the extension. + /// Use the default implementation. @AppExtensionSceneBuilder var body: Body { get } } +public extension CodeEditExtension { + static var shared: Self { Self() } +} + extension CodeEditExtension { + func gatherAvailableExtensions() -> [ExtensionKind] { var extensions: [ExtensionKind] = [] @@ -46,13 +62,16 @@ extension CodeEditExtension { } } -public extension CodeEditExtension{ +public extension CodeEditExtension { + /// XPC Configuration for communication with CodeEdit. + /// Use the default implementation. var configuration: AppExtensionSceneConfiguration { AppExtensionSceneConfiguration(self.body, configuration: SettingsExtensionConfiguration(self)) } } -public struct SettingsExtensionConfiguration: AppExtensionConfiguration { + +struct SettingsExtensionConfiguration: AppExtensionConfiguration { public func accept(connection: NSXPCConnection) -> Bool { connection.exportedInterface = .init(with: XPCWrappable.self) connection.exportedObject = XPCWrapper(appExtension) diff --git a/Sources/CodeEditKit/UIExtensions/Settings/SettingsExtension.swift b/Sources/CodeEditKit/UIExtensions/Settings/SettingsExtension.swift index 1ca33d2..9e7e944 100644 --- a/Sources/CodeEditKit/UIExtensions/Settings/SettingsExtension.swift +++ b/Sources/CodeEditKit/UIExtensions/Settings/SettingsExtension.swift @@ -9,7 +9,7 @@ import Foundation import SwiftUI import ExtensionKit -public protocol SettingsExtension { +public protocol SettingsExtension: ObservableObject { associatedtype SettingsBody: View @ViewBuilder @@ -21,6 +21,7 @@ public extension SettingsExtension { GenericScene(sceneID: "Settings") { Form { self.settings + .environmentObject(self) } .formStyle(.grouped) } diff --git a/Sources/CodeEditKit/UIExtensions/Sidebar/SidebarExtension.swift b/Sources/CodeEditKit/UIExtensions/Sidebar/SidebarExtension.swift index 426ac06..ce8c708 100644 --- a/Sources/CodeEditKit/UIExtensions/Sidebar/SidebarExtension.swift +++ b/Sources/CodeEditKit/UIExtensions/Sidebar/SidebarExtension.swift @@ -10,7 +10,7 @@ import SequenceBuilder import ExtensionKit import SwiftUI -public protocol SidebarExtension { +public protocol SidebarExtension: ObservableObject { associatedtype SidebarBody: Sequence where SidebarBody.Element: SidebarItem @@ -22,7 +22,7 @@ public protocol SidebarExtension { public extension SidebarExtension { var sidebarScenes: some AppExtensionScene { - sidebars.map(\.scene) + sidebars.map { $0.buildScene(with: self) } } var availableExtensions: [ExtensionKind] { diff --git a/Sources/CodeEditKit/UIExtensions/Sidebar/SidebarItem.swift b/Sources/CodeEditKit/UIExtensions/Sidebar/SidebarItem.swift index 0d607d5..3f206c0 100644 --- a/Sources/CodeEditKit/UIExtensions/Sidebar/SidebarItem.swift +++ b/Sources/CodeEditKit/UIExtensions/Sidebar/SidebarItem.swift @@ -14,12 +14,12 @@ public protocol SidebarItem: View, GenericExtension { } extension SidebarItem { - var scene: some AppExtensionScene { + func buildScene(with envModel: T) -> some AppExtensionScene { PrimitiveAppExtensionScene(id: id) { - VStack(alignment: .leading) { self .scrollContentBackground(.hidden) + .environmentObject(envModel) } .frame(maxWidth: .infinity, maxHeight: .infinity) } diff --git a/Sources/CodeEditKit/UIExtensions/ToolbarItem/ToolbarItemExtension.swift b/Sources/CodeEditKit/UIExtensions/ToolbarItem/ToolbarItemExtension.swift index 21da061..c16c5a4 100644 --- a/Sources/CodeEditKit/UIExtensions/ToolbarItem/ToolbarItemExtension.swift +++ b/Sources/CodeEditKit/UIExtensions/ToolbarItem/ToolbarItemExtension.swift @@ -9,7 +9,7 @@ import Foundation import SequenceBuilder import ExtensionKit -public protocol ToolbarItemExtension { +public protocol ToolbarItemExtension: ObservableObject { associatedtype ToolbarItemBody: Sequence where ToolbarItemBody.Element: CEToolbarItem @@ -22,6 +22,7 @@ extension ToolbarItemExtension { toolbaritems.map { nav in PrimitiveAppExtensionScene(id: nav.id) { nav.body + .environmentObject(self) } } } diff --git a/Tests/CodeEditKitTests/Example/FirstExtension.swift b/Tests/CodeEditKitTests/Example/FirstExtension.swift index 3c8e0fb..dcb76a0 100644 --- a/Tests/CodeEditKitTests/Example/FirstExtension.swift +++ b/Tests/CodeEditKitTests/Example/FirstExtension.swift @@ -9,15 +9,23 @@ import SwiftUI import ExtensionKit import CodeEditKit -//@main -struct ExampleExtension: CodeEditExtension { - var description: String = "test" +@main +final class ExampleExtension: CodeEditExtension { + var description: String = "This is an example extension" var entitlements: [Entitlement] = [.currentfile] +} - var body: some AppExtensionScene { - sidebarScenes - toolbarItemScenes +extension ExampleExtension: SettingsExtension { + var settings: some View { + SettingsView() + } +} + +struct SettingsView: View { + @State var enabled = false + var body: some View { + Toggle("Enabled", isOn: $enabled) } } @@ -29,7 +37,7 @@ extension ExampleExtension: SidebarExtension { extension ExampleExtension: ActionExtension { var actions: [some CEAction] { - + ShortcutAction("Test") { print("Blablabla") } From c4e6cc71dc090ea57220c79f5e4387f12d838f3e Mon Sep 17 00:00:00 2001 From: Wouter01 Date: Tue, 3 Jan 2023 05:49:15 +0100 Subject: [PATCH 09/30] Added documentation Signed-off-by: Wouter01 --- .../Documentation.docc/CodeEditExtension.md | 58 +++++++++++++++++++ .../Documentation.docc/Documentation.md | 20 ++++++- .../Documentation.docc/GenericExtension.md | 15 +++++ .../Documentation.docc/LanguageServers.md | 13 +++++ .../Documentation.docc/Settings.md | 13 +++++ .../Documentation.docc/Sidebars.md | 13 +++++ .../Documentation.docc/Snippets.md | 13 +++++ .../CodeEditKit/Documentation.docc/Themes.md | 13 +++++ .../Documentation.docc/ToolbarItems.md | 13 +++++ 9 files changed, 169 insertions(+), 2 deletions(-) create mode 100644 Sources/CodeEditKit/Documentation.docc/CodeEditExtension.md create mode 100644 Sources/CodeEditKit/Documentation.docc/GenericExtension.md create mode 100644 Sources/CodeEditKit/Documentation.docc/LanguageServers.md create mode 100644 Sources/CodeEditKit/Documentation.docc/Settings.md create mode 100644 Sources/CodeEditKit/Documentation.docc/Sidebars.md create mode 100644 Sources/CodeEditKit/Documentation.docc/Snippets.md create mode 100644 Sources/CodeEditKit/Documentation.docc/Themes.md create mode 100644 Sources/CodeEditKit/Documentation.docc/ToolbarItems.md diff --git a/Sources/CodeEditKit/Documentation.docc/CodeEditExtension.md b/Sources/CodeEditKit/Documentation.docc/CodeEditExtension.md new file mode 100644 index 0000000..624da50 --- /dev/null +++ b/Sources/CodeEditKit/Documentation.docc/CodeEditExtension.md @@ -0,0 +1,58 @@ +# ``CodeEditKit/CodeEditExtension`` + +@Metadata { + @DocumentationExtension(mergeBehavior: append) +} + +The mother of all extensions. + +## Overview + +All extensions supported by CodeEdit are defined as a ``CodeEditExtension``. +This protocol provides basic information about the extension, such as the ``description``, name and ``entitlements``. + +This type is the entrypoint of your extension, so it should be marked with `@main`. + +Additional extensions can be defined by extending the struct that implements ``CodeEditExtension``. + +## Example + +```swift +@main +final class ExampleExtension: CodeEditExtension { + var description: String = "test" + + var entitlements: [Entitlement] = [.currentfile] +} + +// Add a Settings Pane +extension ExampleExtension: SettingsExtension { + var settings: some View { + SettingsView() + } +} + +// The Settings View +struct SettingsView: View { + @State var enabled = false + var body: some View { + Toggle("Enabled", isOn: $enabled) + } +} +``` + +> Info: ``CodeEditExtension`` Conforms to ObservableObject and is automatically injected into the environment of each View. This way, it's possible to have shared state between different UI extensions by observing the object in a View. +> ```swift +> struct AView: View { +> @EnvironmentObject var main: ExampleExtension +> } +> ``` +> Non-UI extensions can make use of the ``shared-7xv27`` property of ``CodeEditExtension`` to access the shared state. + + + +## Topics + +### Group + +- ``Symbol`` diff --git a/Sources/CodeEditKit/Documentation.docc/Documentation.md b/Sources/CodeEditKit/Documentation.docc/Documentation.md index 1cc176e..c3123d8 100644 --- a/Sources/CodeEditKit/Documentation.docc/Documentation.md +++ b/Sources/CodeEditKit/Documentation.docc/Documentation.md @@ -6,11 +6,27 @@ CodeEditKit is a dynamic library which is shared between CodeEdit and it's exten Extensions are an essential part of CodeEdit. They can extend the languages CodeEdit supports, add custom actions and behaviors, and even provide custom views of certain data. +CodeEditKit aims to provide an easy and straightforward API to implement these extensions, with modern technologies like Swift, SwiftUI and ExtensionKit. + ### Extension Types There are lots of extension types you can use to extend the functionality of CodeEdit. +#### General Extensions - -- Sidebars -- Test +- + +#### Language Extensions +- +- + +#### UI Extensions +- +- +- + +### Getting Started +First, have a look at ``CodeEditExtension``. This is the base protocol that will define the main structure of your extension. +All extensions that you'll add will extend (:p) this type. +Next, try adding an extension to your newly created type. A good first recommendation is the extension, as you'll likely need this later. diff --git a/Sources/CodeEditKit/Documentation.docc/GenericExtension.md b/Sources/CodeEditKit/Documentation.docc/GenericExtension.md new file mode 100644 index 0000000..507d3bb --- /dev/null +++ b/Sources/CodeEditKit/Documentation.docc/GenericExtension.md @@ -0,0 +1,15 @@ +# ``CodeEditKit/GenericExtension`` + +Summary + +## Overview + +Text + +> Important: If you instantiate multiple instances of a struct that implements ``GenericExtension``, replace the default implementation of ``id`` with an unique ``id``. Otherwise, they'll have the same ``id`` which will cause trouble. + +## Topics + +### Group + +- ``Symbol`` diff --git a/Sources/CodeEditKit/Documentation.docc/LanguageServers.md b/Sources/CodeEditKit/Documentation.docc/LanguageServers.md new file mode 100644 index 0000000..6f4fd35 --- /dev/null +++ b/Sources/CodeEditKit/Documentation.docc/LanguageServers.md @@ -0,0 +1,13 @@ +# Language Servers + +Summary + +## Overview + +Text + +## Topics + +### Group + +- ``Symbol`` diff --git a/Sources/CodeEditKit/Documentation.docc/Settings.md b/Sources/CodeEditKit/Documentation.docc/Settings.md new file mode 100644 index 0000000..883a1ed --- /dev/null +++ b/Sources/CodeEditKit/Documentation.docc/Settings.md @@ -0,0 +1,13 @@ +# Settings + +Summary + +## Overview + +Text + +## Topics + +### Group + +- ``Symbol`` diff --git a/Sources/CodeEditKit/Documentation.docc/Sidebars.md b/Sources/CodeEditKit/Documentation.docc/Sidebars.md new file mode 100644 index 0000000..234d7f8 --- /dev/null +++ b/Sources/CodeEditKit/Documentation.docc/Sidebars.md @@ -0,0 +1,13 @@ +# Sidebars + +Summary + +## Overview + +Text + +## Topics + +### Group + +- ``Symbol`` diff --git a/Sources/CodeEditKit/Documentation.docc/Snippets.md b/Sources/CodeEditKit/Documentation.docc/Snippets.md new file mode 100644 index 0000000..12e8276 --- /dev/null +++ b/Sources/CodeEditKit/Documentation.docc/Snippets.md @@ -0,0 +1,13 @@ +# Snippets + +Summary + +## Overview + +Text + +## Topics + +### Group + +- ``Symbol`` diff --git a/Sources/CodeEditKit/Documentation.docc/Themes.md b/Sources/CodeEditKit/Documentation.docc/Themes.md new file mode 100644 index 0000000..244f67c --- /dev/null +++ b/Sources/CodeEditKit/Documentation.docc/Themes.md @@ -0,0 +1,13 @@ +# Themes + +Summary + +## Overview + +Text + +## Topics + +### Group + +- ``Symbol`` diff --git a/Sources/CodeEditKit/Documentation.docc/ToolbarItems.md b/Sources/CodeEditKit/Documentation.docc/ToolbarItems.md new file mode 100644 index 0000000..f0155e0 --- /dev/null +++ b/Sources/CodeEditKit/Documentation.docc/ToolbarItems.md @@ -0,0 +1,13 @@ +# Toolbar Items + +Summary + +## Overview + +Text + +## Topics + +### Group + +- ``Symbol`` From e2ecf2ae694a0157ddce14b73f597fbddee1de0e Mon Sep 17 00:00:00 2001 From: Wouter01 Date: Tue, 3 Jan 2023 06:31:07 +0100 Subject: [PATCH 10/30] Removed shared instance due to bug Signed-off-by: Wouter01 --- Sources/CodeEditKit/CodeEditExtension.swift | 3 --- Sources/CodeEditKit/Documentation.docc/CodeEditExtension.md | 1 - 2 files changed, 4 deletions(-) diff --git a/Sources/CodeEditKit/CodeEditExtension.swift b/Sources/CodeEditKit/CodeEditExtension.swift index 7b4cc4e..8abb866 100644 --- a/Sources/CodeEditKit/CodeEditExtension.swift +++ b/Sources/CodeEditKit/CodeEditExtension.swift @@ -12,9 +12,6 @@ import SwiftUI import SequenceBuilder public protocol CodeEditExtension: AppExtension { - /// The shared instance of ``CodeEditExtension``. - /// Can be used to access shared state. - static var shared: Self { get } /// UI scenes of the extension. associatedtype Body: AppExtensionScene diff --git a/Sources/CodeEditKit/Documentation.docc/CodeEditExtension.md b/Sources/CodeEditKit/Documentation.docc/CodeEditExtension.md index 624da50..dcd373b 100644 --- a/Sources/CodeEditKit/Documentation.docc/CodeEditExtension.md +++ b/Sources/CodeEditKit/Documentation.docc/CodeEditExtension.md @@ -47,7 +47,6 @@ struct SettingsView: View { > @EnvironmentObject var main: ExampleExtension > } > ``` -> Non-UI extensions can make use of the ``shared-7xv27`` property of ``CodeEditExtension`` to access the shared state. From 483ea1049286bcf3754f1047f9f4e240933df24e Mon Sep 17 00:00:00 2001 From: Wouter01 Date: Fri, 24 Mar 2023 17:22:32 +0100 Subject: [PATCH 11/30] Added extensionURL support Signed-off-by: Wouter01 --- Sources/CodeEditKit/CodeEditExtension.swift | 5 +++++ .../Environment/EnvironmentObjcPublisher.swift | 3 ++- Sources/CodeEditKit/XPCWrapper.swift | 11 +++++++++++ 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/Sources/CodeEditKit/CodeEditExtension.swift b/Sources/CodeEditKit/CodeEditExtension.swift index 8abb866..f62c2af 100644 --- a/Sources/CodeEditKit/CodeEditExtension.swift +++ b/Sources/CodeEditKit/CodeEditExtension.swift @@ -37,6 +37,10 @@ public extension CodeEditExtension { extension CodeEditExtension { + var extensionURL: URL { + Bundle.main.bundleURL + } + func gatherAvailableExtensions() -> [ExtensionKind] { var extensions: [ExtensionKind] = [] @@ -55,6 +59,7 @@ extension CodeEditExtension { if let self = self as? any ToolbarItemExtension { extensions.append(contentsOf: self.availableExtensions) } + return extensions } } diff --git a/Sources/CodeEditKit/UIExtensions/Environment/EnvironmentObjcPublisher.swift b/Sources/CodeEditKit/UIExtensions/Environment/EnvironmentObjcPublisher.swift index 2a0ae24..c1eaea0 100644 --- a/Sources/CodeEditKit/UIExtensions/Environment/EnvironmentObjcPublisher.swift +++ b/Sources/CodeEditKit/UIExtensions/Environment/EnvironmentObjcPublisher.swift @@ -26,7 +26,8 @@ public class EnvironmentPublisher: ObservableObject, EnvironmentPublisherObjc { } } - public func publishEnvironment(@Decoded<_CEEnvironment> data: Data) { + public func publishEnvironment(data: Data) { + @Decoded<_CEEnvironment> var data = data guard let $data else { return } environment = $data diff --git a/Sources/CodeEditKit/XPCWrapper.swift b/Sources/CodeEditKit/XPCWrapper.swift index b8be739..53e7006 100644 --- a/Sources/CodeEditKit/XPCWrapper.swift +++ b/Sources/CodeEditKit/XPCWrapper.swift @@ -16,6 +16,8 @@ public enum XPCError: Error { @objc public protocol XPCWrappable { + func getExtensionURL(reply: @escaping XPCReply) + func getExtensionKinds(reply: @escaping XPCReply) func getTheme(reply: @escaping XPCReply) @@ -32,6 +34,15 @@ class XPCWrapper: XPCWrappable { self.ext = ext } + func getExtensionURL(reply: @escaping XPCReply) { + do { + let encoded = try JSONEncoder().encode(ext.extensionURL) + reply(encoded, nil) + } catch { + reply(nil, error) + } + } + func getExtensionKinds(reply: @escaping XPCReply) { do { let encoded = try JSONEncoder().encode(ext.gatherAvailableExtensions()) From 29530a9969991be4f210ed71fe1893c99e876de1 Mon Sep 17 00:00:00 2001 From: Wouter01 Date: Fri, 24 Mar 2023 22:51:49 +0100 Subject: [PATCH 12/30] updated sidebar api Signed-off-by: Wouter01 --- .../UIExtensions/Sidebar/GenericSidebar.swift | 110 ++++++++++++++++++ .../UIExtensions/Sidebar/Sidebar.swift | 96 +++++++++++++++ .../Sidebar/SidebarExtension.swift | 10 +- .../UIExtensions/Sidebar/SidebarNever.swift | 9 ++ 4 files changed, 221 insertions(+), 4 deletions(-) create mode 100644 Sources/CodeEditKit/UIExtensions/Sidebar/GenericSidebar.swift create mode 100644 Sources/CodeEditKit/UIExtensions/Sidebar/Sidebar.swift create mode 100644 Sources/CodeEditKit/UIExtensions/Sidebar/SidebarNever.swift diff --git a/Sources/CodeEditKit/UIExtensions/Sidebar/GenericSidebar.swift b/Sources/CodeEditKit/UIExtensions/Sidebar/GenericSidebar.swift new file mode 100644 index 0000000..56e5a78 --- /dev/null +++ b/Sources/CodeEditKit/UIExtensions/Sidebar/GenericSidebar.swift @@ -0,0 +1,110 @@ +// +// File.swift +// +// +// Created by Wouter Hennen on 24/03/2023. +// + +import SwiftUI +import ExtensionKit + +public struct Navigator: Sidebar { + public var body: Never { + fatalError() + } + + var id: String + + var icon: String + + public init(id: String, icon: String, content: () -> Content) { + self.id = id + self.icon = icon + self.content = content() + } + + @ViewBuilder var content: Content + + @_spi(CodeEdit) + public func resolve(environment: some ObservableObject) -> [ResolvedSidebar] { + let scene = PrimitiveAppExtensionScene(id: id) { + content + .environmentObject(environment) + } + return [ResolvedSidebar(scene: scene, id: id, icon: icon, kind: .navigator)] + } +} + +public struct Inspector: Sidebar { + public var body: Never { + fatalError() + } + + var id: String + + var icon: String + + public init(id: String, icon: String, content: () -> Content) { + self.id = id + self.icon = icon + self.content = content() + } + + @ViewBuilder var content: Content + + @_spi(CodeEdit) + public func resolve(environment: some ObservableObject) -> [ResolvedSidebar] { + let scene = PrimitiveAppExtensionScene(id: id) { + content + .environmentObject(environment) + } + return [ResolvedSidebar(scene: scene, id: id, icon: icon, kind: .inspector)] + } +} + +struct SidebarHelpModifier: Sidebar { + var help: String + var content: Content + + var body: Never { + fatalError() + } + + func resolve(environment: some ObservableObject) -> [ResolvedSidebar] { + var sidebars = self.content.resolve(environment: environment) + for index in sidebars.indices { + sidebars[index].help = help + } + return sidebars + } +} + +public extension Sidebar { + func help(_ message: String) -> some Sidebar { + SidebarHelpModifier(help: message, content: self) + } + + func title(_ title: String) -> some Sidebar { + self + } + + func description(_ message: String) -> some Sidebar { + self + } +} + +struct GroupSidebar: Sidebar { + + var body: some Sidebar { + Navigator(id: "Hello", icon: "mimi") { + Text("Hello") + } + .help("This shows on hover of icon") + .title("Navigator 1") + .description("This is shown in the settings") + + Inspector(id: "Hello2", icon: "mimi") { + Text("Hello2") + } + } +} diff --git a/Sources/CodeEditKit/UIExtensions/Sidebar/Sidebar.swift b/Sources/CodeEditKit/UIExtensions/Sidebar/Sidebar.swift new file mode 100644 index 0000000..74ad6af --- /dev/null +++ b/Sources/CodeEditKit/UIExtensions/Sidebar/Sidebar.swift @@ -0,0 +1,96 @@ +// +// File.swift +// +// +// Created by Wouter Hennen on 24/03/2023. +// + +import Foundation +//import SwiftUI +import ExtensionKit + +public protocol Sidebar { + associatedtype Body: Sidebar + + @SidebarBuilder + var body: Body { get } + + @_spi(CodeEdit) + func resolve(environment: some ObservableObject) -> [ResolvedSidebar] +} + +public struct ResolvedSidebar { + + enum Kind { + case navigator, inspector + } +// typealias Scene: AppExtensionScene + var scene: PrimitiveAppExtensionScene + + var id: String + + var icon: String + + var help: String? + + var kind: Kind + + var extensionKind: ExtensionKind { + .sidebarItem(sceneID: id, icon: icon) + } +} + + +extension Never: Sidebar { + @_spi(CodeEdit) + public func resolve(environment: some ObservableObject) -> [ResolvedSidebar] { + fatalError() + } +} + +public extension Sidebar { +// @_spi(CodeEdit) + func resolve(environment: some ObservableObject) -> [ResolvedSidebar] { + body.resolve(environment: environment) + } +} + + + +struct TupleSidebar: Sidebar { + var c0: C0 + var c1: C1 + + init(_ c0: C0, _ c1: C1) { + self.c0 = c0 + self.c1 = c1 + } + + var body: Never { + fatalError() + } + + func resolve(environment: some ObservableObject) -> [ResolvedSidebar] { + c0.resolve(environment: environment) + c1.resolve(environment: environment) + } +} + +@resultBuilder +public struct SidebarBuilder { + static func buildBlock(_ c0: Never) -> Never {} + + static public func buildBlock(_ c0: C0) -> some Sidebar { + c0 + } + + static public func buildBlock(_ c0: C0, _ c1: C1) -> some Sidebar { + TupleSidebar(c0, c1) + } + + static public func buildBlock(_ c0: C0, _ c1: C1, _ c2: C2) -> some Sidebar { + TupleSidebar(TupleSidebar(c0, c1), c2) + } +} + + + diff --git a/Sources/CodeEditKit/UIExtensions/Sidebar/SidebarExtension.swift b/Sources/CodeEditKit/UIExtensions/Sidebar/SidebarExtension.swift index ce8c708..b0e80ce 100644 --- a/Sources/CodeEditKit/UIExtensions/Sidebar/SidebarExtension.swift +++ b/Sources/CodeEditKit/UIExtensions/Sidebar/SidebarExtension.swift @@ -12,9 +12,9 @@ import SwiftUI public protocol SidebarExtension: ObservableObject { - associatedtype SidebarBody: Sequence where SidebarBody.Element: SidebarItem + associatedtype SidebarBody: Sidebar - @SequenceBuilder + @SidebarBuilder var sidebars: SidebarBody { get } } @@ -22,10 +22,12 @@ public protocol SidebarExtension: ObservableObject { public extension SidebarExtension { var sidebarScenes: some AppExtensionScene { - sidebars.map { $0.buildScene(with: self) } + sidebars.resolve(environment: self).map(\.scene) +// sidebars.map { $0.buildScene(with: self) } } var availableExtensions: [ExtensionKind] { - sidebars.map { ExtensionKind.sidebarItem(sceneID: $0.id, icon: $0.icon) } + sidebars.resolve(environment: self).map(\.extensionKind) +// sidebars.map { ExtensionKind.sidebarItem(sceneID: $0.id, icon: $0.icon) } } } diff --git a/Sources/CodeEditKit/UIExtensions/Sidebar/SidebarNever.swift b/Sources/CodeEditKit/UIExtensions/Sidebar/SidebarNever.swift new file mode 100644 index 0000000..bfd40d6 --- /dev/null +++ b/Sources/CodeEditKit/UIExtensions/Sidebar/SidebarNever.swift @@ -0,0 +1,9 @@ +// +// File.swift +// +// +// Created by Wouter Hennen on 24/03/2023. +// + +import Foundation + From e187e1687ca074ce9cf3d12175e45f1bd17ed8a9 Mon Sep 17 00:00:00 2001 From: Wouter01 Date: Sat, 25 Mar 2023 00:47:02 +0100 Subject: [PATCH 13/30] refaactored files Signed-off-by: Wouter01 --- Sources/CodeEditKit/ExtensionKind.swift | 2 +- .../UIExtensions/Sidebar/GenericSidebar.swift | 110 ------------------ .../UIExtensions/Sidebar/Inspector.swift | 41 +++++++ .../UIExtensions/Sidebar/Navigator.swift | 41 +++++++ .../Sidebar/ResolvedSidebar.swift | 32 +++++ .../UIExtensions/Sidebar/Sidebar+Help.swift | 40 +++++++ .../UIExtensions/Sidebar/Sidebar.swift | 71 +---------- .../UIExtensions/Sidebar/SidebarBuilder.swift | 21 ++++ .../UIExtensions/Sidebar/SidebarNever.swift | 6 + .../UIExtensions/Sidebar/TupleSidebar.swift | 26 +++++ 10 files changed, 209 insertions(+), 181 deletions(-) delete mode 100644 Sources/CodeEditKit/UIExtensions/Sidebar/GenericSidebar.swift create mode 100644 Sources/CodeEditKit/UIExtensions/Sidebar/Inspector.swift create mode 100644 Sources/CodeEditKit/UIExtensions/Sidebar/Navigator.swift create mode 100644 Sources/CodeEditKit/UIExtensions/Sidebar/ResolvedSidebar.swift create mode 100644 Sources/CodeEditKit/UIExtensions/Sidebar/Sidebar+Help.swift create mode 100644 Sources/CodeEditKit/UIExtensions/Sidebar/SidebarBuilder.swift create mode 100644 Sources/CodeEditKit/UIExtensions/Sidebar/TupleSidebar.swift diff --git a/Sources/CodeEditKit/ExtensionKind.swift b/Sources/CodeEditKit/ExtensionKind.swift index 2a650cf..4b51300 100644 --- a/Sources/CodeEditKit/ExtensionKind.swift +++ b/Sources/CodeEditKit/ExtensionKind.swift @@ -8,7 +8,7 @@ import SwiftUI public enum ExtensionKind: Codable, Hashable, CustomStringConvertible { - case sidebarItem(sceneID: String, icon: String) + case sidebarItem(sceneID: String, data: ResolvedSidebar.SidebarStore) case toolbarItem(sceneID: String, placement: CEToolbarItemPlacement) case action(actionID: String) case theme(themeID: String) diff --git a/Sources/CodeEditKit/UIExtensions/Sidebar/GenericSidebar.swift b/Sources/CodeEditKit/UIExtensions/Sidebar/GenericSidebar.swift deleted file mode 100644 index 56e5a78..0000000 --- a/Sources/CodeEditKit/UIExtensions/Sidebar/GenericSidebar.swift +++ /dev/null @@ -1,110 +0,0 @@ -// -// File.swift -// -// -// Created by Wouter Hennen on 24/03/2023. -// - -import SwiftUI -import ExtensionKit - -public struct Navigator: Sidebar { - public var body: Never { - fatalError() - } - - var id: String - - var icon: String - - public init(id: String, icon: String, content: () -> Content) { - self.id = id - self.icon = icon - self.content = content() - } - - @ViewBuilder var content: Content - - @_spi(CodeEdit) - public func resolve(environment: some ObservableObject) -> [ResolvedSidebar] { - let scene = PrimitiveAppExtensionScene(id: id) { - content - .environmentObject(environment) - } - return [ResolvedSidebar(scene: scene, id: id, icon: icon, kind: .navigator)] - } -} - -public struct Inspector: Sidebar { - public var body: Never { - fatalError() - } - - var id: String - - var icon: String - - public init(id: String, icon: String, content: () -> Content) { - self.id = id - self.icon = icon - self.content = content() - } - - @ViewBuilder var content: Content - - @_spi(CodeEdit) - public func resolve(environment: some ObservableObject) -> [ResolvedSidebar] { - let scene = PrimitiveAppExtensionScene(id: id) { - content - .environmentObject(environment) - } - return [ResolvedSidebar(scene: scene, id: id, icon: icon, kind: .inspector)] - } -} - -struct SidebarHelpModifier: Sidebar { - var help: String - var content: Content - - var body: Never { - fatalError() - } - - func resolve(environment: some ObservableObject) -> [ResolvedSidebar] { - var sidebars = self.content.resolve(environment: environment) - for index in sidebars.indices { - sidebars[index].help = help - } - return sidebars - } -} - -public extension Sidebar { - func help(_ message: String) -> some Sidebar { - SidebarHelpModifier(help: message, content: self) - } - - func title(_ title: String) -> some Sidebar { - self - } - - func description(_ message: String) -> some Sidebar { - self - } -} - -struct GroupSidebar: Sidebar { - - var body: some Sidebar { - Navigator(id: "Hello", icon: "mimi") { - Text("Hello") - } - .help("This shows on hover of icon") - .title("Navigator 1") - .description("This is shown in the settings") - - Inspector(id: "Hello2", icon: "mimi") { - Text("Hello2") - } - } -} diff --git a/Sources/CodeEditKit/UIExtensions/Sidebar/Inspector.swift b/Sources/CodeEditKit/UIExtensions/Sidebar/Inspector.swift new file mode 100644 index 0000000..911c699 --- /dev/null +++ b/Sources/CodeEditKit/UIExtensions/Sidebar/Inspector.swift @@ -0,0 +1,41 @@ +// +// File.swift +// +// +// Created by Wouter Hennen on 25/03/2023. +// + +import SwiftUI +import ExtensionKit + +public struct Inspector: Sidebar { + public var body: Never { + fatalError() + } + + var id: String + + var icon: String + + public init(id: String, icon: String, content: () -> Content) { + self.id = id + self.icon = icon + self.content = content() + } + + @ViewBuilder var content: Content + + @_spi(CodeEdit) + public func resolve(environment: some ObservableObject) -> [ResolvedSidebar] { + let scene = PrimitiveAppExtensionScene(id: id) { + VStack(alignment: .leading) { + content + .scrollContentBackground(.hidden) + .environmentObject(environment) + } + .frame(maxWidth: .infinity, maxHeight: .infinity) + } + let store = ResolvedSidebar.SidebarStore(kind: .inspector) + return [ResolvedSidebar(scene: scene, id: id, store: store)] + } +} diff --git a/Sources/CodeEditKit/UIExtensions/Sidebar/Navigator.swift b/Sources/CodeEditKit/UIExtensions/Sidebar/Navigator.swift new file mode 100644 index 0000000..33ad813 --- /dev/null +++ b/Sources/CodeEditKit/UIExtensions/Sidebar/Navigator.swift @@ -0,0 +1,41 @@ +// +// File.swift +// +// +// Created by Wouter Hennen on 25/03/2023. +// + +import SwiftUI +import ExtensionKit + +public struct Navigator: Sidebar { + public var body: Never { + fatalError() + } + + var id: String + + var icon: String + + public init(id: String, icon: String, content: () -> Content) { + self.id = id + self.icon = icon + self.content = content() + } + + @ViewBuilder var content: Content + + @_spi(CodeEdit) + public func resolve(environment: some ObservableObject) -> [ResolvedSidebar] { + let scene = PrimitiveAppExtensionScene(id: id) { + VStack(alignment: .leading) { + content + .scrollContentBackground(.hidden) + .environmentObject(environment) + } + .frame(maxWidth: .infinity, maxHeight: .infinity) + } + let store = ResolvedSidebar.SidebarStore(kind: .navigator) + return [ResolvedSidebar(scene: scene, id: id, store: store)] + } +} diff --git a/Sources/CodeEditKit/UIExtensions/Sidebar/ResolvedSidebar.swift b/Sources/CodeEditKit/UIExtensions/Sidebar/ResolvedSidebar.swift new file mode 100644 index 0000000..13ab7f1 --- /dev/null +++ b/Sources/CodeEditKit/UIExtensions/Sidebar/ResolvedSidebar.swift @@ -0,0 +1,32 @@ +// +// File.swift +// +// +// Created by Wouter Hennen on 24/03/2023. +// + +import Foundation +import ExtensionKit + +public struct ResolvedSidebar { + + public enum Kind: Codable, Hashable { + case navigator, inspector + } + + var scene: PrimitiveAppExtensionScene + + var id: String + + var store: SidebarStore + + public struct SidebarStore: Codable, Hashable { + public var icon: String? + public var help: String? + public var kind: Kind + } + + var extensionKind: ExtensionKind { + .sidebarItem(sceneID: id, data: store) + } +} diff --git a/Sources/CodeEditKit/UIExtensions/Sidebar/Sidebar+Help.swift b/Sources/CodeEditKit/UIExtensions/Sidebar/Sidebar+Help.swift new file mode 100644 index 0000000..e3c0732 --- /dev/null +++ b/Sources/CodeEditKit/UIExtensions/Sidebar/Sidebar+Help.swift @@ -0,0 +1,40 @@ +// +// File.swift +// +// +// Created by Wouter Hennen on 24/03/2023. +// + +import SwiftUI +import ExtensionKit + +struct SidebarHelpModifier: Sidebar { + var help: String + var content: Content + + var body: Never { + fatalError() + } + + func resolve(environment: some ObservableObject) -> [ResolvedSidebar] { + var sidebars = self.content.resolve(environment: environment) + for index in sidebars.indices { + sidebars[index].store.help = help + } + return sidebars + } +} + +public extension Sidebar { + func help(_ message: String) -> some Sidebar { + SidebarHelpModifier(help: message, content: self) + } + + func title(_ title: String) -> some Sidebar { + self + } + + func description(_ message: String) -> some Sidebar { + self + } +} diff --git a/Sources/CodeEditKit/UIExtensions/Sidebar/Sidebar.swift b/Sources/CodeEditKit/UIExtensions/Sidebar/Sidebar.swift index 74ad6af..3c3dab0 100644 --- a/Sources/CodeEditKit/UIExtensions/Sidebar/Sidebar.swift +++ b/Sources/CodeEditKit/UIExtensions/Sidebar/Sidebar.swift @@ -6,7 +6,6 @@ // import Foundation -//import SwiftUI import ExtensionKit public protocol Sidebar { @@ -19,78 +18,10 @@ public protocol Sidebar { func resolve(environment: some ObservableObject) -> [ResolvedSidebar] } -public struct ResolvedSidebar { - - enum Kind { - case navigator, inspector - } -// typealias Scene: AppExtensionScene - var scene: PrimitiveAppExtensionScene - - var id: String - - var icon: String - - var help: String? - - var kind: Kind - - var extensionKind: ExtensionKind { - .sidebarItem(sceneID: id, icon: icon) - } -} - - -extension Never: Sidebar { - @_spi(CodeEdit) - public func resolve(environment: some ObservableObject) -> [ResolvedSidebar] { - fatalError() - } -} - public extension Sidebar { + // @_spi(CodeEdit) func resolve(environment: some ObservableObject) -> [ResolvedSidebar] { body.resolve(environment: environment) } } - - - -struct TupleSidebar: Sidebar { - var c0: C0 - var c1: C1 - - init(_ c0: C0, _ c1: C1) { - self.c0 = c0 - self.c1 = c1 - } - - var body: Never { - fatalError() - } - - func resolve(environment: some ObservableObject) -> [ResolvedSidebar] { - c0.resolve(environment: environment) + c1.resolve(environment: environment) - } -} - -@resultBuilder -public struct SidebarBuilder { - static func buildBlock(_ c0: Never) -> Never {} - - static public func buildBlock(_ c0: C0) -> some Sidebar { - c0 - } - - static public func buildBlock(_ c0: C0, _ c1: C1) -> some Sidebar { - TupleSidebar(c0, c1) - } - - static public func buildBlock(_ c0: C0, _ c1: C1, _ c2: C2) -> some Sidebar { - TupleSidebar(TupleSidebar(c0, c1), c2) - } -} - - - diff --git a/Sources/CodeEditKit/UIExtensions/Sidebar/SidebarBuilder.swift b/Sources/CodeEditKit/UIExtensions/Sidebar/SidebarBuilder.swift new file mode 100644 index 0000000..cd4fcff --- /dev/null +++ b/Sources/CodeEditKit/UIExtensions/Sidebar/SidebarBuilder.swift @@ -0,0 +1,21 @@ +// +// File.swift +// +// +// Created by Wouter Hennen on 24/03/2023. +// + +import Foundation + +@resultBuilder +public struct SidebarBuilder { + public static func buildPartialBlock(first: Never) -> Never {} + + public static func buildPartialBlock(first: C0) -> some Sidebar { + first + } + + public static func buildPartialBlock(accumulated: C0, next: C1) -> some Sidebar { + TupleSidebar(accumulated, next) + } +} diff --git a/Sources/CodeEditKit/UIExtensions/Sidebar/SidebarNever.swift b/Sources/CodeEditKit/UIExtensions/Sidebar/SidebarNever.swift index bfd40d6..791886f 100644 --- a/Sources/CodeEditKit/UIExtensions/Sidebar/SidebarNever.swift +++ b/Sources/CodeEditKit/UIExtensions/Sidebar/SidebarNever.swift @@ -7,3 +7,9 @@ import Foundation +extension Never: Sidebar { + @_spi(CodeEdit) + public func resolve(environment: some ObservableObject) -> [ResolvedSidebar] { + fatalError() + } +} diff --git a/Sources/CodeEditKit/UIExtensions/Sidebar/TupleSidebar.swift b/Sources/CodeEditKit/UIExtensions/Sidebar/TupleSidebar.swift new file mode 100644 index 0000000..e09053e --- /dev/null +++ b/Sources/CodeEditKit/UIExtensions/Sidebar/TupleSidebar.swift @@ -0,0 +1,26 @@ +// +// File.swift +// +// +// Created by Wouter Hennen on 24/03/2023. +// + +import Foundation + +struct TupleSidebar: Sidebar { + var c0: C0 + var c1: C1 + + init(_ c0: C0, _ c1: C1) { + self.c0 = c0 + self.c1 = c1 + } + + var body: Never { + fatalError() + } + + func resolve(environment: some ObservableObject) -> [ResolvedSidebar] { + c0.resolve(environment: environment) + c1.resolve(environment: environment) + } +} From 1833d85b01fd1b60230fe47fa1825e1c4665bbd7 Mon Sep 17 00:00:00 2001 From: Wouter01 Date: Sat, 25 Mar 2023 00:49:17 +0100 Subject: [PATCH 14/30] removed old sidebar implementation Signed-off-by: Wouter01 --- .../UIExtensions/Sidebar/Examples.swift | 29 ------------------- .../Sidebar/SidebarExtension.swift | 3 -- .../Sidebar/SidebarItem+Either.swift | 16 ---------- .../UIExtensions/Sidebar/SidebarItem.swift | 27 ----------------- 4 files changed, 75 deletions(-) delete mode 100644 Sources/CodeEditKit/UIExtensions/Sidebar/Examples.swift delete mode 100644 Sources/CodeEditKit/UIExtensions/Sidebar/SidebarItem+Either.swift delete mode 100644 Sources/CodeEditKit/UIExtensions/Sidebar/SidebarItem.swift diff --git a/Sources/CodeEditKit/UIExtensions/Sidebar/Examples.swift b/Sources/CodeEditKit/UIExtensions/Sidebar/Examples.swift deleted file mode 100644 index d09e2b2..0000000 --- a/Sources/CodeEditKit/UIExtensions/Sidebar/Examples.swift +++ /dev/null @@ -1,29 +0,0 @@ -// -// File.swift -// -// -// Created by Wouter Hennen on 30/12/2022. -// - -import Foundation -import SwiftUI - -struct DefaultNavigator: SidebarItem { - var icon: String = "Test" - - var label: String = "Test" - - var description: String = "Short description" - var body: some View { - Text("Piep") - } -} - -struct DefaultNavigator2: SidebarItem { - var icon: String = "Test" - var label: String = "Default Navigator 2" - var description: String = "blablabla" - var body: some View { - Text("Piep2") - } -} diff --git a/Sources/CodeEditKit/UIExtensions/Sidebar/SidebarExtension.swift b/Sources/CodeEditKit/UIExtensions/Sidebar/SidebarExtension.swift index b0e80ce..54ca0ee 100644 --- a/Sources/CodeEditKit/UIExtensions/Sidebar/SidebarExtension.swift +++ b/Sources/CodeEditKit/UIExtensions/Sidebar/SidebarExtension.swift @@ -19,15 +19,12 @@ public protocol SidebarExtension: ObservableObject { } - public extension SidebarExtension { var sidebarScenes: some AppExtensionScene { sidebars.resolve(environment: self).map(\.scene) -// sidebars.map { $0.buildScene(with: self) } } var availableExtensions: [ExtensionKind] { sidebars.resolve(environment: self).map(\.extensionKind) -// sidebars.map { ExtensionKind.sidebarItem(sceneID: $0.id, icon: $0.icon) } } } diff --git a/Sources/CodeEditKit/UIExtensions/Sidebar/SidebarItem+Either.swift b/Sources/CodeEditKit/UIExtensions/Sidebar/SidebarItem+Either.swift deleted file mode 100644 index 9991eb1..0000000 --- a/Sources/CodeEditKit/UIExtensions/Sidebar/SidebarItem+Either.swift +++ /dev/null @@ -1,16 +0,0 @@ -// -// File.swift -// -// -// Created by Wouter Hennen on 30/12/2022. -// - -import Foundation -import SequenceBuilder - -extension Either: SidebarItem where Left: SidebarItem, Right: SidebarItem { - - public var icon: String { - fold(left: \.icon, right: \.icon) - } -} diff --git a/Sources/CodeEditKit/UIExtensions/Sidebar/SidebarItem.swift b/Sources/CodeEditKit/UIExtensions/Sidebar/SidebarItem.swift deleted file mode 100644 index 3f206c0..0000000 --- a/Sources/CodeEditKit/UIExtensions/Sidebar/SidebarItem.swift +++ /dev/null @@ -1,27 +0,0 @@ -// -// File.swift -// -// -// Created by Wouter Hennen on 30/12/2022. -// - -import Foundation -import SwiftUI -import ExtensionKit - -public protocol SidebarItem: View, GenericExtension { - var icon: String { get } -} - -extension SidebarItem { - func buildScene(with envModel: T) -> some AppExtensionScene { - PrimitiveAppExtensionScene(id: id) { - VStack(alignment: .leading) { - self - .scrollContentBackground(.hidden) - .environmentObject(envModel) - } - .frame(maxWidth: .infinity, maxHeight: .infinity) - } - } -} From 1d28eaeedbbac39257f2c296e3465615988d7ab5 Mon Sep 17 00:00:00 2001 From: Wouter01 Date: Sat, 25 Mar 2023 01:03:48 +0100 Subject: [PATCH 15/30] small improvements Signed-off-by: Wouter01 --- Sources/CodeEditKit/UIExtensions/Sidebar/Sidebar.swift | 3 +-- Sources/CodeEditKit/UIExtensions/Sidebar/SidebarBuilder.swift | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/Sources/CodeEditKit/UIExtensions/Sidebar/Sidebar.swift b/Sources/CodeEditKit/UIExtensions/Sidebar/Sidebar.swift index 3c3dab0..c102a94 100644 --- a/Sources/CodeEditKit/UIExtensions/Sidebar/Sidebar.swift +++ b/Sources/CodeEditKit/UIExtensions/Sidebar/Sidebar.swift @@ -19,8 +19,7 @@ public protocol Sidebar { } public extension Sidebar { - -// @_spi(CodeEdit) + func resolve(environment: some ObservableObject) -> [ResolvedSidebar] { body.resolve(environment: environment) } diff --git a/Sources/CodeEditKit/UIExtensions/Sidebar/SidebarBuilder.swift b/Sources/CodeEditKit/UIExtensions/Sidebar/SidebarBuilder.swift index cd4fcff..c717f87 100644 --- a/Sources/CodeEditKit/UIExtensions/Sidebar/SidebarBuilder.swift +++ b/Sources/CodeEditKit/UIExtensions/Sidebar/SidebarBuilder.swift @@ -11,11 +11,11 @@ import Foundation public struct SidebarBuilder { public static func buildPartialBlock(first: Never) -> Never {} - public static func buildPartialBlock(first: C0) -> some Sidebar { + public static func buildPartialBlock(first: some Sidebar) -> some Sidebar { first } - public static func buildPartialBlock(accumulated: C0, next: C1) -> some Sidebar { + public static func buildPartialBlock(accumulated: some Sidebar, next: some Sidebar) -> some Sidebar { TupleSidebar(accumulated, next) } } From bd433130767b3ece2ff572c9ea7caf70958a58a1 Mon Sep 17 00:00:00 2001 From: Wouter01 Date: Sat, 25 Mar 2023 14:27:53 +0100 Subject: [PATCH 16/30] Small improvements to Extensionkind enum Signed-off-by: Wouter01 --- Sources/CodeEditKit/ExtensionKind.swift | 6 +++--- Sources/CodeEditKit/UIExtensions/Sidebar/Inspector.swift | 4 ++-- Sources/CodeEditKit/UIExtensions/Sidebar/Navigator.swift | 4 ++-- .../CodeEditKit/UIExtensions/Sidebar/ResolvedSidebar.swift | 5 ++--- 4 files changed, 9 insertions(+), 10 deletions(-) diff --git a/Sources/CodeEditKit/ExtensionKind.swift b/Sources/CodeEditKit/ExtensionKind.swift index 4b51300..ef9658d 100644 --- a/Sources/CodeEditKit/ExtensionKind.swift +++ b/Sources/CodeEditKit/ExtensionKind.swift @@ -8,7 +8,7 @@ import SwiftUI public enum ExtensionKind: Codable, Hashable, CustomStringConvertible { - case sidebarItem(sceneID: String, data: ResolvedSidebar.SidebarStore) + case sidebarItem(data: ResolvedSidebar.SidebarStore) case toolbarItem(sceneID: String, placement: CEToolbarItemPlacement) case action(actionID: String) case theme(themeID: String) @@ -16,8 +16,8 @@ public enum ExtensionKind: Codable, Hashable, CustomStringConvertible { public var description: String { switch self { - case .sidebarItem(let sceneID, _): - return "Sidebar with ID \(sceneID)" + case .sidebarItem(let data): + return "Sidebar with ID \(data.sceneID)" case .toolbarItem(let sceneID, let placement): return "Toolbar Item with ID \(sceneID)" case .action(let actionID): diff --git a/Sources/CodeEditKit/UIExtensions/Sidebar/Inspector.swift b/Sources/CodeEditKit/UIExtensions/Sidebar/Inspector.swift index 911c699..d7e8f0c 100644 --- a/Sources/CodeEditKit/UIExtensions/Sidebar/Inspector.swift +++ b/Sources/CodeEditKit/UIExtensions/Sidebar/Inspector.swift @@ -35,7 +35,7 @@ public struct Inspector: Sidebar { } .frame(maxWidth: .infinity, maxHeight: .infinity) } - let store = ResolvedSidebar.SidebarStore(kind: .inspector) - return [ResolvedSidebar(scene: scene, id: id, store: store)] + let store = ResolvedSidebar.SidebarStore(sceneID: id, kind: .inspector) + return [ResolvedSidebar(scene: scene, store: store)] } } diff --git a/Sources/CodeEditKit/UIExtensions/Sidebar/Navigator.swift b/Sources/CodeEditKit/UIExtensions/Sidebar/Navigator.swift index 33ad813..6d7e3f3 100644 --- a/Sources/CodeEditKit/UIExtensions/Sidebar/Navigator.swift +++ b/Sources/CodeEditKit/UIExtensions/Sidebar/Navigator.swift @@ -35,7 +35,7 @@ public struct Navigator: Sidebar { } .frame(maxWidth: .infinity, maxHeight: .infinity) } - let store = ResolvedSidebar.SidebarStore(kind: .navigator) - return [ResolvedSidebar(scene: scene, id: id, store: store)] + let store = ResolvedSidebar.SidebarStore(sceneID: id, kind: .navigator) + return [ResolvedSidebar(scene: scene, store: store)] } } diff --git a/Sources/CodeEditKit/UIExtensions/Sidebar/ResolvedSidebar.swift b/Sources/CodeEditKit/UIExtensions/Sidebar/ResolvedSidebar.swift index 13ab7f1..0d4f9db 100644 --- a/Sources/CodeEditKit/UIExtensions/Sidebar/ResolvedSidebar.swift +++ b/Sources/CodeEditKit/UIExtensions/Sidebar/ResolvedSidebar.swift @@ -16,17 +16,16 @@ public struct ResolvedSidebar { var scene: PrimitiveAppExtensionScene - var id: String - var store: SidebarStore public struct SidebarStore: Codable, Hashable { + public var sceneID: String public var icon: String? public var help: String? public var kind: Kind } var extensionKind: ExtensionKind { - .sidebarItem(sceneID: id, data: store) + .sidebarItem(data: store) } } From 33b69421da6fd56c880325a5f7efed35b4a6e795 Mon Sep 17 00:00:00 2001 From: Wouter01 Date: Sat, 25 Mar 2023 18:23:36 +0100 Subject: [PATCH 17/30] made var weak Signed-off-by: Wouter01 --- Sources/CodeEditKit/CodeEditExtension.swift | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/Sources/CodeEditKit/CodeEditExtension.swift b/Sources/CodeEditKit/CodeEditExtension.swift index f62c2af..9e8def7 100644 --- a/Sources/CodeEditKit/CodeEditExtension.swift +++ b/Sources/CodeEditKit/CodeEditExtension.swift @@ -64,7 +64,7 @@ extension CodeEditExtension { } } -public extension CodeEditExtension { +public extension CodeEditExtension where Self: AnyObject { /// XPC Configuration for communication with CodeEdit. /// Use the default implementation. var configuration: AppExtensionSceneConfiguration { @@ -73,8 +73,12 @@ public extension CodeEditExtension { } -struct SettingsExtensionConfiguration: AppExtensionConfiguration { +struct SettingsExtensionConfiguration: AppExtensionConfiguration { public func accept(connection: NSXPCConnection) -> Bool { + guard let appExtension else { + return false + } + connection.exportedInterface = .init(with: XPCWrappable.self) connection.exportedObject = XPCWrapper(appExtension) connection.resume() @@ -82,7 +86,7 @@ struct SettingsExtensionConfiguration: AppExtensionConfigu return true } - let appExtension: E + weak var appExtension: E? /// Creates a default configuration for the given extension. /// - Parameter appExtension: An instance of your custom extension that conforms to the ``TextTransformExtension`` protocol. From 02bef66bb8a48cda25a86d9d8befb230c68b8776 Mon Sep 17 00:00:00 2001 From: Wouter01 Date: Sun, 26 Mar 2023 15:10:23 +0200 Subject: [PATCH 18/30] Removed old stuff Signed-off-by: Wouter01 --- .../CodeEditKit/CodeEditExtension+Body.swift | 35 ++++----------- Sources/CodeEditKit/CodeEditExtension.swift | 12 +---- Sources/CodeEditKit/ExtensionKind.swift | 3 -- .../Theme/ThemeExtension.swift | 45 ------------------- .../Theme/ThemeItem+Either.swift | 16 ------- .../NonUIExtensions/Theme/ThemeItem.swift | 12 ----- .../UIExtensions/Sidebar/Sidebar.swift | 1 + .../UIExtensions/Sidebar/SidebarNever.swift | 7 ++- .../ToolbarItem/CEToolbarItem+Either.swift | 16 ------- .../ToolbarItem/CEToolbarItem.swift | 17 ------- .../ToolbarItem/ToolbarItemExtension.swift | 33 -------------- Sources/CodeEditKit/XPCWrapper.swift | 20 --------- 12 files changed, 16 insertions(+), 201 deletions(-) delete mode 100644 Sources/CodeEditKit/NonUIExtensions/Theme/ThemeExtension.swift delete mode 100644 Sources/CodeEditKit/NonUIExtensions/Theme/ThemeItem+Either.swift delete mode 100644 Sources/CodeEditKit/NonUIExtensions/Theme/ThemeItem.swift delete mode 100644 Sources/CodeEditKit/UIExtensions/ToolbarItem/CEToolbarItem+Either.swift delete mode 100644 Sources/CodeEditKit/UIExtensions/ToolbarItem/CEToolbarItem.swift delete mode 100644 Sources/CodeEditKit/UIExtensions/ToolbarItem/ToolbarItemExtension.swift diff --git a/Sources/CodeEditKit/CodeEditExtension+Body.swift b/Sources/CodeEditKit/CodeEditExtension+Body.swift index 04cf7b1..dee0683 100644 --- a/Sources/CodeEditKit/CodeEditExtension+Body.swift +++ b/Sources/CodeEditKit/CodeEditExtension+Body.swift @@ -9,53 +9,34 @@ import Foundation import SequenceBuilder import ExtensionKit -public extension CodeEditExtension where Self: SettingsExtension { - var body: some AppExtensionScene { - settingsScene - } -} - -public extension CodeEditExtension where Self: SidebarExtension { - var body: some AppExtensionScene { - sidebarScenes - } -} - -public extension CodeEditExtension where Self: ToolbarItemExtension { - var body: some AppExtensionScene { - toolbarItemScenes +struct EmptyAppExtensionScene: AppExtensionScene { + var body: Never { + fatalError() } } -public extension CodeEditExtension where Self: SettingsExtension & SidebarExtension { - @AppExtensionSceneBuilder +public extension CodeEditExtension { var body: some AppExtensionScene { - settingsScene - sidebarScenes + EmptyAppExtensionScene() } } -public extension CodeEditExtension where Self: SettingsExtension & ToolbarItemExtension { - @AppExtensionSceneBuilder +public extension CodeEditExtension where Self: SettingsExtension { var body: some AppExtensionScene { settingsScene - toolbarItemScenes } } -public extension CodeEditExtension where Self: SidebarExtension & ToolbarItemExtension { - @AppExtensionSceneBuilder +public extension CodeEditExtension where Self: SidebarExtension { var body: some AppExtensionScene { sidebarScenes - toolbarItemScenes } } -public extension CodeEditExtension where Self: SettingsExtension & SidebarExtension & ToolbarItemExtension { +public extension CodeEditExtension where Self: SettingsExtension & SidebarExtension { @AppExtensionSceneBuilder var body: some AppExtensionScene { settingsScene sidebarScenes - toolbarItemScenes } } diff --git a/Sources/CodeEditKit/CodeEditExtension.swift b/Sources/CodeEditKit/CodeEditExtension.swift index 9e8def7..37bf363 100644 --- a/Sources/CodeEditKit/CodeEditExtension.swift +++ b/Sources/CodeEditKit/CodeEditExtension.swift @@ -5,10 +5,9 @@ // Created by Wouter Hennen on 30/12/2022. // -import Foundation import ExtensionKit import ExtensionFoundation -import SwiftUI +@_exported import SwiftUI import SequenceBuilder public protocol CodeEditExtension: AppExtension { @@ -27,7 +26,6 @@ public protocol CodeEditExtension: AppExtension { /// UI scenes of the extension. /// Use the default implementation. - @AppExtensionSceneBuilder var body: Body { get } } @@ -48,17 +46,9 @@ extension CodeEditExtension { extensions.append(.settings) } - if let self = self as? any ThemeExtension { - extensions.append(contentsOf: self.availableExtensions) - } - if let self = self as? any SidebarExtension { extensions.append(contentsOf: self.availableExtensions) } - - if let self = self as? any ToolbarItemExtension { - extensions.append(contentsOf: self.availableExtensions) - } return extensions } diff --git a/Sources/CodeEditKit/ExtensionKind.swift b/Sources/CodeEditKit/ExtensionKind.swift index ef9658d..7c622c1 100644 --- a/Sources/CodeEditKit/ExtensionKind.swift +++ b/Sources/CodeEditKit/ExtensionKind.swift @@ -9,7 +9,6 @@ import SwiftUI public enum ExtensionKind: Codable, Hashable, CustomStringConvertible { case sidebarItem(data: ResolvedSidebar.SidebarStore) - case toolbarItem(sceneID: String, placement: CEToolbarItemPlacement) case action(actionID: String) case theme(themeID: String) case settings @@ -18,8 +17,6 @@ public enum ExtensionKind: Codable, Hashable, CustomStringConvertible { switch self { case .sidebarItem(let data): return "Sidebar with ID \(data.sceneID)" - case .toolbarItem(let sceneID, let placement): - return "Toolbar Item with ID \(sceneID)" case .action(let actionID): return "Action with ID \(actionID)" case .theme(let themeID): diff --git a/Sources/CodeEditKit/NonUIExtensions/Theme/ThemeExtension.swift b/Sources/CodeEditKit/NonUIExtensions/Theme/ThemeExtension.swift deleted file mode 100644 index efa6ea9..0000000 --- a/Sources/CodeEditKit/NonUIExtensions/Theme/ThemeExtension.swift +++ /dev/null @@ -1,45 +0,0 @@ -// -// File.swift -// -// -// Created by Wouter Hennen on 30/12/2022. -// - -import SwiftUI -import SequenceBuilder - -public protocol ThemeExtension { - associatedtype ThemesBody: Sequence where ThemesBody.Element: ThemeItem - - @SequenceBuilder - var themes: ThemesBody { get } -} - -extension ThemeExtension { - var availableExtensions: [ExtensionKind] { - themes.map { ExtensionKind.theme(themeID: $0.id) } - } - - func getTheme(with id: String) -> GeneralThemeItem? { - guard let theme = themes.first(where: { $0.id == id }) else { return nil } - return GeneralThemeItem(theme) - } -} - -public struct GeneralThemeItem: ThemeItem, Codable { - public var id: String - public var label: String - public var description: String - @CodableColorArray public var colors: [NSColor] - - public init(id: String, label: String, description: String = "Generic Theme", colors: [NSColor]) { - self.id = id - self.label = label - self.description = description - self.colors = colors - } - - init(_ theme: any ThemeItem) { - self.init(id: theme.id, label: theme.label, description: theme.description, colors: theme.colors) - } -} diff --git a/Sources/CodeEditKit/NonUIExtensions/Theme/ThemeItem+Either.swift b/Sources/CodeEditKit/NonUIExtensions/Theme/ThemeItem+Either.swift deleted file mode 100644 index 9870c64..0000000 --- a/Sources/CodeEditKit/NonUIExtensions/Theme/ThemeItem+Either.swift +++ /dev/null @@ -1,16 +0,0 @@ -// -// File.swift -// -// -// Created by Wouter Hennen on 30/12/2022. -// - -import SwiftUI -import SequenceBuilder - -extension Either: ThemeItem where Left: ThemeItem, Right: ThemeItem { - - public var colors: [NSColor] { - fold(left: \.colors, right: \.colors) - } -} diff --git a/Sources/CodeEditKit/NonUIExtensions/Theme/ThemeItem.swift b/Sources/CodeEditKit/NonUIExtensions/Theme/ThemeItem.swift deleted file mode 100644 index bceea84..0000000 --- a/Sources/CodeEditKit/NonUIExtensions/Theme/ThemeItem.swift +++ /dev/null @@ -1,12 +0,0 @@ -// -// File.swift -// -// -// Created by Wouter Hennen on 30/12/2022. -// - -import SwiftUI - -public protocol ThemeItem: GenericExtension { - var colors: [NSColor] { get } -} diff --git a/Sources/CodeEditKit/UIExtensions/Sidebar/Sidebar.swift b/Sources/CodeEditKit/UIExtensions/Sidebar/Sidebar.swift index c102a94..3c8a677 100644 --- a/Sources/CodeEditKit/UIExtensions/Sidebar/Sidebar.swift +++ b/Sources/CodeEditKit/UIExtensions/Sidebar/Sidebar.swift @@ -16,6 +16,7 @@ public protocol Sidebar { @_spi(CodeEdit) func resolve(environment: some ObservableObject) -> [ResolvedSidebar] + } public extension Sidebar { diff --git a/Sources/CodeEditKit/UIExtensions/Sidebar/SidebarNever.swift b/Sources/CodeEditKit/UIExtensions/Sidebar/SidebarNever.swift index 791886f..87d872c 100644 --- a/Sources/CodeEditKit/UIExtensions/Sidebar/SidebarNever.swift +++ b/Sources/CodeEditKit/UIExtensions/Sidebar/SidebarNever.swift @@ -7,7 +7,12 @@ import Foundation -extension Never: Sidebar { +extension Swift.Never: Sidebar { + + public var body: Swift.Never { + fatalError() + } + @_spi(CodeEdit) public func resolve(environment: some ObservableObject) -> [ResolvedSidebar] { fatalError() diff --git a/Sources/CodeEditKit/UIExtensions/ToolbarItem/CEToolbarItem+Either.swift b/Sources/CodeEditKit/UIExtensions/ToolbarItem/CEToolbarItem+Either.swift deleted file mode 100644 index b74c834..0000000 --- a/Sources/CodeEditKit/UIExtensions/ToolbarItem/CEToolbarItem+Either.swift +++ /dev/null @@ -1,16 +0,0 @@ -// -// File.swift -// -// -// Created by Wouter Hennen on 30/12/2022. -// - -import SwiftUI -import SequenceBuilder - -extension Either: CEToolbarItem where Left: CEToolbarItem, Right: CEToolbarItem { - - public var placement: CEToolbarItemPlacement { - fold(left: \.placement, right: \.placement) - } -} diff --git a/Sources/CodeEditKit/UIExtensions/ToolbarItem/CEToolbarItem.swift b/Sources/CodeEditKit/UIExtensions/ToolbarItem/CEToolbarItem.swift deleted file mode 100644 index 7ae5803..0000000 --- a/Sources/CodeEditKit/UIExtensions/ToolbarItem/CEToolbarItem.swift +++ /dev/null @@ -1,17 +0,0 @@ -// -// File.swift -// -// -// Created by Wouter Hennen on 30/12/2022. -// - -import Foundation -import SwiftUI - -public protocol CEToolbarItem: View, GenericExtension { - var placement: CEToolbarItemPlacement { get } -} - -extension CEToolbarItem { - public var placement: CEToolbarItemPlacement { .automatic } -} diff --git a/Sources/CodeEditKit/UIExtensions/ToolbarItem/ToolbarItemExtension.swift b/Sources/CodeEditKit/UIExtensions/ToolbarItem/ToolbarItemExtension.swift deleted file mode 100644 index c16c5a4..0000000 --- a/Sources/CodeEditKit/UIExtensions/ToolbarItem/ToolbarItemExtension.swift +++ /dev/null @@ -1,33 +0,0 @@ -// -// File.swift -// -// -// Created by Wouter Hennen on 30/12/2022. -// - -import Foundation -import SequenceBuilder -import ExtensionKit - -public protocol ToolbarItemExtension: ObservableObject { - - associatedtype ToolbarItemBody: Sequence where ToolbarItemBody.Element: CEToolbarItem - - @SequenceBuilder - var toolbaritems: ToolbarItemBody { get } -} - -extension ToolbarItemExtension { - public var toolbarItemScenes: some AppExtensionScene { - toolbaritems.map { nav in - PrimitiveAppExtensionScene(id: nav.id) { - nav.body - .environmentObject(self) - } - } - } - - var availableExtensions: [ExtensionKind] { - toolbaritems.map { ExtensionKind.toolbarItem(sceneID: $0.id, placement: $0.placement) } - } -} diff --git a/Sources/CodeEditKit/XPCWrapper.swift b/Sources/CodeEditKit/XPCWrapper.swift index 53e7006..8c60c9f 100644 --- a/Sources/CodeEditKit/XPCWrapper.swift +++ b/Sources/CodeEditKit/XPCWrapper.swift @@ -20,8 +20,6 @@ public protocol XPCWrappable { func getExtensionKinds(reply: @escaping XPCReply) - func getTheme(reply: @escaping XPCReply) - func doAction(with identifier: String, reply: @escaping XPCReply) } @@ -52,24 +50,6 @@ class XPCWrapper: XPCWrappable { } } - func getTheme(reply: @escaping XPCReply) { - guard let ext = ext as? any ThemeExtension else { - reply(nil, XPCError.extensionDoesNotExist(description: String(describing: (any ThemeExtension).self))) - return - } - let id = "XcodeLightTheme" - guard let theme = ext.getTheme(with: id) else { - reply(nil, XPCError.identifierDoesNotExist(description: id)) - return - } - do { - let encoded = try JSONEncoder().encode(theme) - reply(encoded, nil) - } catch { - reply(nil, error) - } - } - func doAction(with identifier: String, reply: @escaping XPCReply) { } From 104c545bfad8b9a050eca7101676d70a1c4546f2 Mon Sep 17 00:00:00 2001 From: Wouter01 Date: Sun, 26 Mar 2023 15:58:23 +0200 Subject: [PATCH 19/30] Moved icon into sidebar modifier Signed-off-by: Wouter01 --- .../UIExtensions/Sidebar/Inspector.swift | 5 +---- .../UIExtensions/Sidebar/Navigator.swift | 5 +---- .../UIExtensions/Sidebar/Sidebar+Help.swift | 21 +++++++++++++++++++ 3 files changed, 23 insertions(+), 8 deletions(-) diff --git a/Sources/CodeEditKit/UIExtensions/Sidebar/Inspector.swift b/Sources/CodeEditKit/UIExtensions/Sidebar/Inspector.swift index d7e8f0c..112832f 100644 --- a/Sources/CodeEditKit/UIExtensions/Sidebar/Inspector.swift +++ b/Sources/CodeEditKit/UIExtensions/Sidebar/Inspector.swift @@ -15,11 +15,8 @@ public struct Inspector: Sidebar { var id: String - var icon: String - - public init(id: String, icon: String, content: () -> Content) { + public init(id: String, content: () -> Content) { self.id = id - self.icon = icon self.content = content() } diff --git a/Sources/CodeEditKit/UIExtensions/Sidebar/Navigator.swift b/Sources/CodeEditKit/UIExtensions/Sidebar/Navigator.swift index 6d7e3f3..cd3d8e4 100644 --- a/Sources/CodeEditKit/UIExtensions/Sidebar/Navigator.swift +++ b/Sources/CodeEditKit/UIExtensions/Sidebar/Navigator.swift @@ -15,11 +15,8 @@ public struct Navigator: Sidebar { var id: String - var icon: String - - public init(id: String, icon: String, content: () -> Content) { + public init(id: String, content: () -> Content) { self.id = id - self.icon = icon self.content = content() } diff --git a/Sources/CodeEditKit/UIExtensions/Sidebar/Sidebar+Help.swift b/Sources/CodeEditKit/UIExtensions/Sidebar/Sidebar+Help.swift index e3c0732..f9fa287 100644 --- a/Sources/CodeEditKit/UIExtensions/Sidebar/Sidebar+Help.swift +++ b/Sources/CodeEditKit/UIExtensions/Sidebar/Sidebar+Help.swift @@ -25,11 +25,32 @@ struct SidebarHelpModifier: Sidebar { } } +struct SidebarIconModifier: Sidebar { + var icon: String + var content: Content + + var body: Never { + fatalError() + } + + func resolve(environment: some ObservableObject) -> [ResolvedSidebar] { + var sidebars = self.content.resolve(environment: environment) + for index in sidebars.indices { + sidebars[index].store.icon = icon + } + return sidebars + } +} + public extension Sidebar { func help(_ message: String) -> some Sidebar { SidebarHelpModifier(help: message, content: self) } + func icon(_ systemName: String) -> some Sidebar { + SidebarIconModifier(icon: systemName, content: self) + } + func title(_ title: String) -> some Sidebar { self } From 6e27b8f452b86df056e05acca2fed09fbf8f5ea0 Mon Sep 17 00:00:00 2001 From: Wouter01 Date: Mon, 22 May 2023 22:28:43 +0200 Subject: [PATCH 20/30] Update Signed-off-by: Wouter01 --- Package.swift | 4 +- Sources/CodeEditKit/CodeEditExtension.swift | 5 - Sources/CodeEditKit/Debugging/Logging.swift | 13 ++ .../LSP/LanguageExtension.swift | 150 ++++++++++++++++++ Sources/CodeEditKit/XPCWrapper.swift | 6 + Sources/CodeEditKit/_.swift | 8 + .../Example/ExampleSidebar.swift | 18 --- .../Example/ExampleToolbarItem.swift | 22 --- .../Example/FirstExtension.swift | 78 --------- 9 files changed, 180 insertions(+), 124 deletions(-) create mode 100644 Sources/CodeEditKit/Debugging/Logging.swift create mode 100644 Sources/CodeEditKit/NonUIExtensions/LSP/LanguageExtension.swift create mode 100644 Sources/CodeEditKit/_.swift delete mode 100644 Tests/CodeEditKitTests/Example/ExampleSidebar.swift delete mode 100644 Tests/CodeEditKitTests/Example/ExampleToolbarItem.swift delete mode 100644 Tests/CodeEditKitTests/Example/FirstExtension.swift diff --git a/Package.swift b/Package.swift index 017b33b..ece5d74 100644 --- a/Package.swift +++ b/Package.swift @@ -16,6 +16,8 @@ let package = Package( dependencies: [ .package(url: "https://github.com/andtie/SequenceBuilder", branch: "main"), .package(url: "https://github.com/ChimeHQ/ConcurrencyPlus", branch: "main"), + .package(url: "https://github.com/ChimeHQ/LanguageClient", exact: "0.4.0"), + .package(url: "https://github.com/ChimeHQ/ProcessService", from: "0.2.6"), .package( url: "https://github.com/Flight-School/AnyCodable", from: "0.6.0" @@ -24,7 +26,7 @@ let package = Package( targets: [ .target( name: "CodeEditKit", - dependencies: ["SequenceBuilder", "AnyCodable", "ConcurrencyPlus"]), + dependencies: ["SequenceBuilder", "AnyCodable", "ConcurrencyPlus", "LanguageClient", .product(name: "ProcessServiceClient", package: "ProcessService")]), .testTarget( name: "CodeEditKitTests", dependencies: ["CodeEditKit"]), diff --git a/Sources/CodeEditKit/CodeEditExtension.swift b/Sources/CodeEditKit/CodeEditExtension.swift index 37bf363..c00532b 100644 --- a/Sources/CodeEditKit/CodeEditExtension.swift +++ b/Sources/CodeEditKit/CodeEditExtension.swift @@ -7,7 +7,6 @@ import ExtensionKit import ExtensionFoundation -@_exported import SwiftUI import SequenceBuilder public protocol CodeEditExtension: AppExtension { @@ -29,10 +28,6 @@ public protocol CodeEditExtension: AppExtension { var body: Body { get } } -public extension CodeEditExtension { - static var shared: Self { Self() } -} - extension CodeEditExtension { var extensionURL: URL { diff --git a/Sources/CodeEditKit/Debugging/Logging.swift b/Sources/CodeEditKit/Debugging/Logging.swift new file mode 100644 index 0000000..bcca638 --- /dev/null +++ b/Sources/CodeEditKit/Debugging/Logging.swift @@ -0,0 +1,13 @@ +// +// File.swift +// +// +// Created by Wouter Hennen on 22/05/2023. +// + +import Foundation + +public func print(_ items: Any..., separator: String = " ", terminator: String = "\n") { + let formedString = items.map { String(describing: $0) }.joined(separator: separator) + NSLog(formedString) +} diff --git a/Sources/CodeEditKit/NonUIExtensions/LSP/LanguageExtension.swift b/Sources/CodeEditKit/NonUIExtensions/LSP/LanguageExtension.swift new file mode 100644 index 0000000..58a2b45 --- /dev/null +++ b/Sources/CodeEditKit/NonUIExtensions/LSP/LanguageExtension.swift @@ -0,0 +1,150 @@ +// +// File.swift +// +// +// Created by Wouter Hennen on 27/03/2023. +// + +import Foundation +import LanguageClient +import Combine +import OSLog +import ProcessServiceClient +import ConcurrencyPlus +import LanguageServerProtocol +import ProcessEnv +import JSONRPC + +protocol LanguageExtension { + var client: RemoteLanguageServer { get } + +} + +final class UnrestrictedProcessTransport { + private var readHandler: ReadHandler = { _ in } + private let process: HostedProcess + private let taskQueue = TaskQueue() + private var subscription: AnyCancellable? = nil + private let logger = Logger(subsystem: "com.chimehq.ChimeKit", category: "UnrestrictedProcessTransport") + + init(process: HostedProcess) { + self.process = process + } + + func beginMonitoringProcess() async throws { + let task = taskQueue.addOperation { + self.subscription = try await self.process.processEventPublisher + .sink(receiveCompletion: { _ in + }, receiveValue: { [weak self] event in + switch event { + case .stdout(let data): + self?.readHandler(data) + case .stderr(let data): + let output = String(data: data, encoding: .utf8) ?? "" + + self?.logger.info("stderr: \(output, privacy: .public)") + default: + break + } + }) + } + + try await task.value + } +} + +extension UnrestrictedProcessTransport: DataTransport { + func write(_ data: Data) { + taskQueue.addOperation { + try await self.process.write(data) + } + } + + func setReaderHandler(_ handler: @escaping ReadHandler) { + self.readHandler = handler + } + + func close() { + subscription?.cancel() + } +} + +/// Provides an interface to a LSP language server hosted by an intermediary process. +public class RemoteLanguageServer { + private let wrappedServer: JSONRPCLanguageServer + private var subscription: AnyCancellable? = nil + private let logger = Logger(subsystem: "com.chimehq.ChimeKit", category: "RemoteLanguageServer") + + private let process: HostedProcess + private let taskQueue = TaskQueue() + public var terminationHandler: (() -> Void)? = nil + + init(named serviceName: String, parameters: Process.ExecutionParameters) throws { + self.process = HostedProcess(named: serviceName, parameters: parameters) + let transport = UnrestrictedProcessTransport(process: process) + self.wrappedServer = JSONRPCLanguageServer(dataTransport: transport) + + taskQueue.addOperation { + self.logger.debug("launching remote server") + + do { + try await self.process.launch() + + self.subscription = try await self.process.processEventPublisher + .sink(receiveCompletion: { _ in + + }, receiveValue: { event in + switch event { + case .terminated: + self.terminationHandler?() + default: + break + } + }) + + try await transport.beginMonitoringProcess() + } catch { + self.logger.error("failed to launch: \(String(describing: error), privacy: .public)") + } + } + } + + private func stopProcess() { + self.taskQueue.addOperation { + do { + try await self.process.terminate() + } catch { + self.logger.error("failed to terminate: \(String(describing: error), privacy: .public)") + } + } + } + + public var logMessages: Bool { + get { return wrappedServer.logMessages } + set { wrappedServer.logMessages = newValue } + } +} + +extension RemoteLanguageServer: LanguageServerProtocol.Server { + public func setHandlers(_ handlers: ServerHandlers, completionHandler: @escaping (ServerError?) -> Void) { + wrappedServer.setHandlers(handlers, completionHandler: completionHandler) + } + + public func sendNotification(_ notif: ClientNotification, completionHandler: @escaping (ServerError?) -> Void) { + taskQueue.addOperation { + self.wrappedServer.sendNotification(notif, completionHandler: completionHandler) + } + } + + public func sendRequest(_ request: ClientRequest, completionHandler: @escaping (ServerResult) -> Void) { + taskQueue.addOperation { + self.wrappedServer.sendRequest(request, completionHandler: { (result: ServerResult) in + if case .success = result, case .shutdown = request { + self.stopProcess() + } + + completionHandler(result) + }) + } + } +} diff --git a/Sources/CodeEditKit/XPCWrapper.swift b/Sources/CodeEditKit/XPCWrapper.swift index 8c60c9f..8822dba 100644 --- a/Sources/CodeEditKit/XPCWrapper.swift +++ b/Sources/CodeEditKit/XPCWrapper.swift @@ -20,6 +20,8 @@ public protocol XPCWrappable { func getExtensionKinds(reply: @escaping XPCReply) + func getExtensionProcessIdentifier(reply: @escaping (Int32) -> Void) + func doAction(with identifier: String, reply: @escaping XPCReply) } @@ -50,6 +52,10 @@ class XPCWrapper: XPCWrappable { } } + func getExtensionProcessIdentifier(reply: @escaping (Int32) -> Void) { + reply(ProcessInfo.processInfo.processIdentifier) + } + func doAction(with identifier: String, reply: @escaping XPCReply) { } diff --git a/Sources/CodeEditKit/_.swift b/Sources/CodeEditKit/_.swift new file mode 100644 index 0000000..aed4fc2 --- /dev/null +++ b/Sources/CodeEditKit/_.swift @@ -0,0 +1,8 @@ +// +// File.swift +// +// +// Created by Wouter Hennen on 22/05/2023. +// + +@_exported import SwiftUI diff --git a/Tests/CodeEditKitTests/Example/ExampleSidebar.swift b/Tests/CodeEditKitTests/Example/ExampleSidebar.swift deleted file mode 100644 index fcf63f9..0000000 --- a/Tests/CodeEditKitTests/Example/ExampleSidebar.swift +++ /dev/null @@ -1,18 +0,0 @@ -// -// File.swift -// -// -// Created by Wouter Hennen on 30/12/2022. -// - -import SwiftUI -import CodeEditKit - -struct ExampleSidebar: SidebarItem { - var icon: String = "star" - var label: String = "Example Sidebar" - var description: String = "This is a description of the sidebar" - var body: some View { - Text("Piep") - } -} diff --git a/Tests/CodeEditKitTests/Example/ExampleToolbarItem.swift b/Tests/CodeEditKitTests/Example/ExampleToolbarItem.swift deleted file mode 100644 index b2a93ee..0000000 --- a/Tests/CodeEditKitTests/Example/ExampleToolbarItem.swift +++ /dev/null @@ -1,22 +0,0 @@ -// -// File.swift -// -// -// Created by Wouter Hennen on 30/12/2022. -// - -import SwiftUI -import CodeEditKit - -struct ExampleToolbarItem: CEToolbarItem { - var label: String = "Example Toolbar" - - var description: String = "This is the description" - - var placement: ToolbarItemPlacement = .principal - var body: some View { - Button("Test") { - - } - } -} diff --git a/Tests/CodeEditKitTests/Example/FirstExtension.swift b/Tests/CodeEditKitTests/Example/FirstExtension.swift deleted file mode 100644 index dcb76a0..0000000 --- a/Tests/CodeEditKitTests/Example/FirstExtension.swift +++ /dev/null @@ -1,78 +0,0 @@ -// -// File.swift -// -// -// Created by Wouter Hennen on 30/12/2022. -// - -import SwiftUI -import ExtensionKit -import CodeEditKit - -@main -final class ExampleExtension: CodeEditExtension { - var description: String = "This is an example extension" - - var entitlements: [Entitlement] = [.currentfile] -} - -extension ExampleExtension: SettingsExtension { - var settings: some View { - SettingsView() - } -} - -struct SettingsView: View { - @State var enabled = false - var body: some View { - Toggle("Enabled", isOn: $enabled) - } -} - -extension ExampleExtension: SidebarExtension { - var sidebars: [some SidebarItem] { - ExampleSidebar() - } -} - -extension ExampleExtension: ActionExtension { - var actions: [some CEAction] { - - ShortcutAction("Test") { - print("Blablabla") - } - - ShortcutAction("Test2") { - print("Blablabla") - } - - ToolbarAction("Test") { - print("Hello") - } - } -} - -extension ExampleExtension: ToolbarItemExtension { - var toolbaritems: [some CEToolbarItem] { - ExampleToolbarItem() - } -} - -extension ExampleExtension: ThemeExtension { - var themes: [some ThemeItem] { - XcodeLightTheme() - } -} - -struct XcodeLightTheme: ThemeItem { - - var label: String = "Xcode Light Theme" - - var description: String = "This is the Xcode light theme" - - var colors: [NSColor] = [.blue] -} - - - - From 2aeca8c9fc421280565b066ebeb53ed11586f0f6 Mon Sep 17 00:00:00 2001 From: Wouter01 Date: Mon, 22 May 2023 23:21:21 +0200 Subject: [PATCH 21/30] update dependency Signed-off-by: Wouter01 --- Package.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Package.swift b/Package.swift index ece5d74..c74c89d 100644 --- a/Package.swift +++ b/Package.swift @@ -16,7 +16,7 @@ let package = Package( dependencies: [ .package(url: "https://github.com/andtie/SequenceBuilder", branch: "main"), .package(url: "https://github.com/ChimeHQ/ConcurrencyPlus", branch: "main"), - .package(url: "https://github.com/ChimeHQ/LanguageClient", exact: "0.4.0"), + .package(url: "https://github.com/ChimeHQ/LanguageClient", from: "0.5.0"), .package(url: "https://github.com/ChimeHQ/ProcessService", from: "0.2.6"), .package( url: "https://github.com/Flight-School/AnyCodable", From e09f0948a148e75fef942453e7fbc2505e8b13be Mon Sep 17 00:00:00 2001 From: Wouter01 Date: Tue, 23 May 2023 04:10:54 +0200 Subject: [PATCH 22/30] Added docs Signed-off-by: Wouter01 --- Package.resolved | 63 +++++++++++++++++++ .../Documentation.docc/CodeEditExtension.md | 4 +- .../Documentation.docc/Documentation.md | 28 ++++++--- .../Documentation.docc/Settings.md | 32 +++++++++- .../Documentation.docc/Sidebars.md | 51 +++++++++++++-- Sources/CodeEditKit/XPCWrapper.swift | 10 +++ Sources/CodeEditKit/_.swift | 8 --- 7 files changed, 173 insertions(+), 23 deletions(-) delete mode 100644 Sources/CodeEditKit/_.swift diff --git a/Package.resolved b/Package.resolved index 018481d..3197a87 100644 --- a/Package.resolved +++ b/Package.resolved @@ -18,6 +18,69 @@ "revision" : "b5ba8d5ea6bfe9e43ccc44aa63f9b458057fa0f4" } }, + { + "identity" : "fseventswrapper", + "kind" : "remoteSourceControl", + "location" : "https://github.com/Frizlab/FSEventsWrapper", + "state" : { + "revision" : "e0c59a2ce2775e5f6642da6d19207445f10112d0", + "version" : "1.0.2" + } + }, + { + "identity" : "glob", + "kind" : "remoteSourceControl", + "location" : "https://github.com/Bouke/Glob", + "state" : { + "revision" : "deda6e163d2ff2a8d7e138e2c3326dbd71157faf", + "version" : "1.0.5" + } + }, + { + "identity" : "jsonrpc", + "kind" : "remoteSourceControl", + "location" : "https://github.com/ChimeHQ/JSONRPC", + "state" : { + "revision" : "afc20d00e38674774f84edc325424a32ae3b9e01", + "version" : "0.7.0" + } + }, + { + "identity" : "languageclient", + "kind" : "remoteSourceControl", + "location" : "https://github.com/ChimeHQ/LanguageClient", + "state" : { + "revision" : "92beeecd0bb783da52227839ba6c55e43fc866ec", + "version" : "0.5.1" + } + }, + { + "identity" : "languageserverprotocol", + "kind" : "remoteSourceControl", + "location" : "https://github.com/ChimeHQ/LanguageServerProtocol", + "state" : { + "revision" : "9293fd8a3b4298bab12475ff46f793a6d4055f0e", + "version" : "0.9.0" + } + }, + { + "identity" : "processenv", + "kind" : "remoteSourceControl", + "location" : "https://github.com/ChimeHQ/ProcessEnv", + "state" : { + "revision" : "29487b6581bb785c372c611c943541ef4309d051", + "version" : "0.3.1" + } + }, + { + "identity" : "processservice", + "kind" : "remoteSourceControl", + "location" : "https://github.com/ChimeHQ/ProcessService", + "state" : { + "revision" : "369fb0379983d3b43c7d7ad62c4e91ee020e347c", + "version" : "0.2.6" + } + }, { "identity" : "sequencebuilder", "kind" : "remoteSourceControl", diff --git a/Sources/CodeEditKit/Documentation.docc/CodeEditExtension.md b/Sources/CodeEditKit/Documentation.docc/CodeEditExtension.md index dcd373b..a201c4e 100644 --- a/Sources/CodeEditKit/Documentation.docc/CodeEditExtension.md +++ b/Sources/CodeEditKit/Documentation.docc/CodeEditExtension.md @@ -4,7 +4,7 @@ @DocumentationExtension(mergeBehavior: append) } -The mother of all extensions. +The base extension. ## Overview @@ -13,7 +13,7 @@ This protocol provides basic information about the extension, such as the ``desc This type is the entrypoint of your extension, so it should be marked with `@main`. -Additional extensions can be defined by extending the struct that implements ``CodeEditExtension``. +Additional extensions can be defined by extending the class that implements ``CodeEditExtension``. ## Example diff --git a/Sources/CodeEditKit/Documentation.docc/Documentation.md b/Sources/CodeEditKit/Documentation.docc/Documentation.md index c3123d8..45b0f19 100644 --- a/Sources/CodeEditKit/Documentation.docc/Documentation.md +++ b/Sources/CodeEditKit/Documentation.docc/Documentation.md @@ -13,20 +13,34 @@ CodeEditKit aims to provide an easy and straightforward API to implement these e There are lots of extension types you can use to extend the functionality of CodeEdit. #### General Extensions -- -- +- (WIP) +- (Not Started) #### Language Extensions -- -- +- (Not Started) +- (WIP) #### UI Extensions -- -- -- +- ``SidebarExtension`` (Beta) +- (WIP) +- (Beta) ### Getting Started First, have a look at ``CodeEditExtension``. This is the base protocol that will define the main structure of your extension. All extensions that you'll add will extend (:p) this type. Next, try adding an extension to your newly created type. A good first recommendation is the extension, as you'll likely need this later. + +### Development & Debugging +Developing extensions with ExtensionKit has a few annoyances: +- Prints do not appear in the Xcode console. Instead, the debug information of CodeEdit (not the extension) is printed. +- Modifying extension requires CodeEdit reload. +- An extension needs to be sandboxed. + +CodeEdit tries to overcome these issues by offering a few solutions. + +First, CodeEdit is able to capture log messages (which are also sent to Console.app). Therefore, CodeEdit provides a custom ``print(_:separator:terminator:)`` function which works the same as Swift's one, except it sends its input as an OSLog instead of printing it to stdout. With this change, you are able to view your extensions' outputs in CodeEdit's console. Later on, an extra toggle will be provided which will also print the changes to Xcode's console. + +Additionally, if you choose to use the powerful Logger system to debug, CodeEdit provides support for various log types and will color them accordingly. + +Next, CodeEdit supports a way of hot reloading your extension. Instead of relaunching CodeEdit and the extension, only the extension is restarted, resulting in faster load times. To make use of this, build your extension instead of running it (⌘B instead of ⌘R). Note that this feature is still in beta and may behave unexpectedly. diff --git a/Sources/CodeEditKit/Documentation.docc/Settings.md b/Sources/CodeEditKit/Documentation.docc/Settings.md index 883a1ed..2826d1c 100644 --- a/Sources/CodeEditKit/Documentation.docc/Settings.md +++ b/Sources/CodeEditKit/Documentation.docc/Settings.md @@ -4,7 +4,37 @@ ## Overview -Text +The ``SettingsExtension`` allows an extension to provide additional settings to the settings window of CodeEdit. +Extension-specific settings can be configured this way. + +``SettingsExtension`` expects a SwiftUI View and doesn't take care of the storage of settings. Therefore, you are responsible for storing your extensions' settings in an appropriate manner. + +## Example + +```swift +@main +final class SettingsExampleExtension: CodeEditExtension { + + var description: String = "" + + var entitlements: [Entitlement] = [.currentfile] + +} + +extension SettingsExampleExtension: SettingsExtension { + var settings: some View { + SettingsView() + } +} + +struct SettingsView: View { + @AppStorage("appstoragekey") var appstoragekey = false + + var body: some View { + Toggle("App Storage Key", isOn: $appstoragekey) + } +} +``` ## Topics diff --git a/Sources/CodeEditKit/Documentation.docc/Sidebars.md b/Sources/CodeEditKit/Documentation.docc/Sidebars.md index 234d7f8..b646d6a 100644 --- a/Sources/CodeEditKit/Documentation.docc/Sidebars.md +++ b/Sources/CodeEditKit/Documentation.docc/Sidebars.md @@ -1,13 +1,54 @@ -# Sidebars +# ``CodeEditKit/SidebarExtension`` -Summary +@Metadata { + @DocumentationExtension(mergeBehavior: append) +} + +Navigator & Inspector UI Extensions ## Overview -Text +The ``SidebarExtension`` protocol takes care of Navigator and Inspector extensions. These extensions are added to the tabbar of each sidebar, and can be selected by the user. + +## Example + +```swift +@main +final class SidebarExtensionExample: CodeEditExtension { + var description: String = "" + + var entitlements: [Entitlement] = [] +} + +extension SidebarExtensionExample: SidebarExtension { + var sidebars: some Sidebar { + Inspector(id: "umbrellaInspector") { + Form { + Text("Hello, world!") + } + .formStyle(.grouped) + } + .help("Umbrella Inspector") + .icon("umbrella") + + Navigator(id: "carrotNavigator") { + Form { + Text("Hello, world!") + } + .formStyle(.grouped) + } + .help("Carrot Navigator") + .icon("carrot") + } +} + +``` ## Topics -### Group +### Sidebar Modifiers -- ``Symbol`` +- ``Sidebar/help(_:)`` +- ``Sidebar/icon(_:)`` +- ``Sidebar/description(_:)`` +- ``Sidebar/title(_:)`` diff --git a/Sources/CodeEditKit/XPCWrapper.swift b/Sources/CodeEditKit/XPCWrapper.swift index 8822dba..11d24ab 100644 --- a/Sources/CodeEditKit/XPCWrapper.swift +++ b/Sources/CodeEditKit/XPCWrapper.swift @@ -23,6 +23,8 @@ public protocol XPCWrappable { func getExtensionProcessIdentifier(reply: @escaping (Int32) -> Void) func doAction(with identifier: String, reply: @escaping XPCReply) + + func isDebug(reply: @escaping (Bool) -> Void) } @@ -59,4 +61,12 @@ class XPCWrapper: XPCWrappable { func doAction(with identifier: String, reply: @escaping XPCReply) { } + + func isDebug(reply: @escaping (Bool) -> Void) { +#if DEBUG + reply(true) +#else + reply(false) +#endif + } } diff --git a/Sources/CodeEditKit/_.swift b/Sources/CodeEditKit/_.swift deleted file mode 100644 index aed4fc2..0000000 --- a/Sources/CodeEditKit/_.swift +++ /dev/null @@ -1,8 +0,0 @@ -// -// File.swift -// -// -// Created by Wouter Hennen on 22/05/2023. -// - -@_exported import SwiftUI From b45129649da8716f1c30f5189642a9bd961d678a Mon Sep 17 00:00:00 2001 From: Wouter01 Date: Tue, 23 May 2023 14:15:44 +0200 Subject: [PATCH 23/30] removed deprecated code Signed-off-by: Wouter01 --- Package.resolved | 9 ------- Package.swift | 3 +-- .../CodeEditKit/CEToolbarItemPlacement.swift | 22 ---------------- .../CodeEditKit/CodeEditExtension+Body.swift | 1 - Sources/CodeEditKit/CodeEditExtension.swift | 1 - Sources/CodeEditKit/Debugging/Logging.swift | 2 +- .../GenericExtension/GenericExtension.swift | 25 ------------------- .../Actions/ActionExtension.swift | 16 ------------ .../NonUIExtensions/Actions/ActionKind.swift | 13 ---------- .../Actions/CEAction+Either.swift | 20 --------------- .../NonUIExtensions/Actions/CEAction.swift | 14 ----------- .../Actions/ShortcutAction.swift | 25 ------------------- .../Actions/ToolbarAction.swift | 24 ------------------ .../Sidebar/SidebarExtension.swift | 1 - 14 files changed, 2 insertions(+), 174 deletions(-) delete mode 100644 Sources/CodeEditKit/CEToolbarItemPlacement.swift delete mode 100644 Sources/CodeEditKit/GenericExtension/GenericExtension.swift delete mode 100644 Sources/CodeEditKit/NonUIExtensions/Actions/ActionExtension.swift delete mode 100644 Sources/CodeEditKit/NonUIExtensions/Actions/ActionKind.swift delete mode 100644 Sources/CodeEditKit/NonUIExtensions/Actions/CEAction+Either.swift delete mode 100644 Sources/CodeEditKit/NonUIExtensions/Actions/CEAction.swift delete mode 100644 Sources/CodeEditKit/NonUIExtensions/Actions/ShortcutAction.swift delete mode 100644 Sources/CodeEditKit/NonUIExtensions/Actions/ToolbarAction.swift diff --git a/Package.resolved b/Package.resolved index 3197a87..bfbe90a 100644 --- a/Package.resolved +++ b/Package.resolved @@ -80,15 +80,6 @@ "revision" : "369fb0379983d3b43c7d7ad62c4e91ee020e347c", "version" : "0.2.6" } - }, - { - "identity" : "sequencebuilder", - "kind" : "remoteSourceControl", - "location" : "https://github.com/andtie/SequenceBuilder", - "state" : { - "branch" : "main", - "revision" : "54d3d1eff31a7e35122f616840fff11899ea85b4" - } } ], "version" : 2 diff --git a/Package.swift b/Package.swift index c74c89d..5f55b82 100644 --- a/Package.swift +++ b/Package.swift @@ -14,7 +14,6 @@ let package = Package( targets: ["CodeEditKit"]), ], dependencies: [ - .package(url: "https://github.com/andtie/SequenceBuilder", branch: "main"), .package(url: "https://github.com/ChimeHQ/ConcurrencyPlus", branch: "main"), .package(url: "https://github.com/ChimeHQ/LanguageClient", from: "0.5.0"), .package(url: "https://github.com/ChimeHQ/ProcessService", from: "0.2.6"), @@ -26,7 +25,7 @@ let package = Package( targets: [ .target( name: "CodeEditKit", - dependencies: ["SequenceBuilder", "AnyCodable", "ConcurrencyPlus", "LanguageClient", .product(name: "ProcessServiceClient", package: "ProcessService")]), + dependencies: ["AnyCodable", "ConcurrencyPlus", "LanguageClient", .product(name: "ProcessServiceClient", package: "ProcessService")]), .testTarget( name: "CodeEditKitTests", dependencies: ["CodeEditKit"]), diff --git a/Sources/CodeEditKit/CEToolbarItemPlacement.swift b/Sources/CodeEditKit/CEToolbarItemPlacement.swift deleted file mode 100644 index 60c9d05..0000000 --- a/Sources/CodeEditKit/CEToolbarItemPlacement.swift +++ /dev/null @@ -1,22 +0,0 @@ -// -// File.swift -// -// -// Created by Wouter Hennen on 30/12/2022. -// - -import SwiftUI - -public enum CEToolbarItemPlacement: Codable { - case automatic - case principal - - public var toolbarItemPlacement: ToolbarItemPlacement { - switch self { - case .automatic: - return .automatic - case .principal: - return .principal - } - } -} diff --git a/Sources/CodeEditKit/CodeEditExtension+Body.swift b/Sources/CodeEditKit/CodeEditExtension+Body.swift index dee0683..b0a3b33 100644 --- a/Sources/CodeEditKit/CodeEditExtension+Body.swift +++ b/Sources/CodeEditKit/CodeEditExtension+Body.swift @@ -6,7 +6,6 @@ // import Foundation -import SequenceBuilder import ExtensionKit struct EmptyAppExtensionScene: AppExtensionScene { diff --git a/Sources/CodeEditKit/CodeEditExtension.swift b/Sources/CodeEditKit/CodeEditExtension.swift index c00532b..9799c34 100644 --- a/Sources/CodeEditKit/CodeEditExtension.swift +++ b/Sources/CodeEditKit/CodeEditExtension.swift @@ -7,7 +7,6 @@ import ExtensionKit import ExtensionFoundation -import SequenceBuilder public protocol CodeEditExtension: AppExtension { diff --git a/Sources/CodeEditKit/Debugging/Logging.swift b/Sources/CodeEditKit/Debugging/Logging.swift index bcca638..9171113 100644 --- a/Sources/CodeEditKit/Debugging/Logging.swift +++ b/Sources/CodeEditKit/Debugging/Logging.swift @@ -1,5 +1,5 @@ // -// File.swift +// Logging.swift // // // Created by Wouter Hennen on 22/05/2023. diff --git a/Sources/CodeEditKit/GenericExtension/GenericExtension.swift b/Sources/CodeEditKit/GenericExtension/GenericExtension.swift deleted file mode 100644 index 0b24a5c..0000000 --- a/Sources/CodeEditKit/GenericExtension/GenericExtension.swift +++ /dev/null @@ -1,25 +0,0 @@ -// -// File.swift -// -// -// Created by Wouter Hennen on 02/01/2023. -// - -import Foundation -import SequenceBuilder - -public protocol GenericExtension: Identifiable, CustomStringConvertible where ID == String { - var label: String { get } -} - -public extension GenericExtension { - var id: String { - String(describing: Self.self) - } -} - -extension Either: GenericExtension where Left: GenericExtension, Right: GenericExtension { - public var label: String { - fold(left: \.label, right: \.label) - } -} diff --git a/Sources/CodeEditKit/NonUIExtensions/Actions/ActionExtension.swift b/Sources/CodeEditKit/NonUIExtensions/Actions/ActionExtension.swift deleted file mode 100644 index deed0b7..0000000 --- a/Sources/CodeEditKit/NonUIExtensions/Actions/ActionExtension.swift +++ /dev/null @@ -1,16 +0,0 @@ -// -// File.swift -// -// -// Created by Wouter Hennen on 30/12/2022. -// - -import Foundation -import SequenceBuilder - -public protocol ActionExtension { - associatedtype ActionsBody: Sequence where ActionsBody.Element: CEAction - - @SequenceBuilder - var actions: ActionsBody { get } -} diff --git a/Sources/CodeEditKit/NonUIExtensions/Actions/ActionKind.swift b/Sources/CodeEditKit/NonUIExtensions/Actions/ActionKind.swift deleted file mode 100644 index 51d309e..0000000 --- a/Sources/CodeEditKit/NonUIExtensions/Actions/ActionKind.swift +++ /dev/null @@ -1,13 +0,0 @@ -// -// File.swift -// -// -// Created by Wouter Hennen on 30/12/2022. -// - -import Foundation - -public enum ActionKind { - case shortcut - case toolbar -} diff --git a/Sources/CodeEditKit/NonUIExtensions/Actions/CEAction+Either.swift b/Sources/CodeEditKit/NonUIExtensions/Actions/CEAction+Either.swift deleted file mode 100644 index 666db78..0000000 --- a/Sources/CodeEditKit/NonUIExtensions/Actions/CEAction+Either.swift +++ /dev/null @@ -1,20 +0,0 @@ -// -// File.swift -// -// -// Created by Wouter Hennen on 30/12/2022. -// - -import Foundation -import SequenceBuilder - -extension Either: CEAction where Left: CEAction, Right: CEAction { - - public var kind: ActionKind { - fold(left: \.kind, right: \.kind) - } - - public var action: () -> Void { - fold(left: \.action, right: \.action) - } -} diff --git a/Sources/CodeEditKit/NonUIExtensions/Actions/CEAction.swift b/Sources/CodeEditKit/NonUIExtensions/Actions/CEAction.swift deleted file mode 100644 index 61c9b99..0000000 --- a/Sources/CodeEditKit/NonUIExtensions/Actions/CEAction.swift +++ /dev/null @@ -1,14 +0,0 @@ -// -// File.swift -// -// -// Created by Wouter Hennen on 30/12/2022. -// - -import Foundation - -public protocol CEAction: GenericExtension { - - var kind: ActionKind { get } - var action: () -> Void { get } -} diff --git a/Sources/CodeEditKit/NonUIExtensions/Actions/ShortcutAction.swift b/Sources/CodeEditKit/NonUIExtensions/Actions/ShortcutAction.swift deleted file mode 100644 index d4c5d07..0000000 --- a/Sources/CodeEditKit/NonUIExtensions/Actions/ShortcutAction.swift +++ /dev/null @@ -1,25 +0,0 @@ -// -// File.swift -// -// -// Created by Wouter Hennen on 30/12/2022. -// - -import Foundation - -public struct ShortcutAction: CEAction { - public var kind: ActionKind = .shortcut - - public var label: String - public var id: String { "shortcut\(label)"} - - public var description: String - - public var action: () -> Void - - public init(_ label: String, description: String = "Short description", action: @escaping () -> Void) { - self.label = label - self.description = description - self.action = action - } -} diff --git a/Sources/CodeEditKit/NonUIExtensions/Actions/ToolbarAction.swift b/Sources/CodeEditKit/NonUIExtensions/Actions/ToolbarAction.swift deleted file mode 100644 index 84988e6..0000000 --- a/Sources/CodeEditKit/NonUIExtensions/Actions/ToolbarAction.swift +++ /dev/null @@ -1,24 +0,0 @@ -// -// File.swift -// -// -// Created by Wouter Hennen on 30/12/2022. -// - -import Foundation - -public struct ToolbarAction: CEAction { - public var kind: ActionKind = .toolbar - - public var label: String - public var id: String { "toolbar\(label)"} - - public var description: String - public var action: () -> Void - - public init(_ label: String, description: String = "Toolbar action", action: @escaping () -> Void) { - self.label = label - self.description = description - self.action = action - } -} diff --git a/Sources/CodeEditKit/UIExtensions/Sidebar/SidebarExtension.swift b/Sources/CodeEditKit/UIExtensions/Sidebar/SidebarExtension.swift index 54ca0ee..61aa568 100644 --- a/Sources/CodeEditKit/UIExtensions/Sidebar/SidebarExtension.swift +++ b/Sources/CodeEditKit/UIExtensions/Sidebar/SidebarExtension.swift @@ -6,7 +6,6 @@ // import Foundation -import SequenceBuilder import ExtensionKit import SwiftUI From fd5cbba9fcde0f3a00a41770b67a7c3f10cdb152 Mon Sep 17 00:00:00 2001 From: Wouter01 Date: Tue, 23 May 2023 14:44:46 +0200 Subject: [PATCH 24/30] add swiftlint and fix warnings Signed-off-by: Wouter01 --- .swiftlint.yml | 9 +- Package.resolved | 87 ++++++++++++++++++- Package.swift | 5 +- Sources/CodeEditKit/CodeEditExtension.swift | 10 +-- Sources/CodeEditKit/ExtensionKind.swift | 2 - Sources/CodeEditKit/GenericScene.swift | 1 - .../LSP/LanguageExtension.swift | 6 +- .../Environment/CEEnvironment.swift | 6 +- .../EnvironmentObjcPublisher.swift | 3 +- .../Settings/GeneralSettingsScene.swift | 1 - .../UIExtensions/Sidebar/Sidebar.swift | 2 - .../Sidebar/SidebarExtension.swift | 1 - Sources/CodeEditKit/XPCWrapper.swift | 1 - 13 files changed, 101 insertions(+), 33 deletions(-) diff --git a/.swiftlint.yml b/.swiftlint.yml index 8c2e0c0..ecb6b36 100644 --- a/.swiftlint.yml +++ b/.swiftlint.yml @@ -1,9 +1,10 @@ disabled_rules: - - todo - - trailing_comma - - nesting + - force_cast + +line_length: 160 type_name: + allowed_symbols: ['_'] excluded: - ID @@ -11,6 +12,4 @@ identifier_name: min_length: 2 allowed_symbols: ['_'] excluded: - - c - id - - vc diff --git a/Package.resolved b/Package.resolved index bfbe90a..8e47f41 100644 --- a/Package.resolved +++ b/Package.resolved @@ -9,13 +9,31 @@ "version" : "0.6.7" } }, + { + "identity" : "collectionconcurrencykit", + "kind" : "remoteSourceControl", + "location" : "https://github.com/JohnSundell/CollectionConcurrencyKit.git", + "state" : { + "revision" : "b4f23e24b5a1bff301efc5e70871083ca029ff95", + "version" : "0.2.0" + } + }, { "identity" : "concurrencyplus", "kind" : "remoteSourceControl", "location" : "https://github.com/ChimeHQ/ConcurrencyPlus", "state" : { "branch" : "main", - "revision" : "b5ba8d5ea6bfe9e43ccc44aa63f9b458057fa0f4" + "revision" : "8dc56499412a373d617d50d059116bccf44b9874" + } + }, + { + "identity" : "cryptoswift", + "kind" : "remoteSourceControl", + "location" : "https://github.com/krzyzanowskim/CryptoSwift.git", + "state" : { + "revision" : "eee9ad754926c40a0f7e73f152357d37b119b7fa", + "version" : "1.7.1" } }, { @@ -59,8 +77,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/ChimeHQ/LanguageServerProtocol", "state" : { - "revision" : "9293fd8a3b4298bab12475ff46f793a6d4055f0e", - "version" : "0.9.0" + "revision" : "192bcfdcf7a013da49c6fa1b95de66254ce7c614", + "version" : "0.9.1" } }, { @@ -80,6 +98,69 @@ "revision" : "369fb0379983d3b43c7d7ad62c4e91ee020e347c", "version" : "0.2.6" } + }, + { + "identity" : "sourcekitten", + "kind" : "remoteSourceControl", + "location" : "https://github.com/jpsim/SourceKitten.git", + "state" : { + "revision" : "b6dc09ee51dfb0c66e042d2328c017483a1a5d56", + "version" : "0.34.1" + } + }, + { + "identity" : "swift-argument-parser", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-argument-parser.git", + "state" : { + "revision" : "fee6933f37fde9a5e12a1e4aeaa93fe60116ff2a", + "version" : "1.2.2" + } + }, + { + "identity" : "swift-syntax", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-syntax.git", + "state" : { + "revision" : "27cd6190ce0628847a3f8050794d6e627ad79c08", + "version" : "509.0.0-swift-DEVELOPMENT-SNAPSHOT-2023-05-02-a" + } + }, + { + "identity" : "swiftlint", + "kind" : "remoteSourceControl", + "location" : "https://github.com/realm/SwiftLint", + "state" : { + "revision" : "34f5ffa7f706ed2dfe11bd300e5197e8878e3856", + "version" : "0.52.2" + } + }, + { + "identity" : "swiftytexttable", + "kind" : "remoteSourceControl", + "location" : "https://github.com/scottrhoyt/SwiftyTextTable.git", + "state" : { + "revision" : "c6df6cf533d120716bff38f8ff9885e1ce2a4ac3", + "version" : "0.9.0" + } + }, + { + "identity" : "swxmlhash", + "kind" : "remoteSourceControl", + "location" : "https://github.com/drmohundro/SWXMLHash.git", + "state" : { + "revision" : "a853604c9e9a83ad9954c7e3d2a565273982471f", + "version" : "7.0.2" + } + }, + { + "identity" : "yams", + "kind" : "remoteSourceControl", + "location" : "https://github.com/jpsim/Yams.git", + "state" : { + "revision" : "f47ba4838c30dbd59998a4e4c87ab620ff959e8a", + "version" : "5.0.5" + } } ], "version" : 2 diff --git a/Package.swift b/Package.swift index 5f55b82..427722d 100644 --- a/Package.swift +++ b/Package.swift @@ -17,6 +17,7 @@ let package = Package( .package(url: "https://github.com/ChimeHQ/ConcurrencyPlus", branch: "main"), .package(url: "https://github.com/ChimeHQ/LanguageClient", from: "0.5.0"), .package(url: "https://github.com/ChimeHQ/ProcessService", from: "0.2.6"), + .package(url: "https://github.com/realm/SwiftLint", from: "0.52.2"), .package( url: "https://github.com/Flight-School/AnyCodable", from: "0.6.0" @@ -25,7 +26,9 @@ let package = Package( targets: [ .target( name: "CodeEditKit", - dependencies: ["AnyCodable", "ConcurrencyPlus", "LanguageClient", .product(name: "ProcessServiceClient", package: "ProcessService")]), + dependencies: ["AnyCodable", "ConcurrencyPlus", "LanguageClient", .product(name: "ProcessServiceClient", package: "ProcessService")], + plugins: [.plugin(name: "SwiftLintPlugin", package: "SwiftLint")] + ), .testTarget( name: "CodeEditKitTests", dependencies: ["CodeEditKit"]), diff --git a/Sources/CodeEditKit/CodeEditExtension.swift b/Sources/CodeEditKit/CodeEditExtension.swift index 9799c34..cd5e317 100644 --- a/Sources/CodeEditKit/CodeEditExtension.swift +++ b/Sources/CodeEditKit/CodeEditExtension.swift @@ -43,7 +43,7 @@ extension CodeEditExtension { if let self = self as? any SidebarExtension { extensions.append(contentsOf: self.availableExtensions) } - + return extensions } } @@ -56,13 +56,12 @@ public extension CodeEditExtension where Self: AnyObject { } } - struct SettingsExtensionConfiguration: AppExtensionConfiguration { public func accept(connection: NSXPCConnection) -> Bool { guard let appExtension else { return false } - + connection.exportedInterface = .init(with: XPCWrappable.self) connection.exportedObject = XPCWrapper(appExtension) connection.resume() @@ -72,12 +71,7 @@ struct SettingsExtensionConfiguration: AppExte weak var appExtension: E? - /// Creates a default configuration for the given extension. - /// - Parameter appExtension: An instance of your custom extension that conforms to the ``TextTransformExtension`` protocol. public init(_ appExtension: E) { self.appExtension = appExtension } } - - - diff --git a/Sources/CodeEditKit/ExtensionKind.swift b/Sources/CodeEditKit/ExtensionKind.swift index 7c622c1..c8b5e20 100644 --- a/Sources/CodeEditKit/ExtensionKind.swift +++ b/Sources/CodeEditKit/ExtensionKind.swift @@ -26,5 +26,3 @@ public enum ExtensionKind: Codable, Hashable, CustomStringConvertible { } } } - - diff --git a/Sources/CodeEditKit/GenericScene.swift b/Sources/CodeEditKit/GenericScene.swift index e50cc22..3dc5e93 100644 --- a/Sources/CodeEditKit/GenericScene.swift +++ b/Sources/CodeEditKit/GenericScene.swift @@ -42,4 +42,3 @@ struct GenericScene: AppExtensionScene { } } } - diff --git a/Sources/CodeEditKit/NonUIExtensions/LSP/LanguageExtension.swift b/Sources/CodeEditKit/NonUIExtensions/LSP/LanguageExtension.swift index 58a2b45..cc93c22 100644 --- a/Sources/CodeEditKit/NonUIExtensions/LSP/LanguageExtension.swift +++ b/Sources/CodeEditKit/NonUIExtensions/LSP/LanguageExtension.swift @@ -24,7 +24,7 @@ final class UnrestrictedProcessTransport { private var readHandler: ReadHandler = { _ in } private let process: HostedProcess private let taskQueue = TaskQueue() - private var subscription: AnyCancellable? = nil + private var subscription: AnyCancellable? private let logger = Logger(subsystem: "com.chimehq.ChimeKit", category: "UnrestrictedProcessTransport") init(process: HostedProcess) { @@ -72,12 +72,12 @@ extension UnrestrictedProcessTransport: DataTransport { /// Provides an interface to a LSP language server hosted by an intermediary process. public class RemoteLanguageServer { private let wrappedServer: JSONRPCLanguageServer - private var subscription: AnyCancellable? = nil + private var subscription: AnyCancellable? private let logger = Logger(subsystem: "com.chimehq.ChimeKit", category: "RemoteLanguageServer") private let process: HostedProcess private let taskQueue = TaskQueue() - public var terminationHandler: (() -> Void)? = nil + public var terminationHandler: (() -> Void)? init(named serviceName: String, parameters: Process.ExecutionParameters) throws { self.process = HostedProcess(named: serviceName, parameters: parameters) diff --git a/Sources/CodeEditKit/UIExtensions/Environment/CEEnvironment.swift b/Sources/CodeEditKit/UIExtensions/Environment/CEEnvironment.swift index 552d3b0..bfdb401 100644 --- a/Sources/CodeEditKit/UIExtensions/Environment/CEEnvironment.swift +++ b/Sources/CodeEditKit/UIExtensions/Environment/CEEnvironment.swift @@ -12,7 +12,7 @@ import SwiftUI public struct _CEEnvironment: Codable, Equatable { public var test = false - public var complexValue: Array = [] + public var complexValue: [String] = [] var otherKeys: [String: AnyCodable] = [:] @@ -20,7 +20,7 @@ public struct _CEEnvironment: Codable, Equatable { self[keyPath: keyPath] = value } - public subscript(key: K.Type) -> K.Value where K : CEEnvironmentKey { + public subscript(key: K.Type) -> K.Value where K: CEEnvironmentKey { get { guard let data = otherKeys[key.identifier] else { return key.defaultValue } return data.value as! K.Value @@ -30,7 +30,7 @@ public struct _CEEnvironment: Codable, Equatable { } @propertyWrapper -public struct CEEnvironment : DynamicProperty { +public struct CEEnvironment: DynamicProperty { @Environment(\._ceEnvironment) var environment public init(_ keyPath: KeyPath<_CEEnvironment, Value>) { diff --git a/Sources/CodeEditKit/UIExtensions/Environment/EnvironmentObjcPublisher.swift b/Sources/CodeEditKit/UIExtensions/Environment/EnvironmentObjcPublisher.swift index c1eaea0..e4d785c 100644 --- a/Sources/CodeEditKit/UIExtensions/Environment/EnvironmentObjcPublisher.swift +++ b/Sources/CodeEditKit/UIExtensions/Environment/EnvironmentObjcPublisher.swift @@ -30,8 +30,7 @@ public class EnvironmentPublisher: ObservableObject, EnvironmentPublisherObjc { @Decoded<_CEEnvironment> var data = data guard let $data else { return } environment = $data - + print("update: received data \($data)") } } - diff --git a/Sources/CodeEditKit/UIExtensions/Settings/GeneralSettingsScene.swift b/Sources/CodeEditKit/UIExtensions/Settings/GeneralSettingsScene.swift index 075d2a9..a4f00f0 100644 --- a/Sources/CodeEditKit/UIExtensions/Settings/GeneralSettingsScene.swift +++ b/Sources/CodeEditKit/UIExtensions/Settings/GeneralSettingsScene.swift @@ -9,7 +9,6 @@ import Foundation import SwiftUI import ExtensionKit - struct GeneralSettingsScene: AppExtensionScene { @ViewBuilder diff --git a/Sources/CodeEditKit/UIExtensions/Sidebar/Sidebar.swift b/Sources/CodeEditKit/UIExtensions/Sidebar/Sidebar.swift index 3c8a677..1d5bad3 100644 --- a/Sources/CodeEditKit/UIExtensions/Sidebar/Sidebar.swift +++ b/Sources/CodeEditKit/UIExtensions/Sidebar/Sidebar.swift @@ -16,11 +16,9 @@ public protocol Sidebar { @_spi(CodeEdit) func resolve(environment: some ObservableObject) -> [ResolvedSidebar] - } public extension Sidebar { - func resolve(environment: some ObservableObject) -> [ResolvedSidebar] { body.resolve(environment: environment) } diff --git a/Sources/CodeEditKit/UIExtensions/Sidebar/SidebarExtension.swift b/Sources/CodeEditKit/UIExtensions/Sidebar/SidebarExtension.swift index 61aa568..58a1372 100644 --- a/Sources/CodeEditKit/UIExtensions/Sidebar/SidebarExtension.swift +++ b/Sources/CodeEditKit/UIExtensions/Sidebar/SidebarExtension.swift @@ -17,7 +17,6 @@ public protocol SidebarExtension: ObservableObject { var sidebars: SidebarBody { get } } - public extension SidebarExtension { var sidebarScenes: some AppExtensionScene { sidebars.resolve(environment: self).map(\.scene) diff --git a/Sources/CodeEditKit/XPCWrapper.swift b/Sources/CodeEditKit/XPCWrapper.swift index 11d24ab..af7c310 100644 --- a/Sources/CodeEditKit/XPCWrapper.swift +++ b/Sources/CodeEditKit/XPCWrapper.swift @@ -27,7 +27,6 @@ public protocol XPCWrappable { func isDebug(reply: @escaping (Bool) -> Void) } - class XPCWrapper: XPCWrappable { var ext: any CodeEditExtension From bbda072ae4de6f3bfbf988574868787d72dd5c12 Mon Sep 17 00:00:00 2001 From: Wouter01 Date: Tue, 23 May 2023 14:47:17 +0200 Subject: [PATCH 25/30] fix warnings Signed-off-by: Wouter01 --- Package.swift | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Package.swift b/Package.swift index 427722d..abafb0f 100644 --- a/Package.swift +++ b/Package.swift @@ -11,7 +11,7 @@ let package = Package( .library( name: "CodeEditKit", type: .dynamic, - targets: ["CodeEditKit"]), + targets: ["CodeEditKit"]) ], dependencies: [ .package(url: "https://github.com/ChimeHQ/ConcurrencyPlus", branch: "main"), @@ -21,7 +21,7 @@ let package = Package( .package( url: "https://github.com/Flight-School/AnyCodable", from: "0.6.0" - ), + ) ], targets: [ .target( @@ -31,6 +31,6 @@ let package = Package( ), .testTarget( name: "CodeEditKitTests", - dependencies: ["CodeEditKit"]), + dependencies: ["CodeEditKit"]) ] ) From 21600128afb972fc3960918e11e20c68ed8707aa Mon Sep 17 00:00:00 2001 From: Wouter Hennen <62355975+Wouter01@users.noreply.github.com> Date: Tue, 23 May 2023 15:08:05 +0200 Subject: [PATCH 26/30] Update tests.sh --- .github/scripts/tests.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/scripts/tests.sh b/.github/scripts/tests.sh index 57afd27..8bc6b19 100755 --- a/.github/scripts/tests.sh +++ b/.github/scripts/tests.sh @@ -16,4 +16,5 @@ export LC_CTYPE=en_US.UTF-8 set -o pipefail && arch -"${ARCH}" xcodebuild \ -scheme CodeEditKit \ -destination "platform=macos,arch=${ARCH}" \ + -skipPackagePluginValidation \ clean test | xcpretty From f7452da206d115bf92078c9d52c7a24d0416765b Mon Sep 17 00:00:00 2001 From: Wouter01 Date: Tue, 23 May 2023 15:11:23 +0200 Subject: [PATCH 27/30] small fixes Signed-off-by: Wouter01 --- Sources/CodeEditKit/CEWorkspace.swift | 15 --------------- .../{File.swift => CEOpenWindowEnvKey.swift} | 0 2 files changed, 15 deletions(-) delete mode 100644 Sources/CodeEditKit/CEWorkspace.swift rename Sources/CodeEditKit/UIExtensions/Environment/{File.swift => CEOpenWindowEnvKey.swift} (100%) diff --git a/Sources/CodeEditKit/CEWorkspace.swift b/Sources/CodeEditKit/CEWorkspace.swift deleted file mode 100644 index 00bf80e..0000000 --- a/Sources/CodeEditKit/CEWorkspace.swift +++ /dev/null @@ -1,15 +0,0 @@ -// -// File.swift -// -// -// Created by Wouter Hennen on 30/12/2022. -// - -import Foundation - -@objc -protocol CEWorkSpaceObjc { - func didOpen() - - func willClose() -} diff --git a/Sources/CodeEditKit/UIExtensions/Environment/File.swift b/Sources/CodeEditKit/UIExtensions/Environment/CEOpenWindowEnvKey.swift similarity index 100% rename from Sources/CodeEditKit/UIExtensions/Environment/File.swift rename to Sources/CodeEditKit/UIExtensions/Environment/CEOpenWindowEnvKey.swift From 2d7f53471eccf2322ace41a45ad4ed2460cc59fb Mon Sep 17 00:00:00 2001 From: Wouter01 Date: Tue, 23 May 2023 15:38:55 +0200 Subject: [PATCH 28/30] add some more documentation Signed-off-by: Wouter01 --- .../Documentation.docc/CreatingProject.md | 23 +++++++++++++++++++ .../Documentation.docc/Documentation.md | 6 +++-- 2 files changed, 27 insertions(+), 2 deletions(-) create mode 100644 Sources/CodeEditKit/Documentation.docc/CreatingProject.md diff --git a/Sources/CodeEditKit/Documentation.docc/CreatingProject.md b/Sources/CodeEditKit/Documentation.docc/CreatingProject.md new file mode 100644 index 0000000..9679dc1 --- /dev/null +++ b/Sources/CodeEditKit/Documentation.docc/CreatingProject.md @@ -0,0 +1,23 @@ +# Project Setup + +## Overview + +To start developing extensions, you first need to configure your project. + +## Steps + +This is a WIP, and should be explained better. + +1. Create a new Xcode project. As the template, choose "App" (make sure you select the macOS tab, not the multiplatform tab) +2. Once created, go to File -> New -> Target. In the macOS tab, choose "Generic Extension". Enter a name and leave the other things default. Click "activate" on the popup. +3. In the folder of your new extension, a new "Info" plist file should have been created. In it, replace the value of EXExtensionPointIdentifier with "codeedit.extension" (no quotation marks) +4. Next, add CodeEditKit as a dependency. If you have CodeEditKit as a local package, first make sure no other Xcode projects that also rely on that package are opened. Otherwise, Xcode won't find the package. +5. Go to the project configuration, select the target with the name of your extension, and go to the general tab. There, add CodeEditKit to the "Frameworks and Libraries" section. +6. Now, go to the main swift file in the extension folder. Remove all autogenerated code, we won't need it. Instead, import CodeEditKit and follow the steps for ``CodeEditExtension``. +7. Lastly, press run! The extension will compile and Xcode will ask which app to start. Choose CodeEdit. To prevent this popup from always showing, you can edit the extension scheme to always choose CodeEdit. + +## Topics + +### Group + +- ``Symbol`` diff --git a/Sources/CodeEditKit/Documentation.docc/Documentation.md b/Sources/CodeEditKit/Documentation.docc/Documentation.md index 45b0f19..df45b16 100644 --- a/Sources/CodeEditKit/Documentation.docc/Documentation.md +++ b/Sources/CodeEditKit/Documentation.docc/Documentation.md @@ -26,10 +26,12 @@ There are lots of extension types you can use to extend the functionality of Cod - (Beta) ### Getting Started -First, have a look at ``CodeEditExtension``. This is the base protocol that will define the main structure of your extension. +To setup your Xcode project, have a look at the section. + +Next, have a look at ``CodeEditExtension``. This is the base protocol that will define the main structure of your extension. All extensions that you'll add will extend (:p) this type. -Next, try adding an extension to your newly created type. A good first recommendation is the extension, as you'll likely need this later. +Finally, try adding an extension to your newly created type. A good first recommendation is the extension, as you'll likely need this later. ### Development & Debugging Developing extensions with ExtensionKit has a few annoyances: From faa2a7be8706efdffca3676a5030241b0cca002b Mon Sep 17 00:00:00 2001 From: Wouter01 Date: Tue, 23 May 2023 17:07:06 +0200 Subject: [PATCH 29/30] change swiftlint to swiftlintplugin package Signed-off-by: Wouter01 --- Package.resolved | 80 +++--------------------------------------------- Package.swift | 7 +++-- 2 files changed, 9 insertions(+), 78 deletions(-) diff --git a/Package.resolved b/Package.resolved index 8e47f41..1d539eb 100644 --- a/Package.resolved +++ b/Package.resolved @@ -9,15 +9,6 @@ "version" : "0.6.7" } }, - { - "identity" : "collectionconcurrencykit", - "kind" : "remoteSourceControl", - "location" : "https://github.com/JohnSundell/CollectionConcurrencyKit.git", - "state" : { - "revision" : "b4f23e24b5a1bff301efc5e70871083ca029ff95", - "version" : "0.2.0" - } - }, { "identity" : "concurrencyplus", "kind" : "remoteSourceControl", @@ -27,15 +18,6 @@ "revision" : "8dc56499412a373d617d50d059116bccf44b9874" } }, - { - "identity" : "cryptoswift", - "kind" : "remoteSourceControl", - "location" : "https://github.com/krzyzanowskim/CryptoSwift.git", - "state" : { - "revision" : "eee9ad754926c40a0f7e73f152357d37b119b7fa", - "version" : "1.7.1" - } - }, { "identity" : "fseventswrapper", "kind" : "remoteSourceControl", @@ -100,66 +82,12 @@ } }, { - "identity" : "sourcekitten", + "identity" : "swiftlintplugin", "kind" : "remoteSourceControl", - "location" : "https://github.com/jpsim/SourceKitten.git", + "location" : "https://github.com/lukepistrol/SwiftLintPlugin", "state" : { - "revision" : "b6dc09ee51dfb0c66e042d2328c017483a1a5d56", - "version" : "0.34.1" - } - }, - { - "identity" : "swift-argument-parser", - "kind" : "remoteSourceControl", - "location" : "https://github.com/apple/swift-argument-parser.git", - "state" : { - "revision" : "fee6933f37fde9a5e12a1e4aeaa93fe60116ff2a", - "version" : "1.2.2" - } - }, - { - "identity" : "swift-syntax", - "kind" : "remoteSourceControl", - "location" : "https://github.com/apple/swift-syntax.git", - "state" : { - "revision" : "27cd6190ce0628847a3f8050794d6e627ad79c08", - "version" : "509.0.0-swift-DEVELOPMENT-SNAPSHOT-2023-05-02-a" - } - }, - { - "identity" : "swiftlint", - "kind" : "remoteSourceControl", - "location" : "https://github.com/realm/SwiftLint", - "state" : { - "revision" : "34f5ffa7f706ed2dfe11bd300e5197e8878e3856", - "version" : "0.52.2" - } - }, - { - "identity" : "swiftytexttable", - "kind" : "remoteSourceControl", - "location" : "https://github.com/scottrhoyt/SwiftyTextTable.git", - "state" : { - "revision" : "c6df6cf533d120716bff38f8ff9885e1ce2a4ac3", - "version" : "0.9.0" - } - }, - { - "identity" : "swxmlhash", - "kind" : "remoteSourceControl", - "location" : "https://github.com/drmohundro/SWXMLHash.git", - "state" : { - "revision" : "a853604c9e9a83ad9954c7e3d2a565273982471f", - "version" : "7.0.2" - } - }, - { - "identity" : "yams", - "kind" : "remoteSourceControl", - "location" : "https://github.com/jpsim/Yams.git", - "state" : { - "revision" : "f47ba4838c30dbd59998a4e4c87ab620ff959e8a", - "version" : "5.0.5" + "revision" : "d3ec7fb242ebe1d8e23bf17e58a1e27d43125994", + "version" : "0.2.6" } } ], diff --git a/Package.swift b/Package.swift index abafb0f..311b985 100644 --- a/Package.swift +++ b/Package.swift @@ -17,7 +17,10 @@ let package = Package( .package(url: "https://github.com/ChimeHQ/ConcurrencyPlus", branch: "main"), .package(url: "https://github.com/ChimeHQ/LanguageClient", from: "0.5.0"), .package(url: "https://github.com/ChimeHQ/ProcessService", from: "0.2.6"), - .package(url: "https://github.com/realm/SwiftLint", from: "0.52.2"), + .package( + url: "https://github.com/lukepistrol/SwiftLintPlugin", + from: "0.2.2" + ), .package( url: "https://github.com/Flight-School/AnyCodable", from: "0.6.0" @@ -27,7 +30,7 @@ let package = Package( .target( name: "CodeEditKit", dependencies: ["AnyCodable", "ConcurrencyPlus", "LanguageClient", .product(name: "ProcessServiceClient", package: "ProcessService")], - plugins: [.plugin(name: "SwiftLintPlugin", package: "SwiftLint")] + plugins: [.plugin(name: "SwiftLint", package: "SwiftLintPlugin")] ), .testTarget( name: "CodeEditKitTests", From b0e0c5be9ff5d2cff56bb0cda3df5c0d9c4e029b Mon Sep 17 00:00:00 2001 From: Wouter01 Date: Tue, 23 May 2023 21:08:17 +0200 Subject: [PATCH 30/30] update docs Signed-off-by: Wouter01 --- Sources/CodeEditKit/Documentation.docc/CreatingProject.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/CodeEditKit/Documentation.docc/CreatingProject.md b/Sources/CodeEditKit/Documentation.docc/CreatingProject.md index 9679dc1..7faaed9 100644 --- a/Sources/CodeEditKit/Documentation.docc/CreatingProject.md +++ b/Sources/CodeEditKit/Documentation.docc/CreatingProject.md @@ -9,7 +9,7 @@ To start developing extensions, you first need to configure your project. This is a WIP, and should be explained better. 1. Create a new Xcode project. As the template, choose "App" (make sure you select the macOS tab, not the multiplatform tab) -2. Once created, go to File -> New -> Target. In the macOS tab, choose "Generic Extension". Enter a name and leave the other things default. Click "activate" on the popup. +2. Once created, go to File -> New -> Target. In the macOS tab, choose "Generic Extension". Enter a name, enable the checkbox for UI support, and leave the other things default. Click "activate" on the popup. 3. In the folder of your new extension, a new "Info" plist file should have been created. In it, replace the value of EXExtensionPointIdentifier with "codeedit.extension" (no quotation marks) 4. Next, add CodeEditKit as a dependency. If you have CodeEditKit as a local package, first make sure no other Xcode projects that also rely on that package are opened. Otherwise, Xcode won't find the package. 5. Go to the project configuration, select the target with the name of your extension, and go to the general tab. There, add CodeEditKit to the "Frameworks and Libraries" section.