-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ls: fix issue #6697 (different "ls -lF --dired" from GNU) #6699
Open
kkkykin
wants to merge
5
commits into
uutils:main
Choose a base branch
from
kkkykin:fix-ls-dired-position
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
09f8c93
ls: fix issue #6697 (different "ls -lF --dired" from GNU)
kkkykin f0618b9
style format
kkkykin e84016f
ls: test --dired with --classify format
kkkykin 8b133c8
Merge branch 'uutils:main' into fix-ls-dired-position
kkkykin 0d10b02
rename variable for readability; add new test
kkkykin File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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. | ||
|
@@ -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) | ||
} | ||
} | ||
|
||
|
@@ -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, | ||
dfn_len: usize, | ||
) -> (usize, usize) { | ||
end_line_len: usize, | ||
end_filename_len: 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 + end_line_len; | ||
let end_filename = start + end_filename_len; | ||
(start, end, end_filename) | ||
} | ||
|
||
pub fn indent(out: &mut BufWriter<Stdout>) -> UResult<()> { | ||
|
@@ -100,7 +104,11 @@ 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 }); | ||
dired.subdired_positions.push(BytePosition { | ||
start, | ||
end, | ||
end_filename: end, | ||
}); | ||
} | ||
|
||
/// Prints the dired output based on the given configuration and dired structure. | ||
|
@@ -153,7 +161,8 @@ pub fn add_dir_name(dired: &mut DiredOutput, dir_len: usize) { | |
pub fn calculate_and_update_positions( | ||
dired: &mut DiredOutput, | ||
output_display_len: usize, | ||
dfn_len: usize, | ||
end_line_len: usize, | ||
end_filename_len: usize, | ||
) { | ||
let offset = dired | ||
.dired_positions | ||
|
@@ -162,17 +171,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 + end_line_len; | ||
let end_filename = start + end_filename_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 | ||
|
@@ -195,29 +206,87 @@ mod tests { | |
fn test_calculate_dired() { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. please add a new tests which shows when end and end_filename are different ? |
||
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 dired_positions = vec![BytePosition { | ||
start: 5, | ||
end: 10, | ||
end_filename: 10, | ||
}]; | ||
let (start, end, end_filename) = | ||
calculate_dired(&dired_positions, output_display.len(), dfn.len(), dfn.len()); | ||
|
||
assert_eq!(start, 24); | ||
assert_eq!(end, 35); | ||
assert_eq!(end_filename, 35); | ||
} | ||
|
||
#[test] | ||
fn test_calculate_dired_end_line_diff_end_filename() { | ||
// test when we have | ||
// ls -lF | ||
|
||
// total 0 | ||
// lrwxrwxrwx 1 somebody somegroup 0 Sep 15 22:29 aaa@ -> d:\test\dir\aaa | ||
// drwxrwxrwx 1 somebody somegroup 0 Sep 15 22:29 dir/ | ||
let output_display = "sample_output".to_string(); | ||
let end_line = "aaa@ -> d:\\test\\dir\\aaa".to_string(); | ||
let end_filename = "aaa".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(), | ||
end_line.len(), | ||
end_filename.len(), | ||
); | ||
|
||
assert_eq!(start, 24); | ||
assert_eq!(end, 47); | ||
assert_eq!(end_filename, 27); | ||
} | ||
|
||
#[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, | ||
|
@@ -226,17 +295,33 @@ 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, | ||
|
@@ -247,9 +332,21 @@ 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 : | ||
|
@@ -262,9 +359,21 @@ 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, | ||
|
@@ -285,9 +394,21 @@ 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, | ||
|
@@ -305,19 +426,23 @@ 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); | ||
|
@@ -327,23 +452,57 @@ 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 dfn_len = 5; | ||
calculate_and_update_positions(&mut dired, output_display_len, dfn_len); | ||
let end_line_len = 5; | ||
let end_filename_len = 5; | ||
calculate_and_update_positions( | ||
&mut dired, | ||
output_display_len, | ||
end_line_len, | ||
end_filename_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); | ||
|
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it is not a big deal because --dired isn't used a lot but we are storing extra data every time even this case happens rarely
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know this solution might be a bit silly, but I'm not good at programming.
It seems like 'end_line' is only used to calculate the offset for the next line, so it should be fine to just store 'end_filename' maybe.
I'll try to optimize it. :)