diff options
| author | David Lukes <dafydd.lukes@gmail.com> | 2020-04-28 05:48:35 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-04-27 20:48:35 -0700 |
| commit | 9a8e3543eed294099002413d1b9b99227719bbbf (patch) | |
| tree | 3b5f4c56aaf79ab0dc21289a75ca6f29ebd1f53f /lua | |
| parent | [docgen] Update README.md (diff) | |
| download | nvim-lspconfig-9a8e3543eed294099002413d1b9b99227719bbbf.tar nvim-lspconfig-9a8e3543eed294099002413d1b9b99227719bbbf.tar.gz nvim-lspconfig-9a8e3543eed294099002413d1b9b99227719bbbf.tar.bz2 nvim-lspconfig-9a8e3543eed294099002413d1b9b99227719bbbf.tar.lz nvim-lspconfig-9a8e3543eed294099002413d1b9b99227719bbbf.tar.xz nvim-lspconfig-9a8e3543eed294099002413d1b9b99227719bbbf.tar.zst nvim-lspconfig-9a8e3543eed294099002413d1b9b99227719bbbf.zip | |
Use builtin terminal for util.sh output (#208)
close https://github.com/neovim/nvim-lsp/issues/207
close https://github.com/neovim/nvim-lsp/pull/201
Using `termopen()`, `util.sh` gets full terminal functionality for free:
- progress bars leveraging `\r` and other more fancy output types (e.g.
curses UIs)
- interactive prompts
- canceling with `Ctrl-C`
- etc.
The drawback is that currently (see https://github.com/neovim/neovim/issues/7607),
the `on_exit` callback for `termopen()`/`jobstart()` *has* to be a VimL
function, which means a global VimL function has to be created
on-the-fly with a name which hopefully won't clobber anything that's
already defined.
Like #201, this commit makes sure that the output buffer remains open if
the script exits with anything else than 0.
Diffstat (limited to 'lua')
| -rw-r--r-- | lua/nvim_lsp/util.lua | 67 |
1 files changed, 19 insertions, 48 deletions
diff --git a/lua/nvim_lsp/util.lua b/lua/nvim_lsp/util.lua index 11d3473d..c40c801d 100644 --- a/lua/nvim_lsp/util.lua +++ b/lua/nvim_lsp/util.lua @@ -409,58 +409,29 @@ 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() + -- switching to insert mode makes the buffer scroll as new output is added + -- and makes it easy and intuitive to cancel the operation with Ctrl-C + api.nvim_command("10new | startinsert") 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) - -- luacheck: no unused - 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; - }) + -- TODO: The on_exit callback needs to be a VimL function, so here's a quick + -- and dirty way of creating one with a hopefully unique name, so that + -- different runs of M.sh don't stomp on each other's callbacks (or some + -- other VimL functions for that matter). If it ever becomes possible to pass + -- Lua callbacks to termopen/jobstart, switch to a local Lua function closing + -- over bufnr as a much cleaner alternative. + -- See https://github.com/neovim/neovim/issues/7607 + local viml_on_exit = "Nvim_lspUtilShOn_exit"..bufnr + api.nvim_command([[ + function! ]]..viml_on_exit..[[(job_id, code, event_type) + if !a:code + silent bwipeout! ]]..bufnr..[[| + endif + endfunction + ]]) - 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() + fn.termopen({"sh", "-c", script}, {cwd = cwd, on_exit = viml_on_exit}) end function M.format_vspackage_url(extension_name) |
