aboutsummaryrefslogtreecommitdiffstats
path: root/lua/nvim-lsp-installer/servers/ccls/init.lua
diff options
context:
space:
mode:
Diffstat (limited to 'lua/nvim-lsp-installer/servers/ccls/init.lua')
-rw-r--r--lua/nvim-lsp-installer/servers/ccls/init.lua163
1 files changed, 105 insertions, 58 deletions
diff --git a/lua/nvim-lsp-installer/servers/ccls/init.lua b/lua/nvim-lsp-installer/servers/ccls/init.lua
index 079c9cd2..d5dde3e0 100644
--- a/lua/nvim-lsp-installer/servers/ccls/init.lua
+++ b/lua/nvim-lsp-installer/servers/ccls/init.lua
@@ -1,3 +1,24 @@
+-- __________________
+-- < Here be dragons! >
+-- ------------------
+-- \ ^ /^
+-- \ / \ // \
+-- \ |\___/| / \// .\
+-- \ /O O \__ / // | \ \ *----*
+-- / / \/_/ // | \ \ \ |
+-- @___@` \/_ // | \ \ \/\ \
+-- 0/0/| \/_ // | \ \ \ \
+-- 0/0/0/0/| \/// | \ \ | |
+-- 0/0/0/0/0/_|_ / ( // | \ _\ | /
+-- 0/0/0/0/0/0/`/,_ _ _/ ) ; -. | _ _\.-~ / /
+-- ,-} _ *-.|.-~-. .~ ~
+-- \ \__/ `/\ / ~-. _ .-~ /
+-- \____(@@) *. } { /
+-- ( (--) .----~-.\ \-` .~
+-- //__\\ \__ Ack! ///.----..< \ _ -~
+-- // \\ ///-._ _ _ _ _ _ _{^ - - - - ~
+--
+
local server = require "nvim-lsp-installer.server"
local path = require "nvim-lsp-installer.path"
local installers = require "nvim-lsp-installer.installers"
@@ -6,8 +27,9 @@ local std = require "nvim-lsp-installer.installers.std"
local platform = require "nvim-lsp-installer.platform"
local context = require "nvim-lsp-installer.installers.context"
local process = require "nvim-lsp-installer.process"
+local fs = require "nvim-lsp-installer.fs"
-local coalesce, when = Data.coalesce, Data.when
+local coalesce, when, list_not_nil = Data.coalesce, Data.when, Data.list_not_nil
return function(name, root_dir)
local llvm_installer
@@ -17,32 +39,29 @@ return function(name, root_dir)
---@param os_distribution table<string, string>|nil
---@return string|nil
local function get_archive_name(version, os_distribution)
- local name_template = coalesce(
- when(platform.is_mac, "clang+llvm-%s-x86_64-apple-darwin"),
- when(
- platform.is_linux,
- coalesce(
- when(
- platform.arch == "x64",
- coalesce(
- when(
- os_distribution.id == "ubuntu" and os_distribution.version.major >= 20,
- "clang+llvm-%s-x86_64-linux-gnu-ubuntu-20.04"
- ),
- when(
- os_distribution.id == "ubuntu" and os_distribution.version.major >= 16,
- "clang+llvm-%s-x86_64-linux-gnu-ubuntu-16.04"
- ),
- -- the Ubuntu dist is allegedly the most suitable cross-platform one, so we default to it
+ local name_template = coalesce(when(
+ platform.is_linux,
+ coalesce(
+ when(
+ platform.arch == "x64",
+ coalesce(
+ when(
+ os_distribution.id == "ubuntu" and os_distribution.version.major >= 20,
+ "clang+llvm-%s-x86_64-linux-gnu-ubuntu-20.04"
+ ),
+ when(
+ os_distribution.id == "ubuntu" and os_distribution.version.major >= 16,
"clang+llvm-%s-x86_64-linux-gnu-ubuntu-16.04"
- )
- ),
- when(platform.arch == "arm64", "clang+llvm-%s-aarch64-linux-gnu"),
- when(platform.arch == "armv7", "clang+llvm-%s-armv7a-linux-gnueabihf"),
- when(platform.arch == "x86", "clang+llvm-%s-i386-unknown-freebsd13")
- )
+ ),
+ -- the Ubuntu dist is allegedly the most suitable cross-platform one, so we default to it
+ "clang+llvm-%s-x86_64-linux-gnu-ubuntu-16.04"
+ )
+ ),
+ when(platform.arch == "arm64", "clang+llvm-%s-aarch64-linux-gnu"),
+ when(platform.arch == "armv7", "clang+llvm-%s-armv7a-linux-gnueabihf"),
+ when(platform.arch == "x86", "clang+llvm-%s-i386-unknown-freebsd13")
)
- )
+ ))
return name_template and name_template:format(version)
end
@@ -53,6 +72,7 @@ return function(name, root_dir)
end
llvm_installer = installers.branch_context {
+ context.use_os_distribution(),
context.set(function(ctx)
-- We unset the requested version for llvm because it's not the primary target - the user's requested version should only apply to ccls.
ctx.requested_server_version = nil
@@ -71,6 +91,7 @@ return function(name, root_dir)
get_archive_name(normalize_version(ctx.requested_server_version), ctx.os_distribution),
"llvm"
),
+ -- We move the clang headers out, because they need to be persisted
std.rename(
path.concat { "llvm", "lib", "clang", normalize_version(ctx.requested_server_version) },
"clang-resource"
@@ -80,33 +101,65 @@ return function(name, root_dir)
}
end
- local ccls_installer = installers.branch_context {
+ local ccls_installer = installers.pipe {
+ std.git_clone("https://github.com/MaskRay/ccls", {
+ directory = "ccls-git",
+ recursive = true,
+ }),
+ function(server, callback, ctx)
+ local c = process.chain {
+ cwd = path.concat { ctx.install_dir, "ccls-git" },
+ stdio_sink = ctx.stdio_sink,
+ }
+
+ local clang_resource_dir = path.concat { server.root_dir, "clang-resource" }
+
+ c.run(
+ "cmake",
+ list_not_nil(
+ "-DCMAKE_BUILD_TYPE=Release",
+ "-DUSE_SYSTEM_RAPIDJSON=OFF",
+ "-DCMAKE_FIND_FRAMEWORK=LAST",
+ "-Wno-dev",
+ ("-DCMAKE_INSTALL_PREFIX=%s"):format(ctx.install_dir),
+ ("-DCMAKE_PREFIX_PATH=%s"):format(ctx.llvm_dir),
+ when(platform.is_mac, "-DCMAKE_OSX_SYSROOT=/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk"),
+ when(platform.is_linux, ("-DCLANG_RESOURCE_DIR=%s"):format(clang_resource_dir))
+ )
+ )
+ c.run("make", { "install" })
+ c.spawn(callback)
+ end,
+ std.rmrf "ccls-git",
+ }
+
+ local linux_ccls_installer = installers.pipe {
+ llvm_installer,
context.set(function(ctx)
- ctx.llvm_install_dir = path.concat { ctx.install_dir, "llvm" }
- ctx.clang_resource_dir = path.concat { ctx.install_dir, "clang-resource" }
+ ctx.llvm_dir = path.concat { ctx.install_dir, "llvm" }
end),
- installers.branch_context {
- context.set_working_dir "ccls-git",
- std.git_clone "https://github.com/MaskRay/ccls",
- std.git_submodule_update(),
- function(_, callback, ctx)
- local c = process.chain {
- cwd = ctx.install_dir,
- stdio_sink = ctx.stdio_sink,
- }
+ ccls_installer,
+ std.rmrf "llvm",
+ }
- c.run("cmake", {
- "-H.",
- "-BRelease",
- "-DCMAKE_BUILD_TYPE=Release",
- ("-DCMAKE_PREFIX_PATH=%s"):format(ctx.llvm_install_dir),
- ("-DCLANG_RESOURCE_DIR=%s"):format(ctx.clang_resource_dir),
- })
- c.run("cmake", { "--build", "Release" })
- c.spawn(callback)
- end,
- },
- std.rename(path.concat { "ccls-git", "Release", "ccls" }, "ccls"),
+ local mac_ccls_installer = installers.pipe {
+ context.use_homebrew_prefix(),
+ context.set(function(ctx)
+ ctx.llvm_dir = path.concat { ctx.homebrew_prefix, "opt", "llvm" }
+ end),
+ function(_, callback, ctx)
+ if not fs.dir_exists(ctx.llvm_dir) then
+ ctx.stdio_sink.stderr(
+ (
+ "LLVM does not seem to be installed on this system (looked in %q). Please install LLVM via Homebrew:\n $ brew install llvm\n"
+ ):format(ctx.llvm_dir)
+ )
+ callback(false)
+ return
+ end
+ callback(true)
+ end,
+ ccls_installer,
}
return server.Server:new {
@@ -115,17 +168,11 @@ return function(name, root_dir)
homepage = "https://github.com/MaskRay/ccls",
languages = { "c", "c++", "objective-c" },
installer = installers.when {
- unix = {
- context.use_os_distribution(),
- context.promote_install_dir(), -- ccls hardcodes the path to llvm at compile time, so we need to compile everything in the final directory
- llvm_installer,
- ccls_installer,
- std.rmrf "llvm",
- std.rmrf "ccls-git",
- },
+ mac = mac_ccls_installer,
+ linux = linux_ccls_installer,
},
default_options = {
- cmd = { path.concat { root_dir, "ccls" } },
+ cmd = { path.concat { root_dir, "bin", "ccls" } },
},
}
end