Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lua snippets #8

Merged
merged 15 commits into from
Mar 18, 2021
99 changes: 14 additions & 85 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,101 +6,30 @@ You can install nvim-lspinstall with any neovim package manager.
```vim
Plug 'anott03/nvim-lspinstall'
```
## Languages Currently Supported
#### Bash
- Prerequisites: [nodejs](https://nodejs.org) (and npm)
- Depending on how you have node/npm set it up, you may need sudo permissions to complete the installation.
- `:InstallLS bashls`
#### Cmake
- Prerequisites: [python](https://www.python.org/)
- `:InstallLS cmake`
#### CSS
- Prerequisites: [nodejs](https://nodejs.org) (and npm)
- Depending on how you have node/npm set it up, you may need sudo permissions to complete the installation.
- `:InstallLS cssls`
#### Docker
- Prerequisites: [nodejs](https://nodejs.org) (and npm)
- Depending on how you have node/npm set it up, you may need sudo permissions to complete the installation.
- `:InstallLS docker`
#### Elm
- Prerequisites: [nodejs](https://nodejs.org) (and npm)
- Depending on how you have node/npm set it up, you may need sudo permissions to complete the installation.
- `:InstallLS elmls`
#### Go
- There's nothing for us to install! As long as you have go installed on your system, you're good to go. Look [here](https://github.com/golang/tools/blob/master/gopls/doc/vim.md) for more detailed instructions on setting up LSP with go.
#### html
- prerequisites: [nodejs](https://nodejs.org) (and npm)
- depending on how you have node/npm set it up, you may need sudo permissions to complete the installation.
- `:InstallLS html`
#### json
- prerequisites: [nodejs](https://nodejs.org) (and npm)
- depending on how you have node/npm set it up, you may need sudo permissions to complete the installation.
- `:InstallLS jsonls`
#### Lua
- Prerequisites: [ninja](https://github.com/ninja-build/ninja/wiki/Pre-built-Ninja-packages)
- When configuring LSP for lua, you will need the path to your lua-langauge-server installation. Nvim-lspinstall places it at `$HOME/.local/share/nvim/lspinstall/lua-language-server/`.
- `:InstallLS sumneko_lua`
#### Rust
- `:InstallLS rust_analyzer`
#### Typescript/Javascript
- A prerequisite is that you have [nodejs](https://nodejs.org) and npm installed.
- Depending on how you have node/npm set it up, you may need sudo permissions to complete the installation.
- `:InstallLS tsserver`
#### PHP (Intelephense)
- A prerequisite is that you have [nodejs](https://nodejs.org) and npm installed.
- Depending on how you have node/npm set it up, you may need sudo permissions to complete the installation.
- `:InstalllLS intelephense`
#### Purescript
- A prerequisite is that you have [nodejs](https://nodejs.org) and npm installed.
- Depending on how you have node/npm set it up, you may need sudo permissions to complete the installation.
- `:InstallLS purescriptls`
#### Python (pyls)
- The only prerequisite is that you have python installed.
- `:InstallLS pyls`
#### Svelte
- A prerequisite is that you have [nodejs](https://nodejs.org) and npm installed.
- Depending on how you have node/npm set it up, you may need sudo permissions to complete the installation.
- `:InstallLS svelte`
#### VueJS
- A prerequisite is that you have [nodejs](https://nodejs.org) and npm installed.
- Depending on how you have node/npm set it up, you may need sudo permissions to complete the installation.
- `:InstallLS vuels`
#### Yaml
- A prerequisite is that you have [nodejs](https://nodejs.org) and npm installed.
- Depending on how you have node/npm set it up, you may need sudo permissions to complete the installation.
- `:InstallLS yamlls`
## Where Are All the Scripts?
In order to reduce the size of the plugin on your system, all of the install scripts have been moved to a separate repository, which you can find [here](https://github.com/anott03/nvim-lspinstall-scripts). When you install a language server, the plugin will download the necessary script and execute it. By doing this, adding support for new languages won't take up additional space on your system.
#### What does this mean for contributing?
Unfortunately, this does mean contributers have a little bit of extra work. To add an installer, please make a PR with the install script itself at [anott03/nvim-lspinstall-scripts](https://github.com/anott03/nvim-lspinstall-scripts), and make another PR on this repository to update the README and to add the call to your installer.
## Contributing
Contributions would be greatly appreciated!
- Platform: I am currently only working on nvim-lspinstall for linux. If people want to help add support for windows and macOS, that would be great.
- Languages: The more people writing install scripts for languages, the more languages we can support.
## Ultimate Language List
These are the langauges we plan/hope support. It's the same list that was on the [lspconfig github page](https://github.com/neovim/nvim-lspconfig).
- [ ] als
- [ ] angularls
- [X] bashls
- [ ] bashls
- [ ] ccls
- [ ] clangd
- [X] clangd
- [ ] clojure_lsp
- [X] cmake
- [ ] cmake
- [ ] codeqlls
- [X] cssls
- [ ] cssls
- [ ] dartls
- [ ] denols
- [ ] dhall_lsp_server
- [ ] diagnosticls
- [X] dockerls
- [ ] efm
- [ ] elixirls
- [ ] elmls
- [X] elmls
- [ ] flow
- [ ] fortls
- [ ] gdscript
- [ ] ghcide
- [X] gopls
- [ ] gopls
- [ ] groovyls
- [ ] hie
- [ ] hls
Expand All @@ -114,30 +43,30 @@ These are the langauges we plan/hope support. It's the same list that was on the
- [ ] leanls
- [ ] metals
- [ ] nimls
- [ ] ocamlls
- [X] ocamlls
- [ ] ocamllsp
- [ ] omnisharp
- [X] omnisharp
- [ ] perlls
- [ ] purescriptls
- [X] pyls
- [X] purescriptls
- [ ] pyls
- [ ] pyls_ms
- [ ] pyright
- [X] pyright (not working)
- [ ] r_language_server
- [ ] rls
- [ ] rnix
- [ ] rome
- [X] rust_analyzer
- [ ] rust_analyzer
- [ ] scry
- [ ] solargraph
- [ ] sorbet
- [ ] sourcekit
- [ ] sqlls
- [X] sqlls
- [X] sumneko_lua
- [X] svelte
- [ ] terraformls
- [ ] texlab
- [X] tsserver
- [ ] vimls
- [X] vimls
- [X] vuels
- [X] yamlls
- [ ] zls
226 changes: 226 additions & 0 deletions lua/nvim-lspinstall/configs.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,226 @@
local log = require 'vim.lsp.log'
local util = require 'nvim-lspinstall/util'
local api, validate, lsp = vim.api, vim.validate, vim.lsp
local tbl_extend = vim.tbl_extend

local configs = {}

function configs.__newindex(t, config_name, config_def)
validate {
name = {config_name, 's'};
default_config = {config_def.default_config, 't'};
on_new_config = {config_def.on_new_config, 'f', true};
on_attach = {config_def.on_attach, 'f', true};
commands = {config_def.commands, 't', true};
}
if config_def.commands then
for k, v in pairs(config_def.commands) do
validate {
['command.name'] = {k, 's'};
['command.fn'] = {v[1], 'f'};
}
end
else
config_def.commands = {}
end

local M = {}

local default_config = tbl_extend("keep", config_def.default_config, util.default_config)

-- Force this part.
default_config.name = config_name

-- The config here is the one which will be instantiated for the new server,
-- which is why this is a function, so that it can refer to the settings
-- object on the server.
local function add_handlers(config)
assert(not config.callbacks, "lsp.callbacks has been obsoleted. See here for more: https://github.com/neovim/neovim/pull/12655")
config.handlers["window/logMessage"] = function(err, method, params, client_id)
if params and params.type <= config.log_level then
-- TODO(ashkan) remove this after things have settled.
assert(lsp.handlers["window/logMessage"], "Handler for window/logMessage notification is not defined")
lsp.handlers["window/logMessage"](err, method, params, client_id)
end
end

config.handlers["window/showMessage"] = function(err, method, params, client_id)
if params and params.type <= config.message_level then
-- TODO(ashkan) remove this after things have settled.
assert(lsp.handlers["window/showMessage"], "Handler for window/showMessage notification is not defined")
lsp.handlers["window/showMessage"](err, method, params, client_id)
end
end

-- pyright and jdtls ignore dynamicRegistration settings and sent client/registerCapability handler which are unhandled
config.handlers['client/registerCapability'] = function(_, _, _, _)
log.warn(string.format( [[
The language server %s incorrectly triggers a registerCapability handler
despite dynamicRegistration set to false. Please report upstream.
]] , config.name))
return {
result = nil;
error = nil;
}
end

config.handlers["workspace/configuration"] = function(err, method, params, client_id)
if err then error(tostring(err)) end
if not params.items then
return {}
end

local result = {}
for _, item in ipairs(params.items) do
if item.section then
local value = util.lookup_section(config.settings, item.section) or vim.NIL
-- For empty sections with no explicit '' key, return settings as is
if value == vim.NIL and item.section == '' then
value = config.settings or vim.NIL
end
table.insert(result, value)
end
end
return result
end
end

function M.setup(config)
validate {
root_dir = {config.root_dir, 'f', default_config.root_dir ~= nil};
filetypes = {config.filetype, 't', true};
on_new_config = {config.on_new_config, 'f', true};
on_attach = {config.on_attach, 'f', true};
commands = {config.commands, 't', true};
}
if config.commands then
for k, v in pairs(config.commands) do
validate {
['command.name'] = {k, 's'};
['command.fn'] = {v[1], 'f'};
}
end
end

config = tbl_extend("keep", config, default_config)

local trigger
if config.filetypes then
trigger = "FileType "..table.concat(config.filetypes, ',')
else
trigger = "BufReadPost *"
end
api.nvim_command(string.format(
"autocmd %s lua require'lspconfig'[%q].manager.try_add()"
, trigger
, config.name
))

local get_root_dir = config.root_dir

-- In the case of a reload, close existing things.
if M.manager then
for _, client in ipairs(M.manager.clients()) do
client.stop(true)
end
M.manager = nil
end

local make_config = function(_root_dir)
local new_config = util.tbl_deep_extend("keep", vim.empty_dict(), config)
new_config = util.tbl_deep_extend('keep', new_config, default_config)
new_config.capabilities = new_config.capabilities or lsp.protocol.make_client_capabilities()
new_config.capabilities = util.tbl_deep_extend('keep', new_config.capabilities, {
workspace = {
configuration = true;
}
})

add_handlers(new_config)
if config_def.on_new_config then
pcall(config_def.on_new_config, new_config, _root_dir)
end
if config.on_new_config then
pcall(config.on_new_config, new_config, _root_dir)
end

new_config.on_init = util.add_hook_after(new_config.on_init, function(client, _result)
function client.workspace_did_change_configuration(settings)
if not settings then return end
if vim.tbl_isempty(settings) then
settings = {[vim.type_idx]=vim.types.dictionary}
end
return client.notify('workspace/didChangeConfiguration', {
settings = settings;
})
end
if not vim.tbl_isempty(new_config.settings) then
client.workspace_did_change_configuration(new_config.settings)
end
end)

-- Save the old _on_attach so that we can reference it via the BufEnter.
new_config._on_attach = new_config.on_attach
new_config.on_attach = vim.schedule_wrap(function(client, bufnr)
if bufnr == api.nvim_get_current_buf() then
M._setup_buffer(client.id)
else
api.nvim_command(string.format(
"autocmd BufEnter <buffer=%d> ++once lua require'lspconfig'[%q]._setup_buffer(%d)"
, bufnr
, config_name
, client.id
))
end
end)

new_config.root_dir = _root_dir
return new_config
end

local manager = util.server_per_root_dir_manager(function(_root_dir)
return make_config(_root_dir)
end)

function manager.try_add()
if vim.bo.buftype == 'nofile' then
return
end
local root_dir = get_root_dir(api.nvim_buf_get_name(0), api.nvim_get_current_buf())
local id = manager.add(root_dir)
if id then
lsp.buf_attach_client(0, id)
end
end

M.manager = manager
M.make_config = make_config
end

function M._setup_buffer(client_id)
local client = lsp.get_client_by_id(client_id)
if client.config._on_attach then
client.config._on_attach(client)
end
if client.config.commands and not vim.tbl_isempty(client.config.commands) then
M.commands = util.tbl_deep_extend("force", M.commands, client.config.commands)
end
if not M.commands_created and not vim.tbl_isempty(M.commands) then
-- Create the module commands
util.create_module_commands(config_name, M.commands)
M.commands_created = true
end
end

M.commands_created = false
M.commands = config_def.commands
M.name = config_name
M.document_config = config_def

rawset(t, config_name, M)

return M
end

return setmetatable({}, configs)
-- vim:et ts=2 sw=2
Loading