]> Sergey Matveev's repositories - vim-lsp.git/commitdiff
Add support for using the 'formatexpr' option to format code using a language server
authorYegappan Lakshmanan <yegappan@yahoo.com>
Fri, 17 Mar 2023 04:10:51 +0000 (21:10 -0700)
committerYegappan Lakshmanan <yegappan@yahoo.com>
Fri, 17 Mar 2023 04:10:51 +0000 (21:10 -0700)
autoload/lsp/completion.vim
autoload/lsp/lsp.vim
autoload/lsp/lspserver.vim
doc/lsp.txt
test/unit_tests.vim

index 8ab8d6b8df66db8985ddc44363894ce90114721e..07c648033d8a22bcd785d970d52b0bf426b8aa7a 100644 (file)
@@ -88,7 +88,7 @@ export def CompletionReply(lspserver: dict<any>, 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<dict<any>> = []
   for item in items
@@ -107,7 +107,7 @@ export def CompletionReply(lspserver: dict<any>, 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
index 4cc7d32e65312ddfa93d03a903354e2aec02cb5a..286e97c801fb3ab711eecf7de2f9d2b848cdda06 100644 (file)
@@ -870,6 +870,17 @@ export def TagFunc(pat: string, flags: string, info: dict<any>): any
   return lspserver.tagFunc(pat, flags, info)
 enddef
 
+# Function to use with the 'formatexpr' option.
+export def FormatExpr(): number
+  var lspserver: dict<any> = 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
index 4eac7343004b68eb5d6816a2609413dbd17ac5d0..ca8b66c4aa4b305bd978371ec02e2f2330c15802 100644 (file)
@@ -72,7 +72,7 @@ def StartServer(lspserver: dict<any>): 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<any>, content: dict<any>): 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<any>, method: string, params: any): dict<any>
   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<any>, 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<any>, fname: string, rangeFormat: bool,
   if rangeFormat
     var r: dict<dict<number>> = {
        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
 
index fb4718aa3150248b1d11bca06a42efb0d055d03a..b74f0873249b4fed7d395c0400f1621aaa217f45 100644 (file)
@@ -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
index 0f898815f7b2bfebc0556fdc6ddfbbf499512eba..0c2e8680de262734c0df2875190fe90f95f89c96 100644 (file)
@@ -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()