-
Notifications
You must be signed in to change notification settings - Fork 0
feat: add workspace state and plugin communication #1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
DongyuZhao
wants to merge
2
commits into
main
Choose a base branch
from
codex/design-core-architecture-and-state-management
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,31 +1,26 @@ | ||
| import Foundation | ||
|
|
||
| #if canImport(SwiftUI) | ||
| import SwiftUI | ||
| #endif | ||
|
|
||
| /// Public entry-points for the CodeCanvas module. | ||
| public enum CodeCanvasAPI { | ||
| /// Format the document text (placeholder using SwiftFormat later). | ||
| public static func format(_ doc: CodeDocument) -> CodeDocument { | ||
| // TODO: integrate real formatting via swift-format when needed. | ||
| return doc | ||
| public struct CodeCanvas: View { | ||
| private let extensions: [CodeCanvasExtension] | ||
|
|
||
| public init(extensions: [CodeCanvasExtension]) { | ||
| self.extensions = extensions | ||
| } | ||
|
|
||
| public var body: some View { | ||
| CodeCanvasShell(extensions: extensions) | ||
| } | ||
| } | ||
|
|
||
| #if canImport(SwiftUI) | ||
| /// A minimal SwiftUI-based editor view for Apple platforms. | ||
| public struct CodeCanvasView: View { | ||
| @State private var text: String | ||
| #else | ||
|
|
||
| public init(initialText: String = "// Welcome to CodeCanvas\n") { | ||
| self._text = State(initialValue: initialText) | ||
| } | ||
| public struct CodeCanvas { | ||
| public init() {} | ||
|
|
||
| public var body: some View { | ||
| TextEditor(text: $text) | ||
| .font(.system(.body, design: .monospaced)) | ||
| .padding() | ||
| public func start() { | ||
| CodeCanvasTUI().start() | ||
| } | ||
| } | ||
|
|
||
| #endif |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| import Foundation | ||
|
|
||
| public struct CodeCanvasTUI { | ||
| public func start() { | ||
|
|
||
| } | ||
| } |
This file was deleted.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| #if canImport(SwiftUI) | ||
| import Foundation | ||
| import SwiftUI | ||
|
|
||
| public protocol CodeCanvasBenchAction { | ||
| var id: String { get } | ||
| var title: String { get } | ||
| var icon: String { get } | ||
| func perform(on bench: CodeCanvasBench) | ||
| } | ||
|
|
||
| public protocol CodeCanvasBenchComponent{ | ||
| var id: String { get } | ||
| var title: String { get } | ||
| var icon: String { get } | ||
| var actions: [CodeCanvasBenchAction] { get } | ||
| func content() -> AnyView | ||
| } | ||
|
|
||
| public protocol CodeCanvasBench { | ||
| var id: String { get } | ||
| var name: String { get } | ||
| var icon: String { get } | ||
| var components: [CodeCanvasBenchComponent] { get } | ||
| } | ||
|
|
||
| #endif |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| #if canImport(SwiftUI) | ||
| public struct CodeCanvasExtension { | ||
| public let name: String | ||
| public let icon: String | ||
| public let benches: [CodeCanvasBench] | ||
|
|
||
| public init(name: String, icon: String, benches: [CodeCanvasBench]) { | ||
| self.name = name | ||
| self.icon = icon | ||
| self.benches = benches | ||
| } | ||
| } | ||
| #endif |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| public struct CodeCanvasFile: Identifiable { | ||
| public let id: String | ||
| public let name: String | ||
| public let content: String | ||
|
|
||
| public init(id: String, name: String, content: String) { | ||
| self.id = id | ||
| self.name = name | ||
| self.content = content | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| #if canImport(SwiftUI) | ||
| import SwiftUI | ||
|
|
||
| public protocol CodeCanvasWorkspace: Identifiable { | ||
| func content() -> AnyView | ||
| } | ||
| #endif |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| #if canImport(SwiftUI) | ||
| import SwiftUI | ||
|
|
||
| public final class CodeCanvasStore: ObservableObject { | ||
| @Published public var workspace: (any CodeCanvasWorkspace)? | ||
|
|
||
| public init() {} | ||
|
|
||
| public func open(_ workspace: any CodeCanvasWorkspace) { | ||
| self.workspace = workspace | ||
| } | ||
|
|
||
| public func clear() { | ||
| workspace = nil | ||
| } | ||
| } | ||
| #endif | ||
This file was deleted.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,41 @@ | ||
| #if canImport(SwiftUI) | ||
| import SwiftUI | ||
|
|
||
| public struct CodeCanvasShell: View { | ||
| private let extensions: [CodeCanvasExtension] | ||
|
|
||
| @State private var showInspector = false | ||
| @StateObject private var store = CodeCanvasStore() | ||
|
|
||
| public init(extensions: [CodeCanvasExtension]) { | ||
| self.extensions = extensions | ||
| } | ||
|
|
||
| public var body: some View { | ||
| NavigationSplitView { | ||
| CodeBenchContainer(benches: extensions.flatMap { $0.benches }) | ||
| } detail: { | ||
| CodeSpaceContainer() | ||
| } | ||
| .environmentObject(store) | ||
| .inspector( | ||
| isPresented: $showInspector, | ||
| content: { | ||
| CodeInspectorContainer() | ||
| #if os(macOS) | ||
| .inspectorColumnWidth(min: 340, ideal: 340, max: 680) | ||
| #endif | ||
| .toolbar { | ||
| Spacer() | ||
| Button(action: { | ||
| showInspector.toggle() | ||
| }) { | ||
| Label("Toggle Inspector", systemImage: "sidebar.right") | ||
| } | ||
| } | ||
| } | ||
| ) | ||
| } | ||
| } | ||
|
|
||
| #endif |
53 changes: 53 additions & 0 deletions
53
Sources/CodeCanvas/Views/Contents/CodeBenchContainer.swift
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,53 @@ | ||
| #if canImport(SwiftUI) | ||
| import SwiftUI | ||
|
|
||
| public struct CodeBenchContainer: View { | ||
| private let benches: [CodeCanvasBench] | ||
| @State private var selectedBench: (any CodeCanvasBench)? | ||
| @EnvironmentObject private var store: CodeCanvasStore | ||
|
|
||
| public init(benches: [CodeCanvasBench]) { | ||
| self.benches = benches | ||
| _selectedBench = State(initialValue: benches.first) | ||
| } | ||
|
|
||
| public var body: some View { | ||
| HStack(spacing: 0) { | ||
| CodeBenchSelector(benches: benches) { bench in | ||
| selectedBench = bench | ||
| store.clear() | ||
| } | ||
| .frame(maxHeight: .infinity) | ||
|
|
||
| if let selectedBench { | ||
| ScrollView { | ||
| VStack(alignment: .leading, spacing: 0) { | ||
| ForEach(selectedBench.components, id: \.id) { component in | ||
| DisclosureGroup { | ||
| component.content() | ||
| } label: { | ||
| HStack { | ||
| Text(component.title).font(.headline) | ||
| Spacer() | ||
| ForEach(component.actions, id: \.id) { action in | ||
| Button { | ||
| action.perform(on: selectedBench) | ||
| } label: { | ||
| Image(systemName: action.icon) | ||
| } | ||
| .buttonStyle(.plain) | ||
| .help(action.title) | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } else { | ||
| Spacer() | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
| #endif |
15 changes: 15 additions & 0 deletions
15
Sources/CodeCanvas/Views/Contents/CodeInspectorContainer.swift
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| #if canImport(SwiftUI) | ||
| import SwiftUI | ||
|
|
||
| public struct CodeInspectorContainer: View { | ||
| public init() {} | ||
|
|
||
| public var body: some View { | ||
| VStack { | ||
| Spacer() | ||
| Text("Inspector") | ||
| Spacer() | ||
| } | ||
| } | ||
| } | ||
| #endif |
17 changes: 17 additions & 0 deletions
17
Sources/CodeCanvas/Views/Contents/CodeSpaceContainer.swift
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| #if canImport(SwiftUI) | ||
| import SwiftUI | ||
|
|
||
| public struct CodeSpaceContainer: View { | ||
| @EnvironmentObject private var store: CodeCanvasStore | ||
|
|
||
| public init() {} | ||
|
|
||
| public var body: some View { | ||
| if let workspace = store.workspace { | ||
| workspace.content() | ||
| } else { | ||
| Text("Canvas") | ||
| } | ||
| } | ||
| } | ||
| #endif |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,43 @@ | ||
| #if canImport(SwiftUI) | ||
| import SwiftUI | ||
|
|
||
| public struct CodeBenchSelector: View { | ||
| private let benches: [CodeCanvasBench] | ||
| private let onSelect: (CodeCanvasBench) -> Void | ||
|
|
||
| @State private var selectedID: String? | ||
|
|
||
| public init(benches: [CodeCanvasBench], onSelect: @escaping (CodeCanvasBench) -> Void) { | ||
| self.benches = benches | ||
| self.onSelect = onSelect | ||
| self._selectedID = State(initialValue: benches.first?.id) | ||
| } | ||
|
|
||
| public var body: some View { | ||
| VStack(spacing: 15) { | ||
| ForEach(benches, id: \.id) { bench in | ||
| Button(action: { | ||
| selectedID = bench.id | ||
| onSelect(bench) | ||
| }) { | ||
| Image(systemName: bench.icon) | ||
| .font(.title) | ||
| .symbolVariant(selectedID == bench.id ? .fill : .none) | ||
| .frame(width: 50, height: 50) | ||
| .foregroundColor(selectedID == bench.id ? .accentColor : .secondary) | ||
| .background( | ||
| Color.secondary.opacity(selectedID == bench.id ? 0.25 : 0) | ||
| ) | ||
| .clipShape(RoundedRectangle(cornerRadius: 8)) | ||
| } | ||
| .buttonStyle(.plain) | ||
| .help(bench.name) | ||
| } | ||
| Spacer() | ||
| } | ||
| .padding(.vertical) | ||
| .frame(width: 60) | ||
| } | ||
| } | ||
|
|
||
| #endif |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,24 +1,42 @@ | ||
| import Foundation | ||
| import CodeCanvas | ||
| import Foundation | ||
|
|
||
| #if canImport(SwiftUI) | ||
| import SwiftUI | ||
| import SwiftUI | ||
|
|
||
| @main | ||
| struct CodeCanvasShowCaseApp: App { | ||
| @main | ||
| struct CodeCanvasShowCaseApp: App { | ||
| #if os(macOS) | ||
| // Ensure the app shows in Dock, has menu bar, and supports full screen when launched as a SwiftPM executable | ||
| @NSApplicationDelegateAdaptor(AppDelegate.self) var appDelegate | ||
| #endif | ||
| var body: some Scene { | ||
| WindowGroup { | ||
| CodeCanvasView(initialText: "// CodeCanvas Showcase\nprint(\"Hello, world!\")\n") | ||
| } | ||
| WindowGroup { | ||
| CodeCanvas( | ||
| extensions: [ | ||
| CodeCanvasExtension(name: "Editor", icon: "code", benches: [CodeEditorBench()]), | ||
| CodeCanvasExtension(name: "Restful", icon: "network", benches: [ClientRestfulBench()]), | ||
| ] | ||
| ) | ||
| } | ||
| } | ||
| } | ||
| #if os(macOS) | ||
| import AppKit | ||
| final class AppDelegate: NSObject, NSApplicationDelegate { | ||
| func applicationDidFinishLaunching(_ notification: Notification) { | ||
| // Switch activation policy to regular so we have Dock icon and menu bar | ||
| NSApp.setActivationPolicy(.regular) | ||
| NSApp.activate(ignoringOtherApps: true) | ||
| } | ||
| } | ||
| } | ||
| #endif | ||
| #else | ||
| @main | ||
| struct CodeCanvasShowCaseCLI { | ||
| @main | ||
| struct CodeCanvasShowCaseCLI { | ||
| static func main() { | ||
| let doc = CodeDocument(text: "// CodeCanvas Showcase CLI\nprint(\"Hello, world!\")\n") | ||
| let tui = CodeCanvasTUI() | ||
| tui.start(with: doc) | ||
| let tui = CodeCanvas() | ||
| tui.start() | ||
| } | ||
| } | ||
| } | ||
| #endif |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The workspace property should be private(set) to prevent external modification and maintain encapsulation. External code should only be able to modify the workspace through the open() and clear() methods.