From 3187984bcb6de83e9ef94ed1fb80ec32990cbfc7 Mon Sep 17 00:00:00 2001 From: Auca Maillot Date: Mon, 22 May 2023 17:09:51 -0300 Subject: [PATCH 1/5] :construction: WIP thinking about parsing and ast --- Cargo.lock | 1129 ++++++++++++++++++-- Cargo.toml | 8 +- examples/example.nu | 2399 +++++++++++++++++++++++++++++++++++++++++++ src/config.rs | 21 + src/formatting.rs | 24 + src/lib.rs | 183 ++-- src/main.rs | 164 +-- 7 files changed, 3688 insertions(+), 240 deletions(-) create mode 100644 examples/example.nu create mode 100644 src/config.rs create mode 100644 src/formatting.rs diff --git a/Cargo.lock b/Cargo.lock index dd069ca..788b83d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3,21 +3,125 @@ version = 3 [[package]] -name = "ansi_term" -version = "0.11.0" +name = "ahash" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" +checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" dependencies = [ - "winapi", + "getrandom", + "once_cell", + "version_check", +] + +[[package]] +name = "ahash" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", +] + +[[package]] +name = "aho-corasick" +version = "0.7.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac" +dependencies = [ + "memchr", +] + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "anes" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" + +[[package]] +name = "anstream" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ca84f3628370c59db74ee214b3263d58f9aadd9b4fe7e711fd87dc452b7f163" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is-terminal", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41ed9a86bf92ae6580e0a31281f65a1b1d867c0cc68d5346e2ae128dddfa6a7d" + +[[package]] +name = "anstyle-parse" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e765fd216e48e067936442276d1d57399e37bce53c264d6fefbe298080cb57ee" +dependencies = [ + "utf8parse", ] +[[package]] +name = "anstyle-query" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" +dependencies = [ + "windows-sys 0.48.0", +] + +[[package]] +name = "anstyle-wincon" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "180abfa45703aebe0093f79badacc01b8fd4ea2e35118747e5811127f926e188" +dependencies = [ + "anstyle", + "windows-sys 0.48.0", +] + +[[package]] +name = "anyhow" +version = "1.0.71" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8" + +[[package]] +name = "arrayvec" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" + +[[package]] +name = "arrayvec" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" + [[package]] name = "atty" version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" dependencies = [ - "hermit-abi", + "hermit-abi 0.1.19", "libc", "winapi", ] @@ -28,6 +132,21 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" +[[package]] +name = "bit-set" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" +dependencies = [ + "bit-vec", +] + +[[package]] +name = "bit-vec" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" + [[package]] name = "bitflags" version = "1.3.2" @@ -35,31 +154,32 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] -name = "bstr" -version = "0.2.16" +name = "bumpalo" +version = "3.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9df67f7bf9ef8498769f994239c45613ef0c5899415fb58e9add412d2c1a538" + +[[package]] +name = "byte-unit" +version = "4.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90682c8d613ad3373e66de8c6411e0ae2ab2571e879d2efbf73558cc66f21279" +checksum = "da78b32057b8fdfc352504708feeba7216dcd65a2c9ab02978cbd288d1279b6c" dependencies = [ - "lazy_static", - "memchr", - "regex-automata", "serde", + "utf8-width", ] [[package]] -name = "bumpalo" -version = "3.7.1" +name = "cast" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9df67f7bf9ef8498769f994239c45613ef0c5899415fb58e9add412d2c1a538" +checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] -name = "cast" -version = "0.2.7" +name = "cc" +version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c24dab4283a142afa2fdca129b80ad2c6284e073930f964c3a1293c225ee39a" -dependencies = [ - "rustc_version", -] +checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" [[package]] name = "cfg-if" @@ -67,32 +187,147 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "chrono" +version = "0.4.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e3c5919066adf22df73762e50cffcde3a758f2a848b113b586d1f86728b673b" +dependencies = [ + "iana-time-zone", + "js-sys", + "num-integer", + "num-traits", + "serde", + "time", + "wasm-bindgen", + "winapi", +] + +[[package]] +name = "chrono-humanize" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32dce1ea1988dbdf9f9815ff11425828523bd2a134ec0805d2ac8af26ee6096e" +dependencies = [ + "chrono", +] + +[[package]] +name = "ciborium" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "effd91f6c78e5a4ace8a5d3c0b6bfaec9e2baaef55f3efc00e45fb2e477ee926" +dependencies = [ + "ciborium-io", + "ciborium-ll", + "serde", +] + +[[package]] +name = "ciborium-io" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdf919175532b369853f5d5e20b26b43112613fd6fe7aee757e35f7a44642656" + +[[package]] +name = "ciborium-ll" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "defaa24ecc093c77630e6c15e17c51f5e187bf35ee514f4e2d67baaa96dae22b" +dependencies = [ + "ciborium-io", + "half", +] + [[package]] name = "clap" -version = "2.33.3" +version = "3.2.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002" +checksum = "4ea181bf566f71cb9a5d17a59e1871af638180a18fb0035c92ae62b705207123" dependencies = [ - "ansi_term", - "atty", "bitflags", + "clap_lex 0.2.4", + "indexmap", + "textwrap 0.16.0", +] + +[[package]] +name = "clap" +version = "4.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93aae7a4192245f70fe75dd9157fc7b4a5bf53e88d30bd4396f7d8f9284d5acc" +dependencies = [ + "clap_builder", + "clap_derive", + "once_cell", +] + +[[package]] +name = "clap_builder" +version = "4.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f423e341edefb78c9caba2d9c7f7687d0e72e89df3ce3394554754393ac3990" +dependencies = [ + "anstream", + "anstyle", + "bitflags", + "clap_lex 0.5.0", "strsim", - "textwrap", + "unicase", "unicode-width", - "vec_map", ] +[[package]] +name = "clap_derive" +version = "4.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "191d9573962933b4027f932c600cd252ce27a8ad5979418fe78e43c07996f27b" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 2.0.16", +] + +[[package]] +name = "clap_lex" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5" +dependencies = [ + "os_str_bytes", +] + +[[package]] +name = "clap_lex" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2da6da31387c7e4ef160ffab6d5e7f00c42626fe39aea70a7b0f1773f7dd6c1b" + +[[package]] +name = "colorchoice" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" + +[[package]] +name = "core-foundation-sys" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" + [[package]] name = "criterion" -version = "0.3.5" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1604dafd25fba2fe2d5895a9da139f8dc9b319a5fe5354ca137cbbce4e178d10" +checksum = "e7c76e09c1aae2bc52b3d2f29e13c6572553b30c4aa1b8a49fd70de6412654cb" dependencies = [ + "anes", "atty", "cast", - "clap", + "ciborium", + "clap 3.2.25", "criterion-plot", - "csv", "itertools", "lazy_static", "num-traits", @@ -101,7 +336,6 @@ dependencies = [ "rayon", "regex", "serde", - "serde_cbor", "serde_derive", "serde_json", "tinytemplate", @@ -110,9 +344,9 @@ dependencies = [ [[package]] name = "criterion-plot" -version = "0.4.4" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d00996de9f2f7559f7f4dc286073197f83e92256a59ed395f9aac01fe717da57" +checksum = "6b50826342786a51a89e2da3a28f1c32b06e387201bc2d19791f622c673706b1" dependencies = [ "cast", "itertools", @@ -163,32 +397,94 @@ dependencies = [ ] [[package]] -name = "csv" -version = "1.1.6" +name = "crossterm_winapi" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22813a6dc45b335f9bade10bf7271dc477e81113e89eb251a0bc2a8a81c536e1" +checksum = "2ae1b35a484aa10e07fe0638d02301c5ad24de82d310ccbd2f3693da5f09bf1c" +dependencies = [ + "winapi", +] + +[[package]] +name = "either" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" + +[[package]] +name = "env_logger" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85cdab6a89accf66733ad5a1693a4dcced6aeff64602b634530dd73c1f3ee9f0" +dependencies = [ + "humantime", + "is-terminal", + "log", + "regex", + "termcolor", +] + +[[package]] +name = "erased-serde" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f2b0c2380453a92ea8b6c8e5f64ecaafccddde8ceab55ff7a8ac1029f894569" dependencies = [ - "bstr", - "csv-core", - "itoa", - "ryu", "serde", ] [[package]] -name = "csv-core" -version = "0.1.10" +name = "errno" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b2466559f260f48ad25fe6317b3c8dac77b5bdb5763ac7d9d6103530663bc90" +checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" dependencies = [ - "memchr", + "errno-dragonfly", + "libc", + "windows-sys 0.48.0", ] [[package]] -name = "either" -version = "1.6.1" +name = "errno-dragonfly" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" +checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +dependencies = [ + "cc", + "libc", +] + +[[package]] +name = "fancy-regex" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b95f7c0680e4142284cf8b22c14a476e87d61b004a3a0861872b32ef7ead40a2" +dependencies = [ + "bit-set", + "regex", +] + +[[package]] +name = "getrandom" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c85e1d9ab2eadba7e5040d4e09cbd6d072b76a557ad64e797c2cb9d4da21d7e4" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", +] + +[[package]] +name = "ghost" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e77ac7b51b8e6313251737fcef4b1c01a2ea102bde68415b62c0ee9268fec357" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.16", +] [[package]] name = "half" @@ -196,6 +492,30 @@ version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "62aca2aba2d62b4a7f5b33f3712cb1b0692779a56fb510499d5c0aa594daeaf3" +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +dependencies = [ + "ahash 0.7.6", +] + +[[package]] +name = "hashbrown" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" +dependencies = [ + "ahash 0.8.3", +] + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + [[package]] name = "hermit-abi" version = "0.1.19" @@ -205,6 +525,89 @@ dependencies = [ "libc", ] +[[package]] +name = "hermit-abi" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" + +[[package]] +name = "humantime" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" + +[[package]] +name = "iana-time-zone" +version = "0.1.56" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0722cd7114b7de04316e7ea5456a0bbb20e4adb46fd27a3697adb812cff0f37c" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", +] + +[[package]] +name = "inventory" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0539b5de9241582ce6bd6b0ba7399313560151e58c9aaf8b74b711b1bdce644" +dependencies = [ + "ghost", +] + +[[package]] +name = "io-lifetimes" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c66c74d2ae7e79a5a8f7ac924adbe38ee42a859c6539ad869eb51f0b52dc220" +dependencies = [ + "hermit-abi 0.3.1", + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "is-terminal" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adcf93614601c8129ddf72e2d5633df827ba6551541c6d8c59520a371475be1f" +dependencies = [ + "hermit-abi 0.3.1", + "io-lifetimes", + "rustix", + "windows-sys 0.48.0", +] + +[[package]] +name = "is_ci" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "616cde7c720bb2bb5824a224687d8f77bfd38922027f01d825cd7453be5099fb" + [[package]] name = "itertools" version = "0.10.1" @@ -220,6 +623,12 @@ version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" +[[package]] +name = "itoa" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" + [[package]] name = "js-sys" version = "0.3.55" @@ -237,40 +646,164 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.102" +version = "0.2.144" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2a5ac8f984bfcf3a823267e5fde638acc3325f6496633a5da6bb6eb2171e103" +checksum = "2b00cc1c228a6782d0f076e7b232802e0c5689d41bb5df366f2a6b6621cfdfe1" + +[[package]] +name = "linux-raw-sys" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" [[package]] name = "log" -version = "0.4.14" +version = "0.4.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" +checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" dependencies = [ "cfg-if", ] [[package]] -name = "memchr" -version = "2.4.1" +name = "lru" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03f1160296536f10c833a82dca22267d5486734230d47bf00bf435885814ba1e" +dependencies = [ + "hashbrown 0.13.2", +] + +[[package]] +name = "lscolors" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18a9df1d1fb6d9e92fa043e9eb9a3ecf6892c7b542bae5137cd1e419e40aa8bf" +dependencies = [ + "nu-ansi-term", +] + +[[package]] +name = "memchr" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" + +[[package]] +name = "memoffset" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59accc507f1338036a0477ef61afdae33cde60840f4dfe481319ce3ad116ddf9" +dependencies = [ + "autocfg", +] + +[[package]] +name = "miette" +version = "5.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a236ff270093b0b67451bc50a509bd1bad302cb1d3c7d37d5efe931238581fa9" +dependencies = [ + "is-terminal", + "miette-derive", + "once_cell", + "owo-colors", + "supports-color", + "supports-hyperlinks", + "supports-unicode", + "terminal_size", + "textwrap 0.15.2", + "thiserror", + "unicode-width", +] + +[[package]] +name = "miette-derive" +version = "5.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4901771e1d44ddb37964565c654a3223ba41a594d02b8da471cc4464912b5cfa" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.16", +] + +[[package]] +name = "nu-ansi-term" +version = "0.47.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1df031e117bca634c262e9bd3173776844b6c17a90b3741c9163663b4385af76" +dependencies = [ + "windows-sys 0.45.0", +] + +[[package]] +name = "nu-protocol" +version = "0.80.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" +checksum = "cd7943cef88db9b614326b924125a7342e1a46e4eb9e82547becf917765f62d4" +dependencies = [ + "byte-unit", + "chrono", + "chrono-humanize", + "fancy-regex", + "indexmap", + "lru", + "miette", + "nu-utils", + "num-format", + "serde", + "strum", + "strum_macros", + "sys-locale", + "thiserror", + "typetag", +] [[package]] -name = "memoffset" -version = "0.6.4" +name = "nu-utils" +version = "0.80.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59accc507f1338036a0477ef61afdae33cde60840f4dfe481319ce3ad116ddf9" +checksum = "8da43579f039c9428df85f28fc58c4b1732ba2a7a9971c1b56dbe39b0a8e8ac3" dependencies = [ - "autocfg", + "crossterm_winapi", + "log", + "lscolors", + "num-format", + "strip-ansi-escapes", + "sys-locale", ] [[package]] name = "nufmt" version = "0.1.0" dependencies = [ - "clap", + "anyhow", + "clap 4.3.0", "criterion", + "env_logger", + "log", + "nu-protocol", +] + +[[package]] +name = "num-format" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a652d9771a63711fd3c3deb670acfbe5c30a4072e664d7a3bf5a9e1056ac72c3" +dependencies = [ + "arrayvec 0.7.2", + "itoa 1.0.6", +] + +[[package]] +name = "num-integer" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" +dependencies = [ + "autocfg", + "num-traits", ] [[package]] @@ -288,16 +821,34 @@ version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" dependencies = [ - "hermit-abi", + "hermit-abi 0.1.19", "libc", ] +[[package]] +name = "once_cell" +version = "1.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" + [[package]] name = "oorandom" version = "11.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" +[[package]] +name = "os_str_bytes" +version = "6.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ceedf44fb00f2d1984b0bc98102627ce622e083e49a5bacdb3e514fa4238e267" + +[[package]] +name = "owo-colors" +version = "3.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f" + [[package]] name = "plotters" version = "0.3.1" @@ -328,18 +879,18 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.29" +version = "1.0.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9f5105d4fdaab20335ca9565e106a5d9b82b6219b5ba735731124ac6711d23d" +checksum = "fa1fb82fc0c281dd9671101b66b771ebbe1eaf967b96ac8740dcba4b70005ca8" dependencies = [ - "unicode-xid", + "unicode-ident", ] [[package]] name = "quote" -version = "1.0.9" +version = "1.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" +checksum = "8f4f29d145265ec1c483c7c654450edde0bfe043d3938d6972630663356d9500" dependencies = [ "proc-macro2", ] @@ -375,15 +926,11 @@ version = "1.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461" dependencies = [ + "aho-corasick", + "memchr", "regex-syntax", ] -[[package]] -name = "regex-automata" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" - [[package]] name = "regex-syntax" version = "0.6.25" @@ -391,14 +938,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" [[package]] -name = "rustc_version" -version = "0.4.0" +name = "rustix" +version = "0.37.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +checksum = "acf8729d8542766f1b2cf77eb034d52f40d375bb8b615d0b147089946e16613d" dependencies = [ - "semver", + "bitflags", + "errno", + "io-lifetimes", + "libc", + "linux-raw-sys", + "windows-sys 0.48.0", ] +[[package]] +name = "rustversion" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f3208ce4d8448b3f3e7d168a73f5e0c43a61e32930de3bceeccedb388b6bf06" + [[package]] name = "ryu" version = "1.0.5" @@ -420,37 +978,24 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" -[[package]] -name = "semver" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "568a8e6258aa33c13358f81fd834adb854c6f7c9468520910a9b1e8fac068012" - [[package]] name = "serde" -version = "1.0.130" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f12d06de37cf59146fbdecab66aa99f9fe4f78722e3607577a5375d66bd0c913" - -[[package]] -name = "serde_cbor" -version = "0.11.2" +version = "1.0.163" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bef2ebfde456fb76bbcf9f59315333decc4fda0b2b44b420243c11e0f5ec1f5" +checksum = "2113ab51b87a539ae008b5c6c02dc020ffa39afd2d83cffcb3f4eb2722cebec2" dependencies = [ - "half", - "serde", + "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.130" +version = "1.0.163" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7bc1a1ab1961464eae040d96713baa5a724a8152c1222492465b54322ec508b" +checksum = "8c805777e3930c8883389c602315a24224bcc738b63905ef87cd1420353ea93e" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.16", ] [[package]] @@ -459,16 +1004,78 @@ version = "1.0.68" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0f690853975602e1bfe1ccbf50504d67174e3bcf340f23b5ea9992e0587a52d8" dependencies = [ - "itoa", + "itoa 0.4.8", "ryu", "serde", ] +[[package]] +name = "smawk" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f67ad224767faa3c7d8b6d91985b78e70a1324408abcb1cfcc2be4c06bc06043" + +[[package]] +name = "strip-ansi-escapes" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "011cbb39cf7c1f62871aea3cc46e5817b0937b49e9447370c93cacbe93a766d8" +dependencies = [ + "vte", +] + [[package]] name = "strsim" -version = "0.8.0" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + +[[package]] +name = "strum" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" +checksum = "063e6045c0e62079840579a7e47a355ae92f60eb74daaf156fb1e84ba164e63f" + +[[package]] +name = "strum_macros" +version = "0.24.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "rustversion", + "syn 1.0.76", +] + +[[package]] +name = "supports-color" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4950e7174bffabe99455511c39707310e7e9b440364a2fcb1cc21521be57b354" +dependencies = [ + "is-terminal", + "is_ci", +] + +[[package]] +name = "supports-hyperlinks" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f84231692eb0d4d41e4cdd0cabfdd2e6cd9e255e65f80c9aa7c98dd502b4233d" +dependencies = [ + "is-terminal", +] + +[[package]] +name = "supports-unicode" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b6c2cb240ab5dd21ed4906895ee23fe5a48acdbd15a3ce388e7b62a9b66baf7" +dependencies = [ + "is-terminal", +] [[package]] name = "syn" @@ -481,15 +1088,94 @@ dependencies = [ "unicode-xid", ] +[[package]] +name = "syn" +version = "2.0.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6f671d4b5ffdb8eadec19c0ae67fe2639df8684bd7bc4b83d986b8db549cf01" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "sys-locale" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea0b9eefabb91675082b41eb94c3ecd91af7656caee3fb4961a07c0ec8c7ca6f" +dependencies = [ + "libc", + "windows-sys 0.45.0", +] + +[[package]] +name = "termcolor" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "terminal_size" +version = "0.1.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "633c1a546cee861a1a6d0dc69ebeca693bf4296661ba7852b9d21d159e0506df" +dependencies = [ + "libc", + "winapi", +] + [[package]] name = "textwrap" -version = "0.11.0" +version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" +checksum = "b7b3e525a49ec206798b40326a44121291b530c963cfb01018f63e135bac543d" dependencies = [ + "smawk", + "unicode-linebreak", "unicode-width", ] +[[package]] +name = "textwrap" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d" + +[[package]] +name = "thiserror" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.16", +] + +[[package]] +name = "time" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a" +dependencies = [ + "libc", + "wasi 0.10.0+wasi-snapshot-preview1", + "winapi", +] + [[package]] name = "tinytemplate" version = "1.2.1" @@ -500,6 +1186,55 @@ dependencies = [ "serde_json", ] +[[package]] +name = "typetag" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6898cc6f6a32698cc3e14d5632a14d2b23ed9f7b11e6b8e05ce685990acc22" +dependencies = [ + "erased-serde", + "inventory", + "once_cell", + "serde", + "typetag-impl", +] + +[[package]] +name = "typetag-impl" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c3e1c30cedd24fc597f7d37a721efdbdc2b1acae012c1ef1218f4c7c2c0f3e7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.16", +] + +[[package]] +name = "unicase" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6" +dependencies = [ + "version_check", +] + +[[package]] +name = "unicode-ident" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4" + +[[package]] +name = "unicode-linebreak" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5faade31a542b8b35855fff6e8def199853b2da8da256da52f52f1316ee3137" +dependencies = [ + "hashbrown 0.12.3", + "regex", +] + [[package]] name = "unicode-width" version = "0.1.9" @@ -513,10 +1248,43 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" [[package]] -name = "vec_map" -version = "0.8.2" +name = "utf8-width" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5190c9442dcdaf0ddd50f37420417d219ae5261bbf5db120d0f9bab996c9cba1" + +[[package]] +name = "utf8parse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "vte" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6cbce692ab4ca2f1f3047fcf732430249c0e971bfdd2b234cf2c47ad93af5983" +dependencies = [ + "arrayvec 0.5.2", + "utf8parse", + "vte_generate_state_changes", +] + +[[package]] +name = "vte_generate_state_changes" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" +checksum = "d257817081c7dffcdbab24b9e62d2def62e2ff7d00b1c20062551e6cccc145ff" +dependencies = [ + "proc-macro2", + "quote", +] [[package]] name = "walkdir" @@ -529,6 +1297,18 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "wasi" +version = "0.10.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + [[package]] name = "wasm-bindgen" version = "0.2.78" @@ -550,7 +1330,7 @@ dependencies = [ "log", "proc-macro2", "quote", - "syn", + "syn 1.0.76", "wasm-bindgen-shared", ] @@ -572,7 +1352,7 @@ checksum = "7803e0eea25835f8abdc585cd3021b3deb11543c6fe226dcd30b228857c5c5ab" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.76", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -623,3 +1403,144 @@ name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" +dependencies = [ + "windows-targets 0.48.0", +] + +[[package]] +name = "windows-sys" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +dependencies = [ + "windows-targets 0.42.2", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.0", +] + +[[package]] +name = "windows-targets" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +dependencies = [ + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", +] + +[[package]] +name = "windows-targets" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" +dependencies = [ + "windows_aarch64_gnullvm 0.48.0", + "windows_aarch64_msvc 0.48.0", + "windows_i686_gnu 0.48.0", + "windows_i686_msvc 0.48.0", + "windows_x86_64_gnu 0.48.0", + "windows_x86_64_gnullvm 0.48.0", + "windows_x86_64_msvc 0.48.0", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" + +[[package]] +name = "windows_i686_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" + +[[package]] +name = "windows_i686_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" diff --git a/Cargo.toml b/Cargo.toml index 4eb9874..c0afd60 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,10 +14,14 @@ categories = ["command-line-utilities"] # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -clap = { version= "2.33.3", optional = true } +anyhow = "1.0.71" +clap = { version = "4.3.0", optional = true, features = ["unicode", "derive"] } +env_logger = "0.10.0" +log = "0.4.17" +nu-protocol = "0.80.0" [dev-dependencies] -criterion = "0.3" +criterion = "0.4" [features] default = ["bin"] diff --git a/examples/example.nu b/examples/example.nu new file mode 100644 index 0000000..d53c23b --- /dev/null +++ b/examples/example.nu @@ -0,0 +1,2399 @@ +alias ll = ls -l + + +[[status]; [UP] [UP]] | all {|el| $el.status == UP } +[foo bar 2 baz] | all {|| ($in | describe) == 'string' } +[0 2 4 6] | enumerate | all {|i| $i.item == $i.index * 2 } +let cond = {|el| ($el mod 2) == 0 }; [2 4 6 8] | all $cond + + +ansi green +ansi reset +$'(ansi red_bold)Hello(ansi reset) (ansi green_dimmed)Nu(ansi reset) (ansi purple_italic)World(ansi reset)' +$'(ansi rb)Hello(ansi reset) (ansi gd)Nu(ansi reset) (ansi pi)World(ansi reset)' +$"(ansi -e '3;93;41m')Hello(ansi reset)" # italic bright yellow on red background +let bold_blue_on_red = { # `fg`, `bg`, `attr` are the acceptable keys, all other keys are considered invalid and will throw errors. + fg: '#0000ff' + bg: '#ff0000' + attr: b + } + $"(ansi -e $bold_blue_on_red)Hello Nu World(ansi reset)" + + +'Hello, Nushell! This is a gradient.' | ansi gradient --fgstart '0x40c9ff' --fgend '0xe81cff' +'Hello, Nushell! This is a gradient.' | ansi gradient --fgstart '0x40c9ff' --fgend '0xe81cff' --bgstart '0xe81cff' --bgend '0x40c9ff' +'Hello, Nushell! This is a gradient.' | ansi gradient --fgstart '0x40c9ff' +'Hello, Nushell! This is a gradient.' | ansi gradient --fgend '0xe81cff' + + +'file:///file.txt' | ansi link --text 'Open Me!' +'https://www.nushell.sh/' | ansi link +[[url text]; [https://example.com Text]] | ansi link url + + +$'(ansi green)(ansi cursor_on)hello' | ansi strip + + +[[status]; [UP] [DOWN] [UP]] | any {|el| $el.status == DOWN } +[1 2 3 4] | any {|| ($in | describe) == 'string' } +[9 8 7 6] | enumerate | any {|i| $i.item == $i.index * 2 } +let cond = {|e| $e mod 2 == 1 }; [2 4 1 6 8] | any $cond + + +[0,1,2,3] | append 4 +[0,1] | append [2,3,4] +[0,1] | append [2,nu,4,shell] + + +ast 'hello' +ast 'ls | where name =~ README' +ast 'for x in 1..10 { echo $x ' + + + + +2 | bits and 2 +[4 3 2] | bits and 2 + + +[4 3 2] | bits not +[4 3 2] | bits not -n '2' +[4 3 2] | bits not -s + + +2 | bits or 6 +[8 3 2] | bits or 2 + + +17 | bits rol 2 +[5 3 2] | bits rol 2 + + +17 | bits ror 60 +[15 33 92] | bits ror 2 -n '1' + + +2 | bits shl 7 +2 | bits shl 7 -n '1' +0x7F | bits shl 1 -s +[5 3 2] | bits shl 2 + + +8 | bits shr 2 +[15 35 2] | bits shr 2 + + +2 | bits xor 2 +[8 3 2] | bits xor 2 + + +loop { break } + + + + +0x[1F FF AA AA] | bytes add 0x[AA] +0x[1F FF AA AA] | bytes add 0x[AA BB] -i 1 +0x[FF AA AA] | bytes add 0x[11] -e +0x[FF AA BB] | bytes add 0x[11 22 33] -e -i 1 + + + 0x[33 44 55 10 01 13] | bytes at 3..<4 + 0x[33 44 55 10 01 13] | bytes at 3..6 + 0x[33 44 55 10 01 13] | bytes at 3.. + 0x[33 44 55 10 01 13] | bytes at ..<4 + [[ColA ColB ColC]; [0x[11 12 13] 0x[14 15 16] 0x[17 18 19]]] | bytes at 1.. ColB ColC + + +bytes build 0x[01 02] 0x[03] 0x[04] + + +[0x[11] 0x[13 15]] | bytes collect +[0x[11] 0x[33] 0x[44]] | bytes collect 0x[01] + + +0x[1F FF AA AA] | bytes ends-with 0x[AA] +0x[1F FF AA AA] | bytes ends-with 0x[FF AA AA] +0x[1F FF AA AA] | bytes ends-with 0x[11] + + + 0x[33 44 55 10 01 13 44 55] | bytes index-of 0x[44 55] + 0x[33 44 55 10 01 13 44 55] | bytes index-of -e 0x[44 55] + 0x[33 44 55 10 01 33 44 33 44] | bytes index-of -a 0x[33 44] + 0x[33 44 55 10 01 33 44 33 44] | bytes index-of -a -e 0x[33 44] + [[ColA ColB ColC]; [0x[11 12 13] 0x[14 15 16] 0x[17 18 19]]] | bytes index-of 0x[11] ColA ColC + + +0x[1F FF AA AB] | bytes length +[0x[1F FF AA AB] 0x[1F]] | bytes length + + +0x[10 AA FF AA FF] | bytes remove 0x[10 AA] +0x[10 AA 10 BB 10] | bytes remove -a 0x[10] +0x[10 AA 10 BB CC AA 10] | bytes remove -e 0x[10] +[[ColA ColB ColC]; [0x[11 12 13] 0x[14 15 16] 0x[17 18 19]]] | bytes remove 0x[11] ColA ColC + + +0x[10 AA FF AA FF] | bytes replace 0x[10 AA] 0x[FF] +0x[10 AA 10 BB 10] | bytes replace -a 0x[10] 0x[A0] +[[ColA ColB ColC]; [0x[11 12 13] 0x[14 15 16] 0x[17 18 19]]] | bytes replace -a 0x[11] 0x[13] ColA ColC + + +0x[1F FF AA AA] | bytes reverse +0x[FF AA AA] | bytes reverse + + +0x[1F FF AA AA] | bytes starts-with 0x[1F FF AA] +0x[1F FF AA AA] | bytes starts-with 0x[1F] +0x[1F FF AA AA] | bytes starts-with 0x[11] + + +cal +cal --full-year 2012 +cal --week-start monday + + +cd ~ +cd d/s/9 +cd - + + +char newline +char --list +(char prompt) + (char newline) + (char hamburger) +char -u 1f378 +char -i (0x60 + 1) (0x60 + 2) +char -u 1F468 200D 1F466 200D 1F466 + + +clear + + +[1 2 3] | collect { |x| $x.1 } + + +{ acronym:PWD, meaning:'Print Working Directory' } | columns +[[name,age,grade]; [bill,20,a]] | columns +[[name,age,grade]; [bill,20,a]] | columns | first +[[name,age,grade]; [bill,20,a]] | columns | select 1 + + + + +[["Hello" "World"]; [null 3]] | compact Hello +[["Hello" "World"]; [null 3]] | compact World +[1, null, 2] | compact + + +^external arg1 | complete +do { ^external arg1 } | complete + + + + +config env + + +config nu + + +config reset + + +const x = 10 +const x = { a: 10, b: 20 } + + +for i in 1..10 { if $i == 5 { continue }; print $i } + + +cp myfile dir_b +cp -r dir_a dir_b +cp -r -v dir_a dir_b +cp *.txt dir_a + + + + +"2021-10-22 20:00:12 +01:00" | date format +date now | date format "%Y-%m-%d %H:%M:%S" +date now | date format "%Y-%m-%d %H:%M:%S" +"2021-10-22 20:00:12 +01:00" | date format "%Y-%m-%d" + + +"2021-10-22 20:00:12 +01:00" | date humanize + + +date list-timezone | where timezone =~ Shanghai + + +date now | date format "%Y-%m-%d %H:%M:%S" +(date now) - 2019-05-01 +(date now) - 2019-05-01T04:12:05.20+08:00 +date now | debug + + +date to-record +date now | date to-record +'2020-04-12T22:10:57.123+02:00' | date to-record + + +date to-table +date now | date to-table +2020-04-12T22:10:57.000000789+02:00 | date to-table + + +date now | date to-timezone '+0500' +date now | date to-timezone local +date now | date to-timezone US/Hawaii +"2020-10-10 10:00:00 +02:00" | date to-timezone "+0500" + + +'hello' | debug +['hello'] | debug +[[version patch]; ['0.1.0' false] ['0.1.1' true] ['0.2.0' false]] | debug + + +^cat myfile.q | decode utf-8 +0x[00 53 00 6F 00 6D 00 65 00 20 00 44 00 61 00 74 00 61] | decode utf-16be + + +'U29tZSBEYXRh' | decode base64 +'U29tZSBEYXRh' | decode base64 --binary + + +'0102030A0a0B' | decode hex +'01 02 03 0A 0a 0B' | decode hex + + +def say-hi [] { echo 'hi' }; say-hi +def say-sth [sth: string] { echo $sth }; say-sth hi + + +def-env foo [] { let-env BAR = "BAZ" }; foo; $env.BAR + + +ls -la | default 'nothing' target +$env | get -i MY_ENV | default 'abc' +[1, 2, null, 4] | default 3 + + +'hello' | describe + + +'a b c' | detect columns -n +$'c1 c2 c3(char nl)a b c' | detect columns + + +[[a b]; [1 2] [1 4] [2 6] [2 4]] + | dfr into-df + | dfr group-by a + | dfr agg [ + (dfr col b | dfr min | dfr as "b_min") + (dfr col b | dfr max | dfr as "b_max") + (dfr col b | dfr sum | dfr as "b_sum") + ] +[[a b]; [1 2] [1 4] [2 6] [2 4]] + | dfr into-lazy + | dfr group-by a + | dfr agg [ + (dfr col b | dfr min | dfr as "b_min") + (dfr col b | dfr max | dfr as "b_max") + (dfr col b | dfr sum | dfr as "b_sum") + ] + | dfr collect + + + + + +[false false false] | dfr into-df | dfr all-false +let s = ([5 6 2 10] | dfr into-df); + let res = ($s > 9); + $res | dfr all-false + + +[true true true] | dfr into-df | dfr all-true +let s = ([5 6 2 8] | dfr into-df); + let res = ($s > 9); + $res | dfr all-true + + +let a = ([[a b]; [1 2] [3 4]] | dfr into-df); + $a | dfr append $a +let a = ([[a b]; [1 2] [3 4]] | dfr into-df); + $a | dfr append $a --col + + +[1 3 2] | dfr into-df | dfr arg-max + + +[1 3 2] | dfr into-df | dfr arg-min + + +[1 2 2 3 3] | dfr into-df | dfr arg-sort +[1 2 2 3 3] | dfr into-df | dfr arg-sort -r + + +[false true false] | dfr into-df | dfr arg-true + + +[1 2 2 3 3] | dfr into-df | dfr arg-unique + + +let df = ([[a b]; [one 1] [two 2] [three 3]] | dfr into-df); + $df | dfr select (dfr arg-where ((dfr col b) >= 2) | dfr as b_arg) + + +dfr col a | dfr as new_a | dfr into-nu + + +["2021-12-30" "2021-12-31"] | dfr into-df | dfr as-datetime "%Y-%m-%d" + + +["2021-12-30 00:00:00" "2021-12-31 00:00:00"] | dfr into-df | dfr as-datetime "%Y-%m-%d %H:%M:%S" + + +[[a b]; [6 2] [4 2] [2 2]] | dfr into-df | dfr reverse | dfr cache + + +dfr col a | dfr into-nu + + +[[a b]; [1 2] [3 4]] | dfr into-lazy | dfr collect + + +[[a b]; [1 2] [3 4]] | dfr into-df | dfr columns + + +let df = ([[a b c]; [one two 1] [three four 2]] | dfr into-df); + $df | dfr with-column ((dfr concat-str "-" [(dfr col a) (dfr col b) ((dfr col c) * 2)]) | dfr as concat) + + +let other = ([za xs cd] | dfr into-df); + [abc abc abc] | dfr into-df | dfr concatenate $other + + +[abc acb acb] | dfr into-df | dfr contains ab + + + + + +let s = ([1 1 0 0 3 3 4] | dfr into-df); + ($s / $s) | dfr count-null + + +[1 2 3 4 5] | dfr into-df | dfr cumulative sum + + +[[a b]; [1 2] [3 4]] | dfr into-df | dfr drop a + + +[[a b]; [1 2] [3 4] [1 2]] | dfr into-df | dfr drop-duplicates + + +let df = ([[a b]; [1 2] [3 0] [1 2]] | dfr into-df); + let res = ($df.b / $df.b); + let a = ($df | dfr with-column $res --name res); + $a | dfr drop-nulls +let s = ([1 2 0 0 3 4] | dfr into-df); + ($s / $s) | dfr drop-nulls + + +[[a b]; [1 2] [3 4]] | dfr into-df | dfr dtypes + + +[[a b]; [1 2] [3 4]] | dfr into-df | dfr dummies +[1 2 2 3 3] | dfr into-df | dfr dummies + + + + + +(dfr col a) > 2) | dfr expr-not + + +[[a b]; [6 2] [4 2] [2 2]] | dfr into-df | dfr fetch 2 + + +[1 2 NaN 3 NaN] | dfr into-df | dfr fill-nan 0 +[[a b]; [0.2 1] [0.1 NaN]] | dfr into-df | dfr fill-nan 0 + + +[1 2 2 3 3] | dfr into-df | dfr shift 2 | dfr fill-null 0 + + +[[a b]; [6 2] [4 2] [2 2]] | dfr into-df | dfr filter ((dfr col a) >= 4) + + +let mask = ([true false] | dfr into-df); + [[a b]; [1 2] [3 4]] | dfr into-df | dfr filter-with $mask +[[a b]; [1 2] [3 4]] | dfr into-df | dfr filter-with ((dfr col a) > 1) + + +dfr col a | dfr first + + +[[a b]; [1 2] [3 4]] | dfr into-df | dfr first +[[a b]; [1 2] [3 4]] | dfr into-df | dfr first 2 + + + + + +[[a b]; [1 2] [3 4]] | dfr into-df | dfr get a + + +let dt = ('2020-08-04T16:39:18+00:00' | into datetime -z 'UTC'); + let df = ([$dt $dt] | dfr into-df); + $df | dfr get-day + + +let dt = ('2020-08-04T16:39:18+00:00' | into datetime -z 'UTC'); + let df = ([$dt $dt] | dfr into-df); + $df | dfr get-hour + + +let dt = ('2020-08-04T16:39:18+00:00' | into datetime -z 'UTC'); + let df = ([$dt $dt] | dfr into-df); + $df | dfr get-minute + + +let dt = ('2020-08-04T16:39:18+00:00' | into datetime -z 'UTC'); + let df = ([$dt $dt] | dfr into-df); + $df | dfr get-month + + +let dt = ('2020-08-04T16:39:18+00:00' | into datetime -z 'UTC'); + let df = ([$dt $dt] | dfr into-df); + $df | dfr get-nanosecond + + +let dt = ('2020-08-04T16:39:18+00:00' | into datetime -z 'UTC'); + let df = ([$dt $dt] | dfr into-df); + $df | dfr get-ordinal + + +let dt = ('2020-08-04T16:39:18+00:00' | into datetime -z 'UTC'); + let df = ([$dt $dt] | dfr into-df); + $df | dfr get-second + + +let dt = ('2020-08-04T16:39:18+00:00' | into datetime -z 'UTC'); + let df = ([$dt $dt] | dfr into-df); + $df | dfr get-week + + +let dt = ('2020-08-04T16:39:18+00:00' | into datetime -z 'UTC'); + let df = ([$dt $dt] | dfr into-df); + $df | dfr get-weekday + + +let dt = ('2020-08-04T16:39:18+00:00' | into datetime -z 'UTC'); + let df = ([$dt $dt] | dfr into-df); + $df | dfr get-year + + +[[a b]; [1 2] [1 4] [2 6] [2 4]] + | dfr into-df + | dfr group-by a + | dfr agg [ + (dfr col b | dfr min | dfr as "b_min") + (dfr col b | dfr max | dfr as "b_max") + (dfr col b | dfr sum | dfr as "b_sum") + ] +[[a b]; [1 2] [1 4] [2 6] [2 4]] + | dfr into-lazy + | dfr group-by a + | dfr agg [ + (dfr col b | dfr min | dfr as "b_min") + (dfr col b | dfr max | dfr as "b_max") + (dfr col b | dfr sum | dfr as "b_sum") + ] + | dfr collect + + +[[a b];[1 2] [3 4]] | dfr into-df +[[1 2 a] [3 4 b] [5 6 c]] | dfr into-df +[a b c] | dfr into-df +[true true false] | dfr into-df + + +[[a b];[1 2] [3 4]] | dfr into-lazy + + +dfr col a | dfr into-nu + + +[[a b]; [1 2] [3 4]] | dfr into-df | dfr into-nu +[[a b]; [1 2] [5 6] [3 4]] | dfr into-df | dfr into-nu -t -n 1 + + +[5 6 6 6 8 8 8] | dfr into-df | dfr is-duplicated +[[a, b]; [1 2] [1 2] [3 3] [3 3] [1 1]] | dfr into-df | dfr is-duplicated + + +let other = ([1 3 6] | dfr into-df); + [5 6 6 6 8 8 8] | dfr into-df | dfr is-in $other + + +let df = ([[a b]; [one 1] [two 2] [three 3]] | dfr into-df); + $df | dfr with-column (dfr col a | dfr is-in [one two] | dfr as a_in) + + +dfr col a | dfr is-not-null + + +let s = ([5 6 0 8] | dfr into-df); + let res = ($s / $s); + $res | dfr is-not-null + + +dfr col a | dfr is-null + + +let s = ([5 6 0 8] | dfr into-df); + let res = ($s / $s); + $res | dfr is-null + + +[5 6 6 6 8 8 8] | dfr into-df | dfr is-unique +[[a, b]; [1 2] [1 2] [3 3] [3 3] [1 1]] | dfr into-df | dfr is-unique + + +let df_a = ([[a b c];[1 "a" 0] [2 "b" 1] [1 "c" 2] [1 "c" 3]] | dfr into-lazy); + let df_b = ([["foo" "bar" "ham"];[1 "a" "let"] [2 "c" "var"] [3 "c" "const"]] | dfr into-lazy); + $df_a | dfr join $df_b a foo | dfr collect +let df_a = ([[a b c];[1 "a" 0] [2 "b" 1] [1 "c" 2] [1 "c" 3]] | dfr into-df); + let df_b = ([["foo" "bar" "ham"];[1 "a" "let"] [2 "c" "var"] [3 "c" "const"]] | dfr into-lazy); + $df_a | dfr join $df_b a foo + + +dfr col a | dfr last + + +[[a b]; [1 2] [3 4]] | dfr into-df | dfr last 1 + + + + + +dfr lit 2 | dfr into-nu + + +[Abc aBc abC] | dfr into-df | dfr lowercase + + +let test = ([[a b];[1 2] [3 4]] | dfr into-df); + ls + + +[[a b]; [6 2] [1 4] [4 1]] | dfr into-df | dfr max + + +[[a b]; [one 2] [one 4] [two 1]] + | dfr into-df + | dfr group-by a + | dfr agg (dfr col b | dfr max) + + +[[a b]; [one 2] [one 4] [two 1]] + | dfr into-df + | dfr group-by a + | dfr agg (dfr col b | dfr mean) + + +[[a b]; [6 2] [4 2] [2 2]] | dfr into-df | dfr mean + + +[[a b]; [6 2] [4 2] [2 2]] | dfr into-df | dfr median + + +[[a b]; [one 2] [one 4] [two 1]] + | dfr into-df + | dfr group-by a + | dfr agg (dfr col b | dfr median) + + +[[a b c d]; [x 1 4 a] [y 2 5 b] [z 3 6 c]] | dfr into-df | dfr melt -c [b c] -v [a d] + + +[[a b]; [one 2] [one 4] [two 1]] + | dfr into-df + | dfr group-by a + | dfr agg (dfr col b | dfr min) + + +[[a b]; [6 2] [1 4] [4 1]] | dfr into-df | dfr min + + +dfr col a | dfr n-unique + + +[1 1 2 2 3 3 4] | dfr into-df | dfr n-unique + + +[true false true] | dfr into-df | dfr not + + +dfr open test.csv + + +dfr when ((dfr col a) > 2) 4 | dfr otherwise 5 +dfr when ((dfr col a) > 2) 4 | dfr when ((dfr col a) < 0) 6 | dfr otherwise 0 +[[a b]; [6 2] [1 4] [4 1]] + | dfr into-lazy + | dfr with-column ( + dfr when ((dfr col a) > 2) 4 | dfr otherwise 5 | dfr as c + ) + | dfr with-column ( + dfr when ((dfr col a) > 5) 10 | dfr when ((dfr col a) < 2) 6 | dfr otherwise 0 | dfr as d + ) + | dfr collect + + +[[a b]; [one 2] [one 4] [two 1]] + | dfr into-df + | dfr group-by a + | dfr agg (dfr col b | dfr quantile 0.5) + + +[[a b]; [6 2] [1 4] [4 1]] | dfr into-df | dfr quantile 0.5 + + +[[a b]; [1 2] [3 4]] | dfr into-df | dfr query 'select a from df' + + +[5 6 7 8] | dfr into-df | dfr rename '0' new_name +[[a b]; [1 2] [3 4]] | dfr into-df | dfr rename a a_new +[[a b]; [1 2] [3 4]] | dfr into-df | dfr rename [a b] [a_new b_new] + + +[abc abc abc] | dfr into-df | dfr replace -p ab -r AB + + +[abac abac abac] | dfr into-df | dfr replace-all -p a -r A + + +[[a b]; [6 2] [4 2] [2 2]] | dfr into-df | dfr reverse + + +[1 2 3 4 5] | dfr into-df | dfr rolling sum 2 | dfr drop-nulls +[1 2 3 4 5] | dfr into-df | dfr rolling max 2 | dfr drop-nulls + + +[[a b]; [1 2] [3 4]] | dfr into-df | dfr sample -n 1 +[[a b]; [1 2] [3 4] [5 6]] | dfr into-df | dfr sample -f 0.5 -e + + +[[a b]; [6 2] [4 2] [2 2]] | dfr into-df | dfr select a + + +let s = ([1 2 2 3 3] | dfr into-df | dfr shift 2); + let mask = ($s | dfr is-null); + $s | dfr set 0 --mask $mask + + +let series = ([4 1 5 2 4 3] | dfr into-df); + let indices = ([0 2] | dfr into-df); + $series | dfr set-with-idx 6 -i $indices + + +[[a b]; [1 2] [3 4]] | dfr into-df | dfr shape + + +[1 2 2 3 3] | dfr into-df | dfr shift 2 | dfr drop-nulls + + +[[a b]; [1 2] [3 4]] | dfr into-df | dfr slice 0 1 + + +[[a b]; [6 2] [1 4] [4 1]] | dfr into-df | dfr sort-by a +[[a b]; [6 2] [1 1] [1 4] [2 4]] | dfr into-df | dfr sort-by [a b] -r [false true] + + +[[a b]; [one 2] [one 2] [two 1] [two 1]] + | dfr into-df + | dfr group-by a + | dfr agg (dfr col b | dfr std) + + +[[a b]; [6 2] [4 2] [2 2]] | dfr into-df | dfr std + + +[a ab abc] | dfr into-df | dfr str-lengths + + +[abcded abc321 abc123] | dfr into-df | dfr str-slice 1 -l 2 + + +let dt = ('2020-08-04T16:39:18+00:00' | into datetime -z 'UTC'); + let df = ([$dt $dt] | dfr into-df); + $df | dfr strftime "%Y/%m/%d" + + +[[a b]; [one 2] [one 4] [two 1]] + | dfr into-df + | dfr group-by a + | dfr agg (dfr col b | dfr sum) + + +[[a b]; [6 2] [1 4] [4 1]] | dfr into-df | dfr sum + + +[[a b]; [1 1] [1 1]] | dfr into-df | dfr summary + + +let df = ([[a b]; [4 1] [5 2] [4 3]] | dfr into-df); + let indices = ([0 2] | dfr into-df); + $df | dfr take $indices +let series = ([4 1 5 2 4 3] | dfr into-df); + let indices = ([0 2] | dfr into-df); + $series | dfr take $indices + + +[[a b]; [1 2] [3 4]] | dfr into-df | dfr to-arrow test.arrow + + +[[a b]; [1 2] [3 4]] | dfr into-df | dfr to-csv test.csv +[[a b]; [1 2] [3 4]] | dfr into-df | dfr to-csv test.csv -d '|' + + +[[a b]; [1 2] [3 4]] | dfr into-df | dfr to-parquet test.parquet + + +[2 2 2 2 2] | dfr into-df | dfr unique +col a | unique + + +[Abc aBc abC] | dfr into-df | dfr uppercase + + +[5 5 5 5 6 6] | dfr into-df | dfr value-counts + + +[[a b]; [6 2] [4 2] [2 2]] | dfr into-df | dfr var + + +[[a b]; [one 2] [one 2] [two 1] [two 1]] + | dfr into-df + | dfr group-by a + | dfr agg (dfr col b | dfr var) + + +dfr when ((dfr col a) > 2) 4 +dfr when ((dfr col a) > 2) 4 | dfr when ((dfr col a) < 0) 6 +[[a b]; [6 2] [1 4] [4 1]] + | dfr into-lazy + | dfr with-column ( + dfr when ((dfr col a) > 2) 4 | dfr otherwise 5 | dfr as c + ) + | dfr with-column ( + dfr when ((dfr col a) > 5) 10 | dfr when ((dfr col a) < 2) 6 | dfr otherwise 0 | dfr as d + ) + | dfr collect + + +[[a b]; [1 2] [3 4]] + | dfr into-df + | dfr with-column ([5 6] | dfr into-df) --name c +[[a b]; [1 2] [3 4]] + | dfr into-lazy + | dfr with-column [ + ((dfr col a) * 2 | dfr as "c") + ((dfr col a) * 3 | dfr as "d") + ] + | dfr collect + + +do { echo hello } +let text = "I am enclosed"; let hello = {|| echo $text}; do $hello +do -i { thisisnotarealcommand } +do -s { thisisnotarealcommand } +do -p { nu -c 'exit 1' }; echo "I'll still run" +do -c { nu -c 'exit 1' } | myscarycommand +do {|x| 100 + $x } 77 +77 | do {|x| 100 + $in } + + +[0,1,2,3] | drop +[0,1,2,3] | drop 0 +[0,1,2,3] | drop 2 +[[a, b]; [1, 2] [3, 4]] | drop 1 + + +[[lib, extension]; [nu-lib, rs] [nu-core, rb]] | drop column + + +[sam,sarah,2,3,4,5] | drop nth 0 1 2 +[0,1,2,3,4,5] | drop nth 0 1 2 +[0,1,2,3,4,5] | drop nth 0 2 4 +[0,1,2,3,4,5] | drop nth 2 0 4 +[first second third fourth fifth] | drop nth (1..3) +[0,1,2,3,4,5] | drop nth 1.. +[0,1,2,3,4,5] | drop nth 3.. + + +du + + +[1 2 3] | each {|e| 2 * $e } +{major:2, minor:1, patch:4} | values | each {|| into string } +[1 2 3 2] | each {|e| if $e == 2 { "two" } } +[1 2 3] | enumerate | each {|e| if $e.item == 2 { $"found 2 at ($e.index)!"} } +[1 2 3] | each --keep-empty {|e| if $e == 2 { "found 2!"} } + + +[1 2 3 2 1] | each while {|e| if $e < 3 { $e * 2 } } +[1 2 stop 3 4] | each while {|e| if $e != 'stop' { $"Output: ($e)" } } +[1 2 3] | enumerate | each while {|e| if $e.item < 2 { $"value ($e.item) at ($e.index)!"} } + + +echo 1 2 3 +echo $in + + +"負けると知って戦うのが、遥かに美しいのだ" | encode shift-jis +"🎈" | encode -i shift-jis + + +0x[09 F9 11 02 9D 74 E3 5B D8 41 56 C5 63 56 88 C0] | encode base64 +'Some Data' | encode base64 +'Some Data' | encode base64 --character-set binhex + + +0x[09 F9 11 02 9D 74 E3 5B D8 41 56 C5 63 56 88 C0] | encode hex + + +enter ../dir-foo + + +[a, b, c] | enumerate + + +error make {msg: "my custom error message"} +error make { + msg: "my custom error message" + label: { + text: "my custom label text" # not mandatory unless $.label exists + start: 123 # not mandatory unless $.label.end is set + end: 456 # not mandatory unless $.label.start is set + } + } +def foo [x] { + let span = (metadata $x).span; + error make { + msg: "this is fishy" + label: { + text: "fish right here" + start: $span.start + end: $span.end + } + } + } + + +[1 2 3 4 5] | every 2 +[1 2 3 4 5] | every 2 --skip + + +exec ps aux +exec nautilus + + +exit +exit --now + + +explain {|| ls | sort-by name type -i | get name } | table -e + + +sys | explore +ls | explore --head false +glob *.md | each {|| open } | explore -i +open file.json | explore -p | to json | save part.json + + +module utils { export def my-command [] { "hello" } }; use utils my-command; my-command + + +module spam { export alias ll = ls -l } + + +module spam { export def foo [] { "foo" } }; use spam foo; foo + + +module foo { export def-env bar [] { let-env FOO_BAR = "BAZ" } }; use foo bar; bar; $env.FOO_BAR + + +export extern echo [text: string] + + +export old-alias ll = ls -l + + +module spam { export def foo [] { "foo" } } + module eggs { export use spam foo } + use eggs foo + foo + + + +export-env { let-env SPAM = 'eggs' } +export-env { let-env SPAM = 'eggs' }; $env.SPAM + + +extern echo [text: string] + + +'nushell' | fill -a l -c '─' -w 15 +'nushell' | fill -a r -c '─' -w 15 +'nushell' | fill -a m -c '─' -w 15 +1 | fill --alignment right --character '0' --width 5 +1.1 | fill --alignment center --character '0' --width 5 +1kib | fill --alignment middle --character '0' --width 10 + + +[1 2] | filter {|x| $x > 1} +[{a: 1} {a: 2}] | filter {|x| $x.a > 1} +let cond = {|x| $x.a > 1}; [{a: 1} {a: 2}] | filter $cond + + +ls | find toml md sh +'Cargo.toml' | find toml +[1 5 3kb 4 3Mb] | find 5 3kb +[moe larry curly] | find l +[abc bde arc abf] | find --regex "ab" +[aBc bde Arc abf] | find --regex "ab" -i +[[version name]; ['0.1.0' nushell] ['0.1.1' fish] ['0.2.0' zsh]] | find -r "nu" +[[foo bar]; [abc 123] [def 456]] | find 123 | get bar | ansi strip + + +[1 2 3] | first +[1 2 3] | first 2 +0x[01 23 45] | first 2 + + +[[N, u, s, h, e, l, l]] | flatten +[[N, u, s, h, e, l, l]] | flatten | first +[[origin, people]; [Ecuador, ([[name, meal]; ['Andres', 'arepa']])]] | flatten --all | get meal +[[origin, crate, versions]; [World, ([[name]; ['nu-cli']]), ['0.21', '0.22']]] | flatten versions --all | last | get versions +{ a: b, d: [ 1 2 3 4 ], e: [ 4 3 ] } | flatten d --all + + +42 | fmt + + +for x in [1 2 3] { print ($x * $x) } +for $x in 1..3 { print $x } +for $it in ['bob' 'fred'] --numbered { print $"($it.index) is ($it.item)" } + + +ls | format '{name}: {size}' +[[col1, col2]; [v1, v2] [v3, v4]] | format '{col2}' + + +ls | format filesize KB size +du | format filesize B apparent +4Gb | format filesize MB + + + + +"ColA,ColB +1,2" | from csv +open data.txt | from csv --noheaders +open data.txt | from csv --separator ';' +open data.txt | from csv --comment '#' +open data.txt | from csv --trim all +open data.txt | from csv --trim headers +open data.txt | from csv --trim fields + + +'From: test@email.com +Subject: Welcome +To: someone@somewhere.com +Test' | from eml +'From: test@email.com +Subject: Welcome +To: someone@somewhere.com +Test' | from eml -b 1 + + +'BEGIN:VCALENDAR + END:VCALENDAR' | from ics + + +'[foo] +a=1 +b=2' | from ini + + +'{ "a": 1 }' | from json +'{ "a": 1, "b": [1, 2] }' | from json + + +'{ a:1 }' | from nuon +'{ a:1, b: [1, 2] }' | from nuon + + +open --raw test.ods | from ods +open --raw test.ods | from ods -s [Spreadsheet1] + + +open --raw file.parquet | from parquet +open file.parquet + + + + +'FOO BAR +1 2' | from ssv +'FOO BAR +1 2' | from ssv -n + + +'a = 1' | from toml +'a = 1 +b = [1, 2]' | from toml + + +"ColA ColB +1 2" | from tsv +$'c1(char tab)c2(char tab)c3(char nl)1(char tab)2(char tab)3' | save tsv-data | open tsv-data | from tsv +$'a1(char tab)b1(char tab)c1(char nl)a2(char tab)b2(char tab)c2' | save tsv-data | open tsv-data | from tsv -n +$'a1(char tab)b1(char tab)c1(char nl)a2(char tab)b2(char tab)c2' | save tsv-data | open tsv-data | from tsv --trim all +$'a1(char tab)b1(char tab)c1(char nl)a2(char tab)b2(char tab)c2' | save tsv-data | open tsv-data | from tsv --trim headers +$'a1(char tab)b1(char tab)c1(char nl)a2(char tab)b2(char tab)c2' | save tsv-data | open tsv-data | from tsv --trim fields + + +'bread=baguette&cheese=comt%C3%A9&meat=ham&fat=butter' | from url + + +'BEGIN:VCARD +N:Foo +FN:Bar +EMAIL:foo@bar.com +END:VCARD' | from vcf + + +open --raw test.xlsx | from xlsx +open --raw test.xlsx | from xlsx -s [Spreadsheet1] + + +' + + Event +' | from xml + + +'a: 1' | from yaml +'[ a: 1, b: [1, 2] ]' | from yaml + + +'a: 1' | from yaml +'[ a: 1, b: [1, 2] ]' | from yaml + + +g +mkdir foo bar; enter foo; enter ../bar; g 1 +shells; g 2 +mkdir foo bar; enter foo; enter ../bar; g - + + +[0 1 2] | get 1 +[{A: A0}] | get A +[{A: A0}] | get 0.A +ls | get name.2 +ls | get 2.name +sys | get cpu +$env | get paTH +$env | get -s Path + + +glob *.rs +glob **/*.{rs,toml} --depth 2 +glob "[Cc]*" +glob "{a?c,x?z}" +glob "(?i)c*" +glob "[!cCbMs]*" +glob +glob <[a-d]:1,10> +glob "[A-Z]*" --no-file --no-symlink + + +[1 2 3 a b c] | grid +[1 2 3 a b c] | wrap name | grid +{name: 'foo', b: 1, c: 2} | grid +[{name: 'A', v: 1} {name: 'B', v: 2} {name: 'C', v: 3}] | grid +[[name patch]; [0.1.0 false] [0.1.1 true] [0.2.0 false]] | grid + + +[1 2 3 4] | group 2 + + +ls | group-by type +['1' '3' '1' '3' '2' '1' '1'] | group-by + + + + + + + + +'abcdefghijklmnopqrstuvwxyz' | hash md5 +'abcdefghijklmnopqrstuvwxyz' | hash md5 --binary +open ./nu_0_24_1_windows.zip | hash md5 + + +'abcdefghijklmnopqrstuvwxyz' | hash sha256 +'abcdefghijklmnopqrstuvwxyz' | hash sha256 --binary +open ./nu_0_24_1_windows.zip | hash sha256 + + +"a b c|1 2 3" | split row "|" | split column " " | headers +"a b c|1 2 3|1 2 3 4" | split row "|" | split column " " | headers + + +help match +help str lpad +help --find char + + +help aliases +help aliases my-alias +help aliases --find my-alias + + + + +help externs +help externs smth +help externs --find smth + + +help modules +help modules my-module +help modules --find my-module + + + + +alias lll = ls -l; hide lll +def say-hi [] { echo 'Hi!' }; hide say-hi + + +let-env HZ_ENV_ABC = 1; hide-env HZ_ENV_ABC; 'HZ_ENV_ABC' in (env).name + + + + +ls | histogram type +ls | histogram type freq +[1 2 1] | histogram +[1 2 3 1 1 1 2 2 1 1] | histogram --percentage-type relative + + +history | length +history | last 5 +history | wrap cmd | where cmd =~ cargo + + +history session + + + + +http delete https://www.example.com +http delete -u myuser -p mypass https://www.example.com +http delete -H [my-header-key my-header-value] https://www.example.com +http delete -d 'body' https://www.example.com +http delete -t application/json -d { field: value } https://www.example.com + + +http get https://www.example.com +http get -u myuser -p mypass https://www.example.com +http get -H [my-header-key my-header-value] https://www.example.com + + +http head https://www.example.com +http head -u myuser -p mypass https://www.example.com +http head -H [my-header-key my-header-value] https://www.example.com + + +http patch https://www.example.com 'body' +http patch -u myuser -p mypass https://www.example.com 'body' +http patch -H [my-header-key my-header-value] https://www.example.com +http patch -t application/json https://www.example.com { field: value } + + +http post https://www.example.com 'body' +http post -u myuser -p mypass https://www.example.com 'body' +http post -H [my-header-key my-header-value] https://www.example.com +http post -t application/json https://www.example.com { field: value } + + +http put https://www.example.com 'body' +http put -u myuser -p mypass https://www.example.com 'body' +http put -H [my-header-key my-header-value] https://www.example.com +http put -t application/json https://www.example.com { field: value } + + +if 2 < 3 { 'yes!' } +if 5 < 3 { 'yes!' } else { 'no!' } +if 5 < 3 { 'yes!' } else if 4 < 5 { 'no!' } else { 'okay!' } + + +echo done | ignore + + + + +let user_input = (input) + + +{'name': 'nu', 'stars': 5} | insert alias 'Nushell' +[[project, lang]; ['Nushell', 'Rust']] | insert type 'shell' +[[foo]; [7] [8] [9]] | enumerate | insert bar {|e| $e.item.foo + $e.index } | flatten + + +ls | inspect | get name | inspect + + + + +'This is a string that is exactly 52 characters long.' | into binary +1 | into binary +true | into binary +ls | where name == LICENSE | get size | into binary +ls | where name == LICENSE | get name | path expand | into binary +1.234 | into binary + + +[[value]; ['false'] ['1'] [0] [1.0] [true]] | into bool value +true | into bool +1 | into bool +0.3 | into bool +'0.0' | into bool +'true' | into bool + + +'27.02.2021 1:55 pm +0000' | into datetime +'2021-02-27T13:55:40.2246+00:00' | into datetime +'20210227_135540+0000' | into datetime -f '%Y%m%d_%H%M%S%z' +1614434140123456789 | into datetime --offset -5 +1614434140 * 1_000_000_000 | into datetime + + +[[num]; ['5.01']] | into decimal num +'1.345' | into decimal +'-5.9' | into decimal +true | into decimal + + +[[value]; ['1sec'] ['2min'] ['3hr'] ['4day'] ['5wk']] | into duration value +'7min' | into duration +'7min' | into duration --convert sec +420sec | into duration +420sec | into duration --convert ms +1000000µs | into duration --convert sec +1sec | into duration --convert µs +1sec | into duration --convert us + + +[[bytes]; ['5'] [3.2] [4] [2kb]] | into filesize bytes +'2' | into filesize +8.3 | into filesize +5 | into filesize +4KB | into filesize + + +[[num]; ['-5'] [4] [1.5]] | into int num +'2' | into int +5.9 | into int +'5.9' | into int +4KB | into int +[false, true] | into int +1983-04-13T12:09:14.123456789-05:00 | into int +'1101' | into int -r 2 +'FF' | into int -r 16 +'0o10132' | into int +'0010132' | into int +'0010132' | into int -r 8 + + +[[value]; [false]] | into record +[1 2 3] | into record +0..2 | into record +-500day | into record +{a: 1, b: 2} | into record +2020-04-12T22:10:57+02:00 | into record + + +ls | into sqlite my_ls.db +ls | into sqlite my_ls.db -t my_table +[[name]; [-----] [someone] [=====] [somename] ['(((((']] | into sqlite filename.db +[one 2 5.2 six true 100mib 25sec] | into sqlite variety.db + + +5 | into string -d 3 +1.7 | into string -d 0 +1.7 | into string -d 1 +1.734 | into string -d 2 +1.734 | into string -d -2 +4.3 | into string +'1234' | into string +true | into string +ls Cargo.toml | get name | into string +1KiB | into string + + +if is-admin { "iamroot" } else { "iamnotroot" } + + +'' | is-empty +[] | is-empty +[[meal size]; [arepa small] [taco '']] | is-empty meal size + + +{ new: york, san: francisco } | items {|key, value| echo $'($key) ($value)' } + + +[{a: 1 b: 2}] | join [{a: 1 c: 3}] a + + +open -r test.json | json path '$.store.book[*].author' + + + + +keybindings default + + +keybindings list -m +keybindings list -e -d +keybindings list + + +keybindings listen + + +ps | sort-by mem | last | kill $in.pid +kill --force 12345 +kill -s 2 12345 + + +[1,2,3] | last 2 +[1,2,3] | last + + +[1 2 3 4 5] | length +[{columnA: A0 columnB: B0}] | length -c + + +let x = 10 +let x = 10 + 100 +let x = if false { -1 } else { 1 } + + +let-env MY_ENV_VAR = 1; $env.MY_ENV_VAR + + +$"two\nlines" | lines + + +{NAME: ABE, AGE: UNKNOWN} | load-env; $env.NAME +load-env {NAME: ABE, AGE: UNKNOWN}; $env.NAME + + +mut x = 0; loop { if $x > 10 { break }; $x = $x + 1 }; $x + + +ls +ls subdir +ls -f .. +ls *.rs +ls -s | where name !~ bar +ls -a ~ | where type == dir +ls -as ~ | where type == dir and modified < ((date now) - 7day) +['/path/to/directory' '/path/to/file'] | each {|| ls -D $in } | flatten + + +match 3 { 1..10 => 'yes!' } +match {a: 100} { {a: $my_value} => { $my_value } } +match 3 { 1 => { 'yes!' }, _ => { 'no!' } } +match [1, 2, 3] { [$a, $b, $c] => { $a + $b + $c }, _ => 0 } +{a: {b: 3}} | match $in {{a: { $b }} => ($b + 10) } + + + + +[-50 -100.0 25] | math abs + + +1 | math arccos +-1 | math arccos -d + + +1 | math arccosh + + +1 | math arcsin +1 | math arcsin -d + + +0 | math arcsinh + + +1 | math arctan +-1 | math arctan -d + + +1 | math arctanh + + +[-50 100.0 25] | math avg + + +[1.5 2.3 -3.1] | math ceil + + +math pi | math cos +[0 90 180 270 360] | math cos -d + + +1 | math cosh + + +math e | math round --precision 3 + + + + +0 | math exp +1 | math exp + + +[1.5 2.3 -3.1] | math floor + + +math e | math ln + + +100 | math log 10 +[16 8 4] | math log 2 + + +[-50 100 25] | math max +[{a: 1 b: 3} {a: 2 b: -1}] | math max + + +[3 8 9 12 12 15] | math median +[{a: 1 b: 3} {a: 2 b: -1} {a: -3 b: 5}] | math median + + +[-50 100 25] | math min +[{a: 1 b: 3} {a: 2 b: -1}] | math min + + +[3 3 9 12 12 15] | math mode +[{a: 1 b: 3} {a: 2 b: -1} {a: 1 b: 5}] | math mode + + +math pi | math round --precision 2 + + +[2 3 3 4] | math product + + +[1.5 2.3 -3.1] | math round +[1.555 2.333 -3.111] | math round -p 2 + + +(math pi) / 2 | math sin +[0 90 180 270 360] | math sin -d | math round --precision 4 + + +1 | math sinh + + +[9 16] | math sqrt + + +[1 2 3 4 5] | math stddev +[1 2 3 4 5] | math stddev -s + + +[1 2 3] | math sum +ls | get size | math sum + + +(math pi) / 4 | math tan +[-45 0 45] | math tan -d + + +(math pi) * 10 | math tanh + + +math tau | math round --precision 2 + + +[1 2 3 4 5] | math variance +[1 2 3 4 5] | math variance -s + + +[a b c] | wrap name | merge ( [1 2 3] | wrap index ) +{a: 1, b: 2} | merge {c: 3} +[{columnA: A0 columnB: B0}] | merge [{columnA: 'A0*'}] + + +let a = 42; metadata $a +ls | metadata + + +mkdir foo +mkdir -v foo/bar foo2 + + +module spam { export def foo [] { "foo" } }; use spam foo; foo +module foo { export-env { let-env FOO = "BAZ" } }; use foo; $env.FOO +module foo { export def-env bar [] { let-env FOO_BAR = "BAZ" } }; use foo bar; bar; $env.FOO_BAR + + +[[name value index]; [foo a 1] [bar b 2] [baz c 3]] | move index --before name +[[name value index]; [foo a 1] [bar b 2] [baz c 3]] | move value name --after index +{ name: foo, value: a, index: 1 } | move name --before index + + +mut x = 10; $x = 12 +mut a = {b:{c:1}}; $a.b.c = 2 +mut x = 10 + 100 +mut x = if false { -1 } else { 1 } + + +mv before.txt after.txt +mv test.txt my/subdirectory +mv *.txt my/subdirectory + + +mkdir foo bar; enter foo; enter ../bar; n +n + + +nu-check script.nu +nu-check --as-module module.nu +nu-check -d script.nu +open foo.nu | nu-check -d script.nu +open module.nu | lines | nu-check -d --as-module module.nu +$'two(char nl)lines' | nu-check +nu-check -a script.nu +open foo.nu | lines | nu-check -ad + + +'let x = 3' | nu-highlight + + +old-alias ll = ls -l +old-alias customs = ($nu.scope.commands | where is_custom | get command) + + +open myfile.json +open myfile.json --raw +'myfile.txt' | open +open myfile.txt --raw | decode utf-8 + + + + +module spam { export def foo [] { "foo" } } + overlay use spam + def bar [] { "bar" } + overlay hide spam --keep-custom + bar + +'export alias f = "foo"' | save spam.nu + overlay use spam.nu + overlay hide spam +module spam { export-env { let-env FOO = "foo" } } + overlay use spam + overlay hide +overlay new spam + cd some-dir + overlay hide --keep-env [ PWD ] spam + + +module spam { export def foo [] { "foo" } } + overlay use spam + overlay list | last + + +overlay new spam + + +module spam { export def foo [] { "foo" } } + overlay use spam + foo +module spam { export def foo [] { "foo" } } + overlay use spam as spam_new + foo +'export def foo { "foo" }' + overlay use --prefix spam + spam foo +'export-env { let-env FOO = "foo" }' | save spam.nu + overlay use spam.nu + $env.FOO + + +mkdir foo bar; enter foo; enter ../bar; p +p + + +[1 2 3] | par-each {|| 2 * $in } +[foo bar baz] | par-each {|e| $e + '!' } | sort +1..3 | enumerate | par-each {|p| update item ($p.item * 2)} | sort-by item | get item +[1 2 3] | enumerate | par-each { |e| if $e.item == 2 { $"found 2 at ($e.index)!"} } + + +"hi there" | parse "{foo} {bar}" +"hi there" | parse -r '(?P\w+) (?P\w+)' +"foo bar." | parse -r '\s*(?\w+)(?=\.)' +"foo! bar." | parse -r '(\w+)(?=\.)|(\w+)(?=!)' +" @another(foo bar) " | parse -r '\s*(?<=[() ])(@\w+)(\([^)]*\))?\s*' +"abcd" | parse -r '^a(bc(?=d)|b)cd$' + + + + +'/home/joe/test.txt' | path basename +[[name];[/home/joe]] | path basename -c [ name ] +'/home/joe/test.txt' | path basename -r 'spam.png' + + +'/home/joe/code/test.txt' | path dirname +ls ('.' | path expand) | path dirname -c [ name ] +'/home/joe/code/test.txt' | path dirname -n 2 +'/home/joe/code/test.txt' | path dirname -n 2 -r /home/viking + + +'/home/joe/todo.txt' | path exists +ls | path exists -c [ name ] + + +'/home/joe/foo/../bar' | path expand +ls | path expand -c [ name ] +'foo/../bar' | path expand + + +'/home/viking' | path join spam.txt +'/home/viking' | path join spams this_spam.txt +ls | path join spam.txt -c [ name ] +[ '/' 'home' 'viking' 'spam.txt' ] | path join +[[ parent stem extension ]; [ '/home/viking' 'spam' 'txt' ]] | path join + + +'/home/viking/spam.txt' | path parse +'/home/viking/spam.tar.gz' | path parse -e tar.gz | upsert extension { 'txt' } +'/etc/conf.d' | path parse -e '' +ls | path parse -c [ name ] + + +'/home/viking' | path relative-to '/home' +ls ~ | path relative-to ~ -c [ name ] +'eggs/bacon/sausage/spam' | path relative-to 'eggs/bacon/sausage' + + +'/home/viking/spam.txt' | path split +ls ('.' | path expand) | path split -c [ name ] + + +'.' | path type +ls | path type -c [ name ] + + + + + + +pnet + + +port 3121 4000 +port + + +[1,2,3,4] | prepend 0 +[2,3,4] | prepend [0,1] +[2,nu,4,shell] | prepend [0,1,rocks] + + +print "hello world" +print (2 + 3) + + +def spam [] { "spam" }; profile {|| spam | str length } -d 2 --source + + +ps +ps | sort-by mem | last 5 +ps | sort-by cpu | last 3 +ps | where name =~ 'nu' +ps | where pid == $nu.pid | get ppid + + + + +open foo.db | query db "SELECT * FROM Bar" + + + + +http get https://phoronix.com | query web -q 'header' +http get https://en.wikipedia.org/wiki/List_of_cities_in_India_by_population + | query web -t [Rank City 'Population(2011)[3]' 'Population(2001)' 'State or union territory'] +http get https://www.nushell.sh | query web -q 'h2, h2 + p' | group 2 | each {rotate --ccw tagline description} | flatten +http get https://example.org | query web --query a --attribute href + + + + + + +random bool +random bool --bias 0.75 + + +random chars +random chars -l 20 + + +random decimal +random decimal ..500 +random decimal 100000.. +random decimal 1.0..1.1 + + +random dice +random dice -d 10 -s 12 + + +random integer +random integer ..500 +random integer 100000.. +random integer 1..10 + + +random uuid + + +[0,1,2,3,4,5] | range 4..5 +[0,1,2,3,4,5] | range (-2).. +[0,1,2,3,4,5] | range (-3)..-2 + + +[ 1 2 3 4 ] | reduce {|it, acc| $it + $acc } +[ 8 7 6 ] | enumerate | reduce -f 0 {|it, acc| $acc + $it.item + $it.index } +[ 1 2 3 4 ] | reduce -f 10 {|it, acc| $acc + $it } +[ i o t ] | reduce -f "Arthur, King of the Britons" {|it, acc| $acc | str replace -a $it "X" } +['foo.gz', 'bar.gz', 'baz.gz'] | enumerate | reduce -f '' {|str all| $"($all)(if $str.index != 0 {'; '})($str.index + 1)-($str.item)" } + + +"hello world" | regex '(?P\w+) (?P\w+)' + + +register ~/.cargo/bin/nu_plugin_query +let plugin = ((which nu).path.0 | path dirname | path join 'nu_plugin_query'); nu -c $'register ($plugin); version' + + +ls | reject modified +[[a, b]; [1, 2]] | reject a +{a: 1, b: 2} | reject a +{a: {b: 3, c: 5}} | reject a.b + + +[[a, b]; [1, 2]] | rename my_column +[[a, b, c]; [1, 2, 3]] | rename eggs ham bacon +[[a, b, c]; [1, 2, 3]] | rename -c [a ham] +{a: 1 b: 2} | rename x y + + +def foo [] { return } + + +[0,1,2,3] | reverse +[{a: 1} {a: 2}] | reverse + + +rm file.txt +rm --trash file.txt +rm --permanent file.txt +rm --force file.txt +ls | where size == 0KB and type == file | each { rm $in.name } | null + + + + +[[a b]; [1 2] [3 4] [5 6]] | roll down + + +{a:1 b:2 c:3} | roll left +[[a b c]; [1 2 3] [4 5 6]] | roll left +[[a b c]; [1 2 3] [4 5 6]] | roll left --cells-only + + +{a:1 b:2 c:3} | roll right +[[a b c]; [1 2 3] [4 5 6]] | roll right +[[a b c]; [1 2 3] [4 5 6]] | roll right --cells-only + + +[[a b]; [1 2] [3 4] [5 6]] | roll up + + +{a:1, b:2} | rotate +[[a b]; [1 2] [3 4] [5 6]] | rotate +[[a b]; [1 2]] | rotate col_a col_b +[[a b]; [1 2]] | rotate --ccw +[[a b]; [1 2] [3 4] [5 6]] | rotate --ccw +[[a b]; [1 2]] | rotate --ccw col_a col_b + + +run-external "echo" "-n" "hello" +run-external --redirect-stdout "echo" "-n" "hello" | split chars + + +'save me' | save foo.txt +'append me' | save --append foo.txt +{ a: 1, b: 2 } | save foo.json +do -i {} | save foo.txt --stderr foo.txt +do -i {} | save foo.txt --stderr bar.txt + + +open foo.db | schema + + +[{a: a b: b}] | select a +{a: a b: b} | select a +ls | select name +ls | select 0 1 2 3 + + +seq 1 10 +seq 1.0 0.1 2.0 +seq 1 5 | str join '|' + + +seq char a e +seq char a e | str join '|' + + +seq date --days 10 +seq date --days 10 -r +seq date --days 10 -o '%m/%d/%Y' -r +seq date -b '2020-01-01' -e '2020-01-10' +seq date -b '2020-01-01' -e '2020-01-31' -n 5 + + +enter ..; shells +shells | where active == true + + +[[version patch]; ['1.0.0' false] ['3.0.1' true] ['2.0.0' false]] | shuffle + + +"There are seven words in this sentence" | size +'今天天气真好' | size +"Amélie Amelie" | size + + +[2 4 6 8] | skip 1 +[[editions]; [2015] [2018] [2021]] | skip 2 + + +[-2 0 2 -1] | skip until {|x| $x > 0 } +let cond = {|x| $x > 0 }; [-2 0 2 -1] | skip until $cond +[{a: -2} {a: 0} {a: 2} {a: -1}] | skip until {|x| $x.a > 0 } + + +[-2 0 2 -1] | skip while {|x| $x < 0 } +let cond = {|x| $x < 0 }; [-2 0 2 -1] | skip while $cond +[{a: -2} {a: 0} {a: 2} {a: -1}] | skip while {|x| $x.a < 0 } + + +sleep 1sec + + +[2 0 1] | sort +[2 0 1] | sort -r +[betty amy sarah] | sort +[betty amy sarah] | sort -r +[airplane Truck Car] | sort -i +[airplane Truck Car] | sort -i -r +{b: 3, a: 4} | sort +{b: 4, a: 3, c:1} | sort -v + + +ls | sort-by modified +ls | sort-by name -i +[[fruit count]; [apple 9] [pear 3] [orange 7]] | sort-by fruit -r + + +source foo.nu +source ./foo.nu; say-hi + + +source-env foo.nu + + + + +'hello' | split chars +'🇯🇵ほげ' | split chars -g + + +'a--b--c' | split column '--' +'abc' | split column -c '' +['a-b' 'c-d'] | split column - +['a - b' 'c - d'] | split column -r '\s*-\s*' + + +[a, b, c, d, e, f, g] | split list d +[[1,2], [2,3], [3,4]] | split list [2,3] +[a, b, c, d, a, e, f, g] | split list a +[a, b, c, d, a, e, f, g] | split list -r '(b|e)' + + +'abc' | split row '' +'a--b--c' | split row '--' +'-a-b-c-' | split row '-' +'a b c' | split row -r '\s+' + + +'hello world' | split words +'hello to the world' | split words -l 3 +http get https://www.gutenberg.org/files/11/11-0.txt | str downcase | split words -l 2 | uniq -c | sort-by count --reverse | first 10 + + +{ + '2019': [ + { name: 'andres', lang: 'rb', year: '2019' }, + { name: 'jt', lang: 'rs', year: '2019' } + ], + '2021': [ + { name: 'storm', lang: 'rs', 'year': '2021' } + ] + } | split-by lang + + +start file.txt +start file.jpg +start . +start file.pdf +start https://www.nushell.sh + + + + + 'NuShell' | str camel-case +'this-is-the-first-case' | str camel-case + 'this_is_the_second_case' | str camel-case +[[lang, gems]; [nu_test, 100]] | str camel-case lang + + +'good day' | str capitalize +'anton' | str capitalize +[[lang, gems]; [nu_test, 100]] | str capitalize lang + + + + +'my_library.rb' | str contains '.rb' +'my_library.rb' | str contains -i '.RB' + [[ColA ColB]; [test 100]] | str contains 'e' ColA + [[ColA ColB]; [test 100]] | str contains -i 'E' ColA + [[ColA ColB]; [test hello]] | str contains 'e' ColA ColB +'hello' | str contains 'banana' +[one two three] | str contains o +[one two three] | str contains -n o + + +'nushell' | str distance 'nutshell' +[{a: 'nutshell' b: 'numetal'}] | str distance 'nushell' 'a' 'b' + + +'NU' | str downcase +'TESTa' | str downcase +[[ColA ColB]; [Test ABC]] | str downcase ColA +[[ColA ColB]; [Test ABC]] | str downcase ColA ColB + + +'my_library.rb' | str ends-with '.rb' +'my_library.rb' | str ends-with '.txt' +'my_library.rb' | str ends-with -i '.RB' + + + + + 'my_library.rb' | str index-of '.rb' +'🇯🇵ほげ ふが ぴよ' | str index-of -g 'ふが' + '.rb.rb' | str index-of '.rb' -r 1.. + '123456' | str index-of '6' -r ..4 + '123456' | str index-of '3' -r 1..4 + '/this/is/some/path/file.txt' | str index-of '/' -e + + +['nu', 'shell'] | str join +['nu', 'shell'] | str join '-' + + +'NuShell' | str kebab-case +'thisIsTheFirstCase' | str kebab-case +'THIS_IS_THE_SECOND_CASE' | str kebab-case +[[lang, gems]; [nuTest, 100]] | str kebab-case lang + + +'hello' | str length +'🇯🇵ほげ ふが ぴよ' | str length -g +['hi' 'there'] | str length + + + + +'nu-shell' | str pascal-case +'this-is-the-first-case' | str pascal-case +'this_is_the_second_case' | str pascal-case +[[lang, gems]; [nu_test, 100]] | str pascal-case lang + + +'my_library.rb' | str replace '(.+).rb' '$1.nu' +'abc abc abc' | str replace -a 'b' 'z' +[[ColA ColB ColC]; [abc abc ads]] | str replace -a 'b' 'z' ColA ColC +'dogs_$1_cats' | str replace '\$1' '$2' -n +'c:\some\cool\path' | str replace 'c:\some\cool' '~' -s +'abc abc abc' | str replace -a 'b' 'z' -s +'a successful b' | str replace '\b([sS])uc(?:cs|s?)e(ed(?:ed|ing|s?)|ss(?:es|ful(?:ly)?|i(?:ons?|ve(?:ly)?)|ors?)?)\b' '${1}ucce$2' +'GHIKK-9+*' | str replace '[*[:xdigit:]+]' 'z' + + +'Nushell' | str reverse +['Nushell' 'is' 'cool'] | str reverse + + + + + "NuShell" | str screaming-snake-case + "this_is_the_second_case" | str screaming-snake-case +"this-is-the-first-case" | str screaming-snake-case +[[lang, gems]; [nu_test, 100]] | str screaming-snake-case lang + + + "NuShell" | str snake-case + "this_is_the_second_case" | str snake-case +"this-is-the-first-case" | str snake-case +[[lang, gems]; [nuTest, 100]] | str snake-case lang + + +'my_library.rb' | str starts-with 'my' +'Cargo.toml' | str starts-with 'Car' +'Cargo.toml' | str starts-with '.toml' +'Cargo.toml' | str starts-with -i 'cargo' + + + 'good nushell' | str substring 5..12 + '🇯🇵ほげ ふが ぴよ' | str substring -g 4..6 + + +'nu-shell' | str title-case +'this is a test case' | str title-case +[[title, count]; ['nu test', 100]] | str title-case title + + + + + + + + +'Nu shell ' | str trim +'=== Nu shell ===' | str trim -c '=' | str trim +' Nu shell ' | str trim -l +'=== Nu shell ===' | str trim -c '=' +' Nu shell ' | str trim -r +'=== Nu shell ===' | str trim -r -c '=' + + +'nu' | str upcase + + +sys +(sys).host | get name +(sys).host.name + + +ls | table -n 1 +[[a b]; [1 2] [3 4]] | table +[[a b]; [1 2] [2 [4 4]]] | table --expand +[[a b]; [1 2] [2 [4 4]]] | table --collapse + + +[1 2 3] | take 1 +[1 2 3] | take 2 +[[editions]; [2015] [2018] [2021]] | take 2 +0x[01 23 45] | take 2 +1..10 | take 3 + + +[-1 -2 9 1] | take until {|x| $x > 0 } +let cond = {|x| $x > 0 }; [-1 -2 9 1] | take until $cond +[{a: -1} {a: -2} {a: 9} {a: 1}] | take until {|x| $x.a > 0 } + + +[-1 -2 9 1] | take while {|x| $x < 0 } +let cond = {|x| $x < 0 }; [-1 -2 9 1] | take while $cond +[{a: -1} {a: -2} {a: 9} {a: 1}] | take while {|x| $x.a < 0 } + + +term size +(term size).columns +(term size).rows + + +timeit { sleep 500ms } +http get https://www.nushell.sh/book/ | timeit { split chars } +timeit ls -la + + + + +[[foo bar]; [1 2]] | to csv +[[foo bar]; [1 2]] | to csv -s ';' +{a: 1 b: 2} | to csv + + +[[foo bar]; [1 2]] | to html +[[foo bar]; [1 2]] | to html --partial +[[foo bar]; [1 2]] | to html --dark + + +[a b c] | to json +[Joe Bob Sam] | to json -i 4 +[1 2 3] | to json -r + + +[[foo bar]; [1 2]] | to md +[[foo bar]; [1 2]] | to md --pretty +[{"H1": "Welcome to Nushell" } [[foo bar]; [1 2]]] | to md --per-element --pretty +[0 1 2] | to md --pretty + + +[1 2 3] | to nuon +[1 2 3] | to nuon --indent 2 +[1 2 3] | to nuon --indent 2 --raw +{date: 2000-01-01, data: [1 [2 3] 4.56]} | to nuon --indent 2 + + +1 | to text +git help -a | lines | find -r '^ ' | to text +ls | to text + + +{foo: 1 bar: 'qwe'} | to toml + + +[[foo bar]; [1 2]] | to tsv +{a: 1 b: 2} | to tsv + + +{tag: note attributes: {} content : [{tag: remember attributes: {} content : [{tag: null attrs: null content : Event}]}]} | to xml +{tag: note content : [{tag: remember content : [Event]}]} | to xml +{tag: note content : [{tag: remember content : [Event]}]} | to xml -p 3 + + +[[foo bar]; ["1" "2"]] | to yaml + + +touch fixture.json +touch a b c +touch -m fixture.json +touch -m -d "yesterday" a b c +touch -m -r fixture.json d e +touch -a -d "August 24, 2019; 12:30:30" fixture.json + + +[[c1 c2]; [1 2]] | transpose +[[c1 c2]; [1 2]] | transpose key val +[[c1 c2]; [1 2]] | transpose -i val +{c1: 1, c2: 2} | transpose | transpose -i -r -d + + +try { asdfasdf } +try { asdfasdf } catch { echo 'missing' } + + +tutor begin +tutor -f "$in" + + +[2 3 3 4] | uniq +[1 2 2] | uniq -d +[1 2 2] | uniq -u +['hello' 'goodbye' 'Hello'] | uniq -i +[1 2 2] | uniq -c + + +[[fruit count]; [apple 9] [apple 2] [pear 3] [orange 7]] | uniq-by fruit + + +{'name': 'nu', 'stars': 5} | update name 'Nushell' +[[count fruit]; [1 'apple']] | enumerate | update item.count {|e| ($e.item.fruit | str length) + $e.index } | get item +[[project, authors]; ['nu', ['Andrés', 'JT', 'Yehuda']]] | update authors {|row| $row.authors | str join ','} +[[project, authors]; ['nu', ['Andrés', 'JT', 'Yehuda']]] | update authors {|| str join ','} + + +[ + ["2021-04-16", "2021-06-10", "2021-09-18", "2021-10-15", "2021-11-16", "2021-11-17", "2021-11-18"]; + [ 37, 0, 0, 0, 37, 0, 0] + ] | update cells { |value| + if $value == 0 { + "" + } else { + $value + } + } +[ + ["2021-04-16", "2021-06-10", "2021-09-18", "2021-10-15", "2021-11-16", "2021-11-17", "2021-11-18"]; + [ 37, 0, 0, 0, 37, 0, 0] + ] | update cells -c ["2021-11-18", "2021-11-17"] { |value| + if $value == 0 { + "" + } else { + $value + } + } + + +{'name': 'nu', 'stars': 5} | upsert name 'Nushell' +[[name lang]; [Nushell ''] [Reedline '']] | upsert lang 'Rust' +{'name': 'nu', 'stars': 5} | upsert language 'Rust' +[[count fruit]; [1 'apple']] | enumerate | upsert item.count {|e| ($e.item.fruit | str length) + $e.index } | get item +[1 2 3] | upsert 0 2 +[1 2 3] | upsert 3 4 + + + + +{ mode:normal userid:31415 } | url build-query +[[foo bar]; ["1" "2"]] | url build-query +{a:"AT&T", b: "AT T"} | url build-query + + +'https://example.com/foo bar' | url encode +['https://example.com/foo bar' 'https://example.com/a>b' '中文字/eng/12 34'] | url encode +'https://example.com/foo bar' | url encode --all + + +{ + "scheme": "http", + "username": "", + "password": "", + "host": "www.pixiv.net", + "port": "", + "path": "/member_illust.php", + "query": "mode=medium&illust_id=99260204", + "fragment": "", + "params": + { + "mode": "medium", + "illust_id": "99260204" + } + } | url join +{ + "scheme": "http", + "username": "user", + "password": "pwd", + "host": "www.pixiv.net", + "port": "1234", + "query": "test=a", + "fragment": "" + } | url join +{ + "scheme": "http", + "host": "www.pixiv.net", + "port": "1234", + "path": "user", + "fragment": "frag" + } | url join + + +'http://user123:pass567@www.example.com:8081/foo/bar?param1=section&p2=&f[name]=vldc#hello' | url parse + + +module spam { export def foo [] { "foo" } }; use spam foo; foo +module foo { export def-env bar [] { let-env FOO_BAR = "BAZ" } }; use foo bar; bar; $env.FOO_BAR + + +{ mode:normal userid:31415 } | values +{ f:250 g:191 c:128 d:1024 e:2000 a:16 b:32 } | values +[[name meaning]; [ls list] [mv move] [cd 'change directory']] | values + + +version + + + + +view files + + +let abc = {|| echo 'hi' }; view source $abc +def hi [] { echo 'Hi!' }; view source hi +def-env foo [] { let-env BAR = 'BAZ' }; view source foo +module mod-foo { export-env { let-env FOO_ENV = 'BAZ' } }; view source mod-foo +alias hello = echo hi; view source hello + + +some | pipeline | or | variable | debug -r; view span 1 2 + + +watch . --glob=**/*.rs {|| cargo test } +watch . { |op, path, new_path| $"($op) ($path) ($new_path)"} +watch /foo/bar { |op, path| $"($op) - ($path)(char nl)" | save --append changes_in_bar.log } + + +[{a: 1} {a: 2}] | where a > 1 +[1 2] | where {|x| $x > 1} +ls | where size > 2kb +ls | where type == file +ls | where name =~ "Car" +ls | where modified >= (date now) - 2wk +ls | where type == file | sort-by name -n | enumerate | where {|e| $e.item.name !~ $'^($e.index + 1)' } | each {|| get item } + + +which myapp + + +mut x = 0; while $x < 10 { $x = $x + 1 } + + +[1 2 3 4] | window 2 +[1, 2, 3, 4, 5, 6, 7, 8] | window 2 --stride 3 +[1, 2, 3, 4, 5] | window 3 --stride 3 --remainder + + +with-env [MYENV "my env value"] { $env.MYENV } +with-env [X Y W Z] { $env.X } +with-env [[X W]; [Y Z]] { $env.W } +with-env {X: "Y", W: "Z"} { [$env.X $env.W] } + + +[1 2 3] | wrap num +1..3 | wrap num + + + + +[1 2] | zip [3 4] +1..3 | zip 4..6 +glob *.ogg | zip ['bang.ogg', 'fanfare.ogg', 'laser.ogg'] | each {|| mv $in.0 $in.1 } + + diff --git a/src/config.rs b/src/config.rs new file mode 100644 index 0000000..8b3c49b --- /dev/null +++ b/src/config.rs @@ -0,0 +1,21 @@ +/// options available to the formatter +pub struct Config { + /// number of spaces of indent + pub tab_spaces: usize, + /// max amount of characters per line + /// # Maximum width of each line. + /// Default: 100 + pub max_width: usize, + /// number of lines bafore and after a custom command + pub margin: usize, +} + +impl Default for Config { + fn default() -> Self { + Config { + tab_spaces: 2, + max_width: 100, + margin: 1, + } + } +} diff --git a/src/formatting.rs b/src/formatting.rs new file mode 100644 index 0000000..5210344 --- /dev/null +++ b/src/formatting.rs @@ -0,0 +1,24 @@ +use crate::{config::Config, FileName, Input, Session}; +use std::io::Write; + +impl<'b, T: Write + 'b> Session<'b, T> { + pub fn format_input_inner(&mut self, input: Input) { + println!("formatting ...💭"); + let format_result = format_project(input, &self.config); + } +} + +// Format an entire crate (or subset of the module tree) +fn format_project(input: Input, config: &Config) { + // let mut timer = Timer::start(); + + let main_file = input.file_name(); + let input_is_stdin = main_file == FileName::Stdin; + + // parsing starts + + // timer = timer.done_parsing() + // formatting starts + + // timer = timer.done_formatting() +} diff --git a/src/lib.rs b/src/lib.rs index f43eb2e..ddddb6e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,8 +3,61 @@ //! //! It does not do anything more than that, which makes it so fast. +use log::trace; use std::error::Error; use std::io::{BufReader, BufWriter, Read, Write}; +use std::path::PathBuf; + +pub mod config; +pub mod formatting; + +pub struct Session<'b, T: Write> { + pub config: config::Config, + pub out: Option<&'b mut T>, + pub has_operational_errors: bool, +} + +impl<'b, T: Write + 'b> Session<'b, T> { + pub fn new(config: config::Config, out: Option<&'b mut T>) -> Self { + Self { + config: config, + out: out, + has_operational_errors: false, + } + } + + pub fn has_operational_errors(self) -> bool { + self.has_operational_errors + } + + pub fn add_operational_error(&mut self) { + self.has_operational_errors = true; + } + + pub fn format(&mut self, input: Input) { + self.format_input_inner(input) + } +} + +#[derive(PartialEq)] +pub enum FileName { + Real(PathBuf), + Stdin, +} + +pub enum Input { + File(PathBuf), + Text(String), +} + +impl Input { + fn file_name(&self) -> FileName { + match *self { + Input::File(ref file) => FileName::Real(file.clone()), + Input::Text(..) => FileName::Stdin, + } + } +} /// /// Set the indentation used for the formatting. @@ -22,9 +75,7 @@ pub enum Indentation<'a> { /// /// # Formats a nu string /// -/// The indentation can be set to any value using [Indentation](nufmt::Indentation) -/// The default value is two spaces -/// The default indentation is faster than a custom one +/// The indentation can be set to any value using [`Indentation`]. The default value is two spaces. The default indentation is faster than a custom one /// pub fn format_nu(nu: &str, indentation: Indentation) -> String { let mut reader = BufReader::new(nu.as_bytes()); @@ -37,9 +88,7 @@ pub fn format_nu(nu: &str, indentation: Indentation) -> String { /// /// # Formats a nu string /// -/// The indentation can be set to any value using [Indentation](nufmt::Indentation) -/// The default value is two spaces -/// The default indentation is faster than a custom one +/// The indentation can be set to any value using [`Indentation`]. The default value is two spaces. The default indentation is faster than a custom one /// pub fn format_nu_buffered( reader: &mut BufReader, @@ -52,7 +101,7 @@ where { let mut escaped = false; let mut in_string = false; - let mut indent_level = 0usize; + let mut indent_level: usize = 0; let mut newline_requested = false; // invalidated if next character is ] or } let mut in_comment = false; @@ -60,18 +109,23 @@ where let char = char?; // if we're in a comment, ignore and write everything until a newline if in_comment { + trace!("this character is a comment"); match char { b'\n' => { in_comment = false; writer.write_all(&[char])?; } _ => { + // TODO: read the rest of the line + // write all + // and go to the next line writer.write_all(&[char])?; continue; } } } if in_string { + trace!("this is inside a string"); let mut escape_here = false; match char { b'"' => { @@ -104,28 +158,12 @@ where } b']' | b'}' => { indent_level = indent_level.saturating_sub(1); - if !newline_requested { + if !newline_requested && request_newline { // see comment below about newline_requested - writer.write_all(&[b'\n'])?; + // writer.write_all(&[b'\n'])?; indent_buffered(writer, indent_level, indentation)?; } } - // b'[' => { - // indent_level += 1; - // request_newline = true; - // } - // b'{' => { - // indent_level += 1; - // request_newline = true; - // } - // b'}' | b']' => { - // indent_level = indent_level.saturating_sub(1); - // if !newline_requested { - // // see comment below about newline_requested - // writer.write_all(&[b'\n'])?; - // indent_buffered(writer, indent_level, indentation)?; - // } - // } b':' => { auto_push = false; writer.write_all(&[char])?; @@ -137,7 +175,8 @@ where _ => {} } - if newline_requested { + if newline_requested && request_newline { + trace!("new line requested!"); writer.write_all(&[b'\n'])?; indent_buffered(writer, indent_level, indentation)?; } @@ -150,11 +189,14 @@ where // } if auto_push { + //trace!("this char is autopushed"); writer.write_all(&[char])?; } newline_requested = request_newline; } + // trace the char for guiding + trace!("{:?}", char as char); } Ok(()) @@ -187,9 +229,31 @@ mod test { use super::*; #[test] - fn ignore_comments() { - let nu = "# this is a comment"; - let expected = "# this is a comment"; + fn already_formatted() { + let expected = "[ + { + \"a\": 0 + }, + {}, + { + \"a\": null + } +]"; + assert_eq!(expected, format_nu(expected, Indentation::Default)); + } + + #[test] + fn array_of_object() { + let nu = "[{\"a\": 0}, {}, {\"a\": null}]"; + let expected = "[ + { + \"a\": 0 + }, + {}, + { + \"a\": null + } +]"; assert_eq!(expected, format_nu(nu, Indentation::Default)); } @@ -200,31 +264,29 @@ mod test { } #[test] - fn ignore_whitespace_in_string() { - let nu = "\" hallo \""; - assert_eq!(nu, format_nu(nu, Indentation::Default)); + fn handle_escaped_strings() { + let nu = " \" hallo \\\" \" "; + let expected = "\" hallo \\\" \""; + assert_eq!(expected, format_nu(nu, Indentation::Default)); } #[test] - fn remove_leading_whitespace() { - let nu = " 0"; - let expected = "0"; + fn ignore_comments() { + let nu = "# this is a comment"; + let expected = "# this is a comment"; assert_eq!(expected, format_nu(nu, Indentation::Default)); } #[test] - fn handle_escaped_strings() { - let nu = " \" hallo \\\" \" "; - let expected = "\" hallo \\\" \""; - assert_eq!(expected, format_nu(nu, Indentation::Default)); + fn ignore_whitespace_in_string() { + let nu = "\" hallo \""; + assert_eq!(nu, format_nu(nu, Indentation::Default)); } #[test] - fn simple_object() { - let nu = "{\"a\":0}"; - let expected = "{ - \"a\": 0 -}"; + fn remove_leading_whitespace() { + let nu = " 0"; + let expected = "0"; assert_eq!(expected, format_nu(nu, Indentation::Default)); } @@ -238,35 +300,12 @@ mod test { ]"; assert_eq!(expected, format_nu(nu, Indentation::Default)); } - #[test] - fn array_of_object() { - let nu = "[{\"a\": 0}, {}, {\"a\": null}]"; - let expected = "[ - { - \"a\": 0 - }, - {}, - { - \"a\": null - } -]"; - + fn simple_object() { + let nu = "{\"a\":0}"; + let expected = "{ + \"a\": 0 +}"; assert_eq!(expected, format_nu(nu, Indentation::Default)); } - - #[test] - fn already_formatted() { - let expected = "[ - { - \"a\": 0 - }, - {}, - { - \"a\": null - } -]"; - - assert_eq!(expected, format_nu(expected, Indentation::Default)); - } } diff --git a/src/main.rs b/src/main.rs index 4f7d9db..8f5855d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,79 +1,119 @@ -use clap::clap_app; -use nufmt::{format_nu_buffered, Indentation}; +//! This is the nufmt binary documentation +//! +//! # Usage +//! +//! `nufmt` is inteded to be used as this: +//! +//! To format a single file +//! ```shell +//! nufmt file1.nu +//! ``` +//! +//! `TODO!` +//! +//! Set options file +//! ```shell +//! nufmt --config nufmt.nuon +//! ``` + +// for debug purposes, allow unused imports and variables +#[allow(unused)] +#[allow(unused_imports)] +#[allow(unused_import_braces)] +use anyhow::Result; +use clap::Parser; +use env_logger; +use nufmt::config::Config; +use nufmt::{Input, Session}; use std::error::Error; -use std::fs::File; -use std::io::{BufReader, BufWriter, Read, Write}; +use std::io::{stdout, Write}; +use std::path::PathBuf; + +#[derive(Parser)] +#[command(author, version, about)] +struct Cli { + files: Vec, + #[arg(short, long)] + config: Option, +} fn main() -> Result<(), Box> { - let matches = clap_app!(nufmt => - (version: "1.1") - (author: "fdncred") - (about: "Formats nu from stdin or from a file") - (@arg stdout: -s --stdout "Output the result to stdout instead of the default output file. Windows only.") - (@arg indentation: -i --indent +takes_value "Set the indentation used (\\s for space, \\t for tab)") - (@arg output: -o --output +takes_value "The output file for the formatted nu") - (@arg input: "The input file to format") - ) - .get_matches(); + // set up logger + env_logger::init(); - // Note: on-stack dynamic dispatch - let (mut file, mut stdin); - let reader: &mut dyn Read = match matches.value_of("input") { - Some(path) => { - file = File::open(path)?; - &mut file - } - None => { - stdin = std::io::stdin(); - &mut stdin + let cli = Cli::parse(); + + let exit_code = match execute(cli.files, Config::default()) { + Ok(code) => code, + Err(e) => { + eprintln!("{:#}", e); + 1 } }; + // Make sure standard output is flushed before we exit. + std::io::stdout().flush().unwrap(); - let replaced_indent = matches.value_of("indentation").map(|value| { - value - .to_lowercase() - .chars() - .filter(|c| ['s', 't'].contains(c)) - .collect::() - .replace("s", " ") - .replace("t", "\t") - }); + // Exit with given exit code. + // + // NOTE: this immediately terminates the process without doing any cleanup, + // so make sure to finish all necessary cleanup before this is called. + std::process::exit(exit_code); +} - let indent = match replaced_indent { - Some(ref str) => Indentation::Custom(str), - None => Indentation::Default, - }; +/// sends the files to format in lib.rs +fn execute(files: Vec, mut options: Config) -> Result { + options = Config::default(); - let mut output = matches.value_of("output"); - let mut windows_output_default_file: Option = None; + // open a session + let out = &mut stdout(); + let mut session = Session::new(options, Some(out)); - #[cfg(windows)] - if !matches.is_present("stdout") { - if let Some(file) = matches.value_of("input") { - // on windows, set the default output file if no stdout flag is provided - // this makes it work with drag and drop in windows explorer - windows_output_default_file = Some(file.replace(".nu", "_f.nu")) + for file in files { + // TODO: this would be a great place to create an enum like + // enum + // enum File { + // stdin, + // single_file, + // folder, + // _mod, + // } + if !file.exists() { + eprintln!("Error: {} not found!", file.to_str().unwrap()); + session.add_operational_error() + } else if file.is_dir() { + // TODO: recursive search + eprintln!( + "Error: {} is a directory. Please pass files only.", + file.to_str().unwrap() + ); + session.add_operational_error() + } else { + // send the file to lib.rs + println!("formatting file: {:?}", file); + format_and_emit_report(&mut session, Input::File(file)); } } - output = windows_output_default_file.as_deref().or(output); - - // Note: on-stack dynamic dispatch - let (mut file, mut stdout); - let writer: &mut dyn Write = match output { - Some(filename) => { - file = File::create(filename)?; - &mut file - } - None => { - stdout = std::io::stdout(); - &mut stdout - } + let exit_code = if session.has_operational_errors() { + 1 + } else { + 0 }; - let mut reader = BufReader::new(reader); - let mut writer = BufWriter::new(writer); - format_nu_buffered(&mut reader, &mut writer, indent)?; + Ok(exit_code) +} + +fn format_and_emit_report(session: &mut Session<'_, T>, input: Input) { + match session.format(input) { + _ => todo!("Here `nufmt` gives you a FormatReport"), + } +} - Ok(()) +#[cfg(test)] +mod tests { + + #[test] + fn todo() { + todo!("First fix the library fixes, then we can do the binary tests.") + } } From dca0413905fd9533279dff9d01bb433bf00e4227 Mon Sep 17 00:00:00 2001 From: Auca Maillot Date: Thu, 25 May 2023 12:36:08 -0300 Subject: [PATCH 2/5] :sparkles: standarized Config with minimal defaults --- src/config.rs | 33 +++++++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/src/config.rs b/src/config.rs index 8b3c49b..83e5da4 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,21 +1,38 @@ -/// options available to the formatter +use anyhow::Result; + +/// Configurations available to the formatter pub struct Config { - /// number of spaces of indent + /// Number of spaces of indent. pub tab_spaces: usize, - /// max amount of characters per line - /// # Maximum width of each line. - /// Default: 100 + /// Maximum width of each line. pub max_width: usize, - /// number of lines bafore and after a custom command + /// Number of lines bafore and after a custom command. pub margin: usize, } impl Default for Config { fn default() -> Self { Config { - tab_spaces: 2, - max_width: 100, + tab_spaces: 4, + max_width: 80, margin: 1, } } } + +impl Config { + /// Creates a new config. You need to pass every field to create the config. + /// You cannot skip any field yet. + pub fn new(tab_spaces: usize, max_width: usize, margin: usize) -> Self { + Config { + tab_spaces: tab_spaces, + max_width: max_width, + margin: margin, + } + } +} + +/// Returns a default config. +pub fn load_config(/* file_path: Option<&Path> */) -> Result { + Ok(Config::default()) +} From 01e075f46661a755c641d5e3df19a1b089d3efb7 Mon Sep 17 00:00:00 2001 From: Auca Maillot Date: Mon, 29 May 2023 20:04:07 -0300 Subject: [PATCH 3/5] :sparkles: make `Config` structs debug-printable --- src/config.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/config.rs b/src/config.rs index 83e5da4..9764579 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,5 +1,6 @@ use anyhow::Result; +#[derive(Debug)] /// Configurations available to the formatter pub struct Config { /// Number of spaces of indent. From 3adbd4f5cfd68af37449bc1cfbdd4a13254a6d5b Mon Sep 17 00:00:00 2001 From: Auca Maillot Date: Mon, 29 May 2023 20:05:25 -0300 Subject: [PATCH 4/5] :sparkles: add details to clap and verify its construction --- src/main.rs | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/src/main.rs b/src/main.rs index 8f5855d..5df7e41 100644 --- a/src/main.rs +++ b/src/main.rs @@ -16,6 +16,11 @@ //! nufmt --config nufmt.nuon //! ``` +// throw error if are docs missing +// or finds a broken link doc +#![deny(rustdoc::broken_intra_doc_links)] +#![warn(missing_docs)] + // for debug purposes, allow unused imports and variables #[allow(unused)] #[allow(unused_imports)] @@ -32,8 +37,9 @@ use std::path::PathBuf; #[derive(Parser)] #[command(author, version, about)] struct Cli { + #[arg(help = "The file or files you want to format in nu")] files: Vec, - #[arg(short, long)] + #[arg(short, long, help = "The configuration file")] config: Option, } @@ -60,10 +66,8 @@ fn main() -> Result<(), Box> { std::process::exit(exit_code); } -/// sends the files to format in lib.rs -fn execute(files: Vec, mut options: Config) -> Result { - options = Config::default(); - +/// Sends the files to format in lib.rs +fn execute(files: Vec, options: Config) -> Result { // open a session let out = &mut stdout(); let mut session = Session::new(options, Some(out)); @@ -105,12 +109,19 @@ fn execute(files: Vec, mut options: Config) -> Result { fn format_and_emit_report(session: &mut Session<'_, T>, input: Input) { match session.format(input) { - _ => todo!("Here `nufmt` gives you a FormatReport"), + _ => {} // _ => todo!("Here `nufmt` gives you a FormatReport"), } } #[cfg(test)] mod tests { + use super::*; + + #[test] + fn clap_cli_construction() { + use clap::CommandFactory; + Cli::command().debug_assert() + } #[test] fn todo() { From d1e15cdfaa502f19b0fddb822279c96b7c0231bc Mon Sep 17 00:00:00 2001 From: Auca Maillot Date: Tue, 30 May 2023 13:12:32 -0300 Subject: [PATCH 5/5] :sparkles: parse a file and fmt stripping all whitespace --- Cargo.toml | 1 + src/formatting.rs | 115 ++++++++++++++++++++++++++++++++++++++++++++-- src/lib.rs | 19 ++++++-- 3 files changed, 127 insertions(+), 8 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index c0afd60..7a53bd7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,6 +18,7 @@ anyhow = "1.0.71" clap = { version = "4.3.0", optional = true, features = ["unicode", "derive"] } env_logger = "0.10.0" log = "0.4.17" +nu-parser = "0.80.0" nu-protocol = "0.80.0" [dev-dependencies] diff --git a/src/formatting.rs b/src/formatting.rs index 5210344..766e8d4 100644 --- a/src/formatting.rs +++ b/src/formatting.rs @@ -1,24 +1,131 @@ -use crate::{config::Config, FileName, Input, Session}; +use crate::{config::Config, Input, Session}; +use log::{debug, trace}; +use nu_parser::{flatten_block, parse, FlatShape}; +use nu_protocol::engine::{self, StateWorkingSet}; +use std::fs::File; use std::io::Write; impl<'b, T: Write + 'b> Session<'b, T> { pub fn format_input_inner(&mut self, input: Input) { println!("formatting ...💭"); - let format_result = format_project(input, &self.config); + format_project(input, &self.config); } } // Format an entire crate (or subset of the module tree) +// +// TODO: It is possible that this fucntion return some value. +// For example a Vec[u8], or a String to pass to another function +// which writes the file, or add the indentation. fn format_project(input: Input, config: &Config) { + debug!("using config:{:?}", config); + // nice place to measure parsing and formatting time // let mut timer = Timer::start(); + // parsing starts let main_file = input.file_name(); - let input_is_stdin = main_file == FileName::Stdin; + let main_file_as_str = main_file.unwrap().as_path().to_str().unwrap(); + // TODO: if input is stdin, format the string + // let input_is_stdin = main_file == Input::Text; - // parsing starts + let contents = input.contents(); + let engine_state = engine::EngineState::new(); + let mut working_set = StateWorkingSet::new(&engine_state); + + let parsed_block = parse(&mut working_set, Some(main_file_as_str), &contents, false); + trace!("parsed block:\n{:?}\n", &parsed_block); + // flat is a list of (Span , Flatshape) + // + // Span is the piece of code. You can stringfy the contents. + // Flatshape is an enum of the type of token read by the AST. + let flat = flatten_block(&working_set, &parsed_block); + trace!("flattened block:\n{:#?}\n", &flat); // timer = timer.done_parsing() + // formatting starts + let mut writer = File::create(main_file.unwrap()).unwrap(); + let mut out: Vec = vec![]; + + for (span, shape) in flat { + let mut c_bites = working_set.get_span_contents(span); + let content = String::from_utf8_lossy(c_bites).to_string(); + trace!("shape is {shape}"); + trace!("shape contents: {:?}", &content); + match shape { + // if its one of these types, just do nothing. Write it away. + FlatShape::String | FlatShape::Int | FlatShape::Nothing => out.extend(c_bites), + FlatShape::List | FlatShape::Record => { + c_bites = trim_ascii_whitespace(c_bites); + let printable = String::from_utf8_lossy(c_bites).to_string(); + trace!("stripped the whitespace, result: {:?}", printable); + out.extend(c_bites) + } + FlatShape::Pipe => { + // here you don't have to strip the whitespace. + // The pipe is just a pipe `|`. + // + // return the pipe AND a space after that + out.extend("| ".to_string().bytes()) + } + FlatShape::External => { + // External are some key commands + // + // List of what I've found: seq, each, str, + out.extend(c_bites); + // It doen't have a space after it. You have to add it here. + out.extend([b' '].iter()); + } + FlatShape::ExternalArg => { + // This shape is the argument of an External command (see previous case). + // + // As a result, ExternalArg may be an entire expression. + // like: "{ |row|\r\n let row_data = (seq ... r\n}" + out.extend(c_bites); + // It doen't have a space after it. You have to add it here. + out.extend([b' '].iter()); + } + FlatShape::Garbage => { + // Garbage is not garbage at all + // + // IDK what is it. I groups a bunch of commands like let my_var = 3 + out.extend(c_bites); + out = insert_newline(out); + } + + _ => (), + } + } + // writing + + // just before writing, append a new line to the file. + out = insert_newline(out); + // TODO: check if the last byte is already b'\n' + + // now write the file + let file_bites = out.as_slice(); + trace!("writing {:?}", out); + writer + .write_all(file_bites) + .expect("something went wrong writing"); + trace!("written") // timer = timer.done_formatting() } + +fn insert_newline(mut bytes: Vec) -> Vec { + // If I need cfg windows, then I need \r\n + // let newline = vec![b'\r', b'\n']; + let newline = vec![b'\n']; + bytes.extend(newline.iter()); + bytes +} + +pub fn trim_ascii_whitespace(x: &[u8]) -> &[u8] { + let from = match x.iter().position(|x| !x.is_ascii_whitespace()) { + Some(i) => i, + None => return &x[0..0], + }; + let to = x.iter().rposition(|x| !x.is_ascii_whitespace()).unwrap(); + &x[from..=to] +} diff --git a/src/lib.rs b/src/lib.rs index ddddb6e..db7b0e9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -39,22 +39,33 @@ impl<'b, T: Write + 'b> Session<'b, T> { } } -#[derive(PartialEq)] +// This is getting deprecated. I think +#[derive(Debug, PartialEq)] pub enum FileName { Real(PathBuf), Stdin, } +#[derive(Debug)] pub enum Input { File(PathBuf), Text(String), } impl Input { - fn file_name(&self) -> FileName { + fn file_name(&self) -> Option<&PathBuf> { match *self { - Input::File(ref file) => FileName::Real(file.clone()), - Input::Text(..) => FileName::Stdin, + Input::File(ref file) => Some(file), + Input::Text(..) => None, + } + } + + fn contents(&self) -> Vec { + match self { + Input::File(path) => std::fs::read(path).expect( + format!("something went wrong reading the file {}", path.display()).as_str(), + ), + Input::Text(string) => string.as_bytes().to_vec(), } } }