From: Yegappan Lakshmanan Date: Fri, 17 Mar 2023 04:10:51 +0000 (-0700) Subject: Add support for using the 'formatexpr' option to format code using a language server X-Git-Url: http://www.git.stargrave.org/?a=commitdiff_plain;h=f88153a0a034da14092fbd6812f391a2553fbf63;p=vim-lsp.git Add support for using the 'formatexpr' option to format code using a language server --- diff --git a/autoload/lsp/completion.vim b/autoload/lsp/completion.vim index 8ab8d6b..07c6480 100644 --- a/autoload/lsp/completion.vim +++ b/autoload/lsp/completion.vim @@ -88,7 +88,7 @@ export def CompletionReply(lspserver: dict, cItems: any) # Get the keyword prefix before the current cursor column. var col = charcol('.') var starttext = getline('.')[ : col - 1] - var prefix = tolower(matchstr(starttext, '\k*$')) + var prefix = starttext->tolower()->matchstr('\k*$') var completeItems: list> = [] for item in items @@ -107,7 +107,7 @@ export def CompletionReply(lspserver: dict, cItems: any) else # plain text completion. If the completion item text doesn't start with # the current (case ignored) keyword prefix, skip it. - if prefix != '' && stridx(tolower(d.word), prefix) != 0 + if prefix != '' && d.word->tolower()->stridx(prefix) != 0 continue endif endif diff --git a/autoload/lsp/lsp.vim b/autoload/lsp/lsp.vim index 4cc7d32..286e97c 100644 --- a/autoload/lsp/lsp.vim +++ b/autoload/lsp/lsp.vim @@ -870,6 +870,17 @@ export def TagFunc(pat: string, flags: string, info: dict): any return lspserver.tagFunc(pat, flags, info) enddef +# Function to use with the 'formatexpr' option. +export def FormatExpr(): number + var lspserver: dict = buf.CurbufGetServerChecked() + if lspserver->empty() + return 1 + endif + + lspserver.textDocFormat(@%, true, v:lnum, v:lnum + v:count - 1) + return 0 +enddef + export def RegisterCmdHandler(cmd: string, Handler: func) codeaction.RegisterCmdHandler(cmd, Handler) enddef diff --git a/autoload/lsp/lspserver.vim b/autoload/lsp/lspserver.vim index 4eac734..ca8b66c 100644 --- a/autoload/lsp/lspserver.vim +++ b/autoload/lsp/lspserver.vim @@ -72,7 +72,7 @@ def StartServer(lspserver: dict): number lspserver.signaturePopup = -1 lspserver.workspaceFolders = [getcwd()] - var job = job_start(cmd, opts) + var job = cmd->job_start(opts) if job->job_status() == 'fail' util.ErrMsg($'Error: Failed to start LSP server {lspserver.path}') return 1 @@ -579,7 +579,7 @@ enddef # Send a request message to LSP server def SendMessage(lspserver: dict, content: dict): void var ch = lspserver.job->job_getchannel() - if ch_status(ch) != 'open' + if ch->ch_status() != 'open' # LSP server has exited return endif @@ -605,7 +605,7 @@ def Rpc(lspserver: dict, method: string, params: any): dict req.params->extend(params) var ch = lspserver.job->job_getchannel() - if ch_status(ch) != 'open' + if ch->ch_status() != 'open' # LSP server has exited return {} endif @@ -672,7 +672,7 @@ def AsyncRpc(lspserver: dict, method: string, params: any, Cbfunc: func): n req.params->extend(params) var ch = lspserver.job->job_getchannel() - if ch_status(ch) != 'open' + if ch->ch_status() != 'open' # LSP server has exited return -1 endif @@ -1162,7 +1162,7 @@ def TextDocFormat(lspserver: dict, fname: string, rangeFormat: bool, if rangeFormat var r: dict> = { start: {line: start_lnum - 1, character: 0}, - end: {line: end_lnum - 1, character: 99999}} + end: {line: end_lnum - 1, character: charcol([end_lnum, '$']) - 1}} param.range = r endif diff --git a/doc/lsp.txt b/doc/lsp.txt index fb4718a..b74f087 100644 --- a/doc/lsp.txt +++ b/doc/lsp.txt @@ -2,7 +2,7 @@ Author: Yegappan Lakshmanan (yegappan AT yahoo DOT com) For Vim version 9.0 and above -Last change: Nov 26, 2022 +Last change: March 16, 2023 ============================================================================== *lsp-license* @@ -812,7 +812,18 @@ Note that most of the language servers return only one symbol location even if the symbol is defined in multiple places in the code. ============================================================================== -9. Call Hierarchy *lsp-call-hierarchy* +9. Code Formatting + +The |:LspFormat| command can be used to format either the entire file or a +selected range of lines using the language server. The *shiftwidth* and +*expandtab* values set for the current buffer are used when format is applied. + +To format code using the 'gq' command, you can set the 'formatexpr' option: +> + setlocal formatexpr=lsp#lsp#FormatExpr() +< +============================================================================== +10. Call Hierarchy *lsp-call-hierarchy* The |:LspIncomingCalls| and the |:LspOutoingCalls| commands can be used to display the call hierarchy of a symbol. For example, the functions calling a @@ -847,7 +858,7 @@ In the call hierarchy tree window, the following commands are supported: refreshed to display the outgoing calls. ============================================================================== -10. Autocommands *lsp-autocmds* +11. Autocommands *lsp-autocmds* *LspAttached* LspAttached A |User| autocommand fired when the LSP client @@ -861,7 +872,7 @@ LspDiagsUpdated A |User| autocommand invoked when new has processed the diagnostics. ============================================================================== -11. Highlight Groups *lsp-highlight-groups* +12. Highlight Groups *lsp-highlight-groups* The following highlight groups are used by the LSP plugin. You can define these highlight groups in your .vimrc file before sourcing this plugin to @@ -872,7 +883,7 @@ LspInlayHintsParam Used to highlight inlay hints of kind LspInlayHintsType Used to highlight inlay hints of kind "type". ============================================================================== -12. Debugging *lsp-debug* +13. Debugging *lsp-debug* To debug this plugin, you can log the language server protocol messages sent and received by the plugin from the language server. The following command @@ -904,7 +915,7 @@ use the :LspServerTrace command to set the trace value: > :LspServerTrace { off | messages | verbose } < ============================================================================== -12. Custom Command Handlers *lsp-custom-commands* +14. Custom Command Handlers *lsp-custom-commands* When applying a code action, the language server may issue a non-standard command. For example, the Java language server uses non-standard commands diff --git a/test/unit_tests.vim b/test/unit_tests.vim index 0f89881..0c2e868 100644 --- a/test/unit_tests.vim +++ b/test/unit_tests.vim @@ -188,6 +188,27 @@ def Test_LspFormat() :%bw! enddef +# Test for formatting a file using 'formatexpr' +def Test_LspFormatExpr() + :silent! edit Xtest.c + sleep 200m + setlocal formatexpr=lsp#lsp#FormatExpr() + setline(1, [' int i;', ' int j;']) + :redraw! + normal! ggVGgq + assert_equal(['int i;', 'int j;'], getline(1, '$')) + + # empty line/file + deletebufline('', 1, '$') + setline(1, ['']) + redraw! + normal! ggVGgq + assert_equal([''], getline(1, '$')) + + setlocal formatexpr& + :%bw! +enddef + # Test for :LspShowReferences - showing all the references to a symbol in a # file using LSP def Test_LspShowReferences()