@@ -255,11 +255,6 @@ impl Client {
255255 .await
256256 }
257257
258− // TODO: this is dumb. TextEdit describes changes to the initial doc (concurrent), but
259− // TextDocumentContentChangeEvent describes a series of changes (sequential).
260− // So S -> S1 -> S2, meaning positioning depends on the previous edits.
261− //
262− // Calculation is therefore a bunch trickier.
263258 pub fn changeset_to_changes(
264259 old_text: &Rope,
265260 new_text: &Rope,
@@ -274,6 +269,12 @@ impl Client {
274269 use crate::util::pos_to_lsp_pos;
275270 use helix_core::Operation::*;
276271
272+ // this is dumb. TextEdit describes changes to the initial doc (concurrent), but
273+ // TextDocumentContentChangeEvent describes a series of changes (sequential).
274+ // So S -> S1 -> S2, meaning positioning depends on the previous edits.
275+ //
276+ // Calculation is therefore a bunch trickier.
277+
277278 // TODO: stolen from syntax.rs, share
278279 use helix_core::RopeSlice;
279280 fn traverse(pos: lsp::Position, text: RopeSlice) -> lsp::Position {
@@ -397,8 +398,6 @@ impl Client {
397398 .await
398399 }
399400
400− // TODO: impl into() TextDocumentIdentifier / VersionedTextDocumentIdentifier for Document.
401−
402401 pub async fn text_document_did_close(
403402 &self,
404403 text_document: lsp::TextDocumentIdentifier,
@@ -411,15 +410,22 @@ impl Client {
411410
412411 // will_save / will_save_wait_until
413412
414− pub async fn text_document_did_save(&self) -> anyhow::Result<()> {
415− unimplemented!()
413+ pub async fn text_document_did_save(
414+ &self,
415+ text_document: lsp::TextDocumentIdentifier,
416+ ) -> Result<()> {
417+ self.notify::<lsp::notification::DidSaveTextDocument>(lsp::DidSaveTextDocumentParams {
418+ text_document,
419+ text: None, // TODO:
420+ })
421+ .await
416422 }
417423
418424 pub async fn completion(
419425 &self,
420426 text_document: lsp::TextDocumentIdentifier,
421427 position: lsp::Position,
422− ) -> anyhow::Result<Vec<lsp::CompletionItem>> {
428+ ) -> Result<Vec<lsp::CompletionItem>> {
423429 // TODO: figure out what should happen when you complete with multiple cursors
424430
425431 let params = lsp::CompletionParams {