mirror of
https://github.com/h3pdesign/Neon-Vision-Editor
synced 2026-04-21 13:27:16 +00:00
UI changes. Fixed Sidebar
This commit is contained in:
parent
7589dd4b40
commit
a21b27466d
6 changed files with 645 additions and 729 deletions
|
|
@ -259,7 +259,7 @@
|
|||
AUTOMATION_APPLE_EVENTS = NO;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
CURRENT_PROJECT_VERSION = 25;
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
DEVELOPMENT_TEAM = CS727NF72U;
|
||||
ENABLE_APP_SANDBOX = YES;
|
||||
|
|
@ -296,7 +296,7 @@
|
|||
LD_RUNPATH_SEARCH_PATHS = "@executable_path/Frameworks";
|
||||
"LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks";
|
||||
MACOSX_DEPLOYMENT_TARGET = 26.0;
|
||||
MARKETING_VERSION = 1.0;
|
||||
MARKETING_VERSION = 0.2;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "h3p.Neon-Vision-Editor";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
|
|
@ -330,7 +330,7 @@
|
|||
AUTOMATION_APPLE_EVENTS = NO;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
CURRENT_PROJECT_VERSION = 25;
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
DEVELOPMENT_TEAM = CS727NF72U;
|
||||
ENABLE_APP_SANDBOX = YES;
|
||||
|
|
@ -367,7 +367,7 @@
|
|||
LD_RUNPATH_SEARCH_PATHS = "@executable_path/Frameworks";
|
||||
"LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks";
|
||||
MACOSX_DEPLOYMENT_TARGET = 26.0;
|
||||
MARKETING_VERSION = 1.0;
|
||||
MARKETING_VERSION = 0.2;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "h3p.Neon-Vision-Editor";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
|
|
|
|||
|
|
@ -0,0 +1,78 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "2620"
|
||||
version = "1.7">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES"
|
||||
buildArchitectures = "Automatic">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "98EAE6322E5F15E80050E579"
|
||||
BuildableName = "Neon Vision Editor.app"
|
||||
BlueprintName = "Neon Vision Editor"
|
||||
ReferencedContainer = "container:Neon Vision Editor.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
shouldAutocreateTestPlan = "YES">
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Release"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
allowLocationSimulation = "YES">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "98EAE6322E5F15E80050E579"
|
||||
BuildableName = "Neon Vision Editor.app"
|
||||
BlueprintName = "Neon Vision Editor"
|
||||
ReferencedContainer = "container:Neon Vision Editor.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Release"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
debugDocumentVersioning = "YES">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "98EAE6322E5F15E80050E579"
|
||||
BuildableName = "Neon Vision Editor.app"
|
||||
BlueprintName = "Neon Vision Editor"
|
||||
ReferencedContainer = "container:Neon Vision Editor.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
||||
|
|
@ -10,5 +10,13 @@
|
|||
<integer>0</integer>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>SuppressBuildableAutocreation</key>
|
||||
<dict>
|
||||
<key>98EAE6322E5F15E80050E579</key>
|
||||
<dict>
|
||||
<key>primary</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -18,6 +18,7 @@ class EditorViewModel: ObservableObject {
|
|||
@Published var isBrainDumpMode: Bool = false
|
||||
@Published var showingRename: Bool = false
|
||||
@Published var renameText: String = ""
|
||||
@Published var isLineWrapEnabled: Bool = true
|
||||
|
||||
var selectedTab: TabData? {
|
||||
get { tabs.first(where: { $0.id == selectedTabID }) }
|
||||
|
|
@ -65,7 +66,6 @@ class EditorViewModel: ObservableObject {
|
|||
}
|
||||
}
|
||||
|
||||
<<<<<<< HEAD
|
||||
func closeTab(tab: TabData) {
|
||||
tabs.removeAll { $0.id == tab.id }
|
||||
if tabs.isEmpty {
|
||||
|
|
@ -75,8 +75,6 @@ class EditorViewModel: ObservableObject {
|
|||
}
|
||||
}
|
||||
|
||||
=======
|
||||
>>>>>>> main
|
||||
func saveFile(tab: TabData) {
|
||||
guard let index = tabs.firstIndex(where: { $0.id == tab.id }) else { return }
|
||||
if let url = tabs[index].fileURL {
|
||||
|
|
@ -95,16 +93,14 @@ class EditorViewModel: ObservableObject {
|
|||
let panel = NSSavePanel()
|
||||
panel.nameFieldStringValue = tabs[index].name
|
||||
panel.allowedContentTypes = [.text, .swiftSource, .pythonScript, .javaScript, .html, .css, .cSource, .json, UTType(importedAs: "public.markdown")]
|
||||
|
||||
Task {
|
||||
if panel.runModal() == .OK, let url = panel.url {
|
||||
do {
|
||||
try tabs[index].content.write(to: url, atomically: true, encoding: .utf8)
|
||||
tabs[index].fileURL = url
|
||||
tabs[index].name = url.lastPathComponent
|
||||
} catch {
|
||||
print("Error saving file: \(error)")
|
||||
}
|
||||
|
||||
if panel.runModal() == .OK, let url = panel.url {
|
||||
do {
|
||||
try tabs[index].content.write(to: url, atomically: true, encoding: .utf8)
|
||||
tabs[index].fileURL = url
|
||||
tabs[index].name = url.lastPathComponent
|
||||
} catch {
|
||||
print("Error saving file: \(error)")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -114,20 +110,18 @@ class EditorViewModel: ObservableObject {
|
|||
panel.allowedContentTypes = [.text, .sourceCode, .swiftSource, .pythonScript, .javaScript, .html, .css, .cSource, .json, UTType(importedAs: "public.markdown")]
|
||||
panel.allowsMultipleSelection = false
|
||||
panel.canChooseDirectories = false
|
||||
|
||||
Task {
|
||||
if panel.runModal() == .OK, let url = panel.url {
|
||||
do {
|
||||
let content = try String(contentsOf: url, encoding: .utf8)
|
||||
let newTab = TabData(name: url.lastPathComponent,
|
||||
content: content,
|
||||
language: languageMap[url.pathExtension.lowercased()] ?? "swift",
|
||||
fileURL: url)
|
||||
tabs.append(newTab)
|
||||
selectedTabID = newTab.id
|
||||
} catch {
|
||||
print("Error opening file: \(error)")
|
||||
}
|
||||
|
||||
if panel.runModal() == .OK, let url = panel.url {
|
||||
do {
|
||||
let content = try String(contentsOf: url, encoding: .utf8)
|
||||
let newTab = TabData(name: url.lastPathComponent,
|
||||
content: content,
|
||||
language: languageMap[url.pathExtension.lowercased()] ?? "swift",
|
||||
fileURL: url)
|
||||
tabs.append(newTab)
|
||||
selectedTabID = newTab.id
|
||||
} catch {
|
||||
print("Error opening file: \(error)")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,46 +1,25 @@
|
|||
import SwiftUI
|
||||
<<<<<<< HEAD
|
||||
import FoundationModels
|
||||
|
||||
enum AIModel: String, Identifiable {
|
||||
case appleIntelligence = "Apple Intelligence"
|
||||
case grok = "Grok"
|
||||
|
||||
var id: String { rawValue }
|
||||
}
|
||||
=======
|
||||
>>>>>>> main
|
||||
|
||||
@main
|
||||
struct NeonVisionEditorApp: App {
|
||||
@StateObject private var viewModel = EditorViewModel()
|
||||
<<<<<<< HEAD
|
||||
@State private var showGrokError: Bool = false
|
||||
@State private var grokErrorMessage: String = ""
|
||||
@State private var selectedAIModel: AIModel = .appleIntelligence
|
||||
=======
|
||||
>>>>>>> main
|
||||
@State private var useAppleIntelligence: Bool = true
|
||||
|
||||
var body: some Scene {
|
||||
WindowGroup {
|
||||
ContentView()
|
||||
.environmentObject(viewModel)
|
||||
<<<<<<< HEAD
|
||||
.environment(\.showGrokError, $showGrokError)
|
||||
.environment(\.grokErrorMessage, $grokErrorMessage)
|
||||
.environment(\.selectedAIModel, $selectedAIModel)
|
||||
.frame(minWidth: 600, minHeight: 400)
|
||||
.background(.ultraThinMaterial)
|
||||
.overlay(.ultraThinMaterial.opacity(0.2)) // Fallback for liquidGlassEffect
|
||||
.task {
|
||||
// Pre-warm Apple Intelligence model
|
||||
let session = LanguageModelSession(model: SystemLanguageModel())
|
||||
session.prewarm()
|
||||
}
|
||||
=======
|
||||
.frame(minWidth: 600, minHeight: 400)
|
||||
.background(.ultraThinMaterial)
|
||||
>>>>>>> main
|
||||
}
|
||||
.defaultSize(width: 1000, height: 600)
|
||||
.commands {
|
||||
|
|
@ -75,7 +54,6 @@ struct NeonVisionEditorApp: App {
|
|||
viewModel.renameText = viewModel.selectedTab?.name ?? "Untitled"
|
||||
}
|
||||
.disabled(viewModel.selectedTab == nil)
|
||||
<<<<<<< HEAD
|
||||
|
||||
Button("Close Tab") {
|
||||
if let tab = viewModel.selectedTab {
|
||||
|
|
@ -84,8 +62,6 @@ struct NeonVisionEditorApp: App {
|
|||
}
|
||||
.keyboardShortcut("w", modifiers: .command)
|
||||
.disabled(viewModel.selectedTab == nil)
|
||||
=======
|
||||
>>>>>>> main
|
||||
}
|
||||
|
||||
CommandMenu("Language") {
|
||||
|
|
@ -105,15 +81,16 @@ struct NeonVisionEditorApp: App {
|
|||
|
||||
Toggle("Brain Dump Mode", isOn: $viewModel.isBrainDumpMode)
|
||||
.keyboardShortcut("d", modifiers: [.command, .shift])
|
||||
|
||||
Toggle("Line Wrap", isOn: $viewModel.isLineWrapEnabled)
|
||||
.keyboardShortcut("l", modifiers: [.command, .option])
|
||||
}
|
||||
|
||||
CommandMenu("Tools") {
|
||||
<<<<<<< HEAD
|
||||
Button("Suggest Code") {
|
||||
Task {
|
||||
if let tab = viewModel.selectedTab {
|
||||
switch selectedAIModel {
|
||||
case .appleIntelligence:
|
||||
if useAppleIntelligence {
|
||||
let session = LanguageModelSession(model: SystemLanguageModel())
|
||||
let prompt = "System: Output a code suggestion for this \(tab.language) code.\nUser: \(tab.content.prefix(1000))"
|
||||
do {
|
||||
|
|
@ -123,7 +100,7 @@ struct NeonVisionEditorApp: App {
|
|||
grokErrorMessage = error.localizedDescription
|
||||
showGrokError = true
|
||||
}
|
||||
case .grok:
|
||||
} else {
|
||||
let client = GrokAPIClient(apiKey: "your-xai-api-key") // Replace with your xAI API key from https://x.ai/api
|
||||
let prompt = "Suggest improvements for this \(tab.language) code: \(tab.content.prefix(1000))"
|
||||
do {
|
||||
|
|
@ -133,26 +110,14 @@ struct NeonVisionEditorApp: App {
|
|||
grokErrorMessage = error.localizedDescription
|
||||
showGrokError = true
|
||||
}
|
||||
=======
|
||||
Button("Suggest Code with Grok") {
|
||||
Task {
|
||||
let client = GrokAPIClient(apiKey: "your-xai-api-key") // Replace with your actual xAI API key from https://x.ai/api
|
||||
if let tab = viewModel.selectedTab {
|
||||
let prompt = "Suggest improvements for this \(tab.language) code: \(tab.content.prefix(1000))"
|
||||
do {
|
||||
let suggestion = try await client.generateText(prompt: prompt, maxTokens: 200)
|
||||
// Append suggestion to the current content
|
||||
viewModel.updateTabContent(tab: tab, content: tab.content + "\n\n// Grok Suggestion:\n" + suggestion)
|
||||
} catch {
|
||||
print("Grok API error: \(error)")
|
||||
// Optional: Show an alert or sheet for the error
|
||||
>>>>>>> main
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.keyboardShortcut("g", modifiers: [.command, .shift])
|
||||
.disabled(viewModel.selectedTab == nil)
|
||||
|
||||
Toggle("Use Apple Intelligence", isOn: $useAppleIntelligence)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -166,10 +131,6 @@ struct GrokErrorMessageKey: EnvironmentKey {
|
|||
static let defaultValue: Binding<String> = .constant("")
|
||||
}
|
||||
|
||||
struct SelectedAIModelKey: EnvironmentKey {
|
||||
static let defaultValue: Binding<AIModel> = .constant(.appleIntelligence)
|
||||
}
|
||||
|
||||
extension EnvironmentValues {
|
||||
var showGrokError: Binding<Bool> {
|
||||
get { self[ShowGrokErrorKey.self] }
|
||||
|
|
@ -180,9 +141,4 @@ extension EnvironmentValues {
|
|||
get { self[GrokErrorMessageKey.self] }
|
||||
set { self[GrokErrorMessageKey.self] = newValue }
|
||||
}
|
||||
|
||||
var selectedAIModel: Binding<AIModel> {
|
||||
get { self[SelectedAIModelKey.self] }
|
||||
set { self[SelectedAIModelKey.self] = newValue }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue