Skip to content

Commit 6346731

Browse files
fix: properly trim statement
1 parent b978a5a commit 6346731

File tree

1 file changed

+157
-13
lines changed
  • crates/pgt_workspace/src/workspace/server

1 file changed

+157
-13
lines changed

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

+157-13
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,8 @@ impl Document {
151151
let mut start = change_range.start();
152152
let mut end = change_range.end().min(content_size);
153153

154+
let is_trim = change_range.start() >= content_size;
155+
154156
let mut affected_indices = Vec::new();
155157
let mut prev_index = None;
156158
let mut next_index = None;
@@ -168,23 +170,24 @@ impl Document {
168170
}
169171
}
170172

171-
let start_incl = prev_index
173+
let first_affected_stmt_start = prev_index
172174
.map(|i| self.positions[i].1.start())
173175
.unwrap_or(start);
174-
let end_incl = next_index
176+
177+
let mut last_affected_stmt_end = next_index
175178
.map(|i| self.positions[i].1.end())
176179
.unwrap_or_else(|| end);
177180

178-
let end_incl = if is_addition {
179-
end_incl.add(diff_size)
180-
} else {
181-
end_incl.sub(diff_size)
181+
if is_addition {
182+
last_affected_stmt_end = last_affected_stmt_end.add(diff_size)
183+
} else if !is_trim {
184+
last_affected_stmt_end = last_affected_stmt_end.sub(diff_size)
182185
};
183186

184-
let end = if is_addition {
185-
end.add(diff_size)
186-
} else {
187-
end.sub(diff_size)
187+
if is_addition {
188+
end = end.add(diff_size);
189+
} else if !is_trim {
190+
end = end.sub(diff_size);
188191
};
189192

190193
Affected {
@@ -195,7 +198,10 @@ impl Document {
195198
affected_indices,
196199
prev_index,
197200
next_index,
198-
full_affected_range: TextRange::new(start_incl, end_incl.min(content_size)),
201+
full_affected_range: TextRange::new(
202+
first_affected_stmt_start,
203+
last_affected_stmt_end.min(content_size),
204+
),
199205
}
200206
}
201207

@@ -229,6 +235,7 @@ impl Document {
229235
let mut changed: Vec<StatementChange> = Vec::with_capacity(self.positions.len());
230236

231237
let change_range = change.range.unwrap();
238+
let previous_content = self.content.clone();
232239
let new_content = change.apply_to_text(&self.content);
233240

234241
// we first need to determine the affected range and all affected statements, as well as
@@ -269,7 +276,9 @@ impl Document {
269276
let new_range = new_ranges[0].add(affected_range.start());
270277
let (old_id, old_range) = self.positions[affected_idx];
271278

272-
// move all statements after the afffected range
279+
println!("{:?}", old_range);
280+
281+
// move all statements after the affected range
273282
self.move_ranges(old_range.end(), change.diff_size(), change.is_addition());
274283

275284
let new_id = self.id_generator.next();
@@ -280,7 +289,7 @@ impl Document {
280289
id: old_id,
281290
path: self.path.clone(),
282291
},
283-
old_stmt_text: self.content[old_range].to_string(),
292+
old_stmt_text: previous_content[old_range].to_string(),
284293

285294
new_stmt: Statement {
286295
id: new_id,
@@ -1322,4 +1331,139 @@ mod tests {
13221331

13231332
assert_document_integrity(&d);
13241333
}
1334+
1335+
#[test]
1336+
fn remove_trailing_whitespace() {
1337+
let path = PgTPath::new("test.sql");
1338+
1339+
let mut doc = Document::new(path.clone(), "select * from ".to_string(), 0);
1340+
1341+
let change = ChangeFileParams {
1342+
path: path.clone(),
1343+
version: 1,
1344+
changes: vec![ChangeParams {
1345+
text: "".to_string(),
1346+
range: Some(TextRange::new(13.into(), 14.into())),
1347+
}],
1348+
};
1349+
1350+
let changed = doc.apply_file_change(&change);
1351+
1352+
assert_eq!(doc.content, "select * from");
1353+
1354+
assert_eq!(changed.len(), 1);
1355+
1356+
match &changed[0] {
1357+
StatementChange::Modified(stmt) => {
1358+
let ModifiedStatement {
1359+
change_range,
1360+
change_text,
1361+
new_stmt_text,
1362+
old_stmt_text,
1363+
..
1364+
} = stmt;
1365+
1366+
assert_eq!(change_range, &TextRange::new(13.into(), 14.into()));
1367+
assert_eq!(change_text, "");
1368+
assert_eq!(new_stmt_text, "select * from");
1369+
1370+
// the whitespace was not considered
1371+
// to be a part of the statement
1372+
assert_eq!(old_stmt_text, "select * from");
1373+
}
1374+
1375+
_ => panic!("Did not yield a modified statement."),
1376+
}
1377+
1378+
assert_document_integrity(&doc);
1379+
}
1380+
1381+
#[test]
1382+
fn remove_trailing_whitespace_and_last_char() {
1383+
let path = PgTPath::new("test.sql");
1384+
1385+
let mut doc = Document::new(path.clone(), "select * from ".to_string(), 0);
1386+
1387+
let change = ChangeFileParams {
1388+
path: path.clone(),
1389+
version: 1,
1390+
changes: vec![ChangeParams {
1391+
text: "".to_string(),
1392+
range: Some(TextRange::new(12.into(), 14.into())),
1393+
}],
1394+
};
1395+
1396+
let changed = doc.apply_file_change(&change);
1397+
1398+
assert_eq!(doc.content, "select * fro");
1399+
1400+
assert_eq!(changed.len(), 1);
1401+
1402+
match &changed[0] {
1403+
StatementChange::Modified(stmt) => {
1404+
let ModifiedStatement {
1405+
change_range,
1406+
change_text,
1407+
new_stmt_text,
1408+
old_stmt_text,
1409+
..
1410+
} = stmt;
1411+
1412+
assert_eq!(change_range, &TextRange::new(12.into(), 14.into()));
1413+
assert_eq!(change_text, "");
1414+
assert_eq!(new_stmt_text, "select * fro");
1415+
1416+
// the whitespace was not considered
1417+
// to be a part of the statement
1418+
assert_eq!(old_stmt_text, "select * from");
1419+
}
1420+
1421+
_ => panic!("Did not yield a modified statement."),
1422+
}
1423+
1424+
assert_document_integrity(&doc);
1425+
}
1426+
1427+
#[test]
1428+
fn remove_inbetween_whitespace() {
1429+
let path = PgTPath::new("test.sql");
1430+
1431+
let mut doc = Document::new(path.clone(), "select * from users".to_string(), 0);
1432+
1433+
let change = ChangeFileParams {
1434+
path: path.clone(),
1435+
version: 1,
1436+
changes: vec![ChangeParams {
1437+
text: "".to_string(),
1438+
range: Some(TextRange::new(9.into(), 11.into())),
1439+
}],
1440+
};
1441+
1442+
let changed = doc.apply_file_change(&change);
1443+
1444+
assert_eq!(doc.content, "select * from users");
1445+
1446+
assert_eq!(changed.len(), 1);
1447+
1448+
match &changed[0] {
1449+
StatementChange::Modified(stmt) => {
1450+
let ModifiedStatement {
1451+
change_range,
1452+
change_text,
1453+
new_stmt_text,
1454+
old_stmt_text,
1455+
..
1456+
} = stmt;
1457+
1458+
assert_eq!(change_range, &TextRange::new(9.into(), 11.into()));
1459+
assert_eq!(change_text, "");
1460+
assert_eq!(old_stmt_text, "select * from users");
1461+
assert_eq!(new_stmt_text, "select * from users");
1462+
}
1463+
1464+
_ => panic!("Did not yield a modified statement."),
1465+
}
1466+
1467+
assert_document_integrity(&doc);
1468+
}
13251469
}

0 commit comments

Comments
 (0)