Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 48 additions & 2 deletions src/handlers/grep.rs
Original file line number Diff line number Diff line change
Expand Up @@ -473,6 +473,7 @@ enum GrepLineRegex {
WithFileExtensionAndLineNumber,
WithFileExtension,
WithFileExtensionNoSpaces,
WithoutFileExtensionColonSeparated,
WithoutSeparatorCharacters,
}

Expand All @@ -496,6 +497,11 @@ lazy_static! {
make_grep_line_regex(GrepLineRegex::WithFileExtension);
}

lazy_static! {
static ref GREP_LINE_REGEX_ASSUMING_NO_FILE_EXTENSION_COLON_SEPARATED: Regex =
make_grep_line_regex(GrepLineRegex::WithoutFileExtensionColonSeparated);
}

lazy_static! {
static ref GREP_LINE_REGEX_ASSUMING_NO_INTERNAL_SEPARATOR_CHARS: Regex =
make_grep_line_regex(GrepLineRegex::WithoutSeparatorCharacters);
Expand Down Expand Up @@ -553,6 +559,15 @@ fn make_grep_line_regex(regex_variant: GrepLineRegex) -> Regex {
)
"
}
GrepLineRegex::WithoutFileExtensionColonSeparated => {
r"
( # 1. file name (colons not allowed)
[^:|\ ] # try to be strict about what a file path can start with
[^:]* # anything except a colon
[^:\ ] # a file name cannot end with whitespace
)
"
}
GrepLineRegex::WithoutSeparatorCharacters => {
r"
( # 1. file name (colons not allowed)
Expand Down Expand Up @@ -673,6 +688,7 @@ pub fn parse_grep_line(line: &str) -> Option<GrepLine<'_>> {
&*GREP_LINE_REGEX_ASSUMING_FILE_EXTENSION_AND_LINE_NUMBER,
&*GREP_LINE_REGEX_ASSUMING_FILE_EXTENSION_NO_SPACES,
&*GREP_LINE_REGEX_ASSUMING_FILE_EXTENSION,
&*GREP_LINE_REGEX_ASSUMING_NO_FILE_EXTENSION_COLON_SEPARATED,
&*GREP_LINE_REGEX_ASSUMING_NO_INTERNAL_SEPARATOR_CHARS,
]
.iter()
Expand Down Expand Up @@ -906,10 +922,8 @@ mod tests {
}

#[test]
#[ignore]
fn test_parse_grep_n_match_file_name_with_dashes_and_no_extension() {
// git grep -n
// This fails: we can't parse it currently.
let fake_parent_grep_command =
"/usr/local/bin/git --doesnt-matter grep --nor-this nor_this -- nor_this";
let _args = FakeParentArgs::once(fake_parent_grep_command);
Expand All @@ -927,6 +941,38 @@ mod tests {
);
}

#[test]
fn test_parse_grep_match_file_name_with_dashes_and_no_extension() {
// git grep (no line number); the file name contains a hyphen and has no extension
let fake_parent_grep_command =
"/usr/local/bin/git --doesnt-matter grep --nor-this nor_this -- nor_this";
let _args = FakeParentArgs::for_scope(fake_parent_grep_command);

assert_eq!(
parse_grep_line("foo-bar:content"),
Some(GrepLine {
grep_type: GrepType::Classic,
path: "foo-bar".into(),
line_number: None,
line_type: LineType::Match,
code: "content".into(),
submatches: None,
})
);

assert_eq!(
parse_grep_line("etc/119-within-line-edits:repo=$(mktemp -d)"),
Some(GrepLine {
grep_type: GrepType::Classic,
path: "etc/119-within-line-edits".into(),
line_number: None,
line_type: LineType::Match,
code: "repo=$(mktemp -d)".into(),
submatches: None,
})
);
}

#[test]
fn test_parse_grep_n_match_directory_name_with_dashes() {
let fake_parent_grep_command =
Expand Down