ensure .. and . parse as atoms

This commit is contained in:
Jana Dönszelmann 2026-04-03 15:56:52 +02:00
parent fdfc08e88b
commit bed1d5b38b
No known key found for this signature in database
2 changed files with 161 additions and 30 deletions

View file

@ -130,12 +130,14 @@ impl<'a> FileName<'a> {
}
}
let (new_segment, ext_excluding_dot) =
if let Some((segment, ext_excluding_dot)) = rsplit(segment.segment.clone(), '.') {
(segment, Some(ext_excluding_dot))
} else {
(segment.segment, None)
};
let (new_segment, ext_excluding_dot) = if let Some((segment, ext_excluding_dot)) =
rsplit(segment.segment.clone(), '.')
&& !ext_excluding_dot.is_empty()
{
(segment, Some(ext_excluding_dot))
} else {
(segment.segment, None)
};
Self {
leading_separator: segment.leading_separator,
@ -219,6 +221,13 @@ impl<'a> Path<'a> {
}
})
.verify(|i| {
// just ".." isn't valid
if i.segments.is_empty()
&& (i.filename.segment == ".." || i.filename.segment == ".")
{
return false;
}
!i.segments.is_empty()
|| i.filename.ext_excluding_dot.is_some()
|| !matches!(i.filename.leading_separator, PathSep::None)
@ -418,6 +427,152 @@ mod tests {
parse_input(input).unwrap()
}
#[test]
fn parse_twodots() {
assert_debug_snapshot!(parse(r#".."#), @r#"
Segments {
segments: [
Segment {
leading_space: Space(
"",
),
token: Atom(
Text(
"..",
),
),
},
],
trailing_space: Space(
"",
),
}
"#);
}
#[test]
fn parse_dot() {
assert_debug_snapshot!(parse(r#"."#), @r#"
Segments {
segments: [
Segment {
leading_space: Space(
"",
),
token: Atom(
Text(
".",
),
),
},
],
trailing_space: Space(
"",
),
}
"#);
}
#[test]
fn parse_parent() {
assert_debug_snapshot!(parse_path_only(r#"../foo.rs"#), @r#"
Path {
drive_excluding_colon: None,
segments: [
PathSegment {
leading_separator: None,
segment: "..",
},
],
filename: FileName {
leading_separator: Slash,
segment: "foo",
ext_excluding_dot: Some(
"rs",
),
location: None,
},
}
"#);
}
#[test]
fn parse_cwd() {
assert_debug_snapshot!(parse_path_only(r#"./foo.rs"#), @r#"
Path {
drive_excluding_colon: None,
segments: [
PathSegment {
leading_separator: None,
segment: ".",
},
],
filename: FileName {
leading_separator: Slash,
segment: "foo",
ext_excluding_dot: Some(
"rs",
),
location: None,
},
}
"#);
}
#[test]
fn parse_cwd_in_path() {
assert_debug_snapshot!(parse_path_only(r#"foo/./foo.rs"#), @r#"
Path {
drive_excluding_colon: None,
segments: [
PathSegment {
leading_separator: None,
segment: "foo",
},
PathSegment {
leading_separator: Slash,
segment: ".",
},
],
filename: FileName {
leading_separator: Slash,
segment: "foo",
ext_excluding_dot: Some(
"rs",
),
location: None,
},
}
"#);
}
#[test]
fn parse_parent_in_path() {
assert_debug_snapshot!(parse_path_only(r#"foo/../foo.rs"#), @r#"
Path {
drive_excluding_colon: None,
segments: [
PathSegment {
leading_separator: None,
segment: "foo",
},
PathSegment {
leading_separator: Slash,
segment: "..",
},
],
filename: FileName {
leading_separator: Slash,
segment: "foo",
ext_excluding_dot: Some(
"rs",
),
location: None,
},
}
"#);
}
#[test]
fn parse_path() {
assert_debug_snapshot!(parse_path_only(r#"tests/ui/impl-trait/unsized_coercion.rs"#), @r#"

View file

@ -699,30 +699,6 @@ impl Widget for &mut App {
FieldTree::new(lv, footer_focused)
.styled_mut(&styles)
.render(footer_area, buf);
// let items = lv.footer_fields();
// lv.last_fields_offset = footer_area.y as usize;
// lv.last_fields_height = items.len();
//
// let width = 20;
// let builder = ListBuilder::new(|cx| {
// let Some((k, v)) = &items.get(cx.index) else {
// return (Paragraph::new(""), 1);
// };
//
// let mut res =
// Paragraph::new(format!("{k:width$} {v}")).wrap(Wrap { trim: false });
//
// if cx.is_selected {
// res = res.style(styles.highlighted);
// }
//
// let height = res.line_count(footer_area.width) as u16;
// (res, height)
// });
//
// let list = ListView::new(builder, items.len()).style(styles.default);
// StatefulWidget::render(list, footer_area, buf, &mut lv.footer_list);
}
Tab::Empty => {}
Tab::Help => {