Skip to content
This repository has been archived by the owner on Nov 12, 2022. It is now read-only.

Commit

Permalink
add ccls (#299)
Browse files Browse the repository at this point in the history
  • Loading branch information
williamboman committed Dec 5, 2021
1 parent 9f9e51c commit c82abb3
Show file tree
Hide file tree
Showing 11 changed files with 179 additions and 19 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -149,8 +149,11 @@ lsp_installer.settings({
| Ansible | `ansiblels` |
| Bash | `bashls` |
| Bicep | `bicep` |
| C | `ccls` |
| C | `clangd` |
| C# | `csharpls` |
| C# | `omnisharp` |
| C++ | `ccls` |
| C++ | `clangd` |
| CMake | `cmake` |
| CSS | `cssls` |
Expand Down Expand Up @@ -184,6 +187,7 @@ lsp_installer.settings({
| LaTeX | `texlab` |
| Lua | `sumneko_lua` |
| OCaml | `ocamlls` |
| Objective C | `ccls` |
| PHP | `intelephense` |
| PHP | `phpactor` |
| Powershell | `powershell_es` |
Expand Down
8 changes: 4 additions & 4 deletions lua/nvim-lsp-installer/_generated/filetype_map.lua
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ return {
bib = { "ltex", "texlab" },
bicep = { "bicep" },
blade = { "tailwindcss" },
c = { "clangd" },
c = { "ccls", "clangd" },
clojure = { "clojure_lsp" },
cmake = { "cmake" },
cpp = { "clangd" },
cpp = { "ccls", "clangd" },
cs = { "csharp_ls", "omnisharp" },
css = { "cssls", "emmet_ls", "stylelint_lsp", "tailwindcss" },
d = { "serve_d" },
Expand Down Expand Up @@ -61,8 +61,8 @@ return {
mysql = { "sqlls", "sqls" },
njk = { "tailwindcss" },
nunjucks = { "tailwindcss" },
objc = { "clangd" },
objcpp = { "clangd" },
objc = { "ccls", "clangd" },
objcpp = { "ccls", "clangd" },
ocaml = { "ocamlls" },
org = { "ltex" },
php = { "intelephense", "phpactor", "tailwindcss" },
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
-- THIS FILE IS GENERATED. DO NOT EDIT MANUALLY.
-- stylua: ignore start
return {
c = { "ccls", "clangd" },
["c#"] = { "csharp_ls", "omnisharp" },
["c++"] = { "clangd" },
["c++"] = { "ccls", "clangd" },
d = { "serve_d" },
["f#"] = { "fsautocomplete" },
fortran = { "fortls" },
Expand All @@ -11,6 +12,7 @@ return {
javascript = { "rome", "tsserver" },
latex = { "ltex", "texlab" },
lua = { "sumneko_lua" },
["objective-c"] = { "ccls" },
php = { "intelephense", "phpactor" },
python = { "jedi_language_server", "pylsp", "pyright" },
ruby = { "solargraph", "sorbet" },
Expand Down
3 changes: 3 additions & 0 deletions lua/nvim-lsp-installer/_generated/metadata.lua
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ return {
bicep = {
filetypes = { "bicep" }
},
ccls = {
filetypes = { "c", "cpp", "objc", "objcpp" }
},
clangd = {
filetypes = { "c", "cpp", "objc", "objcpp" }
},
Expand Down
27 changes: 26 additions & 1 deletion lua/nvim-lsp-installer/installers/context.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ local log = require "nvim-lsp-installer.log"
local process = require "nvim-lsp-installer.process"
local installers = require "nvim-lsp-installer.installers"
local platform = require "nvim-lsp-installer.platform"
local fs = require "nvim-lsp-installer.fs"
local path = require "nvim-lsp-installer.path"

local M = {}

Expand Down Expand Up @@ -96,7 +98,12 @@ function M.use_github_release_file(repo, file)
M.use_github_release(repo),
function(server, callback, context)
local function get_download_url(version)
local target_file = type(file) == "function" and file(version) or file
local target_file
if type(file) == "function" then
target_file = file(version)
else
target_file = file
end
if not target_file then
log.fmt_error(
"Unable to find which release file to download. server_name=%s, repo=%s",
Expand Down Expand Up @@ -160,4 +167,22 @@ function M.set(fn)
end
end

---@param rel_path string @The relative path from the current installation working directory.
function M.set_working_dir(rel_path)
---@type ServerInstallerFunction
return vim.schedule_wrap(function(server, callback, context)
log.fmt_debug("Changing installation working directory for %s", server.name)
local new_dir = path.concat { context.install_dir, rel_path }
if not fs.dir_exists(new_dir) then
local ok = pcall(fs.mkdirp, new_dir)
if not ok then
context.stdio_sink.stderr(("Failed to create directory %s.\n"):format(new_dir))
return callback(false)
end
end
context.install_dir = new_dir
callback(true)
end)
end

return M
33 changes: 23 additions & 10 deletions lua/nvim-lsp-installer/installers/init.lua
Original file line number Diff line number Diff line change
@@ -1,9 +1,21 @@
local platform = require "nvim-lsp-installer.platform"
local log = require "nvim-lsp-installer.log"
local Data = require "nvim-lsp-installer.data"
local fs = require "nvim-lsp-installer.fs"
local path = require "nvim-lsp-installer.path"

local M = {}

---@param installer ServerInstallerFunction[]|ServerInstallerFunction
---@return ServerInstallerFunction
local function normalize_installer(installer)
if type(installer) == "table" then
return M.pipe(installer)
else
return installer
end
end

---@alias ServerInstallCallback fun(success: boolean)

---@class ServerInstallContext
Expand Down Expand Up @@ -120,11 +132,7 @@ function M.on(platform_table)
return function(server, callback, context)
local installer = get_by_platform(platform_table)
if installer then
if type(installer) == "function" then
installer(server, callback, context)
else
M.pipe(installer)(server, callback, context)
end
normalize_installer(installer)(server, callback, context)
else
callback(true)
end
Expand All @@ -139,11 +147,7 @@ function M.when(platform_table)
return function(server, callback, context)
local installer = get_by_platform(platform_table)
if installer then
if type(installer) == "function" then
installer(server, callback, context)
else
M.pipe(installer)(server, callback, context)
end
normalize_installer(installer)(server, callback, context)
else
context.stdio_sink.stderr(
("Current operating system is not yet supported for server %q.\n"):format(server.name)
Expand All @@ -153,4 +157,13 @@ function M.when(platform_table)
end
end

---@param installer ServerInstallerFunction|ServerInstallerFunction[] @The installer to execute in a new installer context.
function M.branch_context(installer)
---@type ServerInstallerFunction
return function(server, callback, context)
local new_context = vim.deepcopy(context)
normalize_installer(installer)(server, callback, new_context)
end
end

return M
11 changes: 11 additions & 0 deletions lua/nvim-lsp-installer/installers/std.lua
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,17 @@ function M.git_clone(repo_url)
end
end

function M.git_submodule_update()
---@type ServerInstallerFunction
return function(_, callback, context)
process.spawn("git", {
args = { "submodule", "update", "--init", "--recursive" },
cwd = context.install_dir,
stdio_sink = context.stdio_sink,
}, callback)
end
end

---@param opts {args: string[]}
function M.gradlew(opts)
---@type ServerInstallerFunction
Expand Down
7 changes: 7 additions & 0 deletions lua/nvim-lsp-installer/server.lua
Original file line number Diff line number Diff line change
Expand Up @@ -187,10 +187,16 @@ function M.Server:install_attached(context, callback)
("Failed to promote the temporary installation directory %q.\n"):format(context.install_dir)
)
pcall(fs.rmrf, self:get_tmp_install_dir())
pcall(fs.rmrf, context.install_dir)
callback(false)
return
end

-- The tmp dir should in most cases have been "promoted" and already renamed to its final destination,
-- but we make sure to delete it should the installer modify the installation working directory during
-- installation.
pcall(fs.rmrf, self:get_tmp_install_dir())

-- Dispatch the server is ready
vim.schedule(function()
dispatcher.dispatch_server_ready(self)
Expand All @@ -201,6 +207,7 @@ function M.Server:install_attached(context, callback)
callback(true)
else
pcall(fs.rmrf, self:get_tmp_install_dir())
pcall(fs.rmrf, context.install_dir)
callback(false)
end
end),
Expand Down
4 changes: 1 addition & 3 deletions lua/nvim-lsp-installer/servers/bicep/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,7 @@ return function(name, root_dir)
end),
std.rename(path.concat { "vscode", "extension", "bicepLanguageServer" }, "langserver"),
std.rmrf "vscode",
context.set(function(ctx)
ctx.install_dir = path.concat { ctx.install_dir, "langserver" }
end),
context.set_working_dir "langserver",
},
default_options = {
cmd = { "dotnet", path.concat { root_dir, "Bicep.LangServer.dll" } },
Expand Down
96 changes: 96 additions & 0 deletions lua/nvim-lsp-installer/servers/ccls/init.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
local server = require "nvim-lsp-installer.server"
local path = require "nvim-lsp-installer.path"
local installers = require "nvim-lsp-installer.installers"
local Data = require "nvim-lsp-installer.data"
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 coalesce, when = Data.coalesce, Data.when

return function(name, root_dir)
local llvm_installer

do
---@param version string
---@return string|nil
local function get_archive_name(version)
local name_template = coalesce(
when(platform.is_mac, "clang+llvm-%s-x86_64-apple-darwin"),
when(
platform.is_linux,
coalesce(
when(platform.arch == "x64", "clang+llvm-%s-amd64-unknown-freebsd13"),
when(platform.arch == "arm64", "clang+llvm-%s-aarch64-linux-gnu")
)
)
)
return name_template and name_template:format(version)
end

---@param version string
local function normalize_version(version)
return version:gsub("^llvmorg%-", "")
end

llvm_installer = installers.branch_context {
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
end),
context.use_github_release_file("llvm/llvm-project", function(version)
-- Strip the "llvmorg-" prefix from tags (llvm releases tags like llvmorg-13.0.0)
local archive_name = get_archive_name(normalize_version(version))
return archive_name and ("%s.tar.xz"):format(archive_name)
end),
context.capture(function(ctx)
return installers.pipe {
std.untarxz_remote(ctx.github_release_file),
std.rename(get_archive_name(normalize_version(ctx.requested_server_version)), "llvm"),
}
end),
}
end

local ccls_installer = installers.branch_context {
context.set(function(ctx)
ctx.llvm_install_dir = path.concat { ctx.install_dir, "llvm" }
end),
context.set_working_dir "ccls",
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,
}

c.run("cmake", {
"-H.",
"-BRelease",
"-DCMAKE_BUILD_TYPE=Release",
("-DCMAKE_PREFIX_PATH=%s"):format(path.concat { ctx.llvm_install_dir, "lib", "cmake" }),
})
c.run("cmake", { "--build", "Release" })
c.spawn(callback)
end,
}

return server.Server:new {
name = name,
root_dir = root_dir,
homepage = "https://github.com/MaskRay/ccls",
languages = { "c", "c++", "objective-c" },
installer = installers.when {
unix = {
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,
},
},
default_options = {
cmd = { path.concat { root_dir, "ccls", "Release", "ccls" } },
},
}
end
1 change: 1 addition & 0 deletions lua/nvim-lsp-installer/servers/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ local CORE_SERVERS = Data.set_of {
"ansiblels",
"bashls",
"bicep",
"ccls",
"clangd",
"clojure_lsp",
"cmake",
Expand Down

0 comments on commit c82abb3

Please sign in to comment.