chore(vim): add initial projections structs

This commit is contained in:
dino
2025-11-04 23:22:29 +00:00
parent 7143d4017b
commit 82d86110d2

View File

@@ -24,8 +24,52 @@ use gpui::Window;
use gpui::actions;
use project::ProjectItem;
use project::ProjectPath;
use regex::Regex;
use util::rel_path::RelPath;
#[derive(Debug)]
struct Projection {
source: Regex,
target: String,
}
impl Projection {
fn new(source: &str, target: &str) -> Self {
// Replace the `*` character in the source string, if such a character
// is present, with a capture group, so we can then replace that value
// when determining the target.
// TODO!: Support for multiple `*` characters?
// TODO!: Validation that the number of `{}` in the target matches the
// number of `*` on the source.
// TODO!: Avoid `unwrap` here by updating `new` to return
// `Result<Self>`/`Option<Self>`.
let source = Regex::new(&source.replace("*", "(.*)")).unwrap();
let target = String::from(target);
Self { source, target }
}
/// Determines whether the provided path matches this projection's source.
/// TODO!: We'll likely want to update this to use `ProjectPath` instead of
/// `&str`.
fn matches(&self, path: &str) -> bool {
self.source.is_match(path)
}
/// Returns the alternate path for the provided path.
/// TODO!: Update to work with more than one capture group?
fn alternate(&self, path: &str) -> String {
// Determine the captures for the path.
if let Some(capture) = self.source.captures_iter(path).next() {
let (_, [name]) = capture.extract();
self.target.replace("{}", name)
} else {
// TODO!: Can't find capture. Is this a regex without capture group?
String::new()
}
}
}
actions!(
vim,
[
@@ -86,3 +130,32 @@ impl Vim {
});
}
}
#[cfg(test)]
mod tests {
use super::Projection;
use gpui::TestAppContext;
#[gpui::test]
async fn test_matches(_cx: &mut TestAppContext) {
let source = "lib/app/*.ex";
let target = "test/app/{}_test.exs";
let projection = Projection::new(source, target);
let path = "lib/app/module.ex";
assert_eq!(projection.matches(path), true);
let path = "test/app/module_test.exs";
assert_eq!(projection.matches(path), false);
}
#[gpui::test]
async fn test_alternate(_cx: &mut TestAppContext) {
let source = "lib/app/*.ex";
let target = "test/app/{}_test.exs";
let projection = Projection::new(source, target);
let path = "lib/app/module.ex";
assert_eq!(projection.alternate(path), "test/app/module_test.exs");
}
}