diff options
| -rw-r--r-- | README.md | 197 | ||||
| -rw-r--r-- | lua/nvim_lsp.lua | 3 | ||||
| -rw-r--r-- | lua/nvim_lsp/hie.lua | 1 | ||||
| -rw-r--r-- | lua/nvim_lsp/rls.lua | 1 | ||||
| -rw-r--r-- | lua/nvim_lsp/sumneko_lua.lua | 105 | ||||
| -rw-r--r-- | lua/nvim_lsp/util.lua | 61 | ||||
| -rw-r--r-- | scripts/docgen.lua | 46 |
7 files changed, 395 insertions, 19 deletions
@@ -43,6 +43,7 @@ Implemented language servers: - [pyls](#pyls) - [rls](#rls) - [solargraph](#solargraph) +- [sumneko_lua](#sumneko_lua) - [texlab](#texlab) - [tsserver](#tsserver) @@ -383,6 +384,98 @@ init_options = { } ``` +This server accepts configuration via the `settings` key. +<details><summary>Available settings:</summary> + +- **`languageServerHaskell.completionSnippetsOn`**: `boolean` + + Default: `true` + + Show snippets with type information when using code completion + +- **`languageServerHaskell.diagnosticsOnChange`**: `boolean` + + Default: `true` + + Compute diagnostics continuously as you type. Turn off to only generate diagnostics on file save. + +- **`languageServerHaskell.enableHIE`**: `boolean` + + Default: `true` + + Enable/disable HIE (useful for multi-root workspaces). + +- **`languageServerHaskell.formatOnImportOn`**: `boolean` + + Default: `true` + + When adding an import, use the formatter on the result + +- **`languageServerHaskell.formattingProvider`**: `enum { "brittany", "floskell", "none" }` + + Default: `"brittany"` + + The tool to use for formatting requests. + +- **`languageServerHaskell.hieExecutablePath`**: `string` + + Default: `""` + + Set the path to your hie executable, if it's not already on your $PATH. Works with ~, ${HOME} and ${workspaceFolder}. + +- **`languageServerHaskell.hlintOn`**: `boolean` + + Default: `true` + + Get suggestions from hlint + +- **`languageServerHaskell.liquidOn`**: `boolean` + + Get diagnostics from liquid haskell + +- **`languageServerHaskell.logFile`**: `string` + + Default: `""` + + If set, redirects the logs to a file. + +- **`languageServerHaskell.maxNumberOfProblems`**: `number` + + Default: `100` + + Controls the maximum number of problems produced by the server. + +- **`languageServerHaskell.showTypeForSelection.command.location`**: `enum { "dropdown", "channel" }` + + Default: `"dropdown"` + + Determines where the type information for selected text will be shown when the `showType` command is triggered (distinct from automatically showing this information when hover is triggered). + dropdown: in a dropdown + channel: will be revealed in an output channel + +- **`languageServerHaskell.showTypeForSelection.onHover`**: `boolean` + + Default: `true` + + If true, when an expression is selected, the hover tooltip will attempt to display the type of the entire expression - rather than just the term under the cursor. + +- **`languageServerHaskell.trace.server`**: `enum { "off", "messages", "verbose" }` + + Default: `"off"` + + Traces the communication between VSCode and the languageServerHaskell service. + +- **`languageServerHaskell.useCustomHieWrapper`**: `boolean` + + Use your own custom wrapper for hie (remember to specify the path!). This will take precedence over useHieWrapper and hieExecutablePath. + +- **`languageServerHaskell.useCustomHieWrapperPath`**: `string` + + Default: `""` + + Specify the full path to your own custom hie wrapper (e.g. ${HOME}/.hie-wrapper.sh). Works with ~, ${HOME} and ${workspaceFolder}. + +</details> ```lua nvim_lsp.hie.setup({config}) @@ -403,7 +496,7 @@ https://github.com/palantir/python-language-server `python-language-server`, a language server for Python. This server accepts configuration via the `settings` key. -<details><summary>Python Language Server Configuration</summary> +<details><summary>Available settings:</summary> - **`pyls.configurationSources`**: `array` @@ -698,7 +791,7 @@ cmd = {"rustup", "run", "nightly", "rls"} ``` This server accepts configuration via the `settings` key. -<details><summary>Rust configuration</summary> +<details><summary>Available settings:</summary> - **`rust-client.channel`**: `enum { "stable", "beta", "nightly" }` @@ -891,9 +984,9 @@ This server accepts configuration via the `settings` key. Enable unstable features. -- **`rust.wait_to_build`**: `number|null` +- **`rust.wait_to_build`**: `number` - Default: `vim.NIL` + Default: `1500` Time in milliseconds between receiving a change notification and starting build. @@ -924,7 +1017,7 @@ gem install solargraph ``` This server accepts configuration via the `settings` key. -<details><summary>Solargraph settings for Ruby</summary> +<details><summary>Available settings:</summary> - **`solargraph.autoformat`**: `enum { true, false }` @@ -1034,6 +1127,100 @@ nvim_lsp#setup("solargraph", {config}) settings = {} ``` +## sumneko_lua + +https://github.com/sumneko/lua-language-server + +Lua language server. **By default, this doesn't have a `cmd` set.** This is +because it doesn't provide a global binary. We provide an installer for Linux +using `:LspInstall`. If you wish to install it yourself, [here is a +guide](https://github.com/sumneko/lua-language-server/wiki/Build-and-Run). + +Can be installed in neovim with `:LspInstall sumneko_lua` +This server accepts configuration via the `settings` key. +<details><summary>Available settings:</summary> + +- **`Lua.completion.callSnippet`**: `enum { "Disable", "Both", "Replace" }` + + Default: `"Disable"` + +- **`Lua.completion.enable`**: `boolean` + + Default: `true` + +- **`Lua.completion.keywordSnippet`**: `enum { "Disable", "Both", "Replace" }` + + Default: `"Replace"` + +- **`Lua.diagnostics.disable`**: `array` + + Array items: `{type = "string"}` + +- **`Lua.diagnostics.enable`**: `boolean` + + Default: `true` + +- **`Lua.diagnostics.globals`**: `array` + + Array items: `{type = "string"}` + +- **`Lua.diagnostics.severity`**: `object` + + + +- **`Lua.runtime.path`**: `array` + + Default: `{ "?.lua", "?/init.lua", "?/?.lua" }` + + Array items: `{type = "string"}` + +- **`Lua.runtime.version`**: `enum { "Lua 5.1", "Lua 5.2", "Lua 5.3", "Lua 5.4", "LuaJIT" }` + + Default: `"Lua 5.3"` + +- **`Lua.workspace.ignoreDir`**: `array` + + Default: `{ ".vscode" }` + + Array items: `{type = "string"}` + +- **`Lua.workspace.ignoreSubmodules`**: `boolean` + + Default: `true` + +- **`Lua.workspace.library`**: `object` + + + +- **`Lua.workspace.maxPreload`**: `integer` + + Default: `300` + +- **`Lua.workspace.preloadFileSize`**: `integer` + + Default: `100` + +- **`Lua.workspace.useGitIgnore`**: `boolean` + + Default: `true` + +- **`Lua.zzzzzz.cat`**: `boolean` + + + +</details> + +```lua +nvim_lsp.sumneko_lua.setup({config}) +nvim_lsp#setup("sumneko_lua", {config}) + + Default Values: + filetypes = { "lua" } + log_level = 2 + root_dir = root_pattern(".git") or os_homedir + settings = {} +``` + ## texlab https://texlab.netlify.com/ diff --git a/lua/nvim_lsp.lua b/lua/nvim_lsp.lua index 2e00f079..1d5c35e0 100644 --- a/lua/nvim_lsp.lua +++ b/lua/nvim_lsp.lua @@ -2,8 +2,8 @@ local skeleton = require 'nvim_lsp/skeleton' require 'nvim_lsp/bashls' require 'nvim_lsp/ccls' -require 'nvim_lsp/cssls' require 'nvim_lsp/clangd' +require 'nvim_lsp/cssls' require 'nvim_lsp/elmls' require 'nvim_lsp/flow' require 'nvim_lsp/gopls' @@ -11,6 +11,7 @@ require 'nvim_lsp/hie' require 'nvim_lsp/pyls' require 'nvim_lsp/rls' require 'nvim_lsp/solargraph' +require 'nvim_lsp/sumneko_lua' require 'nvim_lsp/texlab' require 'nvim_lsp/tsserver' diff --git a/lua/nvim_lsp/hie.lua b/lua/nvim_lsp/hie.lua index dac2f7c8..cb18a164 100644 --- a/lua/nvim_lsp/hie.lua +++ b/lua/nvim_lsp/hie.lua @@ -12,6 +12,7 @@ skeleton.hie = { }; docs = { + vscode = "alanz.vscode-hie-server"; description = [[ https://github.com/haskell/haskell-ide-engine diff --git a/lua/nvim_lsp/rls.lua b/lua/nvim_lsp/rls.lua index efecd34d..28067999 100644 --- a/lua/nvim_lsp/rls.lua +++ b/lua/nvim_lsp/rls.lua @@ -11,6 +11,7 @@ skeleton.rls = { settings = {}; }; docs = { + vscode = "rust-lang.rust"; package_json = "https://github.com/rust-lang/rls-vscode/raw/master/package.json"; description = [[ https://github.com/rust-lang/rls diff --git a/lua/nvim_lsp/sumneko_lua.lua b/lua/nvim_lsp/sumneko_lua.lua new file mode 100644 index 00000000..365253cb --- /dev/null +++ b/lua/nvim_lsp/sumneko_lua.lua @@ -0,0 +1,105 @@ +local skeleton = require 'nvim_lsp/skeleton' +local util = require 'nvim_lsp/util' +local vim = vim + +local name = "sumneko_lua" + +local function make_installer() + local P = util.path.join + local install_dir = P{util.base_install_dir, name} + local git_dir = P{install_dir, "lua-language-server"} + + local bin = P{git_dir, "bin", "Linux", "lua-language-server"} + local main_file = P{git_dir, "main.lua"} + local cmd = {bin, '-E', main_file} + + local X = {} + function X.install() + local install_info = X.info() + if install_info.is_installed then + print(name, "is already installed") + return + end + if not (util.has_bins("ninja") or util.has_bins("curl")) then + error('Need either "ninja" or "curl" (to download ninja) to install this.') + return + end + if not util.has_bins("sh", "chmod", "unzip") then + error('Need the binaries "sh", "chmod", "unzip" to install this') + return + end + local script = [=[ +set -e +# Install ninja if not available. +which ninja >/dev/null || { + test -x ninja || { + curl -LO https://github.com/ninja-build/ninja/releases/download/v1.9.0/ninja-linux.zip + unzip ninja-linux.zip + chmod +x ninja + } + export PATH=$PWD:$PATH +} + +# clone project +git clone https://github.com/sumneko/lua-language-server +cd lua-language-server +git submodule update --init --recursive + +# build +cd 3rd/luamake +ninja -f ninja/linux.ninja +cd ../.. +./3rd/luamake/luamake rebuild + ]=] + vim.fn.mkdir(install_info.install_dir, "p") + util.sh(script, install_info.install_dir) + end + function X.info() + return { + is_installed = util.has_bins(bin); + install_dir = install_dir; + cmd = cmd; + } + end + function X.configure(config) + local install_info = X.info() + if install_info.is_installed then + config.cmd = cmd + end + end + return X +end + +local installer = make_installer() + +skeleton[name] = { + default_config = { + filetypes = {'lua'}; + root_dir = function(fname) + return util.find_git_ancestor(fname) or vim.loop.os_homedir() + end; + log_level = vim.lsp.protocol.MessageType.Warning; + settings = {}; + }; + on_new_config = function(config) + installer.configure(config) + end; + docs = { + vscode = "sumneko.lua"; + description = [[ +https://github.com/sumneko/lua-language-server + +Lua language server. **By default, this doesn't have a `cmd` set.** This is +because it doesn't provide a global binary. We provide an installer for Linux +using `:LspInstall`. If you wish to install it yourself, [here is a +guide](https://github.com/sumneko/lua-language-server/wiki/Build-and-Run). +]]; + default_config = { + root_dir = [[root_pattern(".git") or os_homedir]]; + }; + }; +} + +skeleton[name].install = installer.install +skeleton[name].install_info = installer.info +-- vim:et ts=2 diff --git a/lua/nvim_lsp/util.lua b/lua/nvim_lsp/util.lua index d015c932..0f96dd59 100644 --- a/lua/nvim_lsp/util.lua +++ b/lua/nvim_lsp/util.lua @@ -1,3 +1,4 @@ +local vim = vim local validate = vim.validate local api = vim.api local lsp = vim.lsp @@ -361,6 +362,66 @@ function M.npm_installer(config) } end +function M.sh(script, cwd) + api.nvim_command("10new") + assert(cwd and M.path.is_dir(cwd), "sh: Invalid directory") + local winnr = api.nvim_get_current_win() + local bufnr = api.nvim_get_current_buf() + local stdin = uv.new_pipe(false) + local stdout = uv.new_pipe(false) + local stderr = uv.new_pipe(false) + local handle, pid + handle, pid = uv.spawn("sh", { + stdio = {stdin, stdout, stderr}; + cwd = cwd; + }, function() + stdin:close() + stdout:close() + stderr:close() + handle:close() + vim.schedule(function() + api.nvim_command("silent bwipeout! "..bufnr) + end) + end) + + -- If the buffer closes, then kill our process. + api.nvim_buf_attach(bufnr, false, { + on_detach = function() + if not handle:is_closing() then + handle:kill(15) + end + end; + }) + + local output_buf = '' + local function update_chunk(err, chunk) + if chunk then + output_buf = output_buf..chunk + local lines = vim.split(output_buf, '\n', true) + api.nvim_buf_set_option(bufnr, "modifiable", true) + api.nvim_buf_set_lines(bufnr, 0, -1, false, lines) + api.nvim_buf_set_option(bufnr, "modifiable", false) + api.nvim_buf_set_option(bufnr, "modified", false) + if api.nvim_win_is_valid(winnr) then + api.nvim_win_set_cursor(winnr, {#lines, 0}) + end + end + end + update_chunk = vim.schedule_wrap(update_chunk) + stdout:read_start(update_chunk) + stderr:read_start(update_chunk) + stdin:write(script) + stdin:write("\n") + stdin:shutdown() +end + +function M.format_vspackage_url(extension_name) + local org, package = unpack(vim.split(extension_name, ".", true)) + assert(org and package) + return string.format("https://marketplace.visualstudio.com/_apis/public/gallery/publishers/%s/vsextensions/%s/latest/vspackage", org, package) +end + + function M.utf8_config(config) config.capabilities = config.capabilities or lsp.protocol.make_client_capabilities() config.capabilities.offsetEncoding = {"utf-8", "utf-16"} diff --git a/scripts/docgen.lua b/scripts/docgen.lua index 4239ff47..cf474075 100644 --- a/scripts/docgen.lua +++ b/scripts/docgen.lua @@ -115,10 +115,7 @@ local function make_lsp_sections() }) if docs then - local tempdir = os.getenv("PACKAGE_JSON_CACHEDIR") or uv.fs_mkdtemp("/tmp/nvim-lsp.XXXXXX") - if not util.path.is_dir(tempdir) then - fn.mkdir(tempdir) - end + local tempdir = os.getenv("DOCGEN_TEMPDIR") or uv.fs_mkdtemp("/tmp/nvim-lsp.XXXXXX") local preamble_parts = make_parts { function() if docs.description and #docs.description > 0 then @@ -131,19 +128,39 @@ local function make_lsp_sections() end end; function() + local package_json_name = util.path.join(tempdir, template_name..'.package.json'); + if docs.vscode then + docs.vspackage = util.format_vspackage_url(docs.vscode) + end + if docs.vspackage then + local script = [[ + curl -L -o {{vspackage_name}} {{vspackage_url}} + gzip -d {{vspackage_name}} + unzip -j {{vspackage_zip}} extension/package.json + mv package.json {{package_json_name}} + ]] + os.execute(template(script, { + package_json_name = package_json_name; + vspackage_name = util.path.join(tempdir, template_name..'.vspackage.zip.gz'); + vspackage_zip = util.path.join(tempdir, template_name..'.vspackage.zip'); + vspackage_url = docs.vspackage; + })) + if not util.path.is_file(package_json_name) then + print(string.format("Failed to download vspackage for %q at %q", template_name, docs.vspackage)) + return + end + docs.package_json = true + end if docs.package_json then - local filename = util.path.join(tempdir, template_name..'.package.json') - if util.path.is_file(filename) then - os.execute(string.format("curl -L -o %q -z %q %q", filename, filename, docs.package_json)) - else - os.execute(string.format("curl -L -o %q %q", filename, docs.package_json)) + if not util.path.is_file(package_json_name) then + os.execute(string.format("curl -L -o %q %q", package_json_name, docs.package_json)) end - if not util.path.is_file(filename) then - print("Failed to download package.json for %q at %q", template_name, docs.package_json) + if not util.path.is_file(package_json_name) then + print(string.format("Failed to download package.json for %q at %q", template_name, docs.package_json)) os.exit(1) return end - local data = fn.json_decode(readfile(filename)) + local data = fn.json_decode(readfile(package_json_name)) -- The entire autogenerated section. return make_section(0, '\n', { -- The default settings section @@ -153,7 +170,7 @@ local function make_lsp_sections() -- The outer section. return make_section(0, '\n', { 'This server accepts configuration via the `settings` key.'; - '<details><summary>'..(default_settings.title or "Available settings:")..'</summary>'; + '<details><summary>Available settings:</summary>'; ''; -- The list of properties. make_section(0, '\n\n', sorted_map_table(default_settings.properties, function(k, v) @@ -189,6 +206,9 @@ local function make_lsp_sections() end end } + if not os.getenv("DOCGEN_TEMPDIR") then + os.execute("rm -rf "..tempdir) + end -- Insert a newline after the preamble if it exists. if #preamble_parts > 0 then table.insert(preamble_parts, '') end params.preamble = table.concat(preamble_parts, '\n') |
