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

Issue:
Don't send textDocument/didSave unless server advertises support for it
More information: dart-lang/sdk#36464 natebosch/vim-lsc#164 tomv564/LSP#550

I use the follow config 
```
let g:LanguageClient_serverCommands = {
    \ 'python' :["pyls"],
    \ 'rust': ['rustup', 'run', 'stable', 'rls'],
    \ 'dart': ['$DART_SDK/dart', "$DART_SDK/snapshots/analysis_server.dart.snapshot", "--lsp"],
\ }
```

while I try to save a dart file, I get a error 
```
[LC] [Error] Unknown method textDocument/didSave%
```


Discussion / hints:
Is there a way to disable this for a given language explicitly in LanguageClient configuration? reading docs did not yield any useful information on this matter. 

Cheers
Not yet. It should be fairly simple to implement though so if someone is willing to open a PR I would be happy to help and merge. Otherwise I should be able to have a commit ready for this in a few days.
Does anyone have an example of a server that does not advertise support for this? I have something ready-ish but would like to try it out first before pushing any changes.
@martskins dart server has this issue, once you installed dart you can run it with `dart "$DART_SDK/bin/snapshots/analysis_server.dart.snapshot" --lsp`. LC config:

```vim
let g:LanguageClient_serverCommands = {
\ 'dart': ['dart', $DART_SDK.'/bin/snapshots/analysis_server.dart.snapshot', '--lsp'],
\ }
```

Fix patch:
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 286ce358..dc5f5b42 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -29,7 +29,7 @@ jobs:
     - name: Install other dependencies
       run: |
         sudo apt-get update
-        sudo apt-get install --yes --no-install-recommends neovim curl git python3-pip python3-pytest mypy flake8 nodejs-dev node-gyp libssl1.0 npm make
+        sudo apt-get install --yes --no-install-recommends neovim curl git python3-pip python3-pytest mypy flake8 libnode-dev node-gyp libssl1.0 npm make
         sudo apt-get clean
         sudo rm -rf /var/lib/apt/lists/*
         python3 -m pip install neovim vim-vint
diff --git a/src/language_server_protocol.rs b/src/language_server_protocol.rs
index 54948e97..b4da3960 100644
--- a/src/language_server_protocol.rs
+++ b/src/language_server_protocol.rs
@@ -43,9 +43,9 @@ use lsp_types::{
     ShowMessageParams, ShowMessageRequestParams, SignatureHelp, SignatureHelpClientCapabilities,
     SignatureInformationSettings, SymbolInformation, TextDocumentClientCapabilities,
     TextDocumentContentChangeEvent, TextDocumentIdentifier, TextDocumentItem,
-    TextDocumentPositionParams, TextEdit, UnregistrationParams, VersionedTextDocumentIdentifier,
-    WorkDoneProgress, WorkDoneProgressParams, WorkspaceClientCapabilities, WorkspaceEdit,
-    WorkspaceSymbolParams,
+    TextDocumentPositionParams, TextDocumentSyncCapability, TextDocumentSyncKind, TextEdit,
+    UnregistrationParams, VersionedTextDocumentIdentifier, WorkDoneProgress,
+    WorkDoneProgressParams, WorkspaceClientCapabilities, WorkspaceEdit, WorkspaceSymbolParams,
 };
 use maplit::hashmap;
 use serde::de::Deserialize;
@@ -2102,6 +2102,26 @@ impl LanguageClient {
     pub fn text_document_did_save(&self, params: &Value) -> Result<()> {
         let filename = self.vim()?.get_filename(params)?;
         let language_id = self.vim()?.get_language_id(&filename, params)?;
+        let has_capability = self.get_state(|s| {
+            s.capabilities
+                .get(&language_id)
+                .as_ref()
+                .map(|i| match i.capabilities.text_document_sync.as_ref() {
+                    Some(TextDocumentSyncCapability::Kind(TextDocumentSyncKind::None)) => false,
+                    Some(TextDocumentSyncCapability::Kind(_)) => true,
+                    Some(TextDocumentSyncCapability::Options(o)) => match o.save {
+                        Some(lsp_types::TextDocumentSyncSaveOptions::Supported(b)) => b,
+                        Some(lsp_types::TextDocumentSyncSaveOptions::SaveOptions(_)) => true,
+                        None => false,
+                    },
+                    None => false,
+                })
+                .unwrap_or_default()
+        })?;
+        if !has_capability {
+            return Ok(());
+        }
+
         if !self.get_config(|c| c.server_commands.contains_key(&language_id))? {
             return Ok(());
         }


Test patch: