diff --git a/cli/lsp/path_to_regex.rs b/cli/lsp/path_to_regex.rs index 393591785f..16db881940 100644 --- a/cli/lsp/path_to_regex.rs +++ b/cli/lsp/path_to_regex.rs @@ -733,7 +733,7 @@ impl Compiler { let prefix = k.prefix.clone().unwrap_or_default(); let suffix = k.suffix.clone().unwrap_or_default(); for segment in v { - if self.validate { + if !segment.is_empty() && self.validate { if let Some(re) = &self.matches[i] { if !re.is_match(segment) { return Err(anyhow!( @@ -911,6 +911,33 @@ mod tests { assert_eq!(actual, "/x/y@v1.0.0/z/example.ts".to_string()); } + #[test] + fn test_compiler_ends_with_sep() { + let tokens = parse("/x/:a@:b/:c*", None).expect("could not parse"); + let mut params = HashMap::::new(); + params.insert( + StringOrNumber::String("a".to_string()), + StringOrVec::String("y".to_string()), + ); + params.insert( + StringOrNumber::String("b".to_string()), + StringOrVec::String("v1.0.0".to_string()), + ); + params.insert( + StringOrNumber::String("c".to_string()), + StringOrVec::Vec(vec![ + "z".to_string(), + "example".to_string(), + "".to_string(), + ]), + ); + let compiler = Compiler::new(&tokens, None); + let actual = compiler.to_path(¶ms); + assert!(actual.is_ok()); + let actual = actual.unwrap(); + assert_eq!(actual, "/x/y@v1.0.0/z/example/".to_string()); + } + #[test] fn test_string_to_regex() { test_path("/", None, &[("/test", None), ("/", Some(("/", 0, 1)))]); diff --git a/cli/lsp/registries.rs b/cli/lsp/registries.rs index 9b68b8850c..acb6a401a0 100644 --- a/cli/lsp/registries.rs +++ b/cli/lsp/registries.rs @@ -651,12 +651,17 @@ impl ModuleRegistry { is_incomplete = true; } for (idx, item) in items.into_iter().enumerate() { - let label = if let Some(p) = &prefix { + let mut label = if let Some(p) = &prefix { format!("{}{}", p, item) } else { item.clone() }; - let kind = if key.name == last_key_name { + if label.ends_with('/') { + label.pop(); + } + let kind = if key.name == last_key_name + && !item.ends_with('/') + { Some(lsp::CompletionItemKind::FILE) } else { Some(lsp::CompletionItemKind::FOLDER) @@ -666,8 +671,11 @@ impl ModuleRegistry { key.name.clone(), StringOrVec::from_str(&item, &key), ); - let path = + let mut path = compiler.to_path(¶ms).unwrap_or_default(); + if path.ends_with('/') { + path.pop(); + } let item_specifier = base.join(&path).ok()?; let full_text = item_specifier.as_str(); let text_edit = Some(lsp::CompletionTextEdit::Edit( @@ -677,6 +685,7 @@ impl ModuleRegistry { }, )); let command = if key.name == last_key_name + && !item.ends_with('/') && !specifier_exists(&item_specifier) { Some(lsp::Command {