import Foundation import LanguageClient import LanguageServerProtocol import SuggestionModel public protocol CodeiumSuggestionServiceType { func getCompletions( fileURL: URL, content: String, cursorPosition: CursorPosition, tabSize: Int, indentSize: Int, usesTabsForIndentation: Bool, ignoreSpaceOnlySuggestions: Bool ) async throws -> [CodeSuggestion] } enum CodeiumError: Error, LocalizedError { case languageServerNotInstalled var errorDescription: String? { switch self { case .languageServerNotInstalled: return "Language server is not installed." } } } let token = "" public class CodeiumSuggestionService: CodeiumSuggestionServiceType { let projectRootURL: URL var server: CodeiumLSP init(designatedServer: CodeiumLSP) { projectRootURL = URL(fileURLWithPath: "/") server = designatedServer } public init(projectRootURL: URL) throws { self.projectRootURL = projectRootURL let urls = try CodeiumSuggestionService.createFoldersIfNeeded() let languageServerURL = urls.executableURL.appendingPathComponent("language_server") guard FileManager.default.fileExists(atPath: languageServerURL.path) else { throw CodeiumError.languageServerNotInstalled } let tempFolderURL = FileManager.default.temporaryDirectory let managerDirectoryURL = tempFolderURL .appendingPathComponent("com.intii.CopilotForXcode") .appendingPathComponent(UUID().uuidString) if !FileManager.default.fileExists(atPath: managerDirectoryURL.path) { try FileManager.default.createDirectory( at: managerDirectoryURL, withIntermediateDirectories: true ) } let server = CodeiumLanguageServer( languageServerExecutableURL: languageServerURL, managerDirectoryURL: managerDirectoryURL, supportURL: urls.supportURL ) self.server = server server.terminationHandler = { print("terminated") } server.launchHandler = { print("launched") } server.start() } public func getCompletions( fileURL: URL, content: String, cursorPosition: CursorPosition, tabSize: Int, indentSize: Int, usesTabsForIndentation: Bool, ignoreSpaceOnlySuggestions: Bool ) async throws -> [CodeSuggestion] { let languageId = languageIdentifierFromFileURL(fileURL) let relativePath = { let filePath = fileURL.path let rootPath = projectRootURL.path if let range = filePath.range(of: rootPath), range.lowerBound == filePath.startIndex { let relativePath = filePath.replacingCharacters( in: filePath.startIndex.. ( applicationSupportURL: URL, gitHubCopilotURL: URL, executableURL: URL, supportURL: URL ) { let supportURL = FileManager.default.urls( for: .applicationSupportDirectory, in: .userDomainMask ).first!.appendingPathComponent( Bundle.main .object(forInfoDictionaryKey: "APPLICATION_SUPPORT_FOLDER") as! String ) if !FileManager.default.fileExists(atPath: supportURL.path) { try? FileManager.default .createDirectory(at: supportURL, withIntermediateDirectories: false) } let gitHubCopilotFolderURL = supportURL.appendingPathComponent("Codeium") if !FileManager.default.fileExists(atPath: gitHubCopilotFolderURL.path) { try? FileManager.default .createDirectory(at: gitHubCopilotFolderURL, withIntermediateDirectories: false) } let supportFolderURL = gitHubCopilotFolderURL.appendingPathComponent("support") if !FileManager.default.fileExists(atPath: supportFolderURL.path) { try? FileManager.default .createDirectory(at: supportFolderURL, withIntermediateDirectories: false) } let executableFolderURL = gitHubCopilotFolderURL.appendingPathComponent("executable") if !FileManager.default.fileExists(atPath: executableFolderURL.path) { try? FileManager.default .createDirectory(at: executableFolderURL, withIntermediateDirectories: false) } return (supportURL, gitHubCopilotFolderURL, executableFolderURL, supportFolderURL) } }