]> Sergey Matveev's repositories - vim-lsp.git/commitdiff
Update diags location list when the diags for the buffer changes. Update comments
authorYegappan Lakshmanan <yegappan@yahoo.com>
Sat, 17 Jun 2023 21:42:39 +0000 (14:42 -0700)
committerYegappan Lakshmanan <yegappan@yahoo.com>
Sat, 17 Jun 2023 21:42:39 +0000 (14:42 -0700)
13 files changed:
autoload/lsp/buffer.vim
autoload/lsp/callhierarchy.vim
autoload/lsp/codeaction.vim
autoload/lsp/completion.vim
autoload/lsp/diag.vim
autoload/lsp/handlers.vim
autoload/lsp/lsp.vim
autoload/lsp/lspserver.vim
autoload/lsp/symbol.vim
autoload/lsp/typehierarchy.vim
autoload/lsp/util.vim
doc/lsp.txt
test/clangd_tests.vim

index 62d591562b08bfa82188b4699bc7515f9b12ffc4..2d39a19cd4895acb2d1d6ffe27126a9c6d7e31fe 100644 (file)
@@ -84,7 +84,7 @@ export def BufLspServerGet(bnr: number, feature: string = null_string): dict<any
     return {}
   endif
 
-  # LSP server is configured to be a provider for 'feature'
+  # LSP server is configured to be a provider for "feature"
   for lspserver in possibleLSPs
     if lspserver.features->has_key(feature) && lspserver.features[feature]
       return lspserver
@@ -102,7 +102,7 @@ export def BufLspServerGet(bnr: number, feature: string = null_string): dict<any
   return {}
 enddef
 
-# Returns the LSP server for the buffer 'bnr' and with ID 'id'. Returns an empty
+# Returns the LSP server for the buffer "bnr" and with ID "id". Returns an empty
 # dict if the server is not found.
 export def BufLspServerGetById(bnr: number, id: number): dict<any>
   if !bufnrToServers->has_key(bnr)
@@ -118,7 +118,7 @@ export def BufLspServerGetById(bnr: number, id: number): dict<any>
   return {}
 enddef
 
-# Returns the LSP servers for the buffer 'bnr'. Returns an empty list if the
+# Returns the LSP servers for the buffer "bnr". Returns an empty list if the
 # servers are not found.
 export def BufLspServersGet(bnr: number): list<dict<any>>
   if !bufnrToServers->has_key(bnr)
@@ -128,7 +128,7 @@ export def BufLspServersGet(bnr: number): list<dict<any>>
   return bufnrToServers[bnr]
 enddef
 
-# Returns the LSP server for the current buffer with the optionally 'feature'.
+# Returns the LSP server for the current buffer with the optionally "feature".
 # Returns an empty dict if the server is not found.
 export def CurbufGetServer(feature: string = null_string): dict<any>
   return BufLspServerGet(bufnr(), feature)
@@ -146,7 +146,7 @@ export def BufHasLspServer(bnr: number): bool
   return !lspserver->empty()
 enddef
 
-# Returns the LSP server for the current buffer with the optinally 'feature' if
+# Returns the LSP server for the current buffer with the optinally "feature" if
 # it is running and is ready.
 # Returns an empty dict if the server is not found or is not ready.
 export def CurbufGetServerChecked(feature: string = null_string): dict<any>
index e91d08ba71f18b71fc5e85dcf4db53983cd0e99f..aa2ed404de020ea604bcfaa50bc1f9872d92d753 100644 (file)
@@ -12,7 +12,7 @@ def CallHierarchyItemJump()
   util.JumpToLspLocation(item, '')
 enddef
 
-# Refresh the call hierarchy tree for the symbol at index 'idx'.
+# Refresh the call hierarchy tree for the symbol at index "idx".
 def CallHierarchyTreeItemRefresh(idx: number)
   var treeItem: dict<any> = w:LspCallHierItemMap[idx]
 
@@ -22,7 +22,7 @@ def CallHierarchyTreeItemRefresh(idx: number)
   endif
 
   if !treeItem->has_key('children')
-    # First time retrieving the children for the item at index 'idx'
+    # First time retrieving the children for the item at index "idx"
     var lspserver = buf.BufLspServerGet(w:LspBufnr)
     if lspserver->empty() || !lspserver.running
       return
index 3f103e7641ff36092c49beed5f95fec477e91699..9aa9c9a01b388ba2124067bc26566249e4b92f15 100644 (file)
@@ -30,8 +30,8 @@ export def HandleCodeAction(lspserver: dict<any>, selAction: dict<any>)
   # textDocument/codeAction can return either Command[] or CodeAction[].
   # If it is a CodeAction, it can have either an edit, a command or both.
   # Edits should be executed first.
-  # Both Command and CodeAction interfaces has 'command' member
-  # so we should check 'command' type - for Command it will be 'string'
+  # Both Command and CodeAction interfaces has "command" member
+  # so we should check "command" type - for Command it will be "string"
   if selAction->has_key('edit')
      || (selAction->has_key('command') && selAction.command->type() == v:t_dict)
     # selAction is a CodeAction instance, apply edit and command
index e7fd32499b2d96c09c60092c7a86e7ef1a02f272..711f198b1b0fcd70e4d5b6877c49884b7308985e 100644 (file)
@@ -39,13 +39,13 @@ var defaultKinds: dict<string> = {
   'Buffer':         'B',
 }
 
-# Returns true if omni-completion is enabled for filetype 'ftype'.
+# Returns true if omni-completion is enabled for filetype "ftype".
 # Otherwise, returns false.
 def LspOmniComplEnabled(ftype: string): bool
   return ftypeOmniCtrlMap->get(ftype, false)
 enddef
 
-# Enables or disables omni-completion for filetype 'fype'
+# Enables or disables omni-completion for filetype "fype"
 export def OmniComplSet(ftype: string, enabled: bool)
   ftypeOmniCtrlMap->extend({[ftype]: enabled})
 enddef
@@ -96,7 +96,7 @@ def LspCompleteItemKindChar(kind: number): string
   return kindValue
 enddef
 
-# Remove all the snippet placeholders from 'str' and return the value.
+# Remove all the snippet placeholders from "str" and return the value.
 # Based on a similar function in the vim-lsp plugin.
 def MakeValidWord(str_arg: string): string
   var str = str_arg->substitute('\$[0-9]\+\|\${\%(\\.\|[^}]\)\+}', '', 'g')
@@ -596,8 +596,8 @@ def LspResolve()
   endif
 enddef
 
-# If the completion popup documentation window displays 'markdown' content,
-# then set the 'filetype' to 'lspgfm'.
+# If the completion popup documentation window displays "markdown" content,
+# then set the 'filetype' to "lspgfm".
 def LspSetPopupFileType()
   var item = v:event.completed_item
   if !item->has_key('user_data') || item.user_data->empty()
index 9eaa30c07f25713f05516c336e9ed4926d2e1dd8..97556d7c88c4c5e371b459628ed2826b198e52d3 100644 (file)
@@ -99,7 +99,7 @@ def SortDiags(diags: list<dict<any>>): list<dict<any>>
   })
 enddef
 
-# Remove the diagnostics stored for buffer 'bnr'
+# Remove the diagnostics stored for buffer "bnr"
 export def DiagRemoveFile(bnr: number)
   if diagsMap->has_key(bnr)
     diagsMap->remove(bnr)
@@ -160,7 +160,7 @@ def RemoveDiagVisualsForBuffer(bnr: number)
   endif
 enddef
 
-# Refresh the placed diagnostics in buffer 'bnr'
+# Refresh the placed diagnostics in buffer "bnr"
 # This inline signs, inline props, and virtual text diagnostics
 def DiagsRefresh(bnr: number)
   bnr->bufload()
@@ -266,9 +266,7 @@ enddef
 # New LSP diagnostic messages received from the server for a file.
 # Update the signs placed in the buffer for this file
 export def ProcessNewDiags(bnr: number)
-  if opt.lspOptions.autoPopulateDiags
-    DiagsUpdateLocList(bnr)
-  endif
+  DiagsUpdateLocList(bnr)
 
   if opt.lspOptions.aleSupport
     SendAleDiags(bnr, -1)
@@ -417,14 +415,21 @@ enddef
 # Update the location list window for the current window with the diagnostic
 # messages.
 # Returns true if diagnostics is not empty and false if it is empty.
-def DiagsUpdateLocList(bnr: number): bool
+def DiagsUpdateLocList(bnr: number, calledByCmd: bool = false): bool
   var fname: string = bnr->bufname()->fnamemodify(':p')
   if fname->empty()
     return false
   endif
 
   var LspQfId: number = bnr->getbufvar('LspQfId', 0)
+  if LspQfId->empty() && !opt.lspOptions.autoPopulateDiags && !calledByCmd
+    # If a location list for the diagnostics was not opened previously,
+    # and 'autoPopulateDiags' is set to false, then do nothing.
+    return false
+  endif
+
   if !LspQfId->empty() && getloclist(0, {id: LspQfId}).id != LspQfId
+    # Previously used location list for the diagnostics is gone
     LspQfId = 0
   endif
 
@@ -468,7 +473,7 @@ enddef
 # Display the diagnostic messages from the LSP server for the current buffer
 # in a location list
 export def ShowAllDiags(): void
-  if !DiagsUpdateLocList(bufnr())
+  if !DiagsUpdateLocList(bufnr(), true)
     util.WarnMsg($'No diagnostic messages found for {@%}')
     return
   endif
@@ -484,7 +489,7 @@ export def ShowAllDiags(): void
   endif
 enddef
 
-# Display the message of 'diag' in a popup window right below the position in
+# Display the message of "diag" in a popup window right below the position in
 # the diagnostic message.
 def ShowDiagInPopup(diag: dict<any>)
   var dlnum = diag.range.start.line + 1
@@ -527,7 +532,7 @@ def ShowDiagInPopup(diag: dict<any>)
   popup_create(msg, ppopts)
 enddef
 
-# Display the 'diag' message in a popup or in the status message area
+# Display the "diag" message in a popup or in the status message area
 def DisplayDiag(diag: dict<any>)
   if opt.lspOptions.showDiagInPopup
     # Display the diagnostic message in a popup window.
index e213c16227f87c6b5e85683268b74b36de120ee2..9a04cb6feb9ca4db5bf0c556219bf7dd878e422a 100644 (file)
@@ -97,8 +97,8 @@ export def ProcessNotif(lspserver: dict<any>, reply: dict<any>): void
       '$/progress',
       '$/status/report',
       '$/status/show',
-      # PHP intelephense server sends the 'indexingStarted' and
-      # 'indexingEnded' notifications which is not in the LSP specification.
+      # PHP intelephense server sends the "indexingStarted" and
+      # "indexingEnded" notifications which is not in the LSP specification.
       'indexingStarted',
       'indexingEnded',
       # Java language server sends the 'language/status' notification which is
index 8c3859f3baf66e287398433a6199d0932adf2d5f..b66d9f3eaa57f718f3d3196d3fb9465d5192a5f5 100644 (file)
@@ -168,7 +168,7 @@ export def ShowAllServers()
   :setlocal nomodifiable
 enddef
 
-# Create a new window containing the buffer 'bname' or if the window is
+# Create a new window containing the buffer "bname" or if the window is
 # already present then jump to it.
 def OpenScratchWindow(bname: string)
   var wid = bufwinid(bname)
@@ -254,7 +254,7 @@ def ShowServer(arg: string)
   endif
 enddef
 
-# Get LSP server running status for filetype 'ftype'
+# Get LSP server running status for filetype "ftype"
 # Return true if running, or false if not found or not running
 export def ServerRunning(ftype: string): bool
   if ftypeServerMap->has_key(ftype)
@@ -701,7 +701,7 @@ export def AddServer(serverList: list<dict<any>>)
 enddef
 
 # The LSP server is considered ready when the server capabilities are
-# received ('initialize' LSP reply message)
+# received ("initialize" LSP reply message)
 export def ServerReady(): bool
   var fname: string = @%
   if fname->empty()
index 78d814156e7f64cc11acc1f7c0e05de005f2e4a4..8ccf2f590e18657b70226bb29fc4bc88a85d492f 100644 (file)
@@ -91,7 +91,7 @@ def StartServer(lspserver: dict<any>, bnr: number): number
   return 0
 enddef
 
-# process the 'initialize' method reply from the LSP server
+# process the "initialize" method reply from the LSP server
 # Result: InitializeResult
 def ServerInitReply(lspserver: dict<any>, initResult: dict<any>): void
   if initResult->empty()
@@ -148,7 +148,7 @@ def ServerInitReply(lspserver: dict<any>, initResult: dict<any>): void
   endif
 enddef
 
-# Request: 'initialize'
+# Request: "initialize"
 # Param: InitializeParams
 def InitServer(lspserver: dict<any>, bnr: number)
   # interface 'InitializeParams'
index 761ef188dee20db031427488852b8093e2593237..177c761a35bb26499fb74a00b27fd9c1ef90c86e 100644 (file)
@@ -426,8 +426,8 @@ def SymbolFilterCB(lspserver: dict<any>, id: number, key: string): bool
   return false
 enddef
 
-# Display the file specified by LSP 'LocationLink' in a popup window and
-# highlight the range in 'location'.
+# Display the file specified by LSP "LocationLink" in a popup window and
+# highlight the range in "location".
 def PeekSymbolLocation(lspserver: dict<any>, location: dict<any>)
   var [uri, range] = util.LspLocationParse(location)
   var fname = util.LspUriToFile(uri)
index 0464ec8c07a5a29662a43c44561f74fc58fc3455..8786b1ba2a368f60f54c71601cfd736e23d6c135 100644 (file)
@@ -5,7 +5,7 @@ vim9script
 import './util.vim'
 import './symbol.vim'
 
-# Parse the type hierarchy in 'typeHier' and displays a tree of type names
+# Parse the type hierarchy in "typeHier" and displays a tree of type names
 # in the current buffer.  This function is called recursively to display the
 # super/sub type hierarchy.
 #
@@ -135,7 +135,8 @@ def TypeHierPopupCallback(lspserver: dict<any>, typeUriMap: list<dict<any>>,
   util.JumpToLspLocation(typeUriMap[selIdx - 1], '')
 enddef
 
-# Show the super or sub type hierarchy items 'types' as a tree in a popup window
+# Show the super or sub type hierarchy items "types" as a tree in a popup
+# window
 export def ShowTypeHierarchy(lspserver: dict<any>, isSuper: bool, types: dict<any>)
 
   if lspserver.typeHierPopup->winbufnr() != -1
index 708e8b86edc049458e8e6c27ca42cee0e4751a9a..a63953c6a3660553f17ea607a7c1d2c918fd2f32 100644 (file)
@@ -154,7 +154,7 @@ export def LspBufnrToUri(bnr: number): string
   return LspFileToUri(bnr->bufname())
 enddef
 
-# Returns the byte number of the specified LSP position in buffer 'bnr'.
+# Returns the byte number of the specified LSP position in buffer "bnr".
 # LSP's line and characters are 0-indexed.
 # Vim's line and columns are 1-indexed.
 # Returns a zero-indexed column.
@@ -253,9 +253,9 @@ export def PushCursorToTagStack()
                         }]}, 't')
 enddef
 
-# Jump to the LSP 'location'.  The 'location' contains the file name, line
+# Jump to the LSP "location".  The "location" contains the file name, line
 # number and character number. The user specified window command modifiers
-# (e.g. topleft) are in 'cmdmods'.
+# (e.g. topleft) are in "cmdmods".
 export def JumpToLspLocation(location: dict<any>, cmdmods: string)
   var [uri, range] = LspLocationParse(location)
   var fname = LspUriToFile(uri)
@@ -300,7 +300,8 @@ export def JumpToLspLocation(location: dict<any>, cmdmods: string)
                   GetCharIdxWithoutCompChar(bufnr(), range.start) + 1)
 enddef
 
-# 'indexof' is to new to use it, use this instead.
+# indexof() function is not present in older Vim 9 versions.  So use this
+# function.
 export def Indexof(list: list<any>, CallbackFn: func(number, any): bool): number
   var ix = 0
   for val in list
@@ -313,12 +314,12 @@ export def Indexof(list: list<any>, CallbackFn: func(number, any): bool): number
 enddef
 
 # Find the nearest root directory containing a file or directory name from the
-# list of names in 'files' starting with the directory 'startDir'.
+# list of names in "files" starting with the directory "startDir".
 # Based on a similar implementation in the vim-lsp plugin.
-# Searches upwards starting with the directory 'startDir'.
+# Searches upwards starting with the directory "startDir".
 # If a file name ends with '/' or '\', then it is a directory name, otherwise
 # it is a file name.
-# Returns '' if none of the file and directory names in 'files' can be found
+# Returns '' if none of the file and directory names in "files" can be found
 # in one of the parent directories.
 export def FindNearestRootDir(startDir: string, files: list<any>): string
   var foundDirs: dict<bool> = {}
@@ -349,7 +350,7 @@ export def FindNearestRootDir(startDir: string, files: list<any>): string
     return b->len() - a->len()
   })
 
-  # choose the longest matching path (the nearest directory from 'startDir')
+  # choose the longest matching path (the nearest directory from "startDir")
   return sortedList[0]
 enddef
 
index bd774c4a24328c07120197840b6490eb1263939a..55d0995b695d8512b35295d1d75a3d744097e6a2 100644 (file)
@@ -1183,7 +1183,9 @@ the current line.
 The |:LspDiagShow| command creates a new location list with the current list
 of diagnostics for the current buffer.  To automatically add the diagnostics
 messages to the location list, you can set the 'autoPopulateDiags' option to
-true.  By default this option is set to false.
+true.  By default this option is set to false.  When new diagnostics are
+received for a buffer, if a location list with the diagnostics is already
+present, then it is refreshed with the new diagnostics.
 
 When using GUI Vim or in a terminal Vim with 'ballooneval' option set, when
 the mouse is moved over the diagnostic sign displayed in the sign column, then
index 62a832e4e590eec2ae3e75ead77121de226bd091..cc375afc1dd622454ac2cbb56569ec014a80e178 100644 (file)
@@ -369,6 +369,41 @@ def g:Test_LspProcessDiagHandler()
   :%bw!
 enddef
 
+# Diag location list should be automatically updated when the list of diags
+# changes.
+def g:Test_DiagLocListAutoUpdate()
+  :silent! edit XdiagLocListAutoUpdate.c
+  :sleep 200m
+  setloclist(0, [], 'f')
+  var lines: list<string> =<< trim END
+    int i:
+    int j;
+  END
+  setline(1, lines)
+  var bnr = bufnr()
+  g:WaitForServerFileLoad(1)
+  :redraw!
+
+  :LspDiagShow
+  assert_equal(1, line('$'))
+  wincmd w
+  setline(2, 'int j:')
+  redraw!
+  g:WaitForDiags(2)
+  wincmd w
+  assert_equal(2, line('$'))
+  wincmd w
+  deletebufline('', 1, '$')
+  redraw!
+  g:WaitForDiags(0)
+  wincmd w
+  assert_equal([''], getline(1, '$'))
+  :lclose
+
+  setloclist(0, [], 'f')
+  :%bw!
+enddef
+
 # Test that the client have been able to configure the server to speak utf-32
 def g:Test_UnicodeColumnCalc()
   :silent! edit XUnicodeColumn.c
@@ -1068,8 +1103,6 @@ def g:Test_LspHover()
   popup_clear()
 
   :%bw!
-
-
 enddef
 
 # Test for :LspShowSignature