Rewrite which (#1144)

* Detect built-in commands passed as args to `which`

This expands the built-in `which` command to detect nushell commands
that may have the same name as a binary in the path.

* Allow which to interpret multiple arguments

Previously, it would discard any argument besides the first. This allows
`which` to process multiple arguments. It also makes the output a stream
of rows.

* Use map to build the output

* Add boolean column for builtins

* Use macros for entry creation shortcuts

* Process command args and use async_stream

In order to use `ichwh`, I'll need to use async_stream. But in order to
avoid lifetime errors with that, I have to process the command args
before using them. I'll admit I don't fully understand what is going on
with the `args.process(...)` function, but it works.

* Use `ichwh` for path searching

This commit transitions from `which` to `ichwh`. The path search is now
done asynchronously.

* Enable the `--all` flag on `which`

* Make `which` respect external commands

Escaped commands passed to wich (e.g., `which "^ls"`), are now searched
before builtins.

* Fix clippy warnings

This commit resolves two warnings from clippy, in light of #1142.

* Update Cargo.lock to get new `ichwh` version

`ichwh@0.2.1` has support for local paths.

* Add documentation for command
This commit is contained in:
Alex van de Sandt 2020-01-01 01:45:27 -05:00 committed by Jonathan Turner
parent 72838cc083
commit b304de8199
4 changed files with 514 additions and 147 deletions

425
Cargo.lock generated
View File

@ -35,9 +35,9 @@ dependencies = [
[[package]]
name = "anyhow"
version = "1.0.25"
version = "1.0.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9267dff192e68f3399525901e709a48c1d3982c9c072fa32f2127a0cb0babf14"
checksum = "7825f6833612eb2414095684fcf6c635becf3ce97fe48cf6421321e93bfbd53c"
[[package]]
name = "app_dirs"
@ -72,6 +72,42 @@ version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8"
[[package]]
name = "async-attributes"
version = "1.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "efd3d156917d94862e779f356c5acae312b08fd3121e792c857d7928c8088423"
dependencies = [
"quote",
"syn",
]
[[package]]
name = "async-std"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0bf6039b315300e057d198b9d3ab92ee029e31c759b7f1afae538145e6f18a3e"
dependencies = [
"async-attributes",
"async-task",
"crossbeam-channel 0.4.0",
"crossbeam-deque",
"crossbeam-utils 0.7.0",
"futures-core",
"futures-io",
"futures-timer 2.0.2",
"kv-log-macro",
"log",
"memchr",
"mio",
"mio-uds",
"num_cpus",
"once_cell",
"pin-project-lite",
"pin-utils",
"slab",
]
[[package]]
name = "async-stream"
version = "0.1.2"
@ -93,6 +129,15 @@ dependencies = [
"syn",
]
[[package]]
name = "async-task"
version = "1.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d22dc86693d375d2733b536fd8914bea0fa93adf4b1e6bcbd9c7c500cb62d920"
dependencies = [
"crossbeam-utils 0.7.0",
]
[[package]]
name = "atty"
version = "0.2.13"
@ -172,7 +217,7 @@ dependencies = [
"num-bigint",
"num-integer",
"num-traits 0.2.10",
"serde 1.0.103",
"serde 1.0.104",
]
[[package]]
@ -182,7 +227,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5753e2a71534719bf3f4e57006c3a4f0d2c672a4b676eec84161f763eca87dbf"
dependencies = [
"byteorder",
"serde 1.0.103",
"serde 1.0.104",
]
[[package]]
@ -222,7 +267,7 @@ dependencies = [
"linked-hash-map 0.5.2",
"md5",
"rand",
"serde 1.0.103",
"serde 1.0.104",
"serde_json",
"time",
]
@ -236,7 +281,7 @@ dependencies = [
"lazy_static 1.4.0",
"memchr",
"regex-automata",
"serde 1.0.103",
"serde 1.0.104",
]
[[package]]
@ -293,7 +338,7 @@ dependencies = [
"encoding_rs",
"log",
"quick-xml",
"serde 1.0.103",
"serde 1.0.104",
"zip",
]
@ -321,7 +366,7 @@ checksum = "31850b4a4d6bae316f7a09e691c944c28299298837edc0a03f755618c23cbc01"
dependencies = [
"num-integer",
"num-traits 0.2.10",
"serde 1.0.103",
"serde 1.0.104",
"time",
]
@ -398,7 +443,7 @@ dependencies = [
"lazy_static 1.4.0",
"nom 4.2.3",
"rust-ini",
"serde 1.0.103",
"serde 1.0.104",
"serde-hjson 0.8.2",
"serde_json",
"toml 0.4.10",
@ -461,6 +506,15 @@ dependencies = [
"crossbeam-utils 0.6.6",
]
[[package]]
name = "crossbeam-channel"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "acec9a3b0b3559f15aee4f90746c4e5e293b701c0f7d3925d24e01645267b68c"
dependencies = [
"crossbeam-utils 0.7.0",
]
[[package]]
name = "crossbeam-deque"
version = "0.7.2"
@ -487,10 +541,11 @@ dependencies = [
[[package]]
name = "crossbeam-queue"
version = "0.2.0"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dfd6515864a82d2f877b42813d4553292c6659498c9a2aa31bab5a15243c2700"
checksum = "c695eeca1e7173472a32221542ae469b3e9aac3a4fc81f7696bcad82029493db"
dependencies = [
"cfg-if",
"crossbeam-utils 0.7.0",
]
@ -623,7 +678,7 @@ dependencies = [
"csv-core",
"itoa",
"ryu",
"serde 1.0.103",
"serde 1.0.104",
]
[[package]]
@ -717,7 +772,7 @@ dependencies = [
"libc",
"ord_subset",
"rustc-serialize",
"serde 1.0.103",
"serde 1.0.104",
]
[[package]]
@ -822,9 +877,9 @@ checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f"
[[package]]
name = "encoding_rs"
version = "0.8.20"
version = "0.8.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87240518927716f79692c2ed85bfe6e98196d18c6401ec75355760233a7e12e9"
checksum = "cd8d03faa7fe0c1431609dfad7bbe827af30f82e1e2ae6f7ee4fca6bd764bc28"
dependencies = [
"cfg-if",
]
@ -868,7 +923,7 @@ version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3beee4bc16478a1b26f2e80ad819a52d24745e292f521a63c16eea5f74b7eb60"
dependencies = [
"serde 1.0.103",
"serde 1.0.104",
]
[[package]]
@ -935,12 +990,43 @@ version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
[[package]]
name = "fuchsia-zircon"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82"
dependencies = [
"bitflags",
"fuchsia-zircon-sys",
]
[[package]]
name = "fuchsia-zircon-sys"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
[[package]]
name = "futures"
version = "0.1.29"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b980f2816d6ee8673b6517b52cb0e808a180efc92e5c19d02cdda79066703ef"
[[package]]
name = "futures"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6f16056ecbb57525ff698bb955162d0cd03bee84e6241c27ff75c08d8ca5987"
dependencies = [
"futures-channel",
"futures-core",
"futures-executor",
"futures-io",
"futures-sink",
"futures-task",
"futures-util",
]
[[package]]
name = "futures-channel"
version = "0.3.1"
@ -948,6 +1034,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fcae98ca17d102fd8a3603727b9259fcf7fa4239b603d2142926189bc8999b86"
dependencies = [
"futures-core",
"futures-sink",
]
[[package]]
@ -972,6 +1059,17 @@ version = "0.3.0-alpha.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b35b6263fb1ef523c3056565fa67b1d16f0a8604ff12b11b08c25f28a734c60a"
[[package]]
name = "futures-executor"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e274736563f686a837a0568b478bdabfeaec2dca794b5649b04e2fe1627c231"
dependencies = [
"futures-core",
"futures-task",
"futures-util",
]
[[package]]
name = "futures-executor-preview"
version = "0.3.0-alpha.19"
@ -983,6 +1081,12 @@ dependencies = [
"num_cpus",
]
[[package]]
name = "futures-io"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e676577d229e70952ab25f3945795ba5b16d63ca794ca9d2c860e5595d20b5ff"
[[package]]
name = "futures-io-preview"
version = "0.3.0-alpha.19"
@ -1015,6 +1119,12 @@ dependencies = [
"futures-util-preview",
]
[[package]]
name = "futures-sink"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "171be33efae63c2d59e6dbba34186fe0d6394fb378069a76dfd80fdcffd43c16"
[[package]]
name = "futures-sink-preview"
version = "0.3.0-alpha.19"
@ -1037,15 +1147,25 @@ dependencies = [
"pin-utils",
]
[[package]]
name = "futures-timer"
version = "2.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1de7508b218029b0f01662ed8f61b1c964b3ae99d6f25462d0f55a595109df6"
[[package]]
name = "futures-util"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c0d66274fb76985d3c62c886d1da7ac4c0903a8c9f754e8fe0f35a6a6cc39e76"
dependencies = [
"futures-channel",
"futures-core",
"futures-io",
"futures-macro",
"futures-sink",
"futures-task",
"memchr",
"pin-utils",
"proc-macro-hack",
"proc-macro-nested",
@ -1058,7 +1178,7 @@ version = "0.3.0-alpha.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ce968633c17e5f97936bd2797b6e38fb56cf16a7422319f7ec2e30d3c470e8d"
dependencies = [
"futures",
"futures 0.1.29",
"futures-channel-preview",
"futures-core-preview",
"futures-io-preview",
@ -1081,9 +1201,9 @@ dependencies = [
[[package]]
name = "gethostname"
version = "0.2.0"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d4ab273ca2a31eb6ca40b15837ccf1aa59a43c5db69ac10c542be342fae2e01d"
checksum = "e692e296bfac1d2533ef168d0b60ff5897b8b70a4009276834014dd8924cc028"
dependencies = [
"libc",
"winapi 0.3.8",
@ -1182,7 +1302,7 @@ dependencies = [
"lazy_static 1.4.0",
"libc",
"mach 0.3.2",
"nix 0.16.0",
"nix 0.16.1",
"pin-utils",
"uom",
"winapi 0.3.8",
@ -1280,7 +1400,7 @@ dependencies = [
"hex 0.4.0",
"libc",
"macaddr",
"nix 0.16.0",
"nix 0.16.1",
]
[[package]]
@ -1345,9 +1465,9 @@ dependencies = [
[[package]]
name = "hermit-abi"
version = "0.1.3"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "307c3c9f937f38e3534b1d6447ecf090cafcc9744e4a6360e8b037b2cf5af120"
checksum = "f629dc602392d3ec14bfc8a09b5e644d7ffd725102b48b81e59f90f2633621d7"
dependencies = [
"libc",
]
@ -1384,6 +1504,18 @@ dependencies = [
"quick-error",
]
[[package]]
name = "ichwh"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2ee706a4af782acda5a05b7641867dd9c93d7f2884f214fbbad009e5752228d1"
dependencies = [
"async-std",
"cfg-if",
"futures 0.3.1",
"thiserror",
]
[[package]]
name = "idna"
version = "0.2.0"
@ -1416,7 +1548,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712d7b3ea5827fcb9d4fda14bf4da5f136f0db2ae9c8f4bd4e2d1c6fde4e6db2"
dependencies = [
"autocfg",
"serde 1.0.103",
"serde 1.0.104",
]
[[package]]
@ -1430,9 +1562,9 @@ dependencies = [
[[package]]
name = "inventory"
version = "0.1.4"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f4cece20baea71d9f3435e7bbe9adf4765f091c5fe404975f844006964a71299"
checksum = "2bf98296081bd2cb540acc09ef9c97f22b7e487841520350293605db1b2c7a27"
dependencies = [
"ctor",
"ghost",
@ -1441,9 +1573,9 @@ dependencies = [
[[package]]
name = "inventory-impl"
version = "0.1.4"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c2869bf972e998977b1cb87e60df70341d48e48dca0823f534feb91ea44adaf9"
checksum = "0a8e30575afe28eea36a9a39136b70b2fb6b0dd0a212a5bd1f30a498395c0274"
dependencies = [
"proc-macro2",
"quote",
@ -1466,7 +1598,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "17b77027f12e53ae59a379f7074259d32eb10867e6183388020e922832d9c3fb"
dependencies = [
"bytes",
"crossbeam-channel",
"crossbeam-channel 0.3.9",
"crossbeam-utils 0.6.6",
"curl",
"curl-sys",
@ -1537,9 +1669,9 @@ dependencies = [
[[package]]
name = "js-sys"
version = "0.3.32"
version = "0.3.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1c840fdb2167497b0bd0db43d6dfe61e91637fa72f9d061f8bd17ddc44ba6414"
checksum = "367647c532db6f1555d7151e619540ec5f713328235b8c062c6b4f63e84adfe3"
dependencies = [
"wasm-bindgen",
]
@ -1554,6 +1686,15 @@ dependencies = [
"winapi-build",
]
[[package]]
name = "kv-log-macro"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8c54d9f465d530a752e6ebdc217e081a7a614b48cb200f6f0aee21ba6bc9aabb"
dependencies = [
"log",
]
[[package]]
name = "language-reporting"
version = "0.4.0"
@ -1564,7 +1705,7 @@ dependencies = [
"itertools 0.7.11",
"log",
"render-tree",
"serde 1.0.103",
"serde 1.0.104",
"serde_derive",
"termcolor",
]
@ -1782,6 +1923,48 @@ dependencies = [
"adler32",
]
[[package]]
name = "mio"
version = "0.6.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "302dec22bcf6bae6dfb69c647187f4b4d0fb6f535521f7bc022430ce8e12008f"
dependencies = [
"cfg-if",
"fuchsia-zircon",
"fuchsia-zircon-sys",
"iovec",
"kernel32-sys",
"libc",
"log",
"miow",
"net2",
"slab",
"winapi 0.2.8",
]
[[package]]
name = "mio-uds"
version = "0.6.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "966257a94e196b11bb43aca423754d87429960a768de9414f3691d6957abf125"
dependencies = [
"iovec",
"libc",
"mio",
]
[[package]]
name = "miow"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919"
dependencies = [
"kernel32-sys",
"net2",
"winapi 0.2.8",
"ws2_32-sys",
]
[[package]]
name = "natural"
version = "0.3.0"
@ -1797,11 +1980,22 @@ dependencies = [
"bincode",
"cfg-if",
"log",
"serde 1.0.103",
"serde 1.0.104",
"serde_derive",
"wasm-bindgen",
]
[[package]]
name = "net2"
version = "0.2.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88"
dependencies = [
"cfg-if",
"libc",
"winapi 0.3.8",
]
[[package]]
name = "nix"
version = "0.14.1"
@ -1830,9 +2024,9 @@ dependencies = [
[[package]]
name = "nix"
version = "0.16.0"
version = "0.16.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "19a8300bf427d432716764070ff70d5b2b7801c958b9049686e6cbd8b06fad92"
checksum = "dd0eaf8df8bab402257e0a5c17a254e4cc1f72a93588a1ddfb5d356c801aa7cb"
dependencies = [
"bitflags",
"cc",
@ -1935,7 +2129,7 @@ dependencies = [
"dirs 2.0.2",
"dunce",
"futures-preview",
"futures-timer",
"futures-timer 1.0.3",
"futures-util",
"futures_codec",
"getset",
@ -1943,6 +2137,7 @@ dependencies = [
"glob",
"heim",
"hex 0.4.0",
"ichwh",
"indexmap",
"itertools 0.8.2",
"language-reporting",
@ -1986,7 +2181,7 @@ dependencies = [
"roxmltree",
"rusqlite",
"rustyline",
"serde 1.0.103",
"serde 1.0.104",
"serde-hjson 0.9.1",
"serde_bytes",
"serde_ini",
@ -2008,7 +2203,6 @@ dependencies = [
"umask",
"unicode-xid",
"url",
"which",
]
[[package]]
@ -2016,7 +2210,7 @@ name = "nu-build"
version = "0.7.0"
dependencies = [
"lazy_static 1.4.0",
"serde 1.0.103",
"serde 1.0.104",
"serde_json",
"toml 0.5.5",
]
@ -2035,7 +2229,7 @@ dependencies = [
"nu-source",
"num-bigint",
"num-traits 0.2.10",
"serde 1.0.103",
"serde 1.0.104",
"serde_json",
"serde_yaml",
"subprocess",
@ -2076,7 +2270,7 @@ dependencies = [
"pretty_assertions",
"pretty_env_logger",
"ptree",
"serde 1.0.103",
"serde 1.0.104",
"shellexpand",
"termcolor",
"unicode-xid",
@ -2093,7 +2287,7 @@ dependencies = [
"nu-source",
"nu-value-ext",
"num-bigint",
"serde 1.0.103",
"serde 1.0.104",
"serde_json",
]
@ -2120,7 +2314,7 @@ dependencies = [
"num-bigint",
"num-traits 0.2.10",
"query_interface",
"serde 1.0.103",
"serde 1.0.104",
"serde_bytes",
"serde_json",
"serde_yaml",
@ -2140,7 +2334,7 @@ dependencies = [
"nom_locate",
"nu-build",
"pretty",
"serde 1.0.103",
"serde 1.0.104",
"termcolor",
]
@ -2258,7 +2452,7 @@ name = "nu_plugin_ps"
version = "0.7.0"
dependencies = [
"futures-preview",
"futures-timer",
"futures-timer 1.0.3",
"futures-util",
"heim",
"nu-build",
@ -2347,7 +2541,7 @@ dependencies = [
"autocfg",
"num-integer",
"num-traits 0.2.10",
"serde 1.0.103",
"serde 1.0.104",
]
[[package]]
@ -2548,6 +2742,12 @@ dependencies = [
"ordermap",
]
[[package]]
name = "pin-project-lite"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0af6cbca0e6e3ce8692ee19fb8d734b641899e07b68eb73e9bbbd32f1703991"
[[package]]
name = "pin-utils"
version = "0.1.0-alpha.4"
@ -2576,7 +2776,7 @@ dependencies = [
"byteorder",
"humantime",
"line-wrap",
"serde 1.0.103",
"serde 1.0.104",
"xml-rs",
]
@ -2693,7 +2893,7 @@ dependencies = [
"directories",
"isatty",
"petgraph",
"serde 1.0.103",
"serde 1.0.104",
"serde-value",
"serde_derive",
"tint",
@ -2713,9 +2913,9 @@ checksum = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0"
[[package]]
name = "quick-xml"
version = "0.17.1"
version = "0.17.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7219717e55033c0c1c2368d6c469baaf10115ffdb54b1e83a8b1e8bfd95cde19"
checksum = "fe1e430bdcf30c9fdc25053b9c459bb1a4672af4617b6c783d7d91dc17c6bbb0"
dependencies = [
"encoding_rs",
"memchr",
@ -2825,9 +3025,9 @@ dependencies = [
[[package]]
name = "rayon"
version = "1.2.1"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "43739f8831493b276363637423d3622d4bd6394ab6f0a9c4a552e208aeb7fddd"
checksum = "db6ce3297f9c85e16621bb8cca38a06779ffc31bb8184e1be4bed2be4678a098"
dependencies = [
"crossbeam-deque",
"either",
@ -2836,9 +3036,9 @@ dependencies = [
[[package]]
name = "rayon-core"
version = "1.6.1"
version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8bf17de6f23b05473c437eb958b9c850bfc8af0961fe17b4cc92d5a627b4791"
checksum = "08a89b46efaf957e52b18062fb2f4660f8b8a4dde1807ca002690868ef2c85a9"
dependencies = [
"crossbeam-deque",
"crossbeam-queue",
@ -2858,9 +3058,9 @@ dependencies = [
[[package]]
name = "readkey"
version = "0.1.5"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d98db94bb4f3e926c8d8186547cd9366d958d753aff5801214d93d38214e8f0f"
checksum = "86d401b6d6a1725a59f1b4e813275d289dff3ad09c72b373a10a7a8217ba3146"
[[package]]
name = "redox_syscall"
@ -3072,9 +3272,9 @@ checksum = "9dad3f759919b92c3068c696c15c3d17238234498bbdcc80f2c469606f948ac8"
[[package]]
name = "serde"
version = "1.0.103"
version = "1.0.104"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1217f97ab8e8904b57dd22eb61cde455fa7446a9c1cf43966066da047c1f3702"
checksum = "414115f25f818d7dfccec8ee535d76949ae78584fc4f79a6f45a904bf8ab4449"
dependencies = [
"serde_derive",
]
@ -3112,7 +3312,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a663f873dedc4eac1a559d4c6bc0d0b2c34dc5ac4702e105014b8281489e44f"
dependencies = [
"ordered-float",
"serde 1.0.103",
"serde 1.0.104",
]
[[package]]
@ -3121,14 +3321,14 @@ version = "0.11.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "325a073952621257820e7a3469f55ba4726d8b28657e7e36653d1c36dc2c84ae"
dependencies = [
"serde 1.0.103",
"serde 1.0.104",
]
[[package]]
name = "serde_derive"
version = "1.0.103"
version = "1.0.104"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a8c6faef9a2e64b0064f48570289b4bf8823b7581f1d6157c1b52152306651d0"
checksum = "128f9e303a5a29922045a830221b8f78ec74a5f544944f3d5984f8ec3895ef64"
dependencies = [
"proc-macro2",
"quote",
@ -3142,7 +3342,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eb236687e2bb073a7521c021949be944641e671b8505a94069ca37b656c81139"
dependencies = [
"result",
"serde 1.0.103",
"serde 1.0.104",
"void",
]
@ -3155,7 +3355,7 @@ dependencies = [
"indexmap",
"itoa",
"ryu",
"serde 1.0.103",
"serde 1.0.104",
]
[[package]]
@ -3175,7 +3375,7 @@ checksum = "9ec5d77e2d4c73717816afac02670d5c4f534ea95ed430442cad02e7a6e32c97"
dependencies = [
"dtoa",
"itoa",
"serde 1.0.103",
"serde 1.0.104",
"url",
]
@ -3187,7 +3387,7 @@ checksum = "691b17f19fc1ec9d94ec0b5864859290dff279dbd7b03f017afda54eb36c3c35"
dependencies = [
"dtoa",
"linked-hash-map 0.5.2",
"serde 1.0.103",
"serde 1.0.104",
"yaml-rust",
]
@ -3203,9 +3403,12 @@ dependencies = [
[[package]]
name = "shellexpand"
version = "1.0.0"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "de7a5b5a9142fd278a10e0209b021a1b85849352e6951f4f914735c976737564"
checksum = "3a23aed0018ea07316c7826ade41e551772031cf652805f93ebc922215a44d4a"
dependencies = [
"dirs 1.0.5",
]
[[package]]
name = "slab"
@ -3226,9 +3429,9 @@ dependencies = [
[[package]]
name = "smallvec"
version = "1.0.0"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ecf3b85f68e8abaa7555aa5abdb1153079387e60b718283d732f03897fcfc86"
checksum = "44e59e0c9fa00817912ae6e4e6e3c4fe04455e75699d06eedc7d85917ed8e8f4"
[[package]]
name = "socket2"
@ -3332,7 +3535,7 @@ dependencies = [
"log",
"mime",
"mime_guess",
"serde 1.0.103",
"serde 1.0.104",
"serde_json",
"serde_urlencoded",
"url",
@ -3379,7 +3582,7 @@ dependencies = [
"onig",
"plist",
"regex-syntax",
"serde 1.0.103",
"serde 1.0.104",
"serde_derive",
"serde_json",
"walkdir",
@ -3454,6 +3657,26 @@ dependencies = [
"unicode-width",
]
[[package]]
name = "thiserror"
version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6f357d1814b33bc2dc221243f8424104bfe72dbe911d5b71b3816a2dff1c977e"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eb2e25d25307eb8436894f727aba8f65d07adf02e5b35a13cebed48bd282bfef"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "thread_local"
version = "0.3.6"
@ -3499,7 +3722,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5090db468dad16e1a7a54c8c67280c5e4b544f3d3e018f0b913b400261f85926"
dependencies = [
"bytes",
"futures",
"futures 0.1.29",
"log",
]
@ -3509,7 +3732,7 @@ version = "0.4.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "758664fc71a3a69038656bee8b6be6477d2a6c315a6b81f7081f591bffa4111f"
dependencies = [
"serde 1.0.103",
"serde 1.0.104",
]
[[package]]
@ -3518,7 +3741,7 @@ version = "0.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "01d1404644c8b12b16bfcffa4322403a91a451584daaaa7c28d3152e6cbc98cf"
dependencies = [
"serde 1.0.103",
"serde 1.0.104",
]
[[package]]
@ -3551,7 +3774,7 @@ dependencies = [
"erased-serde",
"inventory",
"lazy_static 1.4.0",
"serde 1.0.103",
"serde 1.0.104",
"typetag-impl",
]
@ -3713,9 +3936,9 @@ checksum = "b89c3ce4ce14bdc6fb6beaf9ec7928ca331de5df7e5ea278375642a2f478570d"
[[package]]
name = "wasm-bindgen"
version = "0.2.55"
version = "0.2.56"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "29ae32af33bacd663a9a28241abecf01f2be64e6a185c6139b04f18b6385c5f2"
checksum = "99de4b68939a880d530aed51289a7c7baee154e3ea8ac234b542c49da7134aaf"
dependencies = [
"cfg-if",
"wasm-bindgen-macro",
@ -3723,9 +3946,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-backend"
version = "0.2.55"
version = "0.2.56"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1845584bd3593442dc0de6e6d9f84454a59a057722f36f005e44665d6ab19d85"
checksum = "b58e66a093a7b7571cb76409763c495b8741ac4319ac20acc2b798f6766d92ee"
dependencies = [
"bumpalo",
"lazy_static 1.4.0",
@ -3743,7 +3966,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "83420b37346c311b9ed822af41ec2e82839bfe99867ec6c54e2da43b7538771c"
dependencies = [
"cfg-if",
"futures",
"futures 0.1.29",
"futures-channel-preview",
"futures-util-preview",
"js-sys",
@ -3754,9 +3977,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-macro"
version = "0.2.55"
version = "0.2.56"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87fcc747e6b73c93d22c947a6334644d22cfec5abd8b66238484dc2b0aeb9fe4"
checksum = "a80f89daea7b0a67b11f6e9f911422ed039de9963dce00048a653b63d51194bf"
dependencies = [
"quote",
"wasm-bindgen-macro-support",
@ -3764,9 +3987,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-macro-support"
version = "0.2.55"
version = "0.2.56"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3dc4b3f2c4078c8c4a5f363b92fcf62604c5913cbd16c6ff5aaf0f74ec03f570"
checksum = "4f9dbc3734ad6cff6b76b75b7df98c06982becd0055f651465a08f769bca5c61"
dependencies = [
"proc-macro2",
"quote",
@ -3777,15 +4000,15 @@ dependencies = [
[[package]]
name = "wasm-bindgen-shared"
version = "0.2.55"
version = "0.2.56"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca0b78d6d3be8589b95d1d49cdc0794728ca734adf36d7c9f07e6459508bb53d"
checksum = "d907984f8506b3554eab48b8efff723e764ddbf76d4cd4a3fe4196bc00c49a70"
[[package]]
name = "wasm-bindgen-webidl"
version = "0.2.55"
version = "0.2.56"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3126356474ceb717c8fb5549ae387c9fbf4872818454f4d87708bee997214bb5"
checksum = "f85a3825a459cf6a929d03bacb54dca37a614d43032ad1343ef2d4822972947d"
dependencies = [
"anyhow",
"heck",
@ -3799,9 +4022,9 @@ dependencies = [
[[package]]
name = "web-sys"
version = "0.3.32"
version = "0.3.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "98405c0a2e722ed3db341b4c5b70eb9fe0021621f7350bab76df93b09b649bbf"
checksum = "2fb60433d0dc12c803b9b017b3902d80c9451bab78d27bc3210bf2a7b96593f1"
dependencies = [
"anyhow",
"js-sys",
@ -3819,16 +4042,6 @@ dependencies = [
"nom 4.2.3",
]
[[package]]
name = "which"
version = "3.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5475d47078209a02e60614f7ba5e645ef3ed60f771920ac1906d7c1cc65024c8"
dependencies = [
"failure",
"libc",
]
[[package]]
name = "widestring"
version = "0.4.0"
@ -3888,6 +4101,16 @@ dependencies = [
"winapi-util",
]
[[package]]
name = "ws2_32-sys"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e"
dependencies = [
"winapi 0.2.8",
"winapi-build",
]
[[package]]
name = "x11"
version = "2.18.1"

View File

@ -107,7 +107,7 @@ subprocess = "0.1.18"
pretty-hex = "0.1.1"
hex = "0.4"
tempfile = "3.1.0"
which = "3.1"
ichwh = "0.2"
textwrap = {version = "0.11.0", features = ["term_size"]}
shellexpand = "1.0.0"
pin-utils = "0.1.0-alpha.4"

72
docs/commands/which.md Normal file
View File

@ -0,0 +1,72 @@
# which
Finds a program file.
Usage:
> which ...args{flags}
## Parameters
- ...args: the names of the commands to find the path to
- --all: list all executables
## Examples
`which` finds the location of an executable:
```shell
/home/bob> which python
━━━━━━━━┯━━━━━━━━━━━━━━━━━┯━━━━━━━━━
arg │ path │ builtin
────────┼─────────────────┼─────────
python │ /usr/bin/python │ No
━━━━━━━━┷━━━━━━━━━━━━━━━━━┷━━━━━━━━━
/home/bob> which cargo
━━━━━━━┯━━━━━━━━━━━━━━━━━━━━━━━━━━━━┯━━━━━━━━━
arg │ path │ builtin
───────┼────────────────────────────┼─────────
cargo │ /home/bob/.cargo/bin/cargo │ No
━━━━━━━┷━━━━━━━━━━━━━━━━━━━━━━━━━━━━┷━━━━━━━━━
```
`which` will identify nushell commands:
```shell
/home/bob> which ls
━━━━━┯━━━━━━━━━━━━━━━━━━━━━━━━━━┯━━━━━━━━━
arg │ path │ builtin
─────┼──────────────────────────┼─────────
ls │ nushell built-in command │ Yes
━━━━━┷━━━━━━━━━━━━━━━━━━━━━━━━━━┷━━━━━━━━━
/home/bob> which which
━━━━━━━┯━━━━━━━━━━━━━━━━━━━━━━━━━━┯━━━━━━━━━
arg │ path │ builtin
───────┼──────────────────────────┼─────────
which │ nushell built-in command │ Yes
━━━━━━━┷━━━━━━━━━━━━━━━━━━━━━━━━━━┷━━━━━━━━━
```
Passing the `all` flag identifies all instances of a command or binary
```shell
/home/bob> which ls --all
━━━┯━━━━━┯━━━━━━━━━━━━━━━━━━━━━━━━━━┯━━━━━━━━━
# │ arg │ path │ builtin
───┼─────┼──────────────────────────┼─────────
0 │ ls │ nushell built-in command │ Yes
1 │ ls │ /usr/bin/ls │ No
━━━┷━━━━━┷━━━━━━━━━━━━━━━━━━━━━━━━━━┷━━━━━━━━━
```
`which` will also identify local binaries
```shell
/home/bob> touch foo
/home/bob> chmod +x foo
/home/bob> which ./foo
━━━━━━━┯━━━━━━━━━━━━━━━┯━━━━━━━━━
arg │ path │ builtin
───────┼───────────────┼─────────
./foo │ /home/bob/foo │ No
━━━━━━━┷━━━━━━━━━━━━━━━┷━━━━━━━━━
```

View File

@ -1,7 +1,9 @@
use crate::commands::WholeStreamCommand;
use crate::prelude::*;
use indexmap::map::IndexMap;
use nu_errors::ShellError;
use nu_protocol::{Primitive, Signature, SyntaxShape, UntaggedValue, Value};
use nu_protocol::{Primitive, ReturnSuccess, Signature, SyntaxShape, UntaggedValue, Value};
use nu_source::Tagged;
pub struct Which;
@ -11,11 +13,12 @@ impl WholeStreamCommand for Which {
}
fn signature(&self) -> Signature {
Signature::build("which").required(
"name",
SyntaxShape::Any,
"the name of the command to find the path to",
)
Signature::build("which")
.switch("all", "list all executables")
.rest(
SyntaxShape::String,
"the names of the commands to find the path to",
)
}
fn usage(&self) -> &str {
@ -27,51 +30,120 @@ impl WholeStreamCommand for Which {
args: CommandArgs,
registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> {
which(args, registry)
args.process(registry, which)?.run()
}
}
pub fn which(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream, ShellError> {
let args = args.evaluate_once(registry)?;
/// Shortcuts for creating an entry to the output table
fn entry(arg: impl Into<String>, path: Value, builtin: bool, tag: Tag) -> Value {
let mut map = IndexMap::new();
map.insert(
"arg".to_string(),
UntaggedValue::Primitive(Primitive::String(arg.into())).into_value(tag.clone()),
);
map.insert("path".to_string(), path);
map.insert(
"builtin".to_string(),
UntaggedValue::Primitive(Primitive::Boolean(builtin)).into_value(tag.clone()),
);
let mut which_out = VecDeque::new();
let tag = args.call_info.name_tag.clone();
UntaggedValue::row(map).into_value(tag)
}
if let Some(v) = &args.call_info.args.positional {
if !v.is_empty() {
match &v[0] {
Value {
value: UntaggedValue::Primitive(Primitive::String(s)),
tag,
} => {
if let Ok(ok) = which::which(&s) {
which_out.push_back(
UntaggedValue::Primitive(Primitive::Path(ok)).into_value(tag.clone()),
);
}
}
Value { tag, .. } => {
return Err(ShellError::labeled_error(
"Expected a filename to find",
"needs a filename",
tag,
));
macro_rules! entry_builtin {
($arg:expr, $tag:expr) => {
entry(
$arg.clone(),
UntaggedValue::Primitive(Primitive::String("nushell built-in command".to_string()))
.into_value($tag.clone()),
true,
$tag,
)
};
}
macro_rules! entry_path {
($arg:expr, $path:expr, $tag:expr) => {
entry(
$arg.clone(),
UntaggedValue::Primitive(Primitive::Path($path)).into_value($tag.clone()),
false,
$tag,
)
};
}
#[derive(Deserialize, Debug)]
struct WhichArgs {
bin: Tagged<String>,
all: bool,
}
fn which(
WhichArgs { bin, all }: WhichArgs,
RunnableContext { commands, .. }: RunnableContext,
) -> Result<OutputStream, ShellError> {
let external = bin.starts_with('^');
let item = if external {
bin.item[1..].to_string()
} else {
bin.item.clone()
};
if all {
let stream = async_stream! {
if external {
if let Ok(path) = ichwh::which(&item).await {
yield ReturnSuccess::value(entry_path!(item, path.into(), bin.tag.clone()));
}
}
} else {
return Err(ShellError::labeled_error(
"Expected a binary to find",
"needs application name",
tag,
));
}
} else {
return Err(ShellError::labeled_error(
"Expected a binary to find",
"needs application name",
tag,
));
}
Ok(which_out.to_output_stream())
let builtin = commands.has(&item);
if builtin {
yield ReturnSuccess::value(entry_builtin!(item, bin.tag.clone()));
}
if let Ok(paths) = ichwh::which_all(&item).await {
if !builtin && paths.len() == 0 {
yield Err(ShellError::labeled_error(
"Binary not found for argument, and argument is not a builtin",
"not found",
&bin.tag,
));
} else {
for path in paths {
yield ReturnSuccess::value(entry_path!(item, path.into(), bin.tag.clone()));
}
}
} else {
yield Err(ShellError::labeled_error(
"Error trying to find binary for argument",
"error",
&bin.tag,
));
}
};
Ok(stream.to_output_stream())
} else {
let stream = async_stream! {
if external {
if let Ok(path) = ichwh::which(&item).await {
yield ReturnSuccess::value(entry_path!(item, path.into(), bin.tag.clone()));
}
} else if commands.has(&item) {
yield ReturnSuccess::value(entry_builtin!(item, bin.tag.clone()));
} else if let Ok(path) = ichwh::which(&item).await {
yield ReturnSuccess::value(entry_path!(item, path.into(), bin.tag.clone()));
} else {
yield Err(ShellError::labeled_error(
"Binary not found for argument, and argument is not a builtin",
"not found",
&bin.tag,
));
}
};
Ok(stream.to_output_stream())
}
}