Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions .all-contributorsrc
Original file line number Diff line number Diff line change
Expand Up @@ -794,6 +794,25 @@
"contributions": [
"code"
]
},
{
"login": "rustemd02",
"name": "rustemd02",
"avatar_url": "https://avatars.githubusercontent.com/u/11714456?v=4",
"profile": "https://github.com/rustemd02",
"contributions": [
"bug",
"code"
]
},
{
"login": "SimonKudsk",
"name": "Simon Kudsk",
"avatar_url": "https://avatars.githubusercontent.com/u/10168417?v=4",
"profile": "https://github.com/SimonKudsk",
"contributions": [
"code"
]
}
],
"contributorsPerLine": 7,
Expand Down
10 changes: 5 additions & 5 deletions CodeEdit.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -419,7 +419,7 @@
303E88462C276FD600EEA8D9 /* XCRemoteSwiftPackageReference "LanguageServerProtocol" */,
6C4E37FA2C73E00700AEE7B5 /* XCRemoteSwiftPackageReference "SwiftTerm" */,
6CB94D012CA1205100E8651C /* XCRemoteSwiftPackageReference "swift-async-algorithms" */,
6CFE18222DA59C9F00A7B796 /* XCRemoteSwiftPackageReference "CodeEditSourceEditor" */,
6CF368562DBBD274006A77FD /* XCRemoteSwiftPackageReference "CodeEditSourceEditor" */,
);
preferredProjectObjectVersion = 55;
productRefGroup = B658FB2D27DA9E0F00EA4DBD /* Products */;
Expand Down Expand Up @@ -1622,7 +1622,7 @@
repositoryURL = "https://github.com/CodeEditApp/CodeEditSymbols";
requirement = {
kind = exactVersion;
version = 0.2.2;
version = 0.2.3;
};
};
287136B1292A407E00E9F5F4 /* XCRemoteSwiftPackageReference "SwiftLintPlugin" */ = {
Expand Down Expand Up @@ -1745,12 +1745,12 @@
version = 1.0.1;
};
};
6CFE18222DA59C9F00A7B796 /* XCRemoteSwiftPackageReference "CodeEditSourceEditor" */ = {
6CF368562DBBD274006A77FD /* XCRemoteSwiftPackageReference "CodeEditSourceEditor" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/CodeEditApp/CodeEditSourceEditor";
requirement = {
kind = upToNextMajorVersion;
minimumVersion = 0.11.0;
kind = exactVersion;
version = 0.13.2;
};
};
/* End XCRemoteSwiftPackageReference section */
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -103,12 +103,12 @@ final class CEWorkspaceFileManager {
return nil
}

// Drill down towards the file, indexing any directories needed.
// If file is not in the `workspaceSettingsFolderURL` or subdirectories, exit.
guard url.absoluteString.starts(with: folderUrl.absoluteString),
url.pathComponents.count > folderUrl.pathComponents.count else {
// If file is not in the `folderUrl` or subdirectories, exit.
guard folderUrl.containsSubPath(url) else {
return nil
}

// Drill down towards the file, indexing any directories needed.
let pathComponents = url.pathComponents.dropFirst(folderUrl.pathComponents.count)
var currentURL = folderUrl

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ final class CEWorkspaceSettings: ObservableObject {

private(set) var folderURL: URL

private var settingsURL: URL {
folderURL.appending(path: "settings").appending(path: "json")
var settingsURL: URL {
folderURL.appending(path: "settings").appendingPathExtension("json")
}

init(workspaceURL: URL) {
Expand Down Expand Up @@ -54,7 +54,17 @@ final class CEWorkspaceSettings: ObservableObject {
/// Save``CEWorkspaceSettingsManager`` model to `.codeedit/settings.json`
func savePreferences() throws {
// If the user doesn't have any settings to save, don't save them.
guard !settings.isEmpty() else { return }
guard !settings.isEmpty() else {
// Settings is empty, remove the file & directory if it's empty.
if fileManager.fileExists(atPath: settingsURL.path()) {
try fileManager.removeItem(at: settingsURL)

if try fileManager.contentsOfDirectory(atPath: folderURL.path()).isEmpty {
try fileManager.removeItem(at: folderURL)
}
}
return
}

if !fileManager.fileExists(atPath: folderURL.path()) {
try fileManager.createDirectory(at: folderURL, withIntermediateDirectories: true)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ struct CETaskFormView: View {
@ObservedObject var task: CETask
@State private var selectedEnvID: UUID?

@StateObject var settingsViewModel = SettingsViewModel()
var body: some View {
Form {
Section {
Expand Down Expand Up @@ -85,7 +84,6 @@ struct CETaskFormView: View {
}
}
.formStyle(.grouped)
.environmentObject(settingsViewModel)
}

func removeSelectedEnv() {
Expand All @@ -100,7 +98,3 @@ struct CETaskFormView: View {
})
}
}

// #Preview {
// CETaskFormView()
// }
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@ struct CEWorkspaceSettingsView: View {
@EnvironmentObject var workspaceSettingsManager: CEWorkspaceSettings
@EnvironmentObject var workspace: WorkspaceDocument

@StateObject var settingsViewModel = SettingsViewModel()

@State var selectedTaskID: UUID?
@State var showAddTaskSheet: Bool = false

Expand Down Expand Up @@ -68,7 +66,6 @@ struct CEWorkspaceSettingsView: View {
}
.padding()
}
.environmentObject(settingsViewModel)
.sheet(isPresented: $showAddTaskSheet) {
if let selectedTaskIndex = workspaceSettingsManager.settings.tasks.firstIndex(where: {
$0.id == selectedTaskID
Expand Down
24 changes: 16 additions & 8 deletions CodeEdit/Features/CEWorkspaceSettings/Views/EditCETaskView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,16 @@ struct EditCETaskView: View {
Divider()
HStack {
Button(role: .destructive) {
workspaceSettingsManager.settings.tasks.removeAll(where: {
$0.id == task.id
})
try? workspaceSettingsManager.savePreferences()
taskManager.deleteTask(taskID: task.id)
self.dismiss()
do {
workspaceSettingsManager.settings.tasks.removeAll(where: {
$0.id == task.id
})
try workspaceSettingsManager.savePreferences()
taskManager.deleteTask(taskID: task.id)
self.dismiss()
} catch {
NSAlert(error: error).runModal()
}
} label: {
Text("Delete")
.foregroundStyle(.red)
Expand All @@ -38,8 +42,12 @@ struct EditCETaskView: View {
Spacer()

Button {
try? workspaceSettingsManager.savePreferences()
self.dismiss()
do {
try workspaceSettingsManager.savePreferences()
self.dismiss()
} catch {
NSAlert(error: error).runModal()
}
} label: {
Text("Done")
.frame(minWidth: 56)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,6 @@ final class CodeFileDocument: NSDocument, ObservableObject {
/// See ``CodeEditSourceEditor/CombineCoordinator``.
@Published var contentCoordinator: CombineCoordinator = CombineCoordinator()

/// Set by ``LanguageServer`` when initialized.
@Published var lspCoordinator: LSPContentCoordinator?

/// Used to override detected languages.
@Published var language: CodeLanguage?

Expand All @@ -65,6 +62,9 @@ final class CodeFileDocument: NSDocument, ObservableObject {
/// Document-specific overridden line wrap preference.
@Published var wrapLines: Bool?

/// Set up by ``LanguageServer``, conforms this type to ``LanguageServerDocument``.
@Published var languageServerObjects: LanguageServerDocumentObjects<CodeFileDocument> = .init()

/// The type of data this file document contains.
///
/// If its text content is not nil, a `text` UTType is returned.
Expand All @@ -83,9 +83,6 @@ final class CodeFileDocument: NSDocument, ObservableObject {
return type
}

/// A stable string to use when identifying documents with language servers.
var languageServerURI: String? { fileURL?.absolutePath }

/// Specify options for opening the file such as the initial cursor positions.
/// Nulled by ``CodeFileView`` on first load.
var openOptions: OpenOptions?
Expand Down Expand Up @@ -208,6 +205,10 @@ final class CodeFileDocument: NSDocument, ObservableObject {
}
}

/// Determines the code language of the document.
/// Use ``CodeFileDocument/language`` for the default value before using this. That property is used to override
/// the file's language.
/// - Returns: The detected code language.
func getLanguage() -> CodeLanguage {
guard let url = fileURL else {
return .default
Expand All @@ -223,3 +224,13 @@ final class CodeFileDocument: NSDocument, ObservableObject {
fileURL?.findWorkspace()
}
}

// MARK: LanguageServerDocument

extension CodeFileDocument: LanguageServerDocument {
/// A stable string to use when identifying documents with language servers.
/// Needs to be a valid URI, so always returns with the `file://` prefix to indicate it's a file URI.
var languageServerURI: String? {
fileURL?.lspURI
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -59,20 +59,45 @@ final class CodeEditDocumentController: NSDocumentController {
display displayDocument: Bool,
completionHandler: @escaping (NSDocument?, Bool, Error?) -> Void
) {
super.openDocument(withContentsOf: url, display: displayDocument) { document, documentWasAlreadyOpen, error in
guard !openFileInExistingWorkspace(url: url) else {
return
}

super.openDocument(withContentsOf: url, display: displayDocument) { document, documentWasAlreadyOpen, error in
if let document {
self.addDocument(document)
} else {
let errorMessage = error?.localizedDescription ?? "unknown error"
print("Unable to open document '\(url)': \(errorMessage)")
}

RecentProjectsStore.documentOpened(at: url)
RecentProjectsStore.shared.documentOpened(at: url)
completionHandler(document, documentWasAlreadyOpen, error)
}
}

/// Attempt to open the file URL in an open workspace, finding the nearest workspace to open it in if possible.
/// - Parameter url: The file URL to open.
/// - Returns: True, if the document was opened in a workspace.
private func openFileInExistingWorkspace(url: URL) -> Bool {
guard !url.isFolder else { return false }
let workspaces = documents.compactMap({ $0 as? WorkspaceDocument })

// Check open workspaces for the file being opened. Sorted by shared components with the url so we
// open the nearest workspace possible.
for workspace in workspaces.sorted(by: {
($0.fileURL?.sharedComponents(url) ?? 0) > ($1.fileURL?.sharedComponents(url) ?? 0)
}) {
// createIfNotFound will still return `nil` if the files don't share a common ancestor.
if let newFile = workspace.workspaceFileManager?.getFile(url.absolutePath, createIfNotFound: true) {
workspace.editorManager?.openTab(item: newFile)
workspace.showWindows()
return true
}
}
return false
}

override func removeDocument(_ document: NSDocument) {
super.removeDocument(document)

Expand Down
Loading