mirror of
https://github.com/nushell/nushell.git
synced 2025-07-07 10:01:26 +02:00
allow multiple extensions (#10593)
<!-- if this PR closes one or more issues, you can automatically link the PR with them by using one of the [*linking keywords*](https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue#linking-a-pull-request-to-an-issue-using-a-keyword), e.g. - this PR should close #xxxx - fixes #xxxx you can also mention related issues, PRs or discussions! --> # Description <!-- Thank you for improving Nushell. Please, check our [contributing guide](../CONTRIBUTING.md) and talk to the core team before making major changes. Description of your pull request goes here. **Provide examples and/or screenshots** if your changes affect the user experience. --> This PR allows `open` to handle files with multiple extensions; i.e it will try to call `from tar.gz`, `from gz` when calling ```nu open file.tar.gz ``` # User-Facing Changes <!-- List of all changes that impact the user experience here. This helps us keep track of breaking changes. --> No breaking changes.
This commit is contained in:
@ -171,36 +171,35 @@ impl Command for Open {
|
||||
metadata: None,
|
||||
trim_end_newline: false,
|
||||
};
|
||||
let ext = if raw {
|
||||
let exts_opt: Option<Vec<String>> = if raw {
|
||||
None
|
||||
} else {
|
||||
path.extension()
|
||||
.map(|name| name.to_string_lossy().to_string().to_lowercase())
|
||||
let path_str = path
|
||||
.file_name()
|
||||
.unwrap_or(std::ffi::OsStr::new(path))
|
||||
.to_string_lossy()
|
||||
.to_lowercase();
|
||||
Some(extract_extensions(path_str.as_str()))
|
||||
};
|
||||
|
||||
if let Some(ext) = ext {
|
||||
match engine_state.find_decl(format!("from {ext}").as_bytes(), &[]) {
|
||||
Some(converter_id) => {
|
||||
let decl = engine_state.get_decl(converter_id);
|
||||
let command_output = if let Some(block_id) = decl.get_block_id() {
|
||||
let block = engine_state.get_block(block_id);
|
||||
eval_block(
|
||||
engine_state,
|
||||
stack,
|
||||
block,
|
||||
file_contents,
|
||||
false,
|
||||
false,
|
||||
)
|
||||
} else {
|
||||
decl.run(
|
||||
engine_state,
|
||||
stack,
|
||||
&Call::new(call_span),
|
||||
file_contents,
|
||||
)
|
||||
};
|
||||
output.push(command_output.map_err(|inner| {
|
||||
let converter = exts_opt.and_then(|exts| {
|
||||
exts.iter().find_map(|ext| {
|
||||
engine_state
|
||||
.find_decl(format!("from {}", ext).as_bytes(), &[])
|
||||
.map(|id| (id, ext.to_string()))
|
||||
})
|
||||
});
|
||||
|
||||
match converter {
|
||||
Some((converter_id, ext)) => {
|
||||
let decl = engine_state.get_decl(converter_id);
|
||||
let command_output = if let Some(block_id) = decl.get_block_id() {
|
||||
let block = engine_state.get_block(block_id);
|
||||
eval_block(engine_state, stack, block, file_contents, false, false)
|
||||
} else {
|
||||
decl.run(engine_state, stack, &Call::new(call_span), file_contents)
|
||||
};
|
||||
output.push(command_output.map_err(|inner| {
|
||||
ShellError::GenericError(
|
||||
format!("Error while parsing as {ext}"),
|
||||
format!("Could not parse '{}' with `from {}`", path.display(), ext),
|
||||
@ -209,11 +208,8 @@ impl Command for Open {
|
||||
vec![inner],
|
||||
)
|
||||
})?);
|
||||
}
|
||||
None => output.push(file_contents),
|
||||
}
|
||||
} else {
|
||||
output.push(file_contents)
|
||||
None => output.push(file_contents),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -265,3 +261,23 @@ fn permission_denied(dir: impl AsRef<Path>) -> bool {
|
||||
Ok(_) => false,
|
||||
}
|
||||
}
|
||||
|
||||
fn extract_extensions(filename: &str) -> Vec<String> {
|
||||
let parts: Vec<&str> = filename.split('.').collect();
|
||||
let mut extensions: Vec<String> = Vec::new();
|
||||
let mut current_extension = String::new();
|
||||
|
||||
for part in parts.iter().rev() {
|
||||
if current_extension.is_empty() {
|
||||
current_extension.push_str(part);
|
||||
} else {
|
||||
current_extension = format!("{}.{}", part, current_extension);
|
||||
}
|
||||
extensions.push(current_extension.clone());
|
||||
}
|
||||
|
||||
extensions.pop();
|
||||
extensions.reverse();
|
||||
|
||||
extensions
|
||||
}
|
||||
|
Reference in New Issue
Block a user