]> Sergey Matveev's repositories - vim-lsp.git/commitdiff
When jumping to a diag, display the diag message. When running the tests, wait for...
authorYegappan Lakshmanan <yegappan@yahoo.com>
Sat, 25 Mar 2023 18:34:22 +0000 (11:34 -0700)
committerYegappan Lakshmanan <yegappan@yahoo.com>
Sat, 25 Mar 2023 18:34:22 +0000 (11:34 -0700)
autoload/lsp/diag.vim
doc/lsp.txt
test/clangd_tests.vim
test/common.vim
test/tsserver_tests.vim

index 853f3deb8bbd148645e20cbf3cf5e0300155b6c7..9f5d641dc73fad7771c8b771549592eddeb1dbcd 100644 (file)
@@ -103,6 +103,7 @@ export def DiagNotification(lspserver: dict<any>, uri: string, diags: list<dict<
     diagWithinRange->add(diag)
   endfor
 
+  # sort the diagnostics by line number and column number
   var sortedDiags = diagWithinRange->sort((a, b) => {
     var linediff = a.range.start.line - b.range.start.line
     if linediff == 0
@@ -323,8 +324,11 @@ enddef
 # Get all diagnostics from the LSP server for a particular line in a file
 export def GetDiagsByLine(lspserver: dict<any>, bnr: number, lnum: number): list<dict<any>>
   if lspserver.diagsMap->has_key(bnr)
-    if lspserver.diagsMap[bnr].diagnosticsByLnum->has_key(lnum)
-      return lspserver.diagsMap[bnr].diagnosticsByLnum[lnum]
+    var diagsbyLnum = lspserver.diagsMap[bnr].diagnosticsByLnum
+    if diagsbyLnum->has_key(lnum)
+      return diagsbyLnum[lnum]->sort((a, b) => {
+         return a.range.start.character - b.range.start.character
+       })
     endif
   endif
   return []
@@ -344,11 +348,11 @@ export def LspDiagsJump(lspserver: dict<any>, which: string): void
     return
   endif
 
-  # sort the diagnostics by line number
   var diags = lspserver.diagsMap[bnr].sortedDiagnostics
 
   if which == 'first'
     setcursorcharpos(diags[0].range.start.line + 1, diags[0].range.start.character + 1)
+    DisplayDiag(diags[0])
     return
   endif
 
@@ -364,14 +368,16 @@ export def LspDiagsJump(lspserver: dict<any>, which: string): void
                                                        && col < curcol))
          || (which == 'here' && (lnum == curlnum && col >= curcol))
       setcursorcharpos(lnum, col)
-      if (which == 'here')
-       DisplayDiag(diag)
-      endif
+      DisplayDiag(diag)
       return
     endif
   endfor
 
-  util.WarnMsg('Error: No more diagnostics found')
+  if which == 'here'
+    util.WarnMsg('Error: No more diagnostics found on this line')
+  else
+    util.WarnMsg('Error: No more diagnostics found')
+  endif
 enddef
 
 # Disable the LSP diagnostics highlighting in all the buffers
index 88826b916b0bec9f8fc7af69b01de907ee4f4f63..577b0da28c1b7cd794b9916dacfcd9e5cc4421b0 100644 (file)
@@ -803,7 +803,7 @@ message, you can set the 'autoHighlightDiags' option to v:false:
 <
 By default the 'autoHighlightDiags' option is set to v:true.
 
-The function lsp#lsp#Errorcount() function can be used to get the count of the
+The function lsp#lsp#ErrorCount() function can be used to get the count of the
 diagnostic messages in the current buffer by type.  This function returns a
 Dictionary with the following keys: Info, Hint, Warn and Error.  The value for
 these keys is the number of diagnostic messages of the corresponding type.
index 3bac2ff923c629f1d4e1f85d7271df86724bad84..694f20dbfa9229c80def142aa5f396eb547b6d56 100644 (file)
@@ -226,8 +226,7 @@ def g:Test_LspDiag()
     }
   END
   setline(1, lines)
-  :sleep 1
-  g:WaitForDiags(1)
+  g:WaitForServerFileLoad(1)
   var bnr: number = bufnr()
   :redraw!
   :LspDiagShow
@@ -268,6 +267,7 @@ def g:Test_LspDiag()
   assert_match('No diagnostic messages found for', output[0])
   g:LspOptionsSet({showDiagInPopup: true})
 
+  popup_clear()
   :%bw!
 enddef
 
@@ -283,7 +283,7 @@ def g:Test_LspCodeAction()
     }
   END
   setline(1, lines)
-  sleep 1
+  g:WaitForServerFileLoad(0)
   cursor(4, 1)
   redraw!
   :LspCodeAction 1
@@ -316,7 +316,7 @@ def g:Test_LspCodeAction()
     }
   END
   setline(1, lines2)
-  sleep 1
+  g:WaitForServerFileLoad(0)
   cursor(4, 1)
   redraw!
   :LspCodeAction use
@@ -368,7 +368,7 @@ def g:Test_LspRename()
     }
   END
   setline(1, lines)
-  sleep 1
+  g:WaitForServerFileLoad(0)
   cursor(1, 1)
   search('count')
   redraw!
@@ -435,7 +435,7 @@ def g:Test_LspSelection()
     }
   END
   setline(1, lines)
-  sleep 1
+  g:WaitForServerFileLoad(0)
   # start a block-wise visual mode, LspSelectionExpand should change this to
   # a characterwise visual mode.
   exe "normal! 1G\<C-V>G\"_y"
@@ -660,7 +660,7 @@ def g:Test_LspHighlight()
     }
   END
   setline(1, lines)
-  :sleep 1
+  g:WaitForServerFileLoad(0)
   cursor(1, 13)
   :LspHighlight
   var expected: dict<any>
@@ -696,7 +696,7 @@ def g:Test_LspHover()
     }
   END
   setline(1, lines)
-  :sleep 1
+  g:WaitForServerFileLoad(0)
   cursor(8, 4)
   :LspHover
   var p: list<number> = popup_list()
@@ -725,7 +725,7 @@ def g:Test_LspShowSignature()
     }
   END
   setline(1, lines)
-  :sleep 1
+  g:WaitForServerFileLoad(2)
   cursor(8, 10)
   :LspShowSignature
   var p: list<number> = popup_list()
@@ -770,7 +770,7 @@ def g:Test_LspSymbolSearch()
     }
   END
   setline(1, lines)
-  :sleep 1
+  g:WaitForServerFileLoad(0)
 
   cursor(1, 1)
   feedkeys(":LspSymbolSearch lsptest_funcB\<CR>\<CR>", "xt")
@@ -810,7 +810,7 @@ def g:Test_LspIncomingCalls()
     }
   END
   setline(1, lines)
-  :sleep 1
+  g:WaitForServerFileLoad(0)
   cursor(1, 6)
   :LspIncomingCalls
   assert_equal([1, 2], [winnr(), winnr('$')])
@@ -836,7 +836,7 @@ def g:Test_LspOutline()
     }
   END
   setline(1, lines)
-  :sleep 1
+  g:WaitForServerFileLoad(0)
   :LspOutline
   assert_equal(2, winnr('$'))
   var bnum = winbufnr(1)
@@ -864,7 +864,7 @@ def g:Test_LspTagFunc()
   END
   writefile(lines, 'Xtest.c')
   :silent! edit Xtest.c
-  :sleep 1
+  g:WaitForServerFileLoad(1)
   :setlocal tagfunc=lsp#lsp#TagFunc
   cursor(3, 4)
   :exe "normal \<C-]>"
@@ -890,15 +890,16 @@ def g:Test_LspDiagsUpdated_Autocmd()
     }
   END
   setline(1, lines)
-  :sleep 1
-  g:WaitForDiags(0)
+  g:WaitForServerFileLoad(0)
   setline(3, '    return:')
+  redraw!
   g:WaitForDiags(1)
   setline(3, '    return;')
+  redraw!
   g:WaitForDiags(0)
   :%bw!
   autocmd_delete([{event: 'User', pattern: 'LspDiagsUpdated'}])
-  assert_equal(3, g:LspAutoCmd)
+  assert_equal(6, g:LspAutoCmd)
 enddef
 
 # Test custom notification handlers
@@ -971,7 +972,7 @@ def g:Test_OmniComplete_FirstColumn()
     #define FOO 1
   END
   setline(1, lines)
-  :sleep 1
+  g:WaitForServerFileLoad(0)
   redraw!
 
   feedkeys("G0i\<C-X>\<C-O>", 'xt')
index 135b7f0842bf72d598f5400763b9507a9cf60fa3..fad24a7d1d1923f8f93e5029865eaa8cb44862a0 100644 (file)
@@ -100,17 +100,45 @@ func g:WaitFor(expr, ...)
   return slept
 endfunc
 
-# Wait for diagnostic messages from the LSP server
+# Wait for diagnostic messages from the LSP server.
+# Waits for a maximum of (10 * 1500) / 1000 seconds
 def g:WaitForDiags(errCount: number)
   var retries = 0
-  while retries < 150
+  while retries < 1500
     var d = lsp#lsp#ErrorCount()
     if d.Error == errCount
       break
     endif
     retries += 1
-    :sleep 100m
+    :sleep 10m
   endwhile
+
+  assert_equal(errCount, lsp#lsp#ErrorCount().Error)
+  if lsp#lsp#ErrorCount().Error != errCount
+    :LspDiagShow
+    assert_report(getloclist(0)->string())
+    :lclose
+  endif
+enddef
+
+# Wait for the LSP server to load and process a file.  This works by waiting
+# for a certain number of diagnostic messages from the server.
+def g:WaitForServerFileLoad(diagCount: number)
+  redraw!
+  var waitCount = diagCount
+  if waitCount == 0
+    # Introduce a temporary diagnostic
+    append('$', '-')
+    redraw!
+    waitCount = 1
+  endif
+  g:WaitForDiags(waitCount)
+  if waitCount != diagCount
+    # Remove the temporary line
+    deletebufline('%', '$')
+    redraw!
+    g:WaitForDiags(0)
+  endif
 enddef
 
 # Start the language server.  Returns true on success and false on failure.
index 8f00daee55d6a83eb555ccfb9cb1033b9f968c1f..4cd145c3c642da2c26146f7ad065b614b9c1ee94 100644 (file)
@@ -21,62 +21,76 @@ def g:Test_LspDiag()
   var bnr: number = bufnr()
 
   # This tests that two diagnostics can be on the same line
-  var lines: list<string> = [
-    '  export obj = {',
-    '    foo: 1,',
-    '    bar: 2,',
-    '    baz: 3',
-    '  }'
-  ]
+  var lines: list<string> =<< trim END
+    export obj = {
+      foo: 1,
+      bar: 2,
+      baz; 3
+    }
+  END
 
   setline(1, lines)
-  :sleep 3
-  g:WaitForDiags(2)
+  g:WaitForServerFileLoad(5)
   :redraw!
   :LspDiagShow
   var qfl: list<dict<any>> = getloclist(0)
   assert_equal('quickfix', getwinvar(winnr('$'), '&buftype'))
   assert_equal(bnr, qfl[0].bufnr)
-  assert_equal(2, qfl->len())
-  assert_equal([1, 3, 'E'], [qfl[0].lnum, qfl[0].col, qfl[0].type])
-  assert_equal([1, 10, 'E'], [qfl[1].lnum, qfl[1].col, qfl[1].type])
+  assert_equal(5, qfl->len())
+  assert_equal([1, 1, 'E'], [qfl[0].lnum, qfl[0].col, qfl[0].type])
+  assert_equal([1, 8, 'E'], [qfl[1].lnum, qfl[1].col, qfl[1].type])
+  assert_equal([4, 3, 'E'], [qfl[2].lnum, qfl[2].col, qfl[2].type])
   close
 
   :sleep 100m
-  cursor(5, 1)
+  cursor(3, 1)
   assert_equal('', execute('LspDiagPrev'))
-  assert_equal([1, 10], [line('.'), col('.')])
+  assert_equal([1, 8], [line('.'), col('.')])
 
   assert_equal('', execute('LspDiagPrev'))
-  assert_equal([1, 3], [line('.'), col('.')])
+  assert_equal([1, 1], [line('.'), col('.')])
 
   var output = execute('LspDiagPrev')->split("\n")
   assert_equal('Error: No more diagnostics found', output[0])
 
   cursor(5, 1)
   assert_equal('', execute('LspDiagFirst'))
-  assert_equal([1, 3], [line('.'), col('.')])
+  assert_equal([1, 1], [line('.'), col('.')])
   assert_equal('', execute('LspDiagNext'))
-  assert_equal([1, 10], [line('.'), col('.')])
+  assert_equal([1, 8], [line('.'), col('.')])
+  popup_clear()
 
-  :normal! 0
+  # Test for :LspDiagHere on a line with multiple diagnostics
+  cursor(4, 1)
   :LspDiagHere
-  assert_equal([1, 3], [line('.'), col('.')])
-  :normal! l
+  assert_equal([4, 3], [line('.'), col('.')])
+  var ids = popup_list()
+  assert_equal(1, ids->len())
+  assert_match('No value exists', getbufline(ids[0]->winbufnr(), 1, '$')[0])
+  popup_clear()
+  cursor(4, 4)
   :LspDiagHere
-  assert_equal([1, 10], [line('.'), col('.')])
+  assert_equal([4, 6], [line('.'), col('.')])
+  ids = popup_list()
+  assert_equal(1, ids->len())
+  assert_match("',' expected.", getbufline(ids[0]->winbufnr(), 1, '$')[0])
   popup_clear()
 
+  # Line without diagnostics
+  cursor(3, 1)
+  output = execute('LspDiagHere')->split("\n")
+  assert_equal('Error: No more diagnostics found on this line', output[0])
+
   g:LspOptionsSet({showDiagInPopup: false})
   for i in range(1, 3)
-    cursor(1, i)
+    cursor(4, i)
     output = execute('LspDiagCurrent')->split('\n')
-    assert_equal('Declaration or statement expected.', output[0])
+    assert_match('No value exists in scope', output[0])
   endfor
-  for i in range(4, 16)
-    cursor(1, i)
+  for i in range(4, 8)
+    cursor(4, i)
     output = execute('LspDiagCurrent')->split('\n')
-    assert_equal('Cannot find name ''obj''.', output[0])
+    assert_equal("',' expected.", output[0])
   endfor
   g:LspOptionsSet({showDiagInPopup: true})
 
@@ -100,7 +114,7 @@ def g:Test_LspGoto()
   ]
 
   setline(1, lines)
-  :sleep 3
+  g:WaitForServerFileLoad(0)
 
   cursor(8, 1)
   assert_equal('', execute('LspGotoDefinition'))