type/command: implement optimisation for --all

This was present in the C++ version for command, though never for type.

Checking over all elements of PATH can be slow on some platforms eg
WSL2, so only do that when used with `--all`.

Based on discussion in
https://github.com/fish-shell/fish-shell/pull/9856
This commit is contained in:
David Adam 2023-06-30 05:39:03 +08:00
parent 14cfd268d8
commit ce9f95128a
2 changed files with 19 additions and 8 deletions

View File

@ -5,8 +5,8 @@ use crate::builtins::shared::{
STATUS_CMD_OK, STATUS_CMD_UNKNOWN, STATUS_INVALID_ARGS, STATUS_CMD_OK, STATUS_CMD_UNKNOWN, STATUS_INVALID_ARGS,
}; };
use crate::ffi::parser_t; use crate::ffi::parser_t;
use crate::path::path_get_paths; use crate::path::{path_get_path, path_get_paths};
use crate::wchar::{wstr, WString, L}; use crate::wchar::{wstr, L};
use crate::wgetopt::{wgetopter_t, wopt, woption, woption_argument_t}; use crate::wgetopt::{wgetopter_t, wopt, woption, woption_argument_t};
use crate::wutil::sprintf; use crate::wutil::sprintf;
@ -71,10 +71,14 @@ pub fn r#command(
let mut res = false; let mut res = false;
let optind = w.woptind; let optind = w.woptind;
for arg in argv.iter().take(argc).skip(optind) { for arg in argv.iter().take(argc).skip(optind) {
// TODO: This always gets all paths, and then skips a bunch. let paths = if opts.all {
// For the common case, we want to get just the one path. path_get_paths(arg, &*parser.get_vars())
// Port this over once path.cpp is. } else {
let paths: Vec<WString> = path_get_paths(arg, &*parser.get_vars()); match path_get_path(arg, &*parser.get_vars()) {
Some(p) => vec![p],
None => vec![],
}
};
for path in paths.iter() { for path in paths.iter() {
res = true; res = true;

View File

@ -14,7 +14,7 @@ use crate::ffi::{
function_get_definition_file, function_get_definition_lineno, function_get_props_autoload, function_get_definition_file, function_get_definition_lineno, function_get_props_autoload,
function_is_copy, function_is_copy,
}; };
use crate::path::path_get_paths; use crate::path::{path_get_path, path_get_paths};
use crate::wchar::{wstr, WString, L}; use crate::wchar::{wstr, WString, L};
use crate::wchar_ffi::WCharFromFFI; use crate::wchar_ffi::WCharFromFFI;
use crate::wchar_ffi::WCharToFFI; use crate::wchar_ffi::WCharToFFI;
@ -190,7 +190,14 @@ pub fn r#type(
} }
} }
let paths: Vec<WString> = path_get_paths(arg, &*parser.get_vars()); let paths = if opts.all {
path_get_paths(arg, &*parser.get_vars())
} else {
match path_get_path(arg, &*parser.get_vars()) {
Some(p) => vec![p],
None => vec![],
}
};
for path in paths.iter() { for path in paths.iter() {
found += 1; found += 1;