Skip to content

Commit

Permalink
ls: fix issue uutils#6697 (different "ls -lF --dired" from GNU)
Browse files Browse the repository at this point in the history
  • Loading branch information
kkkykin committed Sep 16, 2024
1 parent a275080 commit 09f8c93
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 43 deletions.
93 changes: 52 additions & 41 deletions src/uu/ls/src/dired.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,9 @@ use uucore::error::UResult;
#[derive(Debug, Clone, PartialEq)]
pub struct BytePosition {
pub start: usize,
// this is end of line
pub end: usize,
pub end_filename: usize,
}

/// Represents the output structure for DIRED, containing positions for both DIRED and SUBDIRED.
Expand All @@ -55,7 +57,7 @@ pub struct DiredOutput {

impl fmt::Display for BytePosition {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{} {}", self.start, self.end)
write!(f, "{} {}", self.start, self.end_filename)
}
}

Expand All @@ -74,13 +76,15 @@ fn get_offset_from_previous_line(dired_positions: &[BytePosition]) -> usize {
pub fn calculate_dired(
dired_positions: &[BytePosition],
output_display_len: usize,
dfl_len: usize,
dfn_len: usize,
) -> (usize, usize) {
) -> (usize, usize, usize) {
let offset_from_previous_line = get_offset_from_previous_line(dired_positions);

let start = output_display_len + offset_from_previous_line;
let end = start + dfn_len;
(start, end)
let end = start + dfl_len;
let end_filename = start + dfn_len;
(start, end, end_filename)
}

pub fn indent(out: &mut BufWriter<Stdout>) -> UResult<()> {
Expand All @@ -100,7 +104,8 @@ pub fn calculate_subdired(dired: &mut DiredOutput, path_len: usize) {

let start = offset_from_previous_line + DIRED_TRAILING_OFFSET + additional_offset;
let end = start + path_len;
dired.subdired_positions.push(BytePosition { start, end });
let end_filename = end;
dired.subdired_positions.push(BytePosition { start, end, end_filename});
}

/// Prints the dired output based on the given configuration and dired structure.
Expand Down Expand Up @@ -153,6 +158,7 @@ pub fn add_dir_name(dired: &mut DiredOutput, dir_len: usize) {
pub fn calculate_and_update_positions(
dired: &mut DiredOutput,
output_display_len: usize,
dfl_len: usize,
dfn_len: usize,
) {
let offset = dired
Expand All @@ -162,17 +168,19 @@ pub fn calculate_and_update_positions(
last_position.start + DIRED_TRAILING_OFFSET
});
let start = output_display_len + offset + DIRED_TRAILING_OFFSET;
let end = start + dfn_len;
update_positions(dired, start, end);
let end = start + dfl_len;
let end_filename = start + dfn_len;
update_positions(dired, start, end, end_filename);
}

/// Updates the dired positions based on the given start and end positions.
/// update when it is the first element in the list (to manage "total X")
/// insert when it isn't the about total
pub fn update_positions(dired: &mut DiredOutput, start: usize, end: usize) {
pub fn update_positions(dired: &mut DiredOutput, start: usize, end: usize, end_filename: usize) {
// padding can be 0 but as it doesn't matter
dired.dired_positions.push(BytePosition {
start: start + dired.padding,
end_filename: end_filename + dired.padding,
end: end + dired.padding,
});
// Remove the previous padding
Expand All @@ -195,29 +203,31 @@ mod tests {
fn test_calculate_dired() {
let output_display = "sample_output".to_string();
let dfn = "sample_file".to_string();
let dired_positions = vec![BytePosition { start: 5, end: 10 }];
let (start, end) = calculate_dired(&dired_positions, output_display.len(), dfn.len());
let dfl = "sample_file@ -> /home/foo/baa.txt".to_string();
let dired_positions = vec![BytePosition { start: 5, end: 10, end_filename: 10 }];
let (start, end, end_filename) = calculate_dired(&dired_positions, output_display.len(), dfl.len(), dfn.len());

assert_eq!(start, 24);
assert_eq!(end, 35);
assert_eq!(end, 57);
assert_eq!(end_filename, 35);
}

#[test]
fn test_get_offset_from_previous_line() {
let positions = vec![
BytePosition { start: 0, end: 3 },
BytePosition { start: 4, end: 7 },
BytePosition { start: 8, end: 11 },
BytePosition { start: 0, end: 3, end_filename: 3 },
BytePosition { start: 4, end: 7, end_filename: 7 },
BytePosition { start: 8, end: 11, end_filename: 11 },
];
assert_eq!(get_offset_from_previous_line(&positions), 12);
}
#[test]
fn test_calculate_subdired() {
let mut dired = DiredOutput {
dired_positions: vec![
BytePosition { start: 0, end: 3 },
BytePosition { start: 4, end: 7 },
BytePosition { start: 8, end: 11 },
BytePosition { start: 0, end: 3, end_filename: 3 },
BytePosition { start: 4, end: 7, end_filename: 7 },
BytePosition { start: 8, end: 11, end_filename: 11 },
],
subdired_positions: vec![],
padding: 0,
Expand All @@ -226,17 +236,17 @@ mod tests {
calculate_subdired(&mut dired, path_len);
assert_eq!(
dired.subdired_positions,
vec![BytePosition { start: 14, end: 19 }],
vec![BytePosition { start: 14, end: 19, end_filename: 19 }],
);
}

#[test]
fn test_add_dir_name() {
let mut dired = DiredOutput {
dired_positions: vec![
BytePosition { start: 0, end: 3 },
BytePosition { start: 4, end: 7 },
BytePosition { start: 8, end: 11 },
BytePosition { start: 0, end: 3, end_filename: 3 },
BytePosition { start: 4, end: 7, end_filename: 7 },
BytePosition { start: 8, end: 11, end_filename: 11 },
],
subdired_positions: vec![],
padding: 0,
Expand All @@ -247,9 +257,9 @@ mod tests {
dired,
DiredOutput {
dired_positions: vec![
BytePosition { start: 0, end: 3 },
BytePosition { start: 4, end: 7 },
BytePosition { start: 8, end: 11 },
BytePosition { start: 0, end: 3, end_filename: 3 },
BytePosition { start: 4, end: 7, end_filename: 7 },
BytePosition { start: 8, end: 11, end_filename: 11 },
],
subdired_positions: vec![],
// 8 = 1 for the \n + 5 for dir_len + 2 for " " + 1 for :
Expand All @@ -262,9 +272,9 @@ mod tests {
fn test_add_total() {
let mut dired = DiredOutput {
dired_positions: vec![
BytePosition { start: 0, end: 3 },
BytePosition { start: 4, end: 7 },
BytePosition { start: 8, end: 11 },
BytePosition { start: 0, end: 3, end_filename: 3 },
BytePosition { start: 4, end: 7, end_filename: 7 },
BytePosition { start: 8, end: 11, end_filename: 11 },
],
subdired_positions: vec![],
padding: 0,
Expand All @@ -285,9 +295,9 @@ mod tests {

let mut dired = DiredOutput {
dired_positions: vec![
BytePosition { start: 0, end: 3 },
BytePosition { start: 4, end: 7 },
BytePosition { start: 8, end: 11 },
BytePosition { start: 0, end: 3, end_filename: 3 },
BytePosition { start: 4, end: 7, end_filename: 7 },
BytePosition { start: 8, end: 11, end_filename: 11 },
],
subdired_positions: vec![],
padding: 0,
Expand All @@ -305,19 +315,19 @@ mod tests {
#[test]
fn test_dired_update_positions() {
let mut dired = DiredOutput {
dired_positions: vec![BytePosition { start: 5, end: 10 }],
dired_positions: vec![BytePosition { start: 5, end: 10, end_filename: 10 }],
subdired_positions: vec![],
padding: 10,
};

// Test with adjust = true
update_positions(&mut dired, 15, 20);
update_positions(&mut dired, 15, 20, 20);
let last_position = dired.dired_positions.last().unwrap();
assert_eq!(last_position.start, 25); // 15 + 10 (end of the previous position)
assert_eq!(last_position.end, 30); // 20 + 10 (end of the previous position)

// Test with adjust = false
update_positions(&mut dired, 30, 35);
update_positions(&mut dired, 30, 35, 35);
let last_position = dired.dired_positions.last().unwrap();
assert_eq!(last_position.start, 30);
assert_eq!(last_position.end, 35);
Expand All @@ -327,23 +337,24 @@ mod tests {
fn test_calculate_and_update_positions() {
let mut dired = DiredOutput {
dired_positions: vec![
BytePosition { start: 0, end: 3 },
BytePosition { start: 4, end: 7 },
BytePosition { start: 8, end: 11 },
BytePosition { start: 0, end: 3, end_filename: 3 },
BytePosition { start: 4, end: 7, end_filename: 7 },
BytePosition { start: 8, end: 11, end_filename: 11 },
],
subdired_positions: vec![],
padding: 5,
};
let output_display_len = 15;
let dfl_len = 5;
let dfn_len = 5;
calculate_and_update_positions(&mut dired, output_display_len, dfn_len);
calculate_and_update_positions(&mut dired, output_display_len, dfl_len, dfn_len);
assert_eq!(
dired.dired_positions,
vec![
BytePosition { start: 0, end: 3 },
BytePosition { start: 4, end: 7 },
BytePosition { start: 8, end: 11 },
BytePosition { start: 32, end: 37 },
BytePosition { start: 0, end: 3, end_filename: 3 },
BytePosition { start: 4, end: 7, end_filename: 7 },
BytePosition { start: 8, end: 11, end_filename: 11 },
BytePosition { start: 32, end: 37, end_filename: 37 },
]
);
assert_eq!(dired.padding, 0);
Expand Down
6 changes: 4 additions & 2 deletions src/uu/ls/src/ls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2861,12 +2861,13 @@ fn display_item_long(
};

if config.dired {
let (start, end) = dired::calculate_dired(
let (start, end, end_filename) = dired::calculate_dired(
&dired.dired_positions,
output_display.len(),
displayed_item.len(),
item.display_name.len(),
);
dired::update_positions(dired, start, end);
dired::update_positions(dired, start, end, end_filename);
}
write!(output_display, "{}{}", displayed_item, config.line_ending).unwrap();
} else {
Expand Down Expand Up @@ -2965,6 +2966,7 @@ fn display_item_long(
dired,
output_display.len(),
displayed_item.trim().len(),
item.display_name.len(),
);
}
write!(output_display, "{}{}", displayed_item, config.line_ending).unwrap();
Expand Down

0 comments on commit 09f8c93

Please sign in to comment.