@@ -2425,7 +2425,10 @@ impl CodeLabel {
"invalid filter range"
);
runs.iter().for_each(|(range, _)| {
- assert!(text.get(range.clone()).is_some(), "invalid run range");
+ assert!(
+ text.get(range.clone()).is_some(),
+ "invalid run range with inputs. Requested range {range:?} in text '{text}'",
+ );
});
Self {
runs,
@@ -375,16 +375,20 @@ impl LspAdapter for RustLspAdapter {
let start_pos = range.start as usize;
let end_pos = range.end as usize;
- label.push_str(&snippet.text[text_pos..end_pos]);
- text_pos = end_pos;
+ label.push_str(&snippet.text[text_pos..start_pos]);
if start_pos == end_pos {
let caret_start = label.len();
label.push('…');
runs.push((caret_start..label.len(), HighlightId::TABSTOP_INSERT_ID));
} else {
- runs.push((start_pos..end_pos, HighlightId::TABSTOP_REPLACE_ID));
+ let label_start = label.len();
+ label.push_str(&snippet.text[start_pos..end_pos]);
+ let label_end = label.len();
+ runs.push((label_start..label_end, HighlightId::TABSTOP_REPLACE_ID));
}
+
+ text_pos = end_pos;
}
label.push_str(&snippet.text[text_pos..]);
@@ -1592,6 +1596,44 @@ mod tests {
],
))
);
+
+ // Test for correct range calculation with mixed empty and non-empty tabstops.(See https://github.com/zed-industries/zed/issues/44825)
+ let res = adapter
+ .label_for_completion(
+ &lsp::CompletionItem {
+ kind: Some(lsp::CompletionItemKind::STRUCT),
+ label: "Particles".to_string(),
+ insert_text_format: Some(lsp::InsertTextFormat::SNIPPET),
+ text_edit: Some(lsp::CompletionTextEdit::Edit(lsp::TextEdit {
+ range: lsp::Range::default(),
+ new_text: "Particles { pos_x: $1, pos_y: $2, vel_x: $3, vel_y: $4, acc_x: ${5:()}, acc_y: ${6:()}, mass: $7 }$0".to_string(),
+ })),
+ ..Default::default()
+ },
+ &language,
+ )
+ .await
+ .unwrap();
+
+ assert_eq!(
+ res,
+ CodeLabel::new(
+ "Particles { pos_x: …, pos_y: …, vel_x: …, vel_y: …, acc_x: (), acc_y: (), mass: … }".to_string(),
+ 0..9,
+ vec![
+ (19..22, HighlightId::TABSTOP_INSERT_ID),
+ (31..34, HighlightId::TABSTOP_INSERT_ID),
+ (43..46, HighlightId::TABSTOP_INSERT_ID),
+ (55..58, HighlightId::TABSTOP_INSERT_ID),
+ (67..69, HighlightId::TABSTOP_REPLACE_ID),
+ (78..80, HighlightId::TABSTOP_REPLACE_ID),
+ (88..91, HighlightId::TABSTOP_INSERT_ID),
+ (0..9, highlight_type),
+ (60..65, highlight_field),
+ (71..76, highlight_field),
+ ],
+ )
+ );
}
#[gpui::test]