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
1 change: 1 addition & 0 deletions Code.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -4238,6 +4238,7 @@
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_DEBUG_DYLIB = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
Expand Down
59 changes: 40 additions & 19 deletions CodeApp/Managers/AppExtensionService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,34 @@ class AppExtensionService: NSObject {
try? await Task.sleep(nanoseconds: 1 * 1_000_000_000)
}

/// The extension exits after every command and is relaunched by the interruption handler,
/// so a command started right after another one has to wait for the server to listen again.
private func connect(sending firstMessage: String) async throws -> URLSessionWebSocketTask {
let url = URL(string: "ws://127.0.0.1:\(String(AppExtensionService.PORT))/websocket")!
var attempt = 0
while true {
let task = URLSession.shared.webSocketTask(with: url)
self.task = task
task.resume()
do {
try await task.send(.string(firstMessage))
return task
} catch let error as URLError
where error.code == .cannotConnectToHost && attempt < 40
{
task.cancel()
attempt += 1
try await Task.sleep(nanoseconds: 250_000_000)
}
}
}

func call(
args: [String],
t_stdin: UnsafeMutablePointer<FILE>,
t_stdout: UnsafeMutablePointer<FILE>
) async throws {
t_stdout: UnsafeMutablePointer<FILE>,
environment: [String: String] = [:]
) async throws -> Int32 {
await prepareServer()

defer {
Expand All @@ -86,10 +109,18 @@ class AppExtensionService: NSObject {
}
signal(SIGINT, signalCallback)

let task = URLSession.shared.webSocketTask(
with: URL(string: "ws://127.0.0.1:\(String(AppExtensionService.PORT))/websocket")!)
self.task = task
task.resume()
let frame = ExecutionRequestFrame(
args: args,
redirectStderr: true,
workingDirectoryBookmark: try? URL(
fileURLWithPath: FileManager.default.currentDirectoryPath
).bookmarkData(),
isLanguageService: false,
environment: environment
)

let task = try await connect(sending: frame.stringRepresentation)
print("Sending -> \(frame.stringRepresentation)")

let handle = FileHandle(fileDescriptor: fileno(t_stdin), closeOnDealloc: false)
handle.readabilityHandler = { fileHandle in
Expand All @@ -101,19 +132,6 @@ class AppExtensionService: NSObject {
}
}

let frame = ExecutionRequestFrame(
args: args,
redirectStderr: true,
workingDirectoryBookmark: try? URL(
fileURLWithPath: FileManager.default.currentDirectoryPath
).bookmarkData(),
isLanguageService: false
)

try await task.send(.string(frame.stringRepresentation))

print("Sending -> \(frame.stringRepresentation)")

while let message = try? await task.receive() {
switch message {
case .string(let text):
Expand All @@ -123,5 +141,8 @@ class AppExtensionService: NSObject {
continue
}
}

let closeCode = task.closeCode.rawValue
return (4000..<5000).contains(closeCode) ? Int32(closeCode - 4000) : 0
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,8 @@ class MonacoImplementation: NSObject {
await applyOptions(options: "minimap: {enabled: \(options.miniMapEnabled)}")
await applyOptions(options: "lineNumbers: \(options.lineNumbersEnabled)")
await applyOptions(options: "smoothScrolling: \(options._smoothScrollingEnabled)")
await applyOptions(options: "readOnly: \(options.readOnly)")
await applyOptions(
options: "readOnly: \(options.readOnly), domReadOnly: \(options.readOnly)")
await applyOptions(options: "tabSize: \(String(options.tabRenderSize))")
await applyOptions(options: "renderWhitespace: '\(options.renderWhiteSpaces)'")
await applyOptions(options: "wordWrap: '\(options.wordWrap)'")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ final class LocalGitCredentialsHelper {
case https, ssh

init?(rawValue: String) {
if rawValue == "https" {
// Plain http remotes (e.g. self-hosted Forgejo on a LAN) use the same plaintext credentials.
if rawValue == "https" || rawValue == "http" {
self = .https
} else if rawValue == "ssh" {
self = .ssh
Expand Down
14 changes: 10 additions & 4 deletions CodeApp/Managers/FileSystem/Local/LocalGitServiceProvider.swift
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,12 @@ class LocalGitServiceProvider: GitServiceProvider {
func checkout(reference: ReferenceType) async throws {
try await WorkerQueueTask {
let repository = try self.checkedRepository()
try repository.checkout(reference, strategy: [.Safe]).get()
var target = reference
// Checking out a remote branch directly leaves HEAD detached; use a local tracking branch instead.
if let branch = reference as? Branch, branch.isRemote, !branch.name.hasSuffix("/HEAD") {
target = try repository.localTrackingBranch(for: branch).get()
}
try repository.checkout(target, strategy: [.Safe]).get()
self.contentCache.removeAllObjects()
}
}
Expand Down Expand Up @@ -350,14 +355,15 @@ class LocalGitServiceProvider: GitServiceProvider {
return try await WorkerQueueTask {
let repository = try self.checkedRepository()

if let cached = self.contentCache.object(forKey: path as NSString) {
return (cached as String)
}
let path =
try path
.replacingOccurrences(of: self.workingURL.absoluteString, with: "")
.removingPercentEncoding

if let cached = self.contentCache.object(forKey: path as NSString) {
return (cached as String)
}

let oid = try self.fileOidAtPathForLastCommit(path: path)
let blob = try repository.blob(oid).get()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ class SFTPTerminalServiceProvider: NSObject, TerminalServiceProvider {
} catch {
print("Unable to start shell,", error)
continuation.resume(throwing: SFTPError.UnableToStartShell)
return
}

continuation.resume()
Expand Down
1 change: 1 addition & 0 deletions CodeApp/Types/Shared/AppExtensionError.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ struct ExecutionRequestFrame: Codable {
var redirectStderr: Bool
var workingDirectoryBookmark: Data?
var isLanguageService: Bool
var environment: [String: String]? = nil
}

enum AppExtensionError: String {
Expand Down
Loading
Loading