-
Notifications
You must be signed in to change notification settings - Fork 98
/
Copy pathtext_document.rs
115 lines (95 loc) · 3.19 KB
/
text_document.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
use crate::adapters::from_lsp;
use crate::{
diagnostics::LspError, documents::Document, session::Session, utils::apply_document_changes,
};
use anyhow::Result;
use pgt_workspace::workspace::{
ChangeFileParams, ChangeParams, CloseFileParams, GetFileContentParams, OpenFileParams,
};
use tower_lsp::lsp_types;
use tracing::error;
/// Handler for `textDocument/didOpen` LSP notification
#[tracing::instrument(level = "debug", skip(session), err)]
pub(crate) async fn did_open(
session: &Session,
params: lsp_types::DidOpenTextDocumentParams,
) -> Result<()> {
let url = params.text_document.uri;
let version = params.text_document.version;
let content = params.text_document.text;
let path = session.file_path(&url)?;
let doc = Document::new(version, &content);
session.workspace.open_file(OpenFileParams {
path,
version,
content,
})?;
session.insert_document(url.clone(), doc);
if let Err(err) = session.update_diagnostics(url).await {
error!("Failed to update diagnostics: {}", err);
}
Ok(())
}
// Handler for `textDocument/didChange` LSP notification
#[tracing::instrument(level = "debug", skip(session), err)]
pub(crate) async fn did_change(
session: &Session,
params: lsp_types::DidChangeTextDocumentParams,
) -> Result<(), LspError> {
let url = params.text_document.uri;
let version = params.text_document.version;
let pgt_path = session.file_path(&url)?;
let old_doc = session.document(&url)?;
let old_text = session.workspace.get_file_content(GetFileContentParams {
path: pgt_path.clone(),
})?;
let start = params
.content_changes
.iter()
.rev()
.position(|change| change.range.is_none())
.map_or(0, |idx| params.content_changes.len() - idx - 1);
let text = apply_document_changes(
session.position_encoding(),
old_text,
¶ms.content_changes[start..],
);
session.workspace.change_file(ChangeFileParams {
path: pgt_path,
version,
changes: params.content_changes[start..]
.iter()
.map(|c| ChangeParams {
range: c.range.and_then(|r| {
from_lsp::text_range(&old_doc.line_index, r, session.position_encoding()).ok()
}),
text: c.text.clone(),
})
.collect(),
})?;
session.insert_document(url.clone(), Document::new(version, &text));
if let Err(err) = session.update_diagnostics(url).await {
error!("Failed to update diagnostics: {}", err);
}
Ok(())
}
/// Handler for `textDocument/didClose` LSP notification
#[tracing::instrument(level = "debug", skip(session), err)]
pub(crate) async fn did_close(
session: &Session,
params: lsp_types::DidCloseTextDocumentParams,
) -> Result<()> {
let url = params.text_document.uri;
let pgt_path = session.file_path(&url)?;
session
.workspace
.close_file(CloseFileParams { path: pgt_path })?;
session.remove_document(&url);
let diagnostics = vec![];
let version = None;
session
.client
.publish_diagnostics(url, diagnostics, version)
.await;
Ok(())
}