Skip to content

Instantly share code, notes, and snippets.

@kuwerty
Created April 17, 2020 10:32
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kuwerty/0d5b673498242e519291c14e10366187 to your computer and use it in GitHub Desktop.
Save kuwerty/0d5b673498242e519291c14e10366187 to your computer and use it in GitHub Desktop.
// requires this fork of sourcekit-lsp:
// https://github.com/kuwerty/sourcekit-lsp
/*
Add buildServer.json to 'root' of source (or wherever sourcekit-lsp reads it):
{
"name": "BuildimotoBuildServer",
"version": "1.0.0",
"bspVersion": "2.0",
"languages": [ "swift", "c", "cpp", "objective-c", "objective-cpp" ],
"argv": [ "./tools/BuildimotoBuildServer/.build/release/BuildimotoBuildServer" ]
}
*/
//
// BuildServer.swift
// Build
//
// Created by Krister Wombell on 19/10/19.
//
import Foundation
import LanguageServerProtocol
import SKCore
import SKSupport
import BuildServerProtocol
import LanguageServerProtocolJSONRPC
import TSCBasic
import TSCLibc
import TSCUtility
import LSPLogging
typealias Notification = LanguageServerProtocol.Notification
public struct MySourceKitOptionsResult: ResponseType, Hashable {
/// The compiler options required for the requested file.
public var options: [String]
/// The working directory for the compile command.
public var workingDirectory: String?
}
let builtinRequests: [_RequestType.Type] = [
InitializeBuild.self,
RegisterForChanges.self,
SourceKitOptions.self,
]
let builtinNotifications: [NotificationType.Type] = [
]
let buildServerProtocol: MessageRegistry =
MessageRegistry(requests: builtinRequests, notifications: builtinNotifications)
public final class BuildServer : LanguageServerEndpoint{
var db : CompilationDatabase?
public override init() {
super.init()
}
public override func _registerBuiltinHandlers() {
_register(BuildServer.initialize)
_register(BuildServer.shutdown)
_register(BuildServer.exit)
_register(BuildServer.buildInitialized)
_register(BuildServer.registerForChanges)
_register(BuildServer.sourceKitOptions)
}
func initialize(_ req: Request<InitializeBuild>) {
Logger.shared.log("BuildServer initialize!")
let caps = BuildServerCapabilities()
let data = LSPAny.dictionary([
"indexDatabasePath" : LSPAny.string(".buildimoto/index/db"),
"indexStorePath" : LSPAny.string(".buildimoto/index/store")
])
let path = AbsolutePath(req.params.rootUri.pseudoPath).appending(component: ".buildimoto")
self.db = tryLoadCompilationDatabase(directory: path)
let result = InitializeBuildResult(
displayName: "BuildimotoBuildServer",
version: "1.0",
bspVersion: "2.0",
capabilities: caps,
data: data
)
req.reply(result)
}
func shutdown(_ request: Request<ShutdownRequest>) {
// Nothing to do yet.
request.reply(VoidResponse())
}
func exit(_ notification: Notification<ExitNotification>) {
}
func buildInitialized(_ notification: Notification<InitializedBuildNotification>) {
}
func registerForChanges(_ req: Request<RegisterForChanges>) {
Logger.shared.log("registerForChanges: \(req.params.uri)")
req.reply(VoidResponse())
}
func sourceKitOptions(_ req: Request<SourceKitOptions>) {
guard let db = db else {
req.reply(.failure(.unknown("no compilation database loaded.")))
return
}
let url = URL(string: req.params.uri.stringValue)!
guard let cmd = db[url].first else {
req.reply(.failure(.unknown("file not in compilation database.")))
return
}
let reply = SourceKitOptionsResult(
options: Array(cmd.commandLine.dropFirst()),
workingDirectory: cmd.directory
)
req.reply(reply)
}
}
let clientConnection = JSONRPCConnection(
protocol: buildServerProtocol,
inFD: STDIN_FILENO,
outFD: STDOUT_FILENO,
syncRequests: false)
let server = BuildServer()
clientConnection.start(receiveHandler: server)
Logger.shared.addLogHandler { message, _ in
clientConnection.send(LogMessageNotification(type: .log, message: message))
}
dispatchMain()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment