Skip to content

Commit a82bec9

Browse files
authored
fix: change at eof (#171)
* undo commit * fix: change * cleanup * cleanup * fix test * fix: test
1 parent 9b92948 commit a82bec9

File tree

2 files changed

+85
-12
lines changed

2 files changed

+85
-12
lines changed

crates/pg_lsp/src/handlers/text_document.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
use crate::{documents::Document, session::Session, utils::apply_document_changes};
1+
use crate::{
2+
diagnostics::LspError, documents::Document, session::Session, utils::apply_document_changes,
3+
};
24
use anyhow::Result;
35
use pg_lsp_converters::from_proto::text_range;
46
use pg_workspace::workspace::{
@@ -47,13 +49,13 @@ pub(crate) async fn did_open(
4749
pub(crate) async fn did_change(
4850
session: &Session,
4951
params: lsp_types::DidChangeTextDocumentParams,
50-
) -> Result<()> {
52+
) -> Result<(), LspError> {
5153
let url = params.text_document.uri;
5254
let version = params.text_document.version;
5355

5456
let pglsp_path = session.file_path(&url)?;
5557

56-
// we need to keep the documents here too for the line index
58+
let old_doc = session.document(&url)?;
5759
let old_text = session.workspace.get_file_content(GetFileContentParams {
5860
path: pglsp_path.clone(),
5961
})?;
@@ -71,23 +73,21 @@ pub(crate) async fn did_change(
7173
&params.content_changes[start..],
7274
);
7375

74-
let new_doc = Document::new(version, &text);
75-
7676
session.workspace.change_file(ChangeFileParams {
7777
path: pglsp_path,
7878
version,
7979
changes: params.content_changes[start..]
8080
.iter()
8181
.map(|c| ChangeParams {
8282
range: c.range.and_then(|r| {
83-
text_range(&new_doc.line_index, r, session.position_encoding()).ok()
83+
text_range(&old_doc.line_index, r, session.position_encoding()).ok()
8484
}),
8585
text: c.text.clone(),
8686
})
8787
.collect(),
8888
})?;
8989

90-
session.insert_document(url.clone(), new_doc);
90+
session.insert_document(url.clone(), Document::new(version, &text));
9191

9292
if let Err(err) = session.update_diagnostics(url).await {
9393
error!("Failed to update diagnostics: {}", err);

crates/pg_workspace/src/workspace/server/change.rs

+78-5
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,10 @@ impl Document {
169169
};
170170

171171
Affected {
172-
affected_range: TextRange::new(start, end.min(content_size)),
172+
affected_range: {
173+
let end = end.min(content_size);
174+
TextRange::new(start.min(end), end)
175+
},
173176
affected_indices,
174177
prev_index,
175178
next_index,
@@ -194,8 +197,6 @@ impl Document {
194197

195198
/// Applies a single change to the document and returns the affected statements
196199
fn apply_change(&mut self, change: &ChangeParams) -> Vec<StatementChange> {
197-
tracing::info!("applying change: {:?}", change);
198-
199200
// if range is none, we have a full change
200201
if change.range.is_none() {
201202
return self.apply_full_change(&change.text);
@@ -273,7 +274,7 @@ impl Document {
273274
new_stmt_text: changed_content[new_ranges[0]].to_string(),
274275
// change must be relative to the statement
275276
change_text: change.text.clone(),
276-
change_range,
277+
change_range: change_range.sub(old_range.start()),
277278
}));
278279

279280
self.content = new_content;
@@ -526,7 +527,7 @@ mod tests {
526527
assert_eq!(changed.old_stmt_text, "select ;");
527528
assert_eq!(changed.new_stmt_text, "select");
528529
assert_eq!(changed.change_text, "");
529-
assert_eq!(changed.change_range, TextRange::new(32.into(), 33.into()));
530+
assert_eq!(changed.change_range, TextRange::new(7.into(), 8.into()));
530531
}
531532
_ => panic!("expected modified statement"),
532533
}
@@ -863,4 +864,76 @@ mod tests {
863864

864865
assert_document_integrity(&doc);
865866
}
867+
868+
#[test]
869+
fn remove_outside_of_content() {
870+
let path = PgLspPath::new("test.sql");
871+
let input = "select id from contacts;\n\nselect * from contacts;";
872+
873+
let mut d = Document::new(path.clone(), input.to_string(), 1);
874+
875+
assert_eq!(d.positions.len(), 2);
876+
877+
let change1 = ChangeFileParams {
878+
path: path.clone(),
879+
version: 2,
880+
changes: vec![ChangeParams {
881+
text: "\n".to_string(),
882+
range: Some(TextRange::new(49.into(), 49.into())),
883+
}],
884+
};
885+
886+
d.apply_file_change(&change1);
887+
888+
assert_eq!(
889+
d.content,
890+
"select id from contacts;\n\nselect * from contacts;\n"
891+
);
892+
893+
let change2 = ChangeFileParams {
894+
path: path.clone(),
895+
version: 3,
896+
changes: vec![ChangeParams {
897+
text: "\n".to_string(),
898+
range: Some(TextRange::new(50.into(), 50.into())),
899+
}],
900+
};
901+
902+
d.apply_file_change(&change2);
903+
904+
assert_eq!(
905+
d.content,
906+
"select id from contacts;\n\nselect * from contacts;\n\n"
907+
);
908+
909+
let change5 = ChangeFileParams {
910+
path: path.clone(),
911+
version: 6,
912+
changes: vec![ChangeParams {
913+
text: "".to_string(),
914+
range: Some(TextRange::new(51.into(), 52.into())),
915+
}],
916+
};
917+
918+
let changes = d.apply_file_change(&change5);
919+
920+
assert!(matches!(
921+
changes[0],
922+
StatementChange::Deleted(Statement { .. })
923+
));
924+
925+
assert!(matches!(
926+
changes[1],
927+
StatementChange::Added(AddedStatement { .. })
928+
));
929+
930+
assert_eq!(changes.len(), 2);
931+
932+
assert_eq!(
933+
d.content,
934+
"select id from contacts;\n\nselect * from contacts;\n\n"
935+
);
936+
937+
assert_document_integrity(&d);
938+
}
866939
}

0 commit comments

Comments
 (0)