Repository: autozimu/LanguageClient-neovim (language: rust)

Issue:
Can't use LanguageClient#explainErrorAtPoint() in CursorHold autocmd
## Is your feature request related to a problem? Please describe.

I have the following autocmd:

```
au CursorHold * sil call LanguageClient#explainErrorAtPoint()
```

It works greater and displays the diagnostic in a floating window with the newest neovim. However, when I'm on a line without error, it outputs the error message "No diagnostic found: ...". This is annoying.

## Describe the solution you'd like

I'd like that calling `explainErrorAtPoint()` on a line without error does nothing.

## Describe alternatives you've considered

I've tried rasing the log level, but this doesn't seem to work.


Discussion / hints:
Probably related: https://github.com/autozimu/LanguageClient-neovim/issues/792

Fix patch:
diff --git a/autoload/LanguageClient.vim b/autoload/LanguageClient.vim
index 772b0fed..36c859c3 100644
--- a/autoload/LanguageClient.vim
+++ b/autoload/LanguageClient.vim
@@ -560,9 +560,9 @@ function! s:OpenHoverPreview(bufname, lines, filetype, ...) abort
     endif
 endfunction
 
-function! s:MoveIntoHoverPreview() abort
+function! s:MoveIntoHoverPreview(bufname) abort
     for bufnr in range(1, bufnr('$'))
-        if bufname(bufnr) ==# '__LanguageClient__'
+        if bufname(bufnr) ==# a:bufname
             let winnr = bufwinnr(bufnr)
             if winnr != -1
                 execute winnr . 'wincmd w'
@@ -865,7 +865,7 @@ function! LanguageClient#Notify(method, params) abort
 endfunction
 
 function! LanguageClient#textDocument_hover(...) abort
-    if s:ShouldUseFloatWindow() && s:MoveIntoHoverPreview()
+    if s:ShouldUseFloatWindow() && s:MoveIntoHoverPreview('__LCNHover__')
         return
     endif
     let l:Callback = get(a:000, 1, v:null)
@@ -1353,7 +1353,9 @@ function! LanguageClient_NCM2OnComplete(context) abort
 endfunction
 
 function! LanguageClient#explainErrorAtPoint(...) abort
-    if s:ShouldUseFloatWindow() && s:MoveIntoHoverPreview()
+    let extra = get(a:000, 0, {})
+    let silent_mode = get(extra, 'silent', v:false)
+    if s:ShouldUseFloatWindow() && !silent_mode && s:MoveIntoHoverPreview('__LCNExplainError__')
         return
     endif
 
@@ -1365,7 +1367,7 @@ function! LanguageClient#explainErrorAtPoint(...) abort
                 \ 'character': LSP#character(),
                 \ 'handle': s:IsFalse(l:Callback),
                 \ }
-    call extend(l:params, get(a:000, 0, {}))
+    call extend(l:params, extra)
     return LanguageClient#Call('languageClient/explainErrorAtPoint', l:params, l:Callback)
 endfunction
 
diff --git a/src/language_server_protocol.rs b/src/language_server_protocol.rs
index f939ffce..e20bcc1d 100644
--- a/src/language_server_protocol.rs
+++ b/src/language_server_protocol.rs
@@ -1046,11 +1046,10 @@ impl LanguageClient {
         Ok(())
     }
 
-    fn preview<D>(&self, to_display: &D) -> Result<()>
+    fn preview<D>(&self, to_display: &D, bufname: &str) -> Result<()>
     where
         D: ToDisplay + ?Sized,
     {
-        let bufname = "__LanguageClient__";
         let filetype = &to_display.vim_filetype();
         let lines = to_display.to_display();
 
@@ -1283,7 +1282,7 @@ impl LanguageClient {
                 HoverPreviewOption::Auto => hover.lines_len() > 1,
             };
             if use_preview {
-                self.preview(&hover)?
+                self.preview(&hover, "__LCNHover__")?
             } else {
                 self.vim()?.echo_ellipsis(hover.to_string())?
             }
@@ -3524,6 +3523,7 @@ impl LanguageClient {
 
     #[tracing::instrument(level = "info", skip(self))]
     pub fn explain_error_at_point(&self, params: &Value) -> Result<Value> {
+        let silent_mode: bool = try_get("silent", params)?.unwrap_or_default();
         let filename = self.vim()?.get_filename(params)?;
         let position = self.vim()?.get_position(params)?;
         let diag = self.get(|state| {
@@ -3542,7 +3542,12 @@ impl LanguageClient {
                         position.character
                     )
                 })
-        })??;
+        })?;
+
+        if silent_mode && diag.is_err() {
+            return Ok(Value::Null);
+        }
+        let diag = diag?;
 
         let language_id = self.vim()?.get_language_id(&filename, params)?;
         let root = self.get(|state| state.roots.get(&language_id).cloned().unwrap_or_default())?;
@@ -3577,7 +3582,7 @@ impl LanguageClient {
             }
         }
 
-        self.preview(explanation.as_str())?;
+        self.preview(explanation.as_str(), "__LCNExplainError__")?;
         Ok(Value::Null)
     }
 


Test patch:
diff --git a/tests/LanguageClient_test.py b/tests/LanguageClient_test.py
index dc40d1dc..47944dc3 100644
--- a/tests/LanguageClient_test.py
+++ b/tests/LanguageClient_test.py
@@ -39,7 +39,7 @@ def assertRetry(predicate, retry_max=100):
 
 
 def getLanguageClientBuffers(nvim):
-    return [b for b in nvim.buffers if b.name.endswith("__LanguageClient__")]
+    return [b for b in nvim.buffers if b.name.endswith("__LCNHover__")]
 
 
 @pytest.fixture(scope="module")
@@ -324,7 +324,7 @@ def test_textDocument_hover_float_window_move_cursor_into_window(nvim):
 
     # Moves cursor into floating window
     nvim.funcs.LanguageClient_textDocument_hover()
-    assert nvim.current.buffer.name.endswith("__LanguageClient__")
+    assert nvim.current.buffer.name.endswith("__LCNHover__")
 
     # Close the window
     nvim.command('close')