Skip to content
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

Add path-separator option. #429

Merged
merged 8 commits into from
Sep 15, 2019
Merged

Add path-separator option. #429

merged 8 commits into from
Sep 15, 2019

Conversation

mookid
Copy link
Contributor

@mookid mookid commented Apr 10, 2019

Example usage: fd.exe --path-separator / on windows.

  • add tests
  • measure performance impact without path-separator option
  • measure performance impact with path-separator option

benchmarks

Average over 15 runs (with warm cache), using the command fd . %userprofile% (full results):

  feature, sep=default feature, sep='=' master
avg 5942.6667 6363.6000 5885.4000
std 105.8730 109.2185 115.7299
std / avg 0.0178 0.0172 0.0197
       
compared to master 1.01 1.08 1.00

without changing the separator, the change does not impact performance; when changing it, it seems to be ~8% slower.

see #428

Example usage: `fd.exe --path-separator /` on windows.
Copy link
Owner

@sharkdp sharkdp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you very much for your contribution!

A few general comments (in addition to the inline comments):

  • Printing paths is not the only place where we deal with paths. We should search the whole code base for std::path::MAIN_SEPARATOR and see if something needs to be done.
  • I would like to see a few tests that check that everything works as expected.
  • We should also perform some benchmarks to see that this does not have any impact on performance (if --path-separator is not used) and to check by how performance degrades when -path-separator is used.

src/app.rs Outdated
arg("path-separator")
.takes_value(true)
.long("path-separator")
.number_of_values(1),
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this needed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Honestly, I don't really know what I am doing here; I am inexperienced with clap and tried to find something that works ok.

src/app.rs Show resolved Hide resolved
src/app.rs Show resolved Hide resolved
src/app.rs Outdated
doc!(h, "path-separator"
, "Set the path separator to use when printing file paths."
, "Set the path separator to use when printing file paths. \
A path separator is limited to a single byte.");
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe "limited to a single character" would be better for users that don't immediately associated 1 byte with 1 character. I know that it's probably not quite correct technically (multi-byte characters).

That makes me wonder: why not allow for general Unicode characters? I would change u8 to char and change the help text to:

Set the path separator to use when printing file paths.
The separator must be a single character like '/' or '\'.

@@ -75,4 +75,7 @@ pub struct FdOptions {

/// Whether or not to display filesystem errors
pub show_filesystem_errors: bool,

/// The separator used to print file paths.
pub path_separator: Option<u8>,
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not char (see above)

src/main.rs Outdated
@@ -113,6 +113,20 @@ fn main() {
_ => atty::is(Stream::Stdout),
};

let path_separator: Option<u8> = match matches.value_of("path-separator") {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the type annotation needed here?

src/main.rs Outdated
let sep = sep_str.as_bytes();
if sep.len() != 1 {
print_error_and_exit!(
"'{}' is not a valid path separator. See 'fd --help'.",
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of referring to the help text, maybe just say explicitly what the problem is: "The argument to --path-separator must be a single character".

src/main.rs Outdated
}
Some(sep[0])
}
None => None,
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, I think that case can not happen (since you require --path-separator to have a value). If this is the case, I think you can simply unwrap the Option:

matches.value_of("path-separator").except("path-separator")

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I confirm that not passing the argument triggers the None case.

src/output.rs Outdated

match config.path_separator {
None => write!(stdout, "{}", style.paint(path_string))?,
Some(sep) => {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A couple of things:

  • This should probably be in a separate function
  • I don't think this is the best way to solve this (convert to byte vector, loop over vector, convert to string). Why not use a string-replacement function?
  • Instead of checking for cfg!(windows), this code should replace std::path::MAIN_SEPARATOR with config.path_separator. Otherwise, on Windows, you would replace both / and \ with the new separator.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we are to use a string replacement, we can also handle any string replacement; it would make the code simpler. Do you have anything against it?

@mookid
Copy link
Contributor Author

mookid commented Apr 12, 2019

Printing paths is not the only place where we deal with paths. We should search the whole code base for std::path::MAIN_SEPARATOR and see if something needs to be done.

I am a bit confused: this PR deals only with the presentation logic, that is why the changes are bound to output.rs + command line arguments.

As far as I can tell the rest of the logic has no issue on windows.

@mookid
Copy link
Contributor Author

mookid commented Apr 14, 2019

@sharkdp I think I addressed most points. Tell me if you think anything should be added.

@mookid
Copy link
Contributor Author

mookid commented Apr 26, 2019

re @sharkdp

do you think that anything prevents merging?

@mookid
Copy link
Contributor Author

mookid commented Sep 2, 2019

ping!

Copy link
Owner

@sharkdp sharkdp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you very much!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants