aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichiel van den Heuvel <michielvdnheuvel@gmail.com>2023-06-16 18:23:58 +0200
committerMichiel van den Heuvel <michielvdnheuvel@gmail.com>2023-06-29 15:13:26 +0200
commite83950a7149f364b653395cdd4d9446875a7f469 (patch)
tree4358faec50ae6e77327dc56a653d03b68055b4dc
parent646f957bdb27f4157ad0d9815f8cfa1533db8f5f (diff)
downloadvis-lspc-e83950a7149f364b653395cdd4d9446875a7f469.tar.gz
vis-lspc-e83950a7149f364b653395cdd4d9446875a7f469.zip
Add textDocument/formatting implementation
This is tested with the Rust language server and the Lua one. Moving the cursor to the correct position afterwards works with Rust, but not with Lua. Being smarter about the ranges is probably necessary for Lua and might make other ones more robust.
-rw-r--r--README.md2
-rw-r--r--init.lua53
2 files changed, 55 insertions, 0 deletions
diff --git a/README.md b/README.md
index 2b98a91..b9d6cae 100644
--- a/README.md
+++ b/README.md
@@ -13,6 +13,7 @@ vis-lspc currently supports:
* `textDocument/implementation`
* `textDocument/hover`
* `textDocument/rename`
+* `textDocument/formatting`
* `[Diagnostics]`
## Whats not working
@@ -109,6 +110,7 @@ vis-lspc is in a early state, but if you are brave there are some default key bi
# workspace edits
lspc-rename <new name> - rename the identifier under the cursor to <new name>
+ lspc-format - format the file in the current window
# development support
lspc-hover - hover over the current line
diff --git a/init.lua b/init.lua
index 9f3e7d4..48f7b97 100644
--- a/init.lua
+++ b/init.lua
@@ -365,6 +365,27 @@ local function vis_apply_textEdit(win, file, textEdit)
win:draw()
end
+-- apply a list of textEdits received from the language server
+local function vis_apply_textEdits(win, file, textEdits)
+ assert(win.file == file)
+
+ local edits = {}
+ for _, textEdit in ipairs(textEdits) do
+ local range = lsp_range_to_vis_range(win, textEdit.range)
+ table.insert(edits, {
+ mark = file:mark_set(range.start),
+ len = range.finish - range.start,
+ newText = textEdit.newText,
+ })
+ end
+ for _, edit in ipairs(edits) do
+ local pos = file:mark_get(edit.mark)
+ file:delete(pos, edit.len)
+ file:insert(pos, edit.newText)
+ end
+ win:draw()
+end
+
-- concatenate all numeric values in choices and pass it on stdin to lspc.menu_cmd
local function lspc_select(choices)
local menu_input = ''
@@ -782,6 +803,10 @@ local function lspc_handle_rename_method_response(win, result)
vis_apply_workspaceEdit(win, win.file, result)
end
+local function lspc_handle_formatting_method_response(win, result)
+ vis_apply_textEdits(win, win.file, result)
+end
+
local function lspc_handle_initialize_response(ls, result)
ls.initialized = true
ls.capabilities = result.capabilities
@@ -841,6 +866,9 @@ local function ls_handle_method_response(ls, method_response, req)
elseif method == 'textDocument/rename' then
lspc_handle_rename_method_response(win, result)
+ elseif method == 'textDocument/formatting' then
+ lspc_handle_formatting_method_response(win, result)
+
elseif method == 'shutdown' then
ls_send_notification(ls, 'exit')
ls.fd:close()
@@ -1298,6 +1326,31 @@ vis:command_register('lspc-rename', function(argv, _, win)
ls_call_text_document_method(ls, 'rename', params, win)
end)
+vis:command_register('lspc-format', function(_, _, win)
+ local ls, err = lspc_get_usable_ls(win.syntax)
+ if err then
+ lspc_err(err)
+ return
+ end
+
+ -- check if the language server has a provider for this method
+ if not ls.capabilities['documentFormattingProvider'] then
+ lspc_err('language server ' .. ls.name .. ' does not provide formatting')
+ return
+ end
+
+ if not ls.open_files[win.file.path] then
+ lspc_open(ls, win, win.file)
+ end
+
+ local params = {
+ textDocument = {uri = path_to_uri(win.file.path)},
+ options = {tabSize = 2, insertSpaces = true},
+ }
+
+ ls_call_text_document_method(ls, 'formatting', params, win)
+end)
+
vis:command_register('lspc-completion', function(_, _, win)
local ls, err = lspc_get_usable_ls(win.syntax)
if err then