From 295b4e89bdbd9cd9d4b0b583e4083646ed86246f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Riegel?= Date: Thu, 1 May 2025 22:15:07 +0200 Subject: [PATCH 01/30] Add check mode and exit codes --- Cargo.lock | 43 +- Cargo.toml | 2 + benches/example.nu | 4473 +++++++++++++++++++++----------------------- src/config.rs | 2 +- src/lib.rs | 60 +- src/main.rs | 234 ++- toolkit.nu | 115 +- 7 files changed, 2489 insertions(+), 2440 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 23778e5..6097225 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "adler2" @@ -233,6 +233,16 @@ dependencies = [ "alloc-stdlib", ] +[[package]] +name = "bstr" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "234113d19d0d7d613b40e86fb654acf958910802bcceab913a4f9e7cda03b1a4" +dependencies = [ + "memchr", + "serde", +] + [[package]] name = "bumpalo" version = "3.16.0" @@ -671,6 +681,19 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" +[[package]] +name = "globset" +version = "0.4.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54a1028dfc5f5df5da8a56a73e6c153c9a9708ec57232470703592a3f18e49f5" +dependencies = [ + "aho-corasick", + "bstr", + "log", + "regex-automata", + "regex-syntax", +] + [[package]] name = "half" version = "2.4.1" @@ -748,6 +771,22 @@ dependencies = [ "cc", ] +[[package]] +name = "ignore" +version = "0.4.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d89fd380afde86567dfba715db065673989d6253f42b88179abd3eae47bda4b" +dependencies = [ + "crossbeam-deque", + "globset", + "log", + "memchr", + "regex-automata", + "same-file", + "walkdir", + "winapi-util", +] + [[package]] name = "indexmap" version = "2.6.0" @@ -1150,10 +1189,12 @@ dependencies = [ "clap", "criterion", "env_logger", + "ignore", "log", "nu-cmd-lang", "nu-parser", "nu-protocol", + "rayon", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index f9ea128..9f0142e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,6 +21,8 @@ log = "0.4.17" nu-cmd-lang = "0.99.0" nu-parser = "0.99.0" nu-protocol = "0.99.0" +ignore = "0.4" +rayon = "1.10" [dev-dependencies] criterion = "0.5.1" diff --git a/benches/example.nu b/benches/example.nu index d53c23b..8ccd05b 100644 --- a/benches/example.nu +++ b/benches/example.nu @@ -1,2399 +1,2232 @@ -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 +alias ll=ls -l +[[status]; [UP] [UP]]| all {|el| $el.status == UP } +[foobar2baz]| all {|| ($in | describe ) == 'string' }[0246]| enumerate | all {|i| $i.item == $i.index * 2 } +let cond = {|el| ($el mod2 +==0[2468] +[2468] +| 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' +$'(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 +brightyellow +onred +backgroundlet 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 +NuWorld(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 } +[1234]| any {|| ($in | describe ) == 'string' }[9876]| enumerate | any {|i| $i.item == $i.index * 2 } +let cond = {|e| $e mod2==1}[24168]| 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 - +2| bits and +2 +[432]| bits and +2 +[432]| bits not +[432]| bits not +-n +'2' +[432]| bits not +-s +2| bits or +6 +[832]| bits or +2 +17| bits rol +2 +[532]| bits rol +2 +17| bits ror +60 +[153392]| bits ror +2 +-n +'1' +2| bits shl +7 +2| bits shl +7 +-n +'1' +0x7F| bits shl +1 +-s +[532]| bits shl +2 +8| bits shr +2 +[15352]| bits shr +2 +2| bits xor +2 +[832]| 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 - +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 - - +(char prompt +)+(char newline +)+(char hamburger +)char -u +1f378 +char -i +(0x60+1)(0x60+2)char -u +1F468 +200D +1F466 +200D +1F466 +clear [123]| 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 - - +const x = 10const 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:00date 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 - - +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-1010: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 [] +{'hi' } +def say-sth [sth: string] +{$sth }hi def-env foo +[]{ let-env BAR = "BAZ" } +$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 +[falsefalsefalse]| dfr into-df +| dfr all-false +let s = ([56210]| dfr into-df +)let res = ($s +>9 +>9 +)$res | dfr all-false +[truetruetrue]| dfr into-df +| dfr all-true +let s = ([5628]| dfr into-df +)let res = ($s +>9 +>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 +[132]| dfr into-df +| dfr arg-max +[132]| dfr into-df +| dfr arg-min +[12233]| dfr into-df +| dfr arg-sort +[12233]| dfr into-df +| dfr arg-sort +-r +[falsetruefalse]| dfr into-df +| dfr arg-true +[12233]| 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-3000: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 = ([zaxscd]| dfr into-df +)[abcabcabc]| dfr into-df +| dfr concatenate +$other [abcacbacb]| dfr into-df +| dfr contains +ab +let s = ([1100334]| dfr into-df +)($s /$s )| dfr count-null +[12345]| 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 = ([120034]| 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 +[12233]| 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 +[12NaN3NaN]| dfr into-df +| dfr fill-nan +0 +[[a b]; [0.2 1] [0.1 NaN]]| dfr into-df +| dfr fill-nan +0 +[12233]| 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 = ([truefalse]| 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 +[[12a][34b][56c]]| dfr into-df +[abc]| dfr into-df +[truetruefalse]| 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 +[5666888]| 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 = ([136]| dfr into-df +)[5666888]| 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 +[onetwo]| dfr as +a_in +)dfr col +a +| dfr is-not-null +let s = ([5608]| dfr into-df +)let res = ($s /$s )$res | dfr is-not-null +dfr col +a +| dfr is-null +let s = ([5608]| dfr into-df +)let res = ($s /$s )$res | dfr is-null +[5666888]| 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 +[AbcaBcabC]| 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 +[bc]-v +[ad][[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 +[1122334]| dfr into-df +| dfr n-unique +[truefalsetrue]| 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' +[5678]| 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 +[ab][a_newb_new][abcabcabc]| dfr into-df +| dfr replace +-p +ab +-r +AB +[abacabacabac]| dfr into-df +| dfr replace-all +-p +a +-r +A +[[a b]; [6 2] [4 2] [2 2]]| dfr into-df +| dfr reverse +[12345]| dfr into-df +| dfr rolling +sum +2 +| dfr drop-nulls +[12345]| 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 = ([12233]| dfr into-df +| dfr shift +2 +)let mask = ($s | dfr is-null +)$s | dfr set +0 +--mask +$mask let series = ([415243]| dfr into-df +)let indices = ([02]| dfr into-df +)$series | dfr set-with-idx +6 +-i +$indices [[a b]; [1 2] [3 4]]| dfr into-df +| dfr shape +[12233]| 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 +[ab]-r +[falsetrue][[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 +[aababc]| dfr into-df +| dfr str-lengths +[abcdedabc321abc123]| 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 = ([02]| dfr into-df +)$df | dfr take +$indices let series = ([415243]| dfr into-df +)let indices = ([02]| 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 +[22222]| dfr into-df +| dfr unique +col a +| unique [AbcaBcabC]| dfr into-df +| dfr uppercase +[555566]| 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 +([56]| 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 {hello}let text = "I +amenclosed"let hello = {||$text }do $hello do -i{thisisnotarealcommand }do -s{thisisnotarealcommand }do -p{nu -c +'exit 1' +}"I'll still run"do -c{nu -c +'exit +1' +}| myscarycommand do {|x| 100+$x }7777| 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 +[firstsecondthirdfourthfifth]| drop nth +(1..3)[0,1,2,3,4,5]| drop nth +1.. +[0,1,2,3,4,5]| drop nth +3.. +du [123]| each {|e| 2 * $e } +{major:2,minor:1,patch:4}| values | each {|| into string } +[1232]| each {|e| if $e == 2 { "two" } } +[123]| enumerate | each {|e| if $e.item == 2 { found 2 at ($e +index +index +)!} }[123]| each --keep-empty +{|e| if $e == 2 { "found 2!"} } +[12321]| each while +{|e| if $e < 3 { $e * 2 } } +[12stop34]| each while +{|e| if $e != 'stop' { Output: ($e +) } }[123]| enumerate | each while +{|e| if $e.item < 2 { value ($e +item +item +) at ($e +index +index +)!} }12 +3 +$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 +'SomeData'| 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 +[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 existsstart:123# not mandatory unless $.label.end is setend:456# not mandatory unless $.label.start is set + }} +def foo [x] +{let span = (metadata $x +)spanerror make {msg:"this is fishy"label:{text:"fish right here"start:$span startend:$span end}}}[12345]| every 2 +[12345]| 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] - - +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 utilsexport def my-command[] +{"hello"}use utilsmy-commandmodule spamexport alias ll= +ls -l +module spamexport def foo[] +{"foo"}use spamfoomodule fooexport def-env bar [] { let-env FOO_BAR = "BAZ" }use foobar$env FOO_BARexport 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 - - - +module spamexport def foo[] +{"foo"}module eggsexport use spamfoouse eggsfooexport-env { let-env SPAM = 'eggs' } 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 - - - - +$env SPAMextern 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 +[12]| 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 +[153kb43Mb]| find 5 +3kb +[moelarrycurly]| find l +[abcbdearcabf]| find --regex +"ab" +[aBcbdeArcabf]| 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 +[123]| first [123]| 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:[1234],e:[43]}| flatten d +--all +42| fmt for x in +[123]{print ($x +*$x +*$x +)}for $x in +1..3{print $x }for $it in +['bob''fred']--numbered{print $"($it +index +index +) is ($it +item +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 +1,2"| from csv +open data.txt +| from csv +--noheaders +open data.txt +| from csv +--separator +' +{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 +--trimall open data.txt +| from csv +--trimheaders open data.txt +| from csv +--trimfields 'From: test@email.com Subject: Welcome To: someone@somewhere.com -Test' | from eml +Test'| from eml 'From: test@email.com Subject: Welcome To: someone@somewhere.com -Test' | from eml -b 1 - - -'BEGIN:VCALENDAR - END:VCALENDAR' | from ics - - +Test'| from eml +-b1'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 +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 +--raw +file.parquet | from parquet open file.parquet - - - - 'FOO BAR -1 2' | from ssv +1 2'| from ssv 'FOO BAR -1 2' | from ssv -n - - -'a = 1' | from toml +1 2'| from ssv +-n'a = 1'| from toml 'a = 1 -b = [1, 2]' | from toml - - +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 - - +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 +--trimall $'a1(char tab +)b1(char tab +)c1(char nl +)a2(char tab +)b2(char tab +)c2'| save tsv-data +| open tsv-data +| from tsv +--trimheaders $'a1(char tab +)b1(char tab +)c1(char nl +)a2(char tab +)b2(char tab +)c2'| save tsv-data +| open tsv-data +| from tsv +--trimfields '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] - - -' +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 +'| 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 +enter foo +enter ../bar +g 1 +shells g +2 +mkdir foo +enter foo +enter ../bar +g - +[012]| 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]*" +$env | get -s +Path glob *.rs +glob **/*.{rs,toml} +--depth2glob "[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 - - +glob "[A-Z]*" +--no-file--no-symlink[123abc]| grid [123abc]| wrap name +| grid {name:'foo',b:1,c:2} +| grid [{name:'A',v:1 +}{name:'B',v:2}{name:'C',v:3 +}]| grid [[namepatch]; [0.1.0 false] [0.1.1 true] [0.2.0 false]]| grid [1234]| 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 - - +['1''3''1''3''2''1''1']| group-by 'abcdefghijklmnopqrstuvwxyz' +| hash md5 +'abcdefghijklmnopqrstuvwxyz'| hash md5 +--binaryopen ./nu_0_24_1_windows.zip +| hash md5 +'abcdefghijklmnopqrstuvwxyz'| hash sha256 +'abcdefghijklmnopqrstuvwxyz'| hash sha256 +--binaryopen ./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 -help aliases my-alias -help aliases --find my-alias - - - - +my-alias help aliases +--findmy-alias help externs help externs -help externs smth -help externs --find smth - - +smth help externs +--findsmth help modules 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 - - - - +my-module help modules +--findmy-module alias lll=ls -l +hide lll +def say-hi [] +{'Hi!' +hide say-hilet-env +HZ_ENV_ABC =1hide-env HZ_ENV_ABC 'HZ_ENV_ABC' in (env )namels | histogram type 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 - - - - - - +freq [121]| histogram [1231112211]| 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-keymy-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-keymy-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-keymy-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-keymy-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-keymy-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-keymy-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!'done +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 itemfoo+$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-51614434140*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 +--convertsec 420sec| into duration +420sec| into duration +--convertms 1000000µs| into duration +--convertsec 1sec| into duration +--convertµs 1sec| into duration +--convertus [[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 +-r2'FF'| into int +-r16'0o10132'| into int +'0010132'| into int +'0010132'| into int +-r8[[value]; [false]]| into record +[123]| 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 -tmy_table [[name]; [-----] [someone] [=====] [somename] ['(((((']]| into sqlite +filename.db [one25.2sixtrue100mib25sec]| into sqlite +variety.db 5| into string +-d31.7| into string +-d01.7| into string +-d11.734| into string +-d21.734| into string +-d-24.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 [[mealsize]; [arepa small] [taco '']]| is-empty meal +size {new:york,san:francisco}| items {|key, value| echo ($key +) ($value +) }[{a:1b:2}]| join [{a:1c:3 + +}]a +open -r +test.json | json path +'$.store.book[*].author'keybindings default +keybindings list +-mkeybindings list +-e-dkeybindings list +keybindings listen +ps | sort-by mem +| last | kill $in pidkill +--force +12345kill -s +212345[1,2,3]| last 2 +[1,2,3]| last [12345]| length [{columnA:A0columnB:B0 +}]| length -c +let x = 10let x +=10+100let x = + +if false{-1}else{1let-env +let-env +MY_ENV_VAR +MY_ENV_VAR +=1$env MY_ENV_VAR$"two\nlines" +| lines {NAME:ABE,AGE:UNKNOWN} +| load-env $env NAMEload-env +{NAME: ABE, AGE: UNKNOWN} +$env NAMEmut +x=0loop { +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 +31..10=> +'yes!'match +{a:100}{a: $my_value }=> +{$my_value }match +31=> +{'yes!'}_=> +{'no!'}match +[1,2,3][$a $b $c ]=>{$a +$b +$c }_=> +0{a:{b:3}} +| match $in {a:{$b +} +}=> +($b +10)[-50-100.025] +| math abs +1| math arccos +-1| math arccos +-d1| math arccosh +1| math arcsin +1| math arcsin +-d0| math arcsinh +1| math arctan +-1| math arctan +-d1| math arctanh +[-50100.025]| math avg +[1.52.3-3.1]| math ceil +math pi +| math cos +[090180270360]| math cos +-d1| math cosh +math e +| math round +--precision30| math exp +1| math exp +[1.52.3-3.1]| math floor +math e +| math ln +100| math log +10[1684]| math log +2[-5010025]| math max +[{a:1b:3 + +}{a:2b:-1 +}]| math max +[389121215]| math median +[{a:1b:3 + +}{a:2b:-1}{a:-3b:5 +}]| math median +[-5010025]| math min +[{a:1b:3 + +}{a:2b:-1 +}]| math min +[339121215]| math mode +[{a:1b:3 + +}{a:2b:-1}{a:1b:5 +}]| math mode +math pi +| math round +--precision2[2334]| math product +[1.52.3-3.1]| math round +[1.5552.333-3.111]| math round +-p2(math pi + +/2 +| math sin +[090180270360]| math sin +-d| math round +--precision41| math sinh +[916]| math sqrt +[12345]| math stddev +[12345]| math stddev +-s[123]| math sum +ls | get size +| math sum +(math pi + +/4 +| math tan +[-45045]| math tan +-d(math pi + +*10 +| math tanh +math tau +| math round +--precision2[12345]| math variance +[12345]| math variance +-s[abc]| wrap name +| merge ([123]| wrap index + +{a:1,b:2} +| merge {c: 3} +[{columnA:A0columnB:B0 +}]| merge [{columnA:'A0*' +}]let +a +=42metadata $a +ls +| metadata mkdir +foo +mkdir -v +foo/bar foo2 module spamexport def foo[] +{"foo"use +use +spamfoomodule +fooexport-env{ let-env FOO = "BAZ" } +{ let-env FOO = "BAZ" } +use foo$envFOOmodulefooexportdef-envbar[]{let-env FOO_BAR +="BAZ" +usefoobar$envFOO_BAR[[name value index]; [foo a 1] [bar b 2] [baz c 3]]| move index +--beforename [[name value index]; [foo a 1] [bar b 2] [baz c 3]]| move value +name --afterindex {name:foo,value:a,index:1}| move name +--beforeindex mut x = 10$x =12mut +a +={b:{c:1} +}$a +bc=2mut +x=10+100mut x = + +if false{-1}else{1mv +mv +before.txt +before.txt +after.txt mv test.txt +my/subdirectory mv *.txt +my/subdirectory mkdir foo +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-modulemodule.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 scopecommands +scopecommands +| where is_custom +| get command +)openmyfile.json +open myfile.json +--raw'myfile.txt'| open open +myfile.txt +--raw| decode utf-8 +module spamexport def foo[] +{"foo"overlay +overlay +use +spam +def bar [] +{"bar" +overlay hide +spam--keep-custom'export alias f = "foo"' | save spam.nu +overlay use spam.nuoverlayhide +spammodulespamexport-env +{ let-env FOO = "foo" } +overlay use spamoverlayhide +overlaynew +spam + +cd some-dir +overlay hide --keep-env[PWD]spammodulespamexportdef +foo[] +{"foo"overlay +overlay +use +spamoverlaylist +list +| last overlay +new +spammodule +spamexport +def +foo[] +{"foo"overlay +overlay +use +spammodulespamexport +deffoo[] +foo[] +{"foo"overlay +overlay +use +spamasspam_new'export def foo { "foo" }'overlay use +--prefixspamfoo +'export-env { let-env FOO = "foo" }'| save spam.nu +overlay use spam.nu$envFOOmkdir +fooenter foo +enter ../bar +p p +[123]| par-each {|| 2 * $in } +[foobarbaz]| par-each {|e| $e + '!' } +| sort 1..3 +| enumerate | par-each {|p| update item ($p +item*2 +item*2 +)}| sort-by item +| get item +[123]| enumerate | par-each { |e| if $e.item == 2 { found 2 at ($e +index +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 +-n2'/home/joe/code/test.txt'| path dirname +-n2-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 +-etar.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]pnetport +31214000port [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 } +{|| 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 +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 -random bool --bias 0.75 - - +--bias 0.75random chars random chars -random chars -l 20 - - +-l 20random decimal random decimal -random decimal ..500 -random decimal 100000.. -random decimal 1.0..1.1 - - +..500random decimal +100000..random decimal +1.0..1.1random dice random dice -random dice -d 10 -s 12 - - +-d 10-s 12random integer 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+)' - - +..500random integer +100000..random integer +1..10random uuid +[0,1,2,3,4,5]| range 4..5 +[0,1,2,3,4,5]| range (-2). | range (-3). | reduce {|it, acc| $it + $acc } +[876]| enumerate | reduce -f +0{|it, acc| $acc +$it item +$it index }[1234]| 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{'; '} +index!=0{'; '} +($str index+1 +-($str item +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 +let plugin = ((which nu + +path0 +| path dirname +| path join +'nu_plugin_query' + +nu +-c +-c +$'register ($plugin ); version'lss| 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 +[aham]{a:1b: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:1b:2c: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:1b:2c: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 [[ab]; [1 2] [3 4] [5 6]]| rotate [[ab]; [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 +--stderrfoo.txt do -i| save foo.txt +--stderrbar.txt open foo.db +| schema [{a:ab:b +}]| select a +{a:ab: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 | select 0 +123seq 1 +10seq 1.0 +0.12.0seq 1 +5| str join +'|'seq char +a e seq char +a e | str join +'|'seq date +--days10seq date +--days10-rseq date +--days10-o'%m/%d/%Y'-rseq date +-b'2020-01-01'-e'2020-01-10'seq date +-b'2020-01-01'-e'2020-01-31'-n5enter .. +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 [2468]| skip 1 +[[editions]; [2015] [2018] [2021]]| skip 2 +[-202-1]| skip until +{|x| $x >0}let cond = {|x| $x >0 +[-202-1]| skip until +$cond [{a:-2}{a:0}{a:2}{a:-1}] +[{a:-2}{a:0}{a:2}{a:-1}] +| skip until +{|x| $x a>0}[-202-1]| skip while +{|x| $x <0}let cond = {|x| $x <0 +[-202-1]| skip while +$cond [{a:-2}{a:0}{a:2}{a:-1}] +[{a:-2}{a:0}{a:2}{a:-1}] +| skip while +{|x| $x a<0}sleep 1sec +[201]| sort [201]| sort -r +[bettyamysarah]| sort [bettyamysarah]| sort -r +[airplaneTruckCar]| sort -i +[airplaneTruckCar]| 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 - - +ls | sort-by name +-i[[fruit count]; [apple 9] [pear 3] [orange 7]]| sort-by fruit +-rsource foo.nu +source ./foo.nu +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 +-l3http get +https://www.gutenberg.org/files/11/11-0.txt | str downcase +| split words +-l2| 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 +'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'[onetwothree]| str contains +o [onetwothree]| str contains +-no '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'-r1..'123456'| str index-of +'6'-r..4'123456'| str index-of +'3'-r1..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 +-g4..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 +hostnamels +| table -n +1[[a b]; [1 2] [3 4]]| table [[ab]; [1 2] [2 [44]]]| table --expand +[[a b]; [1 2] [2 [44]]]| table --collapse +[123]| take 1 +[123]| take 2 +[[editions]; [2015] [2018] [2021]]| take 2 +0x[01 23 45]| take 2 +1..10| take 3 +[-1-291]| take until +{|x| $x >0}let cond = {|x| $x >0 +[-1-291]| take until +$cond [{a:-1}{a:-2}{a:9}{a:1}] +[{a:-1}{a:-2}{a:9}{a:1}] +| take until +{|x| $x a>0}[-1-291]| take while +{|x| $x <0}let cond = {|x| $x <0 +[-1-291]| take while +$cond [{a:-1}{a:-2}{a:9}{a:1}] +[{a:-1}{a:-2}{a:9}{a:1}] +| take while +{|x| $x a<0}term size +(term size + +columns(term size +)rowstimeit{ sleep 500ms } +{ 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:1b:2 +}| to csv +[[foo bar]; [1 2]]| to html +[[foo bar]; [1 2]]| to html +--partial[[foo bar]; [1 2]]| to html +--dark[abc]| to json +[JoeBobSam]| to json +-i4[123]| 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[012]| to md +--pretty[123]| to nuon +[123]| to nuon +--indent2[123]| to nuon +--indent2--raw{date:2000-01-01,data:[1[23]4.56]}| to nuon +--indent21| 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 - - +{foo:1bar:'qwe' +}| to toml +[[foo bar]; [1 2]]| to tsv +{a:1b:2 +}| to tsv +{tag:noteattributes:{}content:[{tag:rememberattributes:{}content:[{tag:nullattrs:nullcontent:Event}]}] +}| to xml +{tag:notecontent:[{tag:remembercontent:[Event]}] +}| to xml +{tag:notecontent:[{tag:remembercontent:[Event]}] +}| to xml +-p3[[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 ','} - - -[ +touch a +b c touch -m +fixture.json touch -m +-d"yesterday"a b c touch -m +-rfixture.json d e touch -a +-d"August 24, 2019; 12:30:30"fixture.json [[c1 c2]; [1 2]]| transpose [[c1c2]; [1 2]]| transpose key +val [[c1 c2]; [1 2]]| transpose -i +val {c1:1,c2:2}| transpose | transpose -i +-r-dtry {asdfasdf +try +{asdfasdf }catch +{asdfasdf }catch +{'missing'tutor +tutor +begin +begin +tutor -f +"$in"[2334]| uniq [122]| uniq -d +[122]| uniq -u +['hello''goodbye''Hello']| uniq -i +[122]| 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 itemfruit +itemfruit +| 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 - } - } -[ + ]| 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| + ]| 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} +{'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 itemfruit +itemfruit +| str length +)+$e index}| get item +[123]| upsert 0 +2[123]| upsert 3 +4{mode:normaluserid: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 spamexport def foo[] +{"foo"use +use +spamfoomodule +fooexportdef-env +bar[] +{let-env FOO_BAR +="BAZ" +usefoobar$env +FOO_BAR{mode:normaluserid:31415}| values {f:250g:191c:128d:1024e:2000a:16b:32} +| values [[namemeaning]; [ls list] [mv move] [cd 'change directory']]| values version +view +files +let abc = {||'hi'view +view +source +source +$abc +def hi [] +{'Hi!' +view source +source +def-env foo +[]{ let-env BAR = 'BAZ' } view source +module mod-fooexport-envlet-env FOO_ENV = 'BAZ' +view source +mod-foo alias hello=hiview source +hello some | pipeline | or | variable | debug -r +view span +12watch . +--glob=**/*.rs{||cargo test +}watch . +{ |op, path, new_path| ($op )($path +) +($new_path )watch +watch +/foo/bar +/foo/bar +{ |op, path| ($op )-($path +(char nl +)| save --append +changes_in_bar.log + +[{a:1 +}{a:2 +}]| where a > 1 +[12]| 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 } - - +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 } - - +mut x = 0while $x <10{$x =$x +1}[1234] +| window 2 +[1,2,3,4,5,6,7,8]| window 2 +--stride3[1,2,3,4,5]| window 3 +--stride3--remainderwith-env [MYENV"my env value"]{ $env.MYENV }with-env [XYWZ]{ $env.X }with-env [[XW]; [Y Z]]{ $env.W }with-env {X: "Y", W: "Z"} +{[$env X$env W]}[123]| wrap num +1..3| wrap num +[12]| zip [34]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 index 09c311e..4a539ed 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,6 +1,6 @@ //! Keeps all the options, tweaks and dials of the configuration. -#[derive(Debug)] +#[derive(Debug, Clone, PartialEq, Eq)] pub struct Config { pub tab_spaces: usize, pub max_width: usize, diff --git a/src/lib.rs b/src/lib.rs index 8d5649e..a804029 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,7 +3,7 @@ //! It does not do anything more than that, which makes it so fast. use config::Config; use formatting::{add_newline_at_end_of_file, format_inner}; -use log::{debug, trace}; +use log::debug; use std::fs::File; use std::io::Write; use std::path::PathBuf; @@ -11,23 +11,69 @@ use std::path::PathBuf; pub mod config; mod formatting; -/// format a Nushell file inplace -pub fn format_single_file(file: &PathBuf, config: &Config) { - let contents = std::fs::read(file) - .unwrap_or_else(|_| panic!("something went wrong reading the file {}", file.display())); +/// The possible outcome of checking a file +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum CheckOutcome { + /// File is already correctly formatted + AlreadyFormatted, + /// File would be reformatted if check mode was off + NeedsFormatting, + /// An error occurred while trying to access or write to the file + Failure(String), +} + +/// The possible outcome of checking or formatting a file +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum FormatOutcome { + /// File was left unchanged, as it is already correctly formatted + AlreadyFormatted, + /// File was formatted successfully + Reformatted, + /// An error occurred while trying to access or write to the file + Failure(String), +} + +/// check a Nushell file +pub fn check_single_file(file: PathBuf, config: &Config) -> (PathBuf, CheckOutcome) { + let contents = match std::fs::read(&file) { + Ok(content) => content, + Err(err) => { + return (file, CheckOutcome::Failure(err.to_string())); + } + }; + + let formatted_bytes = add_newline_at_end_of_file(format_inner(&contents, config)); + + if formatted_bytes == contents { + (file, CheckOutcome::AlreadyFormatted) + } else { + (file, CheckOutcome::NeedsFormatting) + } +} + +/// format a Nushell file in place +pub fn format_single_file(file: PathBuf, config: &Config) -> (PathBuf, FormatOutcome) { + let contents = match std::fs::read(&file) { + Ok(content) => content, + Err(err) => { + return (file, FormatOutcome::Failure(err.to_string())); + } + }; let formatted_bytes = add_newline_at_end_of_file(format_inner(&contents, config)); if formatted_bytes == contents { debug!("File is already formatted correctly."); + return (file, FormatOutcome::AlreadyFormatted); } - let mut writer = File::create(file).unwrap(); + let mut writer = File::create(&file).unwrap(); let file_bytes = formatted_bytes.as_slice(); writer .write_all(file_bytes) .expect("something went wrong writing"); - trace!("written"); + debug!("File formatted."); + (file, FormatOutcome::Reformatted) } /// format a string of Nushell code diff --git a/src/main.rs b/src/main.rs index a3de0f2..0047c36 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,46 +1,72 @@ #![doc = include_str!("../README.md")] use clap::Parser; +use ignore::{DirEntry, WalkBuilder}; use log::{error, info, trace}; use nu_formatter::config::Config; +use nu_formatter::{CheckOutcome, FormatOutcome}; +use rayon::iter::{IntoParallelIterator, ParallelIterator}; use std::{ - fs, io::{self, Write}, path::{Path, PathBuf}, }; +/// The possible exit codes enum ExitCode { + /// nufmt terminates successfully, regardless of whether files or stdin were formatted. Success, + /// only used in check mode: nufmt terminates successfully and at least one file or stdin would be formatted if check mode was off. + CheckFailed, + /// nufmt terminates abnormally due to invalid configuration, invalid CLI options, or an internal error. Failure, } +impl ExitCode { + /// Return the exit code to use. + /// If check mode is off: return 2 if at least one file could not be formatted, 0 otherwise (regardless of whether any files were formatted). + /// If check mode is on: return 1 if some files would be formatted if check mode was off, 0 otherwise. + fn code(&self) -> i32 { + match self { + ExitCode::Success => 0, + ExitCode::CheckFailed => 1, + ExitCode::Failure => 2, + } + } +} + /// the CLI signature of the `nufmt` executable. #[derive(Parser)] #[command(author, version, about)] struct Cli { #[arg( - required_unless_present("stdin"), - help = "one of more Nushell files you want to format" + value_name = "FILES", + default_value = ".", + conflicts_with("stdin"), + help = "One of more Nushell files or directories to format" )] files: Vec, #[arg( - short, long, + conflicts_with = "stdin", + help = "Avoid writing any formatted files back; instead, exit with a non-zero status code if any files would have been modified, and zero otherwise" + )] + check: bool, + + #[arg( + long, + conflicts_with = "check", conflicts_with = "files", - help = "a string of Nushell directly given to the formatter" + help = "A string of Nushell directly given to the formatter" )] stdin: bool, - #[arg(short, long, help = "the configuration file")] + #[arg(short, long, help = "nufmt configuration file")] config: Option, } fn exit_with_code(exit_code: ExitCode) { - let code = match exit_code { - ExitCode::Success => 0, - ExitCode::Failure => 1, - }; + let code = exit_code.code(); trace!("exit code: {code}"); // NOTE: this immediately terminates the process without doing any cleanup, @@ -56,7 +82,7 @@ fn main() { trace!("recieved cli.stdin: {:?}", cli.stdin); trace!("recieved cli.config: {:?}", cli.config); - let cli_config = match cli.config { + let config = match cli.config { None => Config::default(), Some(input_cli) => { todo!( @@ -69,9 +95,16 @@ fn main() { let exit_code = match cli.files[..] { [] if cli.stdin => { let stdin_input = io::stdin().lines().map(|x| x.unwrap()).collect(); - format_string(Some(stdin_input), &cli_config) + format_string(stdin_input, &config) + } + [] if cli.check => { + let results = check_files(cli.files, &config); + exit_from_check(&results) + } + _ => { + let results = format_files(cli.files, &config); + exit_from_format(&results) } - _ => format_files(cli.files, &cli_config), }; std::io::stdout().flush().unwrap(); @@ -80,62 +113,161 @@ fn main() { } /// format a string passed via stdin and output it directly to stdout -fn format_string(string: Option, options: &Config) -> ExitCode { - let output = nu_formatter::format_string(&string.unwrap(), options); +fn format_string(string: String, options: &Config) -> ExitCode { + let output = nu_formatter::format_string(&string, options); println!("{output}"); ExitCode::Success } -/// format a list of files, possibly one, and modify them inplace -fn format_files(files: Vec, options: &Config) -> ExitCode { - for file in &files { - if !file.exists() { - error!("Error: {} not found!", file.to_str().unwrap()); - return ExitCode::Failure; - } else if file.is_dir() { - for path in recurse_files(file).unwrap() { - if is_file_extension(&path, ".nu") { - info!("formatting file: {:?}", &path); - nu_formatter::format_single_file(&path, options); - } else { - info!("not nu file: skipping"); - } +/// check a list of files, possibly one +fn check_files(files: Vec, options: &Config) -> Vec<(PathBuf, CheckOutcome)> { + let target_files = discover_files(&files); + target_files + .into_par_iter() + .map(|file| { + info!("formatting file: {:?}", &file); + nu_formatter::check_single_file(file, options) + }) + .collect() +} + +/// format a list of files, possibly one, and modify them in place +fn format_files(files: Vec, options: &Config) -> Vec<(PathBuf, FormatOutcome)> { + let target_files = discover_files(&files); + target_files + .into_par_iter() + .map(|file| { + info!("formatting file: {:?}", &file); + nu_formatter::format_single_file(file, options) + }) + .collect() +} + +/// Display results and return the appropriate exit code after formatting in check mode +fn exit_from_check(results: &[(PathBuf, CheckOutcome)]) -> ExitCode { + let mut already_formatted: usize = 0; + let mut need_formatting: Vec<&PathBuf> = vec![]; + let mut at_least_one_failure = false; + + for (file, result) in results { + match result { + CheckOutcome::AlreadyFormatted => already_formatted += 1, + CheckOutcome::NeedsFormatting => need_formatting.push(file), + CheckOutcome::Failure(reason) => { + error!( + "\x1b[1mFailed to check {}:\x1b[0m{}", + make_relative(file), + &reason + ); + at_least_one_failure = true; } - // Files only - } else { - info!("formatting file: {:?}", file); - nu_formatter::format_single_file(file, options); } } - ExitCode::Success -} + for file in &need_formatting { + let file_rel = make_relative(file); + println!("Would reformat: \x1b[1m{}\x1b[0m", file_rel); + } -fn recurse_files(path: impl AsRef) -> std::io::Result> { - let mut buf = vec![]; - let entries = fs::read_dir(path)?; + let need_formatting_count = need_formatting.len(); + if need_formatting_count > 0 { + println!( + "{} file{} would be reformatted", + need_formatting_count, + if need_formatting_count == 1 { "" } else { "s" } + ); + } - for entry in entries { - let entry = entry?; - let meta = entry.metadata()?; + if already_formatted > 0 { + println!( + "{} file{} already formatted", + already_formatted, + if already_formatted == 1 { "" } else { "s" } + ); + }; - if meta.is_dir() { - let mut subdir = recurse_files(entry.path())?; - buf.append(&mut subdir); - } + if at_least_one_failure { + ExitCode::Failure + } else if need_formatting_count > 0 { + ExitCode::CheckFailed + } else { + ExitCode::Success + } +} + +/// Display results and return the appropriate exit code after formatting in format mode +fn exit_from_format(results: &[(PathBuf, FormatOutcome)]) -> ExitCode { + let mut left_unchanged: usize = 0; + let mut reformatted: usize = 0; + let mut at_least_one_failure = false; - if meta.is_file() { - buf.push(entry.path()); + for (file, result) in results { + match result { + FormatOutcome::AlreadyFormatted => left_unchanged += 1, + FormatOutcome::Reformatted => reformatted += 1, + FormatOutcome::Failure(reason) => { + error!( + "\x1b[1mFailed to format {}:\x1b[0m{}", + make_relative(file), + &reason + ); + at_least_one_failure = true; + } } } - Ok(buf) + if reformatted > 0 { + println!( + "{} file{} were reformatted", + reformatted, + if reformatted == 1 { "" } else { "s" } + ); + } + + if left_unchanged > 0 { + println!( + "{} file{} already formatted", + left_unchanged, + if left_unchanged == 1 { "" } else { "s" } + ); + }; + + if at_least_one_failure { + ExitCode::Failure + } else { + ExitCode::Success + } +} + +/// Return the different files to analyze, taking only files with .nu extension and discarding files in .nufmtignore +fn discover_files(paths: &[PathBuf]) -> Vec { + paths + .iter() + .flat_map(|path| { + WalkBuilder::new(path) + .add_custom_ignore_filename(".nufmtignore") + .build() + .filter_map(Result::ok) + .filter(is_nu_file) + .map(|path| path.into_path()) + .collect::>() + }) + .collect() +} + +/// Return whether a DirEntry is a .nu file or not +fn is_nu_file(entry: &DirEntry) -> bool { + entry.file_type().map(|ft| ft.is_file()).unwrap_or(false) + && entry.path().extension().is_some_and(|ext| ext == "nu") } -/// Get the file extension -fn is_file_extension(file: &Path, extension: &str) -> bool { - String::from(file.to_str().unwrap()).ends_with(extension) +fn make_relative(path: &Path) -> String { + let current = std::env::current_dir().expect("Failed to get current directory"); + path.strip_prefix(¤t) + .unwrap_or(path) + .display() + .to_string() } #[cfg(test)] diff --git a/toolkit.nu b/toolkit.nu index 4b7c519..2ac6da8 100644 --- a/toolkit.nu +++ b/toolkit.nu @@ -7,71 +7,66 @@ # make sure all the tests pass. # print the pipe input inside backticks, dimmed and italic, as a pretty command -def pretty-print-command [] { - $"`(ansi default_dimmed)(ansi default_italic)($in)(ansi reset)`" -} -# check standard code formatting and apply the changes -export def fmt [ +def pretty-print-command [] +{$"` (ansi default_dimmed +)(ansi default_italic +)($in )(ansi reset +)` "}#check +standard code +formatting andapply the +changes export def fmt[ --check # do not apply the format changes, only check the syntax --verbose # print extra information about the command's progress -] { - if $verbose { - print $"running ('toolkit fmt' | pretty-print-command)" - } - - if $check { - try { - cargo fmt --all -- --check - } catch { - error make --unspanned { - msg: $"\nplease run ('toolkit fmt' | pretty-print-command) to fix formatting!" - } - } - } else { - cargo fmt --all - } -} - -# check that you're using the standard code style +] +{ +if $verbose {print $"running ('toolkit fmt'| )"} +if $check {try {cargo fmt +--all----check catch +{error make --unspanned{msg:$"\nplease run ('toolkit fmt'| ) to fix formatting!"}}else +else +{cargo fmt +--all}}#check +thatyou're using the standard code style # # > it is important to make `clippy` happy :relieved: -export def clippy [ - --verbose # print extra information about the command's progress -] { - if $verbose { - print $"running ('toolkit clippy' | pretty-print-command)" - } - - try {( - cargo clippy - --all-targets - --no-deps - --workspace - -- - -D warnings - -D rustdoc::broken_intra_doc_links - -W clippy::explicit_iter_loop - -W clippy::explicit_into_iter_loop - -W clippy::semicolon_if_nothing_returned - -W clippy::doc_markdown - -W clippy::manual_let_else - )} catch { - error make --unspanned { - msg: $"\nplease fix the above ('clippy' | pretty-print-command) errors before continuing!" - } - } -} -# check that all the tests pass -export def test [ +export def clippy [ + --verbose # print extra information about the command's +progress] { +if $verbose {print $"running ('toolkit clippy'| )"}try +{print $"running ('toolkit clippy'| )"}try +{(cargo clippy +--all-targets +--no-deps +--workspace +-- +-D +warnings +-D +rustdoc::broken_intra_doc_links +-W +clippy::explicit_iter_loop +-W +clippy::explicit_into_iter_loop +-W +clippy::semicolon_if_nothing_returned +-W +clippy::doc_markdown +-W +clippy::manual_let_else +)catch +catch +{error make --unspanned{msg:$"\nplease fix the above ('clippy'| ) errors before continuing!"}}}#check +thatall +thetests +passexport def test[ --fast # use the "nextext" `cargo` subcommand to speed up the tests (see [`cargo-nextest`](https://nexte.st/) and [`nextest-rs/nextest`](https://github.com/nextest-rs/nextest)) -] { - if $fast { - cargo nextest run --all - } else { - cargo test --workspace - } +] +{ +if $fast {cargo nextest +run --all else +{cargo test +--workspace}}export def main[] +{help toolkit } - -export def main [] { help toolkit } From 908ef3ab66979bedbe62704f01e2b9c8e0f51728 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Riegel?= Date: Thu, 1 May 2025 22:17:06 +0200 Subject: [PATCH 02/30] add --check in README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 488b0cc..ad638cb 100644 --- a/README.md +++ b/README.md @@ -60,6 +60,7 @@ nufmt my-file1.nu my-file2.nu my-file3.nu ### Options +- `--check` if you just want to check files without formatting them. It cannot be combined with stdin. - `-s` or `--stdin` formats from `stdin`, returns to `stdout` as a String. It cannot be used combined with `files`. - `-c` or `--config` pass the config file path. Sample: @@ -73,7 +74,6 @@ nufmt my-file1.nu my-file2.nu my-file3.nu ```text nufmt --stdin --config my-stdin-config.json ``` - - `-h` or `--help` show help and exit - `-v` or `--version` prints the version and exit From 87b8aa267c68a7cb21a4aae0d5581fa1bf2088e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Riegel?= Date: Thu, 1 May 2025 22:24:06 +0200 Subject: [PATCH 03/30] add warning if 0 files found --- src/main.rs | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/main.rs b/src/main.rs index 0047c36..17f274d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,7 +2,7 @@ use clap::Parser; use ignore::{DirEntry, WalkBuilder}; -use log::{error, info, trace}; +use log::{error, info, trace, warn}; use nu_formatter::config::Config; use nu_formatter::{CheckOutcome, FormatOutcome}; use rayon::iter::{IntoParallelIterator, ParallelIterator}; @@ -171,6 +171,12 @@ fn exit_from_check(results: &[(PathBuf, CheckOutcome)]) -> ExitCode { } let need_formatting_count = need_formatting.len(); + + if already_formatted + need_formatting_count == 0 { + warn!("No Nushell files found under the given path(s)"); + return ExitCode::Success; + } + if need_formatting_count > 0 { println!( "{} file{} would be reformatted", @@ -178,7 +184,6 @@ fn exit_from_check(results: &[(PathBuf, CheckOutcome)]) -> ExitCode { if need_formatting_count == 1 { "" } else { "s" } ); } - if already_formatted > 0 { println!( "{} file{} already formatted", @@ -186,7 +191,6 @@ fn exit_from_check(results: &[(PathBuf, CheckOutcome)]) -> ExitCode { if already_formatted == 1 { "" } else { "s" } ); }; - if at_least_one_failure { ExitCode::Failure } else if need_formatting_count > 0 { @@ -217,6 +221,11 @@ fn exit_from_format(results: &[(PathBuf, FormatOutcome)]) -> ExitCode { } } + if left_unchanged + reformatted == 0 { + warn!("No Nushell files found under the given path(s)"); + return ExitCode::Success; + } + if reformatted > 0 { println!( "{} file{} were reformatted", From 94a54fa92a3727b662e10888d92cca3bd9d2a99a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Riegel?= Date: Thu, 1 May 2025 22:55:14 +0200 Subject: [PATCH 04/30] add colored dependency and fix running checks --- .gitignore | 3 + Cargo.lock | 11 + Cargo.toml | 3 +- benches/example.nu | 653 +++++++++++++++++++++++++++++---------------- src/main.rs | 35 ++- toolkit.nu | 41 +-- 6 files changed, 475 insertions(+), 271 deletions(-) diff --git a/.gitignore b/.gitignore index 1492cc9..16215cb 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,6 @@ result # editors .idea/ .vscode/ + +# Everyone their own +tmp/ diff --git a/Cargo.lock b/Cargo.lock index 6097225..e9c3069 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -445,6 +445,16 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" +[[package]] +name = "colored" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "117725a109d387c937a1533ce01b450cbde6b88abceea8473c4d7a85853cda3c" +dependencies = [ + "lazy_static", + "windows-sys 0.59.0", +] + [[package]] name = "const_format" version = "0.2.33" @@ -1187,6 +1197,7 @@ version = "0.1.0" dependencies = [ "anyhow", "clap", + "colored", "criterion", "env_logger", "ignore", diff --git a/Cargo.toml b/Cargo.toml index 9f0142e..9f76226 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,12 +16,13 @@ categories = ["command-line-utilities"] [dependencies] anyhow = "1.0.71" clap = { version = "4.3.0", optional = true, features = ["unicode", "derive"] } +colored = "2" env_logger = "0.10.0" +ignore = "0.4" log = "0.4.17" nu-cmd-lang = "0.99.0" nu-parser = "0.99.0" nu-protocol = "0.99.0" -ignore = "0.4" rayon = "1.10" [dev-dependencies] diff --git a/benches/example.nu b/benches/example.nu index 8ccd05b..5838a29 100644 --- a/benches/example.nu +++ b/benches/example.nu @@ -1,13 +1,13 @@ -alias ll=ls -l -[[status]; [UP] [UP]]| all {|el| $el.status == UP } +alias ll=ls-l[[status]; [UP] [UP]]| all {|el| $el.status == UP } [foobar2baz]| all {|| ($in | describe ) == 'string' }[0246]| enumerate | all {|i| $i.item == $i.index * 2 } let cond = {|el| ($el mod2 -==0[2468] +==0[2468][2468] [2468] | all $cond ansi green -ansi reset +ansi +reset $'(ansi red_bold )Hello(ansi reset ) (ansi green_dimmed @@ -23,12 +23,11 @@ $'(ansi red_bold )'$"(ansi -e '3;93;41m' )Hello(ansi reset -)"##italic -brightyellow +)"##italiccbrightyellow onred -backgroundlet 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 -NuWorld(ansi reset +backgroundlet +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_redHello NuWorld(ansi reset )"'Hello, Nushell! This is a gradient.'| ansi gradient --fgstart '0x40c9ff' @@ -242,26 +241,21 @@ dir_a dir_b cp *.txt dir_a -"2021-10-22 -20:00:12+01:00"| date format +"2021-10-2220:00:12+01:00"| date format date now | date format -"%Y-%m-%d -%H:%M:%S" +"%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 +"2021-10-22 20:00:12+01:00"| date format "%Y-%m-%d" -"2021-10-22 -20:00:12+01:00"| date humanize +"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" +"%Y-%m-%d %H:%M:%S" (date now )-2019-05-01(date now )-2019-05-01T04:12:05.20+08:00date now @@ -282,8 +276,7 @@ local date now | date to-timezone US/Hawaii -"2020-10-1010:00:00 -+02:00"| date to-timezone +"2020-10-1010: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 @@ -398,8 +391,7 @@ new_a ["2021-12-30""2021-12-31"]| dfr into-df | dfr as-datetime "%Y-%m-%d" -["2021-12-3000:00:00""2021-12-31 -00:00:00"]| dfr into-df +["2021-12-3000: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 @@ -945,12 +937,10 @@ a )*3| dfr as "d" )]| dfr collect -do {hello}let text = "I -amenclosed"let hello = {||$text }do $hello do -i{thisisnotarealcommand }do -s{thisisnotarealcommand }do -p{nu -c +do {hello}let text = "I amenclosed"let hello = {||$text }do $hello do -i{thisisnotarealcommand }do -s{thisisnotarealcommand }do -p{nu -c 'exit 1' }"I'll still run"do -c{nu -c -'exit -1' +'exit 1' }| myscarycommand do {|x| 100+$x }7777| 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 @@ -1002,8 +992,7 @@ $in "負けると知って戦うのが、遥かに美しいのだ"| encode shift shift-jis 0x[09 F9 11 02 9D 74 E3 5B D8 41 56 C5 63 56 88 C0]| encode base64 'SomeData'| 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 @@ -1134,8 +1123,7 @@ open data.txt open data.txt | from csv --separator -' -{size}' +' {size ' [[col1, col2]; [v1, v2] [v3, v4]]| format '{col2}' ls | format filesize KB @@ -1154,20 +1142,23 @@ open data.txt | from csv --separator ' -' -open data.txt -| from csv ---comment -'#'open data.txt +#'open +data.txt +data.txt | from csv ---trimall open data.txt -| from csv ---trimheaders open data.txt -| from csv ---trimfields 'From: test@email.com +--trimallopen +data.txt| from csv +--trimheadersopen +data.txt| from csv +--trimfields'From: test@email.com Subject: Welcome To: someone@somewhere.com -Test'| from eml +Test' +'From: test@email.com +Subject: Welcome +To: someone@somewhere.com +Test' +| from eml 'From: test@email.com Subject: Welcome To: someone@somewhere.com @@ -1185,9 +1176,7 @@ open --raw test.ods | from ods open --raw test.ods | from ods --s[Spreadsheet1]open--raw ---raw -file.parquet | from parquet +-s[Spreadsheet1]open--raw--rawfile.parquet | from parquet open file.parquet 'FOO BAR 1 2'| from ssv @@ -1222,23 +1211,39 @@ $'a1(char tab )c2'| save tsv-data | open tsv-data | from tsv ---trimall $'a1(char tab +--trimall$'a1(char tab )b1(char tab )c1(char nl )a2(char tab )b2(char tab -)c2'| save tsv-data +)c2' +$'a1(char tab +)b1(char tab +)c1(char nl +)a2(char tab +)b2(char tab +)c2' +| save tsv-data | open tsv-data | from tsv ---trimheaders $'a1(char tab +--trimheaders$'a1(char tab )b1(char tab )c1(char nl )a2(char tab )b2(char tab -)c2'| save tsv-data +)c2' +$'a1(char tab +)b1(char tab +)c1(char nl +)a2(char tab +)b2(char tab +)c2' +| save tsv-data | open tsv-data | from tsv ---trimfields 'bread=baguette&cheese=comt%C3%A9&meat=ham&fat=butter'| from url +--trimfields'bread=baguette&cheese=comt%C3%A9&meat=ham&fat=butter' +'bread=baguette&cheese=comt%C3%A9&meat=ham&fat=butter' +| from url 'BEGIN:VCARD N:Foo FN:Bar @@ -1257,13 +1262,11 @@ test.xlsx | from xlsx 'a: 1'| from yaml '[ a: 1, b: [1, 2] ]'| from yaml g mkdir -foo -enter foo +foo enter foo enter ../bar g 1 shells g -2 -mkdir foo +2mkdir foo enter foo enter ../bar g - @@ -1275,9 +1278,11 @@ ls | get 2.name sys | get cpu $env | get paTH $env | get -s -Path glob *.rs +Path glob +*.rs glob **/*.{rs,toml} ---depth2glob "[Cc]*" +--depth2glob"[Cc]*" +"[Cc]*" glob "{a?c,x?z}" glob "(?i)c*" glob "[!cCbMs]*" @@ -1288,16 +1293,19 @@ glob "[A-Z]*" | grid {name:'foo',b:1,c:2} | grid [{name:'A',v:1 }{name:'B',v:2}{name:'C',v:3 + }]| grid [[namepatch]; [0.1.0 false] [0.1.1 true] [0.2.0 false]]| grid [1234]| group 2 ls | group-by type ['1''3''1''3''2''1''1']| group-by 'abcdefghijklmnopqrstuvwxyz' | hash md5 'abcdefghijklmnopqrstuvwxyz'| hash md5 ---binaryopen ./nu_0_24_1_windows.zip +--binaryopen./nu_0_24_1_windows.zip +./nu_0_24_1_windows.zip | hash md5 'abcdefghijklmnopqrstuvwxyz'| hash sha256 'abcdefghijklmnopqrstuvwxyz'| hash sha256 ---binaryopen ./nu_0_24_1_windows.zip +--binaryopen./nu_0_24_1_windows.zip +./nu_0_24_1_windows.zip | hash sha256 "a b c|1 2 3"| split row "|"| split column @@ -1307,53 +1315,119 @@ ls | group-by type " "| headers help match help str -lpad help --find -char help aliases +lpad help +--find +char help +aliases help aliases -my-alias help aliases ---findmy-alias help externs -help externs -smth help externs ---findsmth help modules -help modules -my-module help modules ---findmy-module alias lll=ls -l +my-alias help +aliases +--findmy-aliashelp +externshelp externs +smth help +externs +--findsmthhelp +moduleshelp modules +my-module help +modules +--findmy-modulealias +lll=ls-l +-l hide lll def say-hi [] -{'Hi!' -hide say-hilet-env -HZ_ENV_ABC =1hide-env HZ_ENV_ABC 'HZ_ENV_ABC' in (env )namels | histogram type +{'Hi!' hide say-hilet-envHZ_ENV_ABC =1hide-env +HZ_ENV_ABC +'HZ_ENV_ABC' +in +(env +namels +| histogram type ls | histogram type freq [121]| histogram [1231112211]| histogram --percentage-type -relative history | length history +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-keymy-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-keymy-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-keymy-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-keymy-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-keymy-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-keymy-header-value]https://www example com http put --t application/json https://www.example.com {field :value } +https://www.example.com http +delete +-umyuser +-pmypass +https://www.example.comhttp +delete-H[my-header-keymy-header-value]https://www +examplecom +httpdelete +delete +-d'body' +https://www.example.comhttp +delete-tapplication/json +-d{field :value }https://www.example.com +httpget +get +https://www.example.com http +get +-umyuser +-pmypass +https://www.example.comhttp +get-H[my-header-keymy-header-value]https://www +examplecom +httphead +head +https://www.example.com http +head +-umyuser +-pmypass +https://www.example.comhttp +head-H[my-header-keymy-header-value]https://www +examplecom +httppatch +patch +https://www.example.com 'body' +http +patch +-umyuser +-pmypass +https://www.example.com'body' +httppatch +patch +-H[my-header-keymy-header-value]https://www +examplecom +httppatch +patch +-tapplication/json +https://www.example.com{field :value }http +posthttps://www.example.com 'body' +http +post +-umyuser +-pmypass +https://www.example.com'body' +httppost +post +-H[my-header-keymy-header-value]https://www +examplecom +httppost +post +-tapplication/json +https://www.example.com{field :value }http +puthttps://www.example.com 'body' +http +put +-umyuser +-pmypass +https://www.example.com'body' +httpput +put +-H[my-header-keymy-header-value]https://www +examplecom +httpput +put +-tapplication/json +https://www.example.com{field :value } +{field :value } + if 2<3{'yes!'} if 5<3{'yes!'}else{'no!'} if 5<3{'yes!'}else @@ -1361,89 +1435,162 @@ if 4<5{'no!'}else{'okay!'done done | ignore let user_input -=(input -{'name':'nu','stars':5} +=(input {'name':'nu','stars':5} | insert alias -'Nushell'[[project, lang]; ['Nushell', 'Rust']]| insert type -'shell'[[foo]; [7] [8] [9]]| enumerate | insert bar -{|e| $e itemfoo+$e index}| flatten ls +'Nushell'[[project, lang]; ['Nushell', 'Rust']] +| insert type +'shell'[[foo]; [7] [8] [9]] +| enumerate | insert bar +{|e| $e itemfoo+$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 +1 +| into binary +true +| into binary +ls +| where name == LICENSE | get size | into binary -ls | where name == LICENSE +ls +| where name == LICENSE | get name | path expand | into binary -1.234| 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-51614434140*1_000_000_000 | into datetime +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-51614434140*1_000_000_000 +| into datetime [[num]; ['5.01']]| into decimal -num '1.345'| into decimal -'-5.9'| into decimal -true| 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 ---convertsec 420sec| into duration -420sec| into duration ---convertms 1000000µs| into duration ---convertsec 1sec| into duration ---convertµs 1sec| into duration ---convertus [[bytes]; ['5'] [3.2] [4] [2kb]]| into filesize -bytes '2'| into filesize -8.3| into filesize -5| into filesize -4KB| into filesize +value +'7min' +| into duration +'7min' +| into duration +--convertsec +420sec +| into duration +420sec +| into duration +--convertms +1000000µs +| into duration +--convertsec +1sec +| into duration +--convertµs +1sec +| into duration +--convertus +[[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 +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 --r2'FF'| into int --r16'0o10132'| into int -'0010132'| into int -'0010132'| into int --r8[[value]; [false]]| into record +1983-04-13T12:09:14.123456789-05:00 +| into int +'1101' +| into int +-r2'FF' +| into int +-r16'0o10132' +| into int +'0010132' +| into int +'0010132' +| into int +-r8[[value]; [false]] +| into record [123]| 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 -tmy_table [[name]; [-----] [someone] [=====] [somename] ['(((((']]| into sqlite -filename.db [one25.2sixtrue100mib25sec]| into sqlite -variety.db 5| into string --d31.7| into string --d01.7| into string --d11.734| into string --d21.734| into string --d-24.3| into string -'1234'| into string -true| into string -ls Cargo.toml +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 +-tmy_table +[[name]; [-----] [someone] [=====] [somename] ['(((((']]| into sqlite +filename.db +[one25.2sixtrue100mib25sec]| into sqlite +variety.db +5 +| into string +-d31.7 +| into string +-d01.7 +| into string +-d11.734 +| into string +-d21.734 +| into string +-d-24.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"'' +1KiB +| into string +if +is-admin{"iamroot"}else{"iamnotroot"'' '' | is-empty []| is-empty [[mealsize]; [arepa small] [taco '']]| is-empty meal size {new:york,san:francisco}| items {|key, value| echo ($key @@ -1489,7 +1636,8 @@ ls -s ls -a ~ | where type == dir ls -as -~ | where type == dir and modified < ((date now) - 7day) +~ | where type == dir and modified < ((date now +)-7day) ['/path/to/directory''/path/to/file']| each {|| ls -D $in } | flatten match 31..10=> @@ -1504,7 +1652,10 @@ ls -as | match $in {a:{$b } }=> -($b +10)[-50-100.025] +($b ++10 ++10 +)[-50-100.025] | math abs 1| math arccos -1| math arccos @@ -1556,38 +1707,41 @@ math pi [1.52.3-3.1]| math round [1.5552.333-3.111]| math round -p2(math pi - /2 | math sin [090180270360]| math sin --d| math round ---precision41| math sinh +-d +| math round +--precision41 +| math sinh [916]| math sqrt [12345]| math stddev [12345]| math stddev --s[123]| math sum -ls | get size +-s[123] +| math sum +ls +| get size | math sum (math pi - /4 | math tan [-45045]| math tan -d(math pi - *10 | math tanh -math tau +math +tau | math round ---precision2[12345]| math variance +--precision2[12345] +| math variance [12345]| math variance --s[abc]| wrap name +-s[abc] +| wrap name | merge ([123]| wrap index - {a:1,b:2} | merge {c: 3} [{columnA:A0columnB:B0 -}]| merge [{columnA:'A0*' +}]| merge [{columnA: 'A0*' }]let a =42metadata $a @@ -1631,8 +1785,8 @@ script.nu open foo.nu | nu-check -d script.nu open module.nu | lines | nu-check -d ---as-modulemodule.nu $'two(char nl -)lines'| nu-check nu-check +--as-modulemodule.nu two(char nl +)lines| nu-check nu-check -a script.nu open foo.nu | lines | nu-check -ad @@ -1641,8 +1795,7 @@ ll =ls -l old-alias customs =($nu scopecommands -scopecommands -| where is_custom +scopecommands| where is_custom | get command )openmyfile.json open myfile.json @@ -1700,13 +1853,11 @@ p p | sort 1..3 | enumerate | par-each {|p| update item ($p item*2 -item*2 -)}| sort-by item +item*2)}| sort-by item | get item [123]| enumerate | par-each { |e| if $e.item == 2 { found 2 at ($e index -index -)!} }"hi there"| parse "{foo} {bar}" +index)!} }"hi there"| parse "{foo} {bar}" "hi there"| parse -r '(?P\w+) (?P\w+)'"foo bar."| parse -r '\s*(?\w+)(?=\.)'"foo! bar."| parse -r @@ -1716,7 +1867,7 @@ index [[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 +ls '.'| path expand )| path dirname -c[name]'/home/joe/code/test.txt'| path dirname -n2'/home/joe/code/test.txt'| path dirname @@ -1740,7 +1891,7 @@ spam.txt -c[name]['/''home''viking''spam.txt']| path join | path relative-to ~ -c[name]'eggs/bacon/sausage/spam'| path relative-to 'eggs/bacon/sausage''/home/viking/spam.txt'| path split -ls ('.'| path expand +ls '.'| path expand )| path split -c[name]'.'| path type ls | path type @@ -1798,18 +1949,20 @@ random integer -a $it "X" }['foo.gz' ,'bar.gz' ,'baz.gz' ]| enumerate | reduce -f -'' {|str all| ($all +'' {|str all| ($all ( -if $str index!=0{'; '} +if $str index!=0{ +( +if $str index!=0{ +'; '} index!=0{'; '} -($str index+1 --($str item +($str +index+1 +-($str item -) -"hello world"| regex '(?P\w+) (?P\w+)' +item)"hello world"| regex '(?P\w+) (?P\w+)' register ~/.cargo/bin/nu_plugin_query let plugin = ((which nu - path0 | path dirname | path join @@ -1818,7 +1971,8 @@ path0 nu -c -c -$'register ($plugin ); version'lss| reject modified +register ($plugin +); versionlss| reject modified [[a, b]; [1, 2]]| reject a {a:1,b:2}| reject a {a:{b:3,c:5}}| reject a.b @@ -2020,43 +2174,63 @@ title 'Nu shell '| str trim -c'='' Nu shell '| str trim -r'=== Nu shell ==='| str trim -r-c'=''nu'| str upcase -sys (sys -host +sys (sys host | get name -(sys -hostnamels +(sys hostnamels | table -n -1[[a b]; [1 2] [3 4]]| table [[ab]; [1 2] [2 [44]]]| table --expand -[[a b]; [1 2] [2 [44]]]| table --collapse +1[[a b]; [1 2] [3 4]] +| table [[ab]; [1 2] [2 [44]]]| table --expand +[[ab]; [1 2] [2 [44]]]| table --collapse [123]| take 1 [123]| take 2 [[editions]; [2015] [2018] [2021]]| take 2 -0x[01 23 45]| take 2 -1..10| take 3 +0x[01 23 45] +| take 2 +1..10 +| take 3 [-1-291]| take until -{|x| $x >0}let cond = {|x| $x >0 +{|x| $x >0}let +cond +={|x| $x >0 +>0 [-1-291]| take until -$cond [{a:-1}{a:-2}{a:9}{a:1}] +$cond [{a:-1}{a:-2}{a:9}{a:1}] -| take until -{|x| $x a>0}[-1-291]| take while -{|x| $x <0}let cond = {|x| $x <0 +[{a:-1}{a:-2}{a:9}{a:1}] +[{a:-1 +}{a:-2}{a:9}{a:1 +}]| take until +{|x| $x a>0 [-1-291]| take while -$cond [{a:-1}{a:-2}{a:9}{a:1}] +{|x| $x <0 +letcond +cond +={|x| $x <0 +<0 +[-1-291]| take while +$cond +[{a:-1}{a:-2}{a:9}{a:1}] [{a:-1}{a:-2}{a:9}{a:1}] -| take while -{|x| $x a<0}term size +[{a:-1 +}{a:-2}{a:9}{a:1 +}]| take while +{|x| $x a<0 +termsize +size (term size - columns(term size -)rowstimeit{ sleep 500ms } -{ 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:1b:2 +)rowstimeit{ sleep 500ms }{ sleep 500ms } +http +get +https://www.nushell.sh/book/ +| timeit { split chars } +timeit +ls +-la[[foo bar]; [1 2]] +| to csv +[[foobar]; [1 2]]| to csv +-s +';'{a:1b:2 }| to csv [[foo bar]; [1 2]]| to html [[foo bar]; [1 2]]| to html @@ -2116,9 +2290,9 @@ tutor -f [[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 itemfruit +{|e| ($e itemfruit -| str length +itemfruit| str length )+$e index}| get item [[project, authors]; ['nu', ['Andrés','JT','Yehuda']]]| update authors {|row| $row authors| str join @@ -2147,9 +2321,9 @@ if $value ==0{""}else '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 itemfruit +{|e| ($e itemfruit -| str length +itemfruit| str length )+$e index}| get item [123]| upsert 0 2[123]| upsert 3 @@ -2196,28 +2370,41 @@ view span 12watch . --glob=**/*.rs{||cargo test }watch . -{ |op, path, new_path| ($op )($path +{ |op, path, new_path| ($op +)($path ) -($new_path )watch +($new_path +)watch watch /foo/bar /foo/bar -{ |op, path| ($op )-($path +{ |op, path| ($op +)-($path +(char nl +) (char nl -)| save --append +) +| save --append changes_in_bar.log - [{a:1 }{a:2 + }]| where a > 1 -[12]| where {|x| $x > 1} -ls | where size > 2kb -ls | where type == file -ls | where name =~ "Car" -ls | where modified >= (date now) - 2wk +[12] +| 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)' } +-n| enumerate | where {|e| $e.item.name !~ ^($e +index+1) } | each {|| get item } which myapp mut x = 0while $x <10{$x =$x +1}[1234] diff --git a/src/main.rs b/src/main.rs index 17f274d..52b8480 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,7 @@ #![doc = include_str!("../README.md")] use clap::Parser; +use colored::*; use ignore::{DirEntry, WalkBuilder}; use log::{error, info, trace, warn}; use nu_formatter::config::Config; @@ -92,19 +93,15 @@ fn main() { } }; - let exit_code = match cli.files[..] { - [] if cli.stdin => { - let stdin_input = io::stdin().lines().map(|x| x.unwrap()).collect(); - format_string(stdin_input, &config) - } - [] if cli.check => { - let results = check_files(cli.files, &config); - exit_from_check(&results) - } - _ => { - let results = format_files(cli.files, &config); - exit_from_format(&results) - } + let exit_code = if cli.stdin { + let stdin_input = io::stdin().lines().map(|x| x.unwrap()).collect(); + format_string(stdin_input, &config) + } else if cli.check { + let results = check_files(cli.files, &config); + exit_from_check(&results) + } else { + let results = format_files(cli.files, &config); + exit_from_format(&results) }; std::io::stdout().flush().unwrap(); @@ -156,8 +153,9 @@ fn exit_from_check(results: &[(PathBuf, CheckOutcome)]) -> ExitCode { CheckOutcome::NeedsFormatting => need_formatting.push(file), CheckOutcome::Failure(reason) => { error!( - "\x1b[1mFailed to check {}:\x1b[0m{}", - make_relative(file), + "{} {}: {}", + "Failed to check".bold(), + make_relative(file).bold(), &reason ); at_least_one_failure = true; @@ -167,7 +165,7 @@ fn exit_from_check(results: &[(PathBuf, CheckOutcome)]) -> ExitCode { for file in &need_formatting { let file_rel = make_relative(file); - println!("Would reformat: \x1b[1m{}\x1b[0m", file_rel); + println!("Would reformat: {}", file_rel.bold()); } let need_formatting_count = need_formatting.len(); @@ -212,8 +210,9 @@ fn exit_from_format(results: &[(PathBuf, FormatOutcome)]) -> ExitCode { FormatOutcome::Reformatted => reformatted += 1, FormatOutcome::Failure(reason) => { error!( - "\x1b[1mFailed to format {}:\x1b[0m{}", - make_relative(file), + "{} {}: {}", + "Failed to format".bold(), + make_relative(file).bold(), &reason ); at_least_one_failure = true; diff --git a/toolkit.nu b/toolkit.nu index 2ac6da8..40ad371 100644 --- a/toolkit.nu +++ b/toolkit.nu @@ -9,33 +9,35 @@ # print the pipe input inside backticks, dimmed and italic, as a pretty command def pretty-print-command [] -{$"` (ansi default_dimmed +{$"` (ansi default_dimmed )(ansi default_italic )($in )(ansi reset -)` "}#check -standard code -formatting andapply the -changes export def fmt[ +)` "}#checkstandard code +formatting andapply +the +changes export +def +fmt[ --check # do not apply the format changes, only check the syntax --verbose # print extra information about the command's progress ] { -if $verbose {print $"running ('toolkit fmt'| )"} -if $check {try {cargo fmt ---all----check catch -{error make --unspanned{msg:$"\nplease run ('toolkit fmt'| ) to fix formatting!"}}else -else -{cargo fmt ---all}}#check -thatyou're using the standard code style +if $verbose +{print $"running ('toolkit fmt'| )"} +if $check +{try {cargo fmt +--all----checkcatch +catch +{error make --unspanned{msg:$"\nplease run ('toolkit fmt'| ) to fix formatting!"}else +else {cargo fmt +--all}}#checkthatyou're using the standard code style # # > it is important to make `clippy` happy :relieved: export def clippy [ - --verbose # print extra information about the command's -progress] { -if $verbose {print $"running ('toolkit clippy'| )"}try -{print $"running ('toolkit clippy'| )"}try + --verbose # print extra information about the command's progress] { +if $verbose {print running ('toolkit clippy'| )}try +{print running ('toolkit clippy'| )}try {(cargo clippy --all-targets --no-deps @@ -57,11 +59,12 @@ clippy::doc_markdown clippy::manual_let_else )catch catch -{error make --unspanned{msg:$"\nplease fix the above ('clippy'| ) errors before continuing!"}}}#check +{error make --unspanned{msg:\nplease fix the above ('clippy'| ) errors before continuing!}}}#check thatall thetests passexport def test[ - --fast # use the "nextext" `cargo` subcommand to speed up the tests (see [`cargo-nextest`](https://nexte.st/) and [`nextest-rs/nextest`](https://github.com/nextest-rs/nextest)) + --fast # use the "nextext" `cargo` subcommand to speed up the tests (see [`cargo-nextest`](https://nexte.st/)and +[`nextest-rs/nextest`](https://github.com/nextest-rs/nextest)) ] { if $fast {cargo nextest From 190b3f651c08ef21585e16dd97fec8897cfcbdc2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Riegel?= Date: Thu, 1 May 2025 23:32:46 +0200 Subject: [PATCH 05/30] add FormatError with thiserror, remove anyhow, and use it in format_inner --- Cargo.lock | 70 +++++++++++++++++++++++++++------------------ Cargo.toml | 2 +- src/format_error.rs | 7 +++++ src/formatting.rs | 16 +++++------ src/lib.rs | 23 +++++++++++---- src/main.rs | 16 ++++++++--- 6 files changed, 88 insertions(+), 46 deletions(-) create mode 100644 src/format_error.rs diff --git a/Cargo.lock b/Cargo.lock index e9c3069..d792272 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -119,12 +119,6 @@ dependencies = [ "windows-sys 0.52.0", ] -[[package]] -name = "anyhow" -version = "1.0.89" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86fdf8605db99b54d3cd748a44c6d04df638eb5dafb219b135d0149bd0db01f6" - [[package]] name = "arrayvec" version = "0.7.6" @@ -152,7 +146,7 @@ dependencies = [ "regex", "rustc-hash", "shlex", - "syn 2.0.79", + "syn 2.0.101", ] [[package]] @@ -208,7 +202,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.101", "syn_derive", ] @@ -430,7 +424,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.101", ] [[package]] @@ -977,7 +971,7 @@ dependencies = [ "supports-unicode", "terminal_size", "textwrap", - "thiserror", + "thiserror 1.0.64", "unicode-width 0.1.14", ] @@ -989,7 +983,7 @@ checksum = "dcf09caffaac8068c346b6df2a7fc27a177fd20b39421a39ce0a211bde679a6c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.101", ] [[package]] @@ -1071,7 +1065,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.101", ] [[package]] @@ -1149,7 +1143,7 @@ dependencies = [ "os_pipe", "rmp-serde", "serde", - "thiserror", + "thiserror 1.0.64", "typetag", "windows-sys 0.48.0", ] @@ -1195,7 +1189,6 @@ dependencies = [ name = "nufmt" version = "0.1.0" dependencies = [ - "anyhow", "clap", "colored", "criterion", @@ -1206,6 +1199,7 @@ dependencies = [ "nu-parser", "nu-protocol", "rayon", + "thiserror 2.0.12", ] [[package]] @@ -1365,9 +1359,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.87" +version = "1.0.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3e4daa0dcf6feba26f985457cdf104d4b4256fc5a09547140f3631bb076b19a" +checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" dependencies = [ "unicode-ident", ] @@ -1431,7 +1425,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72c71c0c79b9701efe4e1e4b563b2016dd4ee789eb99badcb09d61ac4b92e4a2" dependencies = [ "libc", - "thiserror", + "thiserror 1.0.64", ] [[package]] @@ -1507,7 +1501,7 @@ checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" dependencies = [ "getrandom", "libredox", - "thiserror", + "thiserror 1.0.64", ] [[package]] @@ -1672,7 +1666,7 @@ checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.101", ] [[package]] @@ -1765,9 +1759,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.79" +version = "2.0.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590" +checksum = "8ce2b7fc941b3a24138a0a7cf8e858bfc6a992e7978a068a5c760deb0ed43caf" dependencies = [ "proc-macro2", "quote", @@ -1783,7 +1777,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.101", ] [[package]] @@ -1852,7 +1846,16 @@ version = "1.0.64" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84" dependencies = [ - "thiserror-impl", + "thiserror-impl 1.0.64", +] + +[[package]] +name = "thiserror" +version = "2.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" +dependencies = [ + "thiserror-impl 2.0.12", ] [[package]] @@ -1863,7 +1866,18 @@ checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.101", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.101", ] [[package]] @@ -1968,7 +1982,7 @@ checksum = "70b20a22c42c8f1cd23ce5e34f165d4d37038f5b663ad20fb6adbdf029172483" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.101", ] [[package]] @@ -2092,7 +2106,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.101", "wasm-bindgen-shared", ] @@ -2114,7 +2128,7 @@ checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.101", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -2398,5 +2412,5 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.101", ] diff --git a/Cargo.toml b/Cargo.toml index 9f76226..72576b3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,7 +14,6 @@ categories = ["command-line-utilities"] # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -anyhow = "1.0.71" clap = { version = "4.3.0", optional = true, features = ["unicode", "derive"] } colored = "2" env_logger = "0.10.0" @@ -24,6 +23,7 @@ nu-cmd-lang = "0.99.0" nu-parser = "0.99.0" nu-protocol = "0.99.0" rayon = "1.10" +thiserror = "2" [dev-dependencies] criterion = "0.5.1" diff --git a/src/format_error.rs b/src/format_error.rs new file mode 100644 index 0000000..1293a1a --- /dev/null +++ b/src/format_error.rs @@ -0,0 +1,7 @@ +use thiserror::Error; + +#[derive(Clone, Debug, Error)] +pub enum FormatError { + #[error("Found invalid Nushell syntax")] + GarbageFound, +} diff --git a/src/formatting.rs b/src/formatting.rs index 52298d4..84397d2 100644 --- a/src/formatting.rs +++ b/src/formatting.rs @@ -2,7 +2,8 @@ //! //! It has functions to format slice of bytes and some help functions to separate concerns while doing the job. use crate::config::Config; -use log::{error, info, trace}; +use crate::format_error::FormatError; +use log::{debug, trace}; use nu_parser::{flatten_block, parse, FlatShape}; use nu_protocol::{ ast::Block, @@ -32,7 +33,7 @@ fn get_engine_state() -> EngineState { /// format an array of bytes /// /// Reading the file gives you a list of bytes -pub(crate) fn format_inner(contents: &[u8], _config: &Config) -> Vec { +pub(crate) fn format_inner(contents: &[u8], _config: &Config) -> Result, FormatError> { let engine_state = get_engine_state(); let decls_sorted: Vec<(Vec, nu_protocol::Id)> = engine_state.get_decls_sorted(false); @@ -44,8 +45,8 @@ pub(crate) fn format_inner(contents: &[u8], _config: &Config) -> Vec { if !block_has_pipelines(&parsed_block) { trace!("block has no pipelines!"); - info!("File has no code to format."); - return contents.to_vec(); + debug!("File has no code to format."); + return Ok(contents.to_vec()); } let flat = flatten_block(&working_set, &parsed_block); @@ -122,9 +123,8 @@ pub(crate) fn format_inner(contents: &[u8], _config: &Config) -> Vec { out.extend(b" "); } FlatShape::Garbage => { - error!("found garbage 😢 {content}"); - out.extend(bytes); - out = insert_newline(out); + debug!("found garbage 😢 {content}"); + return Err(FormatError::GarbageFound); } _ => out.extend(bytes), @@ -147,7 +147,7 @@ pub(crate) fn format_inner(contents: &[u8], _config: &Config) -> Vec { start = span.end + 1; } - out + Ok(out) } /// insert a newline at the end of a buffer diff --git a/src/lib.rs b/src/lib.rs index a804029..cd4f114 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,6 +2,7 @@ //! //! It does not do anything more than that, which makes it so fast. use config::Config; +use format_error::FormatError; use formatting::{add_newline_at_end_of_file, format_inner}; use log::debug; use std::fs::File; @@ -9,6 +10,7 @@ use std::io::Write; use std::path::PathBuf; pub mod config; +pub mod format_error; mod formatting; /// The possible outcome of checking a file @@ -42,7 +44,12 @@ pub fn check_single_file(file: PathBuf, config: &Config) -> (PathBuf, CheckOutco } }; - let formatted_bytes = add_newline_at_end_of_file(format_inner(&contents, config)); + let formatted_bytes = add_newline_at_end_of_file(match format_inner(&contents, config) { + Ok(bytes) => bytes, + Err(err) => { + return (file, CheckOutcome::Failure(err.to_string())); + } + }); if formatted_bytes == contents { (file, CheckOutcome::AlreadyFormatted) @@ -60,7 +67,12 @@ pub fn format_single_file(file: PathBuf, config: &Config) -> (PathBuf, FormatOut } }; - let formatted_bytes = add_newline_at_end_of_file(format_inner(&contents, config)); + let formatted_bytes = add_newline_at_end_of_file(match format_inner(&contents, config) { + Ok(bytes) => bytes, + Err(err) => { + return (file, FormatOutcome::Failure(err.to_string())); + } + }); if formatted_bytes == contents { debug!("File is already formatted correctly."); @@ -77,10 +89,11 @@ pub fn format_single_file(file: PathBuf, config: &Config) -> (PathBuf, FormatOut } /// format a string of Nushell code -pub fn format_string(input_string: &String, config: &Config) -> String { +pub fn format_string(input_string: &String, config: &Config) -> Result { let contents = input_string.as_bytes(); - let formatted_bytes = format_inner(contents, config); - String::from_utf8(formatted_bytes).unwrap() + let formatted_bytes = format_inner(contents, config)?; + Ok(String::from_utf8(formatted_bytes) + .expect("Formatted string could not be converted to a UTF-8 string")) } #[cfg(test)] diff --git a/src/main.rs b/src/main.rs index 52b8480..22db736 100644 --- a/src/main.rs +++ b/src/main.rs @@ -111,10 +111,16 @@ fn main() { /// format a string passed via stdin and output it directly to stdout fn format_string(string: String, options: &Config) -> ExitCode { - let output = nu_formatter::format_string(&string, options); - println!("{output}"); - - ExitCode::Success + match nu_formatter::format_string(&string, options) { + Ok(output) => { + println!("{output}"); + ExitCode::Success + } + Err(err) => { + println!("{}: {}", "Could not format stdin".red(), err); + ExitCode::Failure + } + } } /// check a list of files, possibly one @@ -143,6 +149,8 @@ fn format_files(files: Vec, options: &Config) -> Vec<(PathBuf, FormatOu /// Display results and return the appropriate exit code after formatting in check mode fn exit_from_check(results: &[(PathBuf, CheckOutcome)]) -> ExitCode { + dbg!(results); + let mut already_formatted: usize = 0; let mut need_formatting: Vec<&PathBuf> = vec![]; let mut at_least_one_failure = false; From 6badc307a7dffe800e4b968abf2bb2a774c8bb80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Riegel?= Date: Thu, 1 May 2025 23:45:58 +0200 Subject: [PATCH 06/30] fix warning message --- src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.rs b/src/main.rs index 22db736..6d16c49 100644 --- a/src/main.rs +++ b/src/main.rs @@ -179,7 +179,7 @@ fn exit_from_check(results: &[(PathBuf, CheckOutcome)]) -> ExitCode { let need_formatting_count = need_formatting.len(); if already_formatted + need_formatting_count == 0 { - warn!("No Nushell files found under the given path(s)"); + print!("{}: {}", "Warning".bright_yellow(), "no Nushell files found under the given path(s)"); return ExitCode::Success; } From b21d9d31885cda62a4ce36428ceea6f35b793ee1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Riegel?= Date: Fri, 2 May 2025 00:03:50 +0200 Subject: [PATCH 07/30] fixed tests and clippy --- src/format_error.rs | 2 +- src/lib.rs | 7 +++++-- src/main.rs | 17 +++++++++++------ 3 files changed, 17 insertions(+), 9 deletions(-) diff --git a/src/format_error.rs b/src/format_error.rs index 1293a1a..11d6d76 100644 --- a/src/format_error.rs +++ b/src/format_error.rs @@ -1,6 +1,6 @@ use thiserror::Error; -#[derive(Clone, Debug, Error)] +#[derive(Clone, Debug, Error, PartialEq, Eq)] pub enum FormatError { #[error("Found invalid Nushell syntax")] GarbageFound, diff --git a/src/lib.rs b/src/lib.rs index cd4f114..e9ddadd 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -104,10 +104,13 @@ mod test { /// 1. formatting the input gives the expected result /// 2. formatting the output of `nufmt` a second time does not change the content fn run_test(input: &str, expected: &str) { - let formatted = format_string(&input.to_string(), &Config::default()); + let formatted = format_string(&input.to_string(), &Config::default()).unwrap(); assert_eq!(expected.to_string(), formatted); - assert_eq!(formatted, format_string(&formatted, &Config::default())); + assert_eq!( + formatted, + format_string(&formatted, &Config::default()).unwrap() + ); } #[test] diff --git a/src/main.rs b/src/main.rs index 6d16c49..ddb8795 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,7 +3,7 @@ use clap::Parser; use colored::*; use ignore::{DirEntry, WalkBuilder}; -use log::{error, info, trace, warn}; +use log::{info, trace, warn}; use nu_formatter::config::Config; use nu_formatter::{CheckOutcome, FormatOutcome}; use rayon::iter::{IntoParallelIterator, ParallelIterator}; @@ -160,8 +160,9 @@ fn exit_from_check(results: &[(PathBuf, CheckOutcome)]) -> ExitCode { CheckOutcome::AlreadyFormatted => already_formatted += 1, CheckOutcome::NeedsFormatting => need_formatting.push(file), CheckOutcome::Failure(reason) => { - error!( - "{} {}: {}", + println!( + "{}: {} {}: {}", + "Error".bright_red(), "Failed to check".bold(), make_relative(file).bold(), &reason @@ -179,7 +180,10 @@ fn exit_from_check(results: &[(PathBuf, CheckOutcome)]) -> ExitCode { let need_formatting_count = need_formatting.len(); if already_formatted + need_formatting_count == 0 { - print!("{}: {}", "Warning".bright_yellow(), "no Nushell files found under the given path(s)"); + print!( + "{}: no Nushell files found under the given path(s)", + "Warning".bright_yellow(), + ); return ExitCode::Success; } @@ -217,8 +221,9 @@ fn exit_from_format(results: &[(PathBuf, FormatOutcome)]) -> ExitCode { FormatOutcome::AlreadyFormatted => left_unchanged += 1, FormatOutcome::Reformatted => reformatted += 1, FormatOutcome::Failure(reason) => { - error!( - "{} {}: {}", + println!( + "{}: {} {}: {}", + "Error".bright_red(), "Failed to format".bold(), make_relative(file).bold(), &reason From 26395e7a8f7168805ba59395e7350cece58ac05c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Riegel?= Date: Fri, 2 May 2025 00:32:28 +0200 Subject: [PATCH 08/30] error if invalid path provided --- src/format_error.rs | 2 +- src/main.rs | 86 +++++++++++++++++++++++++++++---------------- 2 files changed, 57 insertions(+), 31 deletions(-) diff --git a/src/format_error.rs b/src/format_error.rs index 11d6d76..1c28bf9 100644 --- a/src/format_error.rs +++ b/src/format_error.rs @@ -2,6 +2,6 @@ use thiserror::Error; #[derive(Clone, Debug, Error, PartialEq, Eq)] pub enum FormatError { - #[error("Found invalid Nushell syntax")] + #[error("found invalid Nushell syntax")] GarbageFound, } diff --git a/src/main.rs b/src/main.rs index ddb8795..13a77b8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -125,44 +125,61 @@ fn format_string(string: String, options: &Config) -> ExitCode { /// check a list of files, possibly one fn check_files(files: Vec, options: &Config) -> Vec<(PathBuf, CheckOutcome)> { - let target_files = discover_files(&files); - target_files + let (target_files, invalid_paths) = discover_files(files); + let mut results = target_files .into_par_iter() .map(|file| { - info!("formatting file: {:?}", &file); + info!("checking file: {:?}", &file); nu_formatter::check_single_file(file, options) }) - .collect() + .collect::>(); + for path in invalid_paths { + results.push(( + path, + CheckOutcome::Failure("cannot find the file specified".to_string()), + )); + } + results } /// format a list of files, possibly one, and modify them in place fn format_files(files: Vec, options: &Config) -> Vec<(PathBuf, FormatOutcome)> { - let target_files = discover_files(&files); - target_files + let (target_files, invalid_paths) = discover_files(files); + let mut results = target_files .into_par_iter() .map(|file| { info!("formatting file: {:?}", &file); nu_formatter::format_single_file(file, options) }) - .collect() + .collect::>(); + for path in invalid_paths { + results.push(( + path, + FormatOutcome::Failure("cannot find the file specified".to_string()), + )); + } + results } /// Display results and return the appropriate exit code after formatting in check mode fn exit_from_check(results: &[(PathBuf, CheckOutcome)]) -> ExitCode { - dbg!(results); - let mut already_formatted: usize = 0; - let mut need_formatting: Vec<&PathBuf> = vec![]; + let mut need_formatting: usize = 0; + let mut failures: usize = 0; let mut at_least_one_failure = false; for (file, result) in results { match result { CheckOutcome::AlreadyFormatted => already_formatted += 1, - CheckOutcome::NeedsFormatting => need_formatting.push(file), + CheckOutcome::NeedsFormatting => { + need_formatting += 1; + println!("Would reformat: {}", make_relative(file).bold()); + } CheckOutcome::Failure(reason) => { + failures += 1; println!( "{}: {} {}: {}", - "Error".bright_red(), + "error".bright_red(), "Failed to check".bold(), make_relative(file).bold(), &reason @@ -172,26 +189,19 @@ fn exit_from_check(results: &[(PathBuf, CheckOutcome)]) -> ExitCode { } } - for file in &need_formatting { - let file_rel = make_relative(file); - println!("Would reformat: {}", file_rel.bold()); - } - - let need_formatting_count = need_formatting.len(); - - if already_formatted + need_formatting_count == 0 { + if already_formatted + need_formatting + failures == 0 { print!( "{}: no Nushell files found under the given path(s)", - "Warning".bright_yellow(), + "warning".bright_yellow(), ); return ExitCode::Success; } - if need_formatting_count > 0 { + if need_formatting > 0 { println!( "{} file{} would be reformatted", - need_formatting_count, - if need_formatting_count == 1 { "" } else { "s" } + need_formatting, + if need_formatting == 1 { "" } else { "s" } ); } if already_formatted > 0 { @@ -203,7 +213,7 @@ fn exit_from_check(results: &[(PathBuf, CheckOutcome)]) -> ExitCode { }; if at_least_one_failure { ExitCode::Failure - } else if need_formatting_count > 0 { + } else if need_formatting > 0 { ExitCode::CheckFailed } else { ExitCode::Success @@ -214,6 +224,7 @@ fn exit_from_check(results: &[(PathBuf, CheckOutcome)]) -> ExitCode { fn exit_from_format(results: &[(PathBuf, FormatOutcome)]) -> ExitCode { let mut left_unchanged: usize = 0; let mut reformatted: usize = 0; + let mut failures: usize = 0; let mut at_least_one_failure = false; for (file, result) in results { @@ -221,9 +232,10 @@ fn exit_from_format(results: &[(PathBuf, FormatOutcome)]) -> ExitCode { FormatOutcome::AlreadyFormatted => left_unchanged += 1, FormatOutcome::Reformatted => reformatted += 1, FormatOutcome::Failure(reason) => { + failures += 1; println!( "{}: {} {}: {}", - "Error".bright_red(), + "error".bright_red(), "Failed to format".bold(), make_relative(file).bold(), &reason @@ -233,7 +245,7 @@ fn exit_from_format(results: &[(PathBuf, FormatOutcome)]) -> ExitCode { } } - if left_unchanged + reformatted == 0 { + if left_unchanged + reformatted + failures == 0 { warn!("No Nushell files found under the given path(s)"); return ExitCode::Success; } @@ -262,8 +274,20 @@ fn exit_from_format(results: &[(PathBuf, FormatOutcome)]) -> ExitCode { } /// Return the different files to analyze, taking only files with .nu extension and discarding files in .nufmtignore -fn discover_files(paths: &[PathBuf]) -> Vec { - paths +/// and the invalid paths provided +fn discover_files(paths: Vec) -> (Vec, Vec) { + let mut valid_paths: Vec = vec![]; + let mut invalid_paths: Vec = vec![]; + + for path in paths { + if path.exists() { + valid_paths.push(path); + } else { + invalid_paths.push(path); + } + } + + let nu_files = valid_paths .iter() .flat_map(|path| { WalkBuilder::new(path) @@ -274,7 +298,9 @@ fn discover_files(paths: &[PathBuf]) -> Vec { .map(|path| path.into_path()) .collect::>() }) - .collect() + .collect(); + + (nu_files, invalid_paths) } /// Return whether a DirEntry is a .nu file or not From e3857c3d06137b077339ff1e27f5913fb8a408c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Riegel?= Date: Fri, 2 May 2025 00:44:35 +0200 Subject: [PATCH 09/30] errors always displayed first --- src/main.rs | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/main.rs b/src/main.rs index 13a77b8..5262bcd 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,7 +3,7 @@ use clap::Parser; use colored::*; use ignore::{DirEntry, WalkBuilder}; -use log::{info, trace, warn}; +use log::{info, trace}; use nu_formatter::config::Config; use nu_formatter::{CheckOutcome, FormatOutcome}; use rayon::iter::{IntoParallelIterator, ParallelIterator}; @@ -167,13 +167,14 @@ fn exit_from_check(results: &[(PathBuf, CheckOutcome)]) -> ExitCode { let mut need_formatting: usize = 0; let mut failures: usize = 0; let mut at_least_one_failure = false; + let mut warning_messages: Vec = vec![]; for (file, result) in results { match result { CheckOutcome::AlreadyFormatted => already_formatted += 1, CheckOutcome::NeedsFormatting => { need_formatting += 1; - println!("Would reformat: {}", make_relative(file).bold()); + warning_messages.push(format!("Would reformat: {}", make_relative(file).bold())); } CheckOutcome::Failure(reason) => { failures += 1; @@ -189,6 +190,10 @@ fn exit_from_check(results: &[(PathBuf, CheckOutcome)]) -> ExitCode { } } + for msg in warning_messages { + println!("{}", msg); + } + if already_formatted + need_formatting + failures == 0 { print!( "{}: no Nushell files found under the given path(s)", @@ -246,7 +251,10 @@ fn exit_from_format(results: &[(PathBuf, FormatOutcome)]) -> ExitCode { } if left_unchanged + reformatted + failures == 0 { - warn!("No Nushell files found under the given path(s)"); + print!( + "{}: no Nushell files found under the given path(s)", + "warning".bright_yellow(), + ); return ExitCode::Success; } From 7b11e2be0484e176edcf8c85dc1444917cd03b0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Riegel?= Date: Fri, 2 May 2025 00:50:58 +0200 Subject: [PATCH 10/30] revert unwanted changes --- benches/example.nu | 4740 ++++++++++++++++++++++---------------------- toolkit.nu | 120 +- 2 files changed, 2421 insertions(+), 2439 deletions(-) diff --git a/benches/example.nu b/benches/example.nu index 5838a29..d53c23b 100644 --- a/benches/example.nu +++ b/benches/example.nu @@ -1,2419 +1,2399 @@ -alias ll=ls-l[[status]; [UP] [UP]]| all {|el| $el.status == UP } -[foobar2baz]| all {|| ($in | describe ) == 'string' }[0246]| enumerate | all {|i| $i.item == $i.index * 2 } -let cond = {|el| ($el mod2 -==0[2468][2468] -[2468] -| 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 -)"##italiccbrightyellow -onred -backgroundlet -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_redHello NuWorld(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 } -[1234]| any {|| ($in | describe ) == 'string' }[9876]| enumerate | any {|i| $i.item == $i.index * 2 } -let cond = {|e| $e mod2==1}[24168]| any $cond [0,1,2,3]| append 4 -[0,1]| append [2,3,4][0,1]| append [2,nu,4,shell]ast 'hello' +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 -[432]| bits and -2 -[432]| bits not -[432]| bits not --n -'2' -[432]| bits not --s -2| bits or -6 -[832]| bits or -2 -17| bits rol -2 -[532]| bits rol -2 -17| bits ror -60 -[153392]| bits ror -2 --n -'1' -2| bits shl -7 -2| bits shl -7 --n -'1' -0x7F| bits shl -1 --s -[532]| bits shl -2 -8| bits shr -2 -[15352]| bits shr -2 -2| bits xor -2 -[832]| 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 + +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 [123]| 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 +(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 = 10const 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-2220: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:00date now -| debug date to-record -date now -| date to-record -'2020-04-12T22:10:57.123+02:00'| date to-record + + +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-1010: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 [] -{'hi' } -def say-sth [sth: string] -{$sth }hi def-env foo -[]{ let-env BAR = "BAZ" } -$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 -[falsefalsefalse]| dfr into-df -| dfr all-false -let s = ([56210]| dfr into-df -)let res = ($s ->9 ->9 -)$res | dfr all-false -[truetruetrue]| dfr into-df -| dfr all-true -let s = ([5628]| dfr into-df -)let res = ($s ->9 ->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 -[132]| dfr into-df -| dfr arg-max -[132]| dfr into-df -| dfr arg-min -[12233]| dfr into-df -| dfr arg-sort -[12233]| dfr into-df -| dfr arg-sort --r -[falsetruefalse]| dfr into-df -| dfr arg-true -[12233]| 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-3000: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 = ([zaxscd]| dfr into-df -)[abcabcabc]| dfr into-df -| dfr concatenate -$other [abcacbacb]| dfr into-df -| dfr contains -ab -let s = ([1100334]| dfr into-df -)($s /$s )| dfr count-null -[12345]| 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 = ([120034]| 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 -[12233]| 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 -[12NaN3NaN]| dfr into-df -| dfr fill-nan -0 -[[a b]; [0.2 1] [0.1 NaN]]| dfr into-df -| dfr fill-nan -0 -[12233]| 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 = ([truefalse]| 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 -[[12a][34b][56c]]| dfr into-df -[abc]| dfr into-df -[truetruefalse]| 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 -[5666888]| 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 = ([136]| dfr into-df -)[5666888]| 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 -[onetwo]| dfr as -a_in -)dfr col -a -| dfr is-not-null -let s = ([5608]| dfr into-df -)let res = ($s /$s )$res | dfr is-not-null -dfr col -a -| dfr is-null -let s = ([5608]| dfr into-df -)let res = ($s /$s )$res | dfr is-null -[5666888]| 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 -[AbcaBcabC]| 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 -[bc]-v -[ad][[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 -[1122334]| dfr into-df -| dfr n-unique -[truefalsetrue]| 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' -[5678]| 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 -[ab][a_newb_new][abcabcabc]| dfr into-df -| dfr replace --p -ab --r -AB -[abacabacabac]| dfr into-df -| dfr replace-all --p -a --r -A -[[a b]; [6 2] [4 2] [2 2]]| dfr into-df -| dfr reverse -[12345]| dfr into-df -| dfr rolling -sum -2 -| dfr drop-nulls -[12345]| 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 = ([12233]| dfr into-df -| dfr shift -2 -)let mask = ($s | dfr is-null -)$s | dfr set -0 ---mask -$mask let series = ([415243]| dfr into-df -)let indices = ([02]| dfr into-df -)$series | dfr set-with-idx -6 --i -$indices [[a b]; [1 2] [3 4]]| dfr into-df -| dfr shape -[12233]| 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 -[ab]-r -[falsetrue][[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 -[aababc]| dfr into-df -| dfr str-lengths -[abcdedabc321abc123]| 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 = ([02]| dfr into-df -)$df | dfr take -$indices let series = ([415243]| dfr into-df -)let indices = ([02]| 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 -[22222]| dfr into-df -| dfr unique -col a -| unique [AbcaBcabC]| dfr into-df -| dfr uppercase -[555566]| 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 -([56]| 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 {hello}let text = "I amenclosed"let hello = {||$text }do $hello do -i{thisisnotarealcommand }do -s{thisisnotarealcommand }do -p{nu -c -'exit 1' -}"I'll still run"do -c{nu -c -'exit 1' -}| myscarycommand do {|x| 100+$x }7777| 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 -[firstsecondthirdfourthfifth]| drop nth -(1..3)[0,1,2,3,4,5]| drop nth -1.. -[0,1,2,3,4,5]| drop nth -3.. -du [123]| each {|e| 2 * $e } -{major:2,minor:1,patch:4}| values | each {|| into string } -[1232]| each {|e| if $e == 2 { "two" } } -[123]| enumerate | each {|e| if $e.item == 2 { found 2 at ($e -index -index -)!} }[123]| each --keep-empty -{|e| if $e == 2 { "found 2!"} } -[12321]| each while -{|e| if $e < 3 { $e * 2 } } -[12stop34]| each while -{|e| if $e != 'stop' { Output: ($e -) } }[123]| enumerate | each while -{|e| if $e.item < 2 { value ($e -item -item -) at ($e -index -index -)!} }12 -3 -$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 -'SomeData'| 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 existsstart:123# not mandatory unless $.label.end is setend:456# not mandatory unless $.label.start is set - }} -def foo [x] -{let span = (metadata $x -)spanerror make {msg:"this is fishy"label:{text:"fish right here"start:$span startend:$span end}}}[12345]| every 2 -[12345]| 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 utilsexport def my-command[] -{"hello"}use utilsmy-commandmodule spamexport alias ll= -ls -l -module spamexport def foo[] -{"foo"}use spamfoomodule fooexport def-env bar [] { let-env FOO_BAR = "BAZ" }use foobar$env FOO_BARexport extern echo[text: string] -export old-alias ll = ls -l -module spamexport def foo[] -{"foo"}module eggsexport use spamfoouse eggsfooexport-env { let-env SPAM = 'eggs' } -export-env { let-env SPAM = 'eggs' } -$env SPAMextern 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 -[12]| 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 -[153kb43Mb]| find 5 -3kb -[moelarrycurly]| find l -[abcbdearcabf]| find --regex -"ab" -[aBcbdeArcabf]| 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 -[123]| first [123]| 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:[1234],e:[43]}| flatten d ---all -42| fmt for x in -[123]{print ($x -*$x -*$x -)}for $x in -1..3{print $x }for $it in -['bob''fred']--numbered{print $"($it -index -index -) is ($it -item -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 -' {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 -data.txt -| from csv ---trimallopen -data.txt| from csv ---trimheadersopen -data.txt| from csv ---trimfields'From: test@email.com -Subject: Welcome -To: someone@somewhere.com -Test' -'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 --b1'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--rawfile.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 ---trimall$'a1(char tab -)b1(char tab -)c1(char nl -)a2(char tab -)b2(char tab -)c2' -$'a1(char tab -)b1(char tab -)c1(char nl -)a2(char tab -)b2(char tab -)c2' -| save tsv-data -| open tsv-data -| from tsv ---trimheaders$'a1(char tab -)b1(char tab -)c1(char nl -)a2(char tab -)b2(char tab -)c2' -$'a1(char tab -)b1(char tab -)c1(char nl -)a2(char tab -)b2(char tab -)c2' -| save tsv-data -| open tsv-data -| from tsv ---trimfields'bread=baguette&cheese=comt%C3%A9&meat=ham&fat=butter' -'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 enter foo -enter ../bar -g 1 -shells g -2mkdir foo -enter foo -enter ../bar -g - -[012]| 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} ---depth2glob"[Cc]*" -"[Cc]*" -glob "{a?c,x?z}" -glob "(?i)c*" -glob "[!cCbMs]*" -glob -glob <[a-d]:1,10> -glob "[A-Z]*" ---no-file--no-symlink[123abc]| grid [123abc]| wrap name -| grid {name:'foo',b:1,c:2} -| grid [{name:'A',v:1 -}{name:'B',v:2}{name:'C',v:3 +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 + + + + + -}]| grid [[namepatch]; [0.1.0 false] [0.1.1 true] [0.2.0 false]]| grid [1234]| group 2 -ls | group-by type -['1''3''1''3''2''1''1']| group-by 'abcdefghijklmnopqrstuvwxyz' -| hash md5 -'abcdefghijklmnopqrstuvwxyz'| hash md5 ---binaryopen./nu_0_24_1_windows.zip -./nu_0_24_1_windows.zip -| hash md5 -'abcdefghijklmnopqrstuvwxyz'| hash sha256 -'abcdefghijklmnopqrstuvwxyz'| hash sha256 ---binaryopen./nu_0_24_1_windows.zip -./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 ---findmy-aliashelp -externshelp externs -smth help -externs ---findsmthhelp -moduleshelp modules -my-module help -modules ---findmy-modulealias -lll=ls-l --l -hide lll -def say-hi [] -{'Hi!' hide say-hilet-envHZ_ENV_ABC =1hide-env -HZ_ENV_ABC -'HZ_ENV_ABC' -in -(env -namels -| histogram type -ls | histogram type -freq [121]| histogram [1231112211]| 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 --umyuser --pmypass -https://www.example.comhttp -delete-H[my-header-keymy-header-value]https://www -examplecom -httpdelete -delete --d'body' -https://www.example.comhttp -delete-tapplication/json --d{field :value }https://www.example.com -httpget -get -https://www.example.com http -get --umyuser --pmypass -https://www.example.comhttp -get-H[my-header-keymy-header-value]https://www -examplecom -httphead -head -https://www.example.com http -head --umyuser --pmypass -https://www.example.comhttp -head-H[my-header-keymy-header-value]https://www -examplecom -httppatch -patch -https://www.example.com 'body' -http -patch --umyuser --pmypass -https://www.example.com'body' -httppatch -patch --H[my-header-keymy-header-value]https://www -examplecom -httppatch -patch --tapplication/json -https://www.example.com{field :value }http -posthttps://www.example.com 'body' -http -post --umyuser --pmypass -https://www.example.com'body' -httppost -post --H[my-header-keymy-header-value]https://www -examplecom -httppost -post --tapplication/json -https://www.example.com{field :value }http -puthttps://www.example.com 'body' -http -put --umyuser --pmypass -https://www.example.com'body' -httpput -put --H[my-header-keymy-header-value]https://www -examplecom -httpput -put --tapplication/json -https://www.example.com{field :value } -{field :value } - -if 2<3{'yes!'} -if 5<3{'yes!'}else{'no!'} -if 5<3{'yes!'}else -if 4<5{'no!'}else{'okay!'done -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 itemfoo+$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-51614434140*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 ---convertsec -420sec -| into duration -420sec -| into duration ---convertms -1000000µs -| into duration ---convertsec -1sec -| into duration ---convertµs -1sec -| into duration ---convertus -[[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 --r2'FF' -| into int --r16'0o10132' -| into int -'0010132' -| into int -'0010132' -| into int --r8[[value]; [false]] -| into record -[123]| 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 --tmy_table -[[name]; [-----] [someone] [=====] [somename] ['(((((']]| into sqlite -filename.db -[one25.2sixtrue100mib25sec]| into sqlite -variety.db -5 -| into string --d31.7 -| into string --d01.7 -| into string --d11.734 -| into string --d21.734 -| into string --d-24.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 [[mealsize]; [arepa small] [taco '']]| is-empty meal -size {new:york,san:francisco}| items {|key, value| echo ($key -) ($value -) }[{a:1b:2}]| join [{a:1c:3 - -}]a -open -r -test.json | json path -'$.store.book[*].author'keybindings default -keybindings list --mkeybindings list --e-dkeybindings list -keybindings listen -ps | sort-by mem -| last | kill $in pidkill ---force -12345kill -s -212345[1,2,3]| last 2 -[1,2,3]| last [12345]| length [{columnA:A0columnB:B0 -}]| length -c -let x = 10let x -=10+100let x = - -if false{-1}else{1let-env -let-env -MY_ENV_VAR -MY_ENV_VAR -=1$env MY_ENV_VAR$"two\nlines" -| lines {NAME:ABE,AGE:UNKNOWN} -| load-env $env NAMEload-env -{NAME: ABE, AGE: UNKNOWN} -$env NAMEmut -x=0loop { -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 -31..10=> -'yes!'match -{a:100}{a: $my_value }=> -{$my_value }match -31=> -{'yes!'}_=> -{'no!'}match -[1,2,3][$a $b $c ]=>{$a +$b +$c }_=> -0{a:{b:3}} -| match $in {a:{$b -} -}=> -($b -+10 -+10 -)[-50-100.025] -| math abs -1| math arccos --1| math arccos --d1| math arccosh -1| math arcsin -1| math arcsin --d0| math arcsinh -1| math arctan --1| math arctan --d1| math arctanh -[-50100.025]| math avg -[1.52.3-3.1]| math ceil -math pi -| math cos -[090180270360]| math cos --d1| math cosh -math e -| math round ---precision30| math exp -1| math exp -[1.52.3-3.1]| math floor -math e -| math ln -100| math log -10[1684]| math log -2[-5010025]| math max -[{a:1b:3 - -}{a:2b:-1 -}]| math max -[389121215]| math median -[{a:1b:3 - -}{a:2b:-1}{a:-3b:5 -}]| math median -[-5010025]| math min -[{a:1b:3 - -}{a:2b:-1 -}]| math min -[339121215]| math mode -[{a:1b:3 - -}{a:2b:-1}{a:1b:5 -}]| math mode -math pi -| math round ---precision2[2334]| math product -[1.52.3-3.1]| math round -[1.5552.333-3.111]| math round --p2(math pi -/2 -| math sin -[090180270360]| math sin --d -| math round ---precision41 -| math sinh -[916]| math sqrt -[12345]| math stddev -[12345]| math stddev --s[123] -| math sum -ls -| get size -| math sum -(math pi -/4 -| math tan -[-45045]| math tan --d(math pi -*10 -| math tanh -math -tau -| math round ---precision2[12345] -| math variance -[12345]| math variance --s[abc] -| wrap name -| merge ([123]| wrap index -{a:1,b:2} -| merge {c: 3} -[{columnA:A0columnB:B0 -}]| merge [{columnA: 'A0*' -}]let -a -=42metadata $a -ls -| metadata mkdir -foo -mkdir -v -foo/bar foo2 module spamexport def foo[] -{"foo"use -use -spamfoomodule -fooexport-env{ let-env FOO = "BAZ" } -{ let-env FOO = "BAZ" } -use foo$envFOOmodulefooexportdef-envbar[]{let-env FOO_BAR -="BAZ" -usefoobar$envFOO_BAR[[name value index]; [foo a 1] [bar b 2] [baz c 3]]| move index ---beforename [[name value index]; [foo a 1] [bar b 2] [baz c 3]]| move value -name --afterindex {name:foo,value:a,index:1}| move name ---beforeindex mut x = 10$x =12mut -a -={b:{c:1} -}$a -bc=2mut -x=10+100mut x = - -if false{-1}else{1mv -mv -before.txt -before.txt -after.txt mv test.txt -my/subdirectory mv *.txt -my/subdirectory mkdir foo -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-modulemodule.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 scopecommands -scopecommands| where is_custom -| get command -)openmyfile.json -open myfile.json ---raw'myfile.txt'| open open -myfile.txt ---raw| decode utf-8 -module spamexport def foo[] -{"foo"overlay -overlay -use -spam -def bar [] -{"bar" -overlay hide -spam--keep-custom'export alias f = "foo"' | save spam.nu -overlay use spam.nuoverlayhide -spammodulespamexport-env -{ let-env FOO = "foo" } -overlay use spamoverlayhide -overlaynew -spam - -cd some-dir -overlay hide --keep-env[PWD]spammodulespamexportdef -foo[] -{"foo"overlay -overlay -use -spamoverlaylist -list -| last overlay -new -spammodule -spamexport -def -foo[] -{"foo"overlay -overlay -use -spammodulespamexport -deffoo[] -foo[] -{"foo"overlay -overlay -use -spamasspam_new'export def foo { "foo" }'overlay use ---prefixspamfoo -'export-env { let-env FOO = "foo" }'| save spam.nu -overlay use spam.nu$envFOOmkdir -fooenter foo -enter ../bar -p p -[123]| par-each {|| 2 * $in } -[foobarbaz]| par-each {|e| $e + '!' } -| sort 1..3 -| enumerate | par-each {|p| update item ($p -item*2 -item*2)}| sort-by item -| get item -[123]| enumerate | par-each { |e| if $e.item == 2 { found 2 at ($e -index -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 --n2'/home/joe/code/test.txt'| path dirname --n2-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 --etar.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]pnetport -31214000port [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 } -{|| 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 -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.75random chars +random bool --bias 0.75 + + random chars --l 20random decimal +random chars -l 20 + + random decimal -..500random decimal -100000..random decimal -1.0..1.1random dice +random decimal ..500 +random decimal 100000.. +random decimal 1.0..1.1 + + random dice --d 10-s 12random integer +random dice -d 10 -s 12 + + random integer -..500random integer -100000..random integer -1..10random uuid -[0,1,2,3,4,5]| range 4..5 -[0,1,2,3,4,5]| range (-2). | range (-3). | reduce {|it, acc| $it + $acc } -[876]| enumerate | reduce -f -0{|it, acc| $acc +$it item +$it index }[1234]| 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{ -( -if $str index!=0{ -'; '} -index!=0{'; '} -($str -index+1 --($str -item -item)"hello world"| regex '(?P\w+) (?P\w+)' +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 -path0 -| path dirname -| path join -'nu_plugin_query' - -nu --c --c -register ($plugin -); versionlss| 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 -[aham]{a:1b: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:1b:2c: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:1b:2c: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 [[ab]; [1 2] [3 4] [5 6]]| rotate [[ab]; [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 ---stderrfoo.txt do -i| save foo.txt ---stderrbar.txt open foo.db -| schema [{a:ab:b -}]| select a -{a:ab:b -}| select a +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 -123seq 1 -10seq 1.0 -0.12.0seq 1 -5| str join -'|'seq char -a e seq char -a e | str join -'|'seq date ---days10seq date ---days10-rseq date ---days10-o'%m/%d/%Y'-rseq date --b'2020-01-01'-e'2020-01-10'seq date --b'2020-01-01'-e'2020-01-31'-n5enter .. -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 [2468]| skip 1 -[[editions]; [2015] [2018] [2021]]| skip 2 -[-202-1]| skip until -{|x| $x >0}let cond = {|x| $x >0 -[-202-1]| skip until -$cond [{a:-2}{a:0}{a:2}{a:-1}] -[{a:-2}{a:0}{a:2}{a:-1}] -| skip until -{|x| $x a>0}[-202-1]| skip while -{|x| $x <0}let cond = {|x| $x <0 -[-202-1]| skip while -$cond [{a:-2}{a:0}{a:2}{a:-1}] -[{a:-2}{a:0}{a:2}{a:-1}] -| skip while -{|x| $x a<0}sleep 1sec -[201]| sort [201]| sort -r -[bettyamysarah]| sort [bettyamysarah]| sort -r -[airplaneTruckCar]| sort -i -[airplaneTruckCar]| sort -i --r{b:3,a:4}| sort {b:4,a:3,c:1} -| sort -v +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 --rsource foo.nu -source ./foo.nu -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 --l3http get -https://www.gutenberg.org/files/11/11-0.txt | str downcase -| split words --l2| 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 +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'[onetwothree]| str contains -o [onetwothree]| str contains --no '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'-r1..'123456'| str index-of -'6'-r..4'123456'| str index-of -'3'-r1..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 --g4..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 hostnamels -| table -n -1[[a b]; [1 2] [3 4]] -| table [[ab]; [1 2] [2 [44]]]| table --expand -[[ab]; [1 2] [2 [44]]]| table --collapse -[123]| take 1 -[123]| take 2 -[[editions]; [2015] [2018] [2021]]| take 2 -0x[01 23 45] -| take 2 -1..10 -| take 3 -[-1-291]| take until -{|x| $x >0}let -cond -={|x| $x >0 ->0 -[-1-291]| take until -$cond -[{a:-1}{a:-2}{a:9}{a:1}] -[{a:-1}{a:-2}{a:9}{a:1}] -[{a:-1 -}{a:-2}{a:9}{a:1 -}]| take until -{|x| $x a>0 -[-1-291]| take while -{|x| $x <0 -letcond -cond -={|x| $x <0 -<0 -[-1-291]| take while -$cond -[{a:-1}{a:-2}{a:9}{a:1}] -[{a:-1}{a:-2}{a:9}{a:1}] -[{a:-1 -}{a:-2}{a:9}{a:1 -}]| take while -{|x| $x a<0 -termsize -size -(term size -columns(term size -)rowstimeit{ sleep 500ms }{ sleep 500ms } -http -get -https://www.nushell.sh/book/ -| timeit { split chars } -timeit -ls --la[[foo bar]; [1 2]] -| to csv -[[foobar]; [1 2]]| to csv --s -';'{a:1b:2 -}| to csv -[[foo bar]; [1 2]]| to html -[[foo bar]; [1 2]]| to html ---partial[[foo bar]; [1 2]]| to html ---dark[abc]| to json -[JoeBobSam]| to json --i4[123]| 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[012]| to md ---pretty[123]| to nuon -[123]| to nuon ---indent2[123]| to nuon ---indent2--raw{date:2000-01-01,data:[1[23]4.56]}| to nuon ---indent21| to text -git help --a| lines | find -r -'^ '| to text + + + + + '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:1bar:'qwe' -}| to toml -[[foo bar]; [1 2]]| to tsv -{a:1b:2 -}| to tsv -{tag:noteattributes:{}content:[{tag:rememberattributes:{}content:[{tag:nullattrs:nullcontent:Event}]}] -}| to xml -{tag:notecontent:[{tag:remembercontent:[Event]}] -}| to xml -{tag:notecontent:[{tag:remembercontent:[Event]}] -}| to xml --p3[[foo bar]; ["1" "2"]]| to yaml + + +{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 --rfixture.json d e touch -a --d"August 24, 2019; 12:30:30"fixture.json [[c1 c2]; [1 2]]| transpose [[c1c2]; [1 2]]| transpose key -val [[c1 c2]; [1 2]]| transpose -i -val {c1:1,c2:2}| transpose | transpose -i --r-dtry {asdfasdf -try -{asdfasdf }catch -{asdfasdf }catch -{'missing'tutor -tutor -begin -begin -tutor -f -"$in"[2334]| uniq [122]| uniq -d -[122]| uniq -u -['hello''goodbye''Hello']| uniq -i -[122]| 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 -itemfruit -itemfruit| 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 -',' -}[ +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 }}[ + ] | 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| + ] | 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 -itemfruit -itemfruit| str length -)+$e index}| get item -[123]| upsert 0 -2[123]| upsert 3 -4{mode:normaluserid: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 spamexport def foo[] -{"foo"use -use -spamfoomodule -fooexportdef-env -bar[] -{let-env FOO_BAR -="BAZ" -usefoobar$env -FOO_BAR{mode:normaluserid:31415}| values {f:250g:191c:128d:1024e:2000a:16b:32} -| values [[namemeaning]; [ls list] [mv move] [cd 'change directory']]| values version -view -files -let abc = {||'hi'view -view -source -source -$abc -def hi [] -{'Hi!' -view source -source -def-env foo -[]{ let-env BAR = 'BAZ' } view source -module mod-fooexport-envlet-env FOO_ENV = 'BAZ' -view source -mod-foo alias hello=hiview source -hello some | pipeline | or | variable | debug -r -view span -12watch . ---glob=**/*.rs{||cargo test -}watch . -{ |op, path, new_path| ($op -)($path -) -($new_path -)watch -watch -/foo/bar -/foo/bar -{ |op, path| ($op -)-($path -(char nl -) -(char nl -) -| save --append -changes_in_bar.log -[{a:1 -}{a:2 - -}]| where a > 1 -[12] -| where {|x| $x > 1} -ls -| where size > 2kb -ls -| where type == file -ls -| where name =~ -"Car" -ls | where modified >= (date now -) - 2wk + + +{'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 -| sort-by name --n| enumerate | where {|e| $e.item.name !~ ^($e -index+1) } -| each {|| get item } +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 = 0while $x <10{$x =$x +1}[1234] -| window 2 -[1,2,3,4,5,6,7,8]| window 2 ---stride3[1,2,3,4,5]| window 3 ---stride3--remainderwith-env [MYENV"my env value"]{ $env.MYENV }with-env [XYWZ]{ $env.X }with-env [[XW]; [Y Z]]{ $env.W }with-env {X: "Y", W: "Z"} -{[$env X$env W]}[123]| wrap num -1..3| wrap num -[12]| zip [34]1..3| zip 4..6 -glob *.ogg -| zip ['bang.ogg','fanfare.ogg','laser.ogg']| each {|| mv $in.0 $in.1 } + + +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/toolkit.nu b/toolkit.nu index 40ad371..4b7c519 100644 --- a/toolkit.nu +++ b/toolkit.nu @@ -7,69 +7,71 @@ # make sure all the tests pass. # print the pipe input inside backticks, dimmed and italic, as a pretty command +def pretty-print-command [] { + $"`(ansi default_dimmed)(ansi default_italic)($in)(ansi reset)`" +} -def pretty-print-command [] -{$"` (ansi default_dimmed -)(ansi default_italic -)($in )(ansi reset -)` "}#checkstandard code -formatting andapply -the -changes export -def -fmt[ +# check standard code formatting and apply the changes +export def fmt [ --check # do not apply the format changes, only check the syntax --verbose # print extra information about the command's progress -] -{ -if $verbose -{print $"running ('toolkit fmt'| )"} -if $check -{try {cargo fmt ---all----checkcatch -catch -{error make --unspanned{msg:$"\nplease run ('toolkit fmt'| ) to fix formatting!"}else -else {cargo fmt ---all}}#checkthatyou're using the standard code style +] { + if $verbose { + print $"running ('toolkit fmt' | pretty-print-command)" + } + + if $check { + try { + cargo fmt --all -- --check + } catch { + error make --unspanned { + msg: $"\nplease run ('toolkit fmt' | pretty-print-command) to fix formatting!" + } + } + } else { + cargo fmt --all + } +} + +# check that you're using the standard code style # # > it is important to make `clippy` happy :relieved: - export def clippy [ - --verbose # print extra information about the command's progress] { -if $verbose {print running ('toolkit clippy'| )}try -{print running ('toolkit clippy'| )}try -{(cargo clippy ---all-targets ---no-deps ---workspace --- --D -warnings --D -rustdoc::broken_intra_doc_links --W -clippy::explicit_iter_loop --W -clippy::explicit_into_iter_loop --W -clippy::semicolon_if_nothing_returned --W -clippy::doc_markdown --W -clippy::manual_let_else -)catch -catch -{error make --unspanned{msg:\nplease fix the above ('clippy'| ) errors before continuing!}}}#check -thatall -thetests -passexport def test[ - --fast # use the "nextext" `cargo` subcommand to speed up the tests (see [`cargo-nextest`](https://nexte.st/)and -[`nextest-rs/nextest`](https://github.com/nextest-rs/nextest)) -] -{ -if $fast {cargo nextest -run --all else -{cargo test ---workspace}}export def main[] -{help toolkit + --verbose # print extra information about the command's progress +] { + if $verbose { + print $"running ('toolkit clippy' | pretty-print-command)" + } + + try {( + cargo clippy + --all-targets + --no-deps + --workspace + -- + -D warnings + -D rustdoc::broken_intra_doc_links + -W clippy::explicit_iter_loop + -W clippy::explicit_into_iter_loop + -W clippy::semicolon_if_nothing_returned + -W clippy::doc_markdown + -W clippy::manual_let_else + )} catch { + error make --unspanned { + msg: $"\nplease fix the above ('clippy' | pretty-print-command) errors before continuing!" + } + } } + +# check that all the tests pass +export def test [ + --fast # use the "nextext" `cargo` subcommand to speed up the tests (see [`cargo-nextest`](https://nexte.st/) and [`nextest-rs/nextest`](https://github.com/nextest-rs/nextest)) +] { + if $fast { + cargo nextest run --all + } else { + cargo test --workspace + } +} + +export def main [] { help toolkit } From 61adf7aed24ae9f955efdee6978fa727438a1408 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Riegel?= Date: Fri, 2 May 2025 01:02:17 +0200 Subject: [PATCH 11/30] better looking relative paths --- src/main.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main.rs b/src/main.rs index 5262bcd..ecd0ab1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -318,11 +318,14 @@ fn is_nu_file(entry: &DirEntry) -> bool { } fn make_relative(path: &Path) -> String { - let current = std::env::current_dir().expect("Failed to get current directory"); + let current = std::env::current_dir().unwrap_or(PathBuf::from(".")); path.strip_prefix(¤t) .unwrap_or(path) .display() .to_string() + .replace("\\", "/") + .trim_start_matches("./") + .to_string() } #[cfg(test)] From 4f3ee8bb8d2b13421fb2f8b61da84ed19b4a20f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Riegel?= Date: Sat, 3 May 2025 12:31:02 +0200 Subject: [PATCH 12/30] exit codes in readme --- README.md | 8 ++++++++ src/main.rs | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index ad638cb..8bb8651 100644 --- a/README.md +++ b/README.md @@ -77,6 +77,14 @@ nufmt my-file1.nu my-file2.nu my-file3.nu - `-h` or `--help` show help and exit - `-v` or `--version` prints the version and exit +### Exit codes + +``nufmt`` exits with the following status codes: +- **0**: if ``nufmt`` terminates successfully, regardless of whether files or stdin were formatted. +- **1** (only used in check mode): ``nufmt`` terminates successfully and at least one file would be formatted if check mode was off. +- **2**: ``nufmt`` terminates abnormally due to invalid configuration, invalid CLI options, or an internal error. + + ## Contributing We have a [contribution guide](docs/CONTRIBUTING.md). If you still have doubts, you can mention @`AucaCoyan` who is active on this repo. diff --git a/src/main.rs b/src/main.rs index ecd0ab1..7d6fcf5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -16,7 +16,7 @@ use std::{ enum ExitCode { /// nufmt terminates successfully, regardless of whether files or stdin were formatted. Success, - /// only used in check mode: nufmt terminates successfully and at least one file or stdin would be formatted if check mode was off. + /// only used in check mode: nufmt terminates successfully and at least one file would be formatted if check mode was off. CheckFailed, /// nufmt terminates abnormally due to invalid configuration, invalid CLI options, or an internal error. Failure, From de3fb2ba79b957d0e2d802d0d806aec807865bb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Riegel?= Date: Sat, 3 May 2025 14:32:03 +0200 Subject: [PATCH 13/30] read config from file --- Cargo.lock | 860 +++++++++++++-------------------- Cargo.toml | 7 +- README.md | 2 +- scripts/update-nushell-version | 4 + src/config.rs | 109 ++++- src/lib.rs | 1 + src/main.rs | 21 +- 7 files changed, 473 insertions(+), 531 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d792272..65f9bc6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8,17 +8,6 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" -[[package]] -name = "ahash" -version = "0.7.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" -dependencies = [ - "getrandom", - "once_cell", - "version_check", -] - [[package]] name = "aho-corasick" version = "1.1.3" @@ -28,21 +17,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "alloc-no-stdlib" -version = "2.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3" - -[[package]] -name = "alloc-stdlib" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece" -dependencies = [ - "alloc-no-stdlib", -] - [[package]] name = "allocator-api2" version = "0.2.18" @@ -146,23 +120,23 @@ dependencies = [ "regex", "rustc-hash", "shlex", - "syn 2.0.101", + "syn", ] [[package]] name = "bit-set" -version = "0.5.3" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" +checksum = "08807e080ed7f9d5433fa9b275196cfc35414f66a0c79d864dc51a0d825231a3" dependencies = [ "bit-vec", ] [[package]] name = "bit-vec" -version = "0.6.3" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" +checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" [[package]] name = "bitflags" @@ -170,63 +144,6 @@ version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" -[[package]] -name = "bitvec" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" -dependencies = [ - "funty", - "radium", - "tap", - "wyz", -] - -[[package]] -name = "borsh" -version = "1.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6362ed55def622cddc70a4746a68554d7b687713770de539e59a739b249f8ed" -dependencies = [ - "borsh-derive", - "cfg_aliases", -] - -[[package]] -name = "borsh-derive" -version = "1.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3ef8005764f53cd4dca619f5bf64cafd4664dada50ece25e4d81de54c80cc0b" -dependencies = [ - "once_cell", - "proc-macro-crate", - "proc-macro2", - "quote", - "syn 2.0.101", - "syn_derive", -] - -[[package]] -name = "brotli" -version = "5.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19483b140a7ac7174d34b5a581b406c64f84da5409d3e09cf4fff604f9270e67" -dependencies = [ - "alloc-no-stdlib", - "alloc-stdlib", - "brotli-decompressor", -] - -[[package]] -name = "brotli-decompressor" -version = "4.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a45bd2e4095a8b518033b128020dd4a55aab1c0a381ba4404a472630f4bc362" -dependencies = [ - "alloc-no-stdlib", - "alloc-stdlib", -] - [[package]] name = "bstr" version = "1.12.0" @@ -243,45 +160,6 @@ version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" -[[package]] -name = "byte-unit" -version = "5.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33ac19bdf0b2665407c39d82dbc937e951e7e2001609f0fb32edd0af45a2d63e" -dependencies = [ - "rust_decimal", - "serde", - "utf8-width", -] - -[[package]] -name = "bytecheck" -version = "0.6.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23cdc57ce23ac53c931e88a43d06d070a6fd142f2617be5855eb75efc9beb1c2" -dependencies = [ - "bytecheck_derive", - "ptr_meta", - "simdutf8", -] - -[[package]] -name = "bytecheck_derive" -version = "0.6.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3db406d29fbcd95542e92559bed4d8ad92636d1ca8b3b72ede10b4bcc010e659" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "byteorder" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" - [[package]] name = "bytes" version = "1.7.2" @@ -290,9 +168,9 @@ checksum = "428d9aa8fbc0670b7b8d6030a7fadd0f86151cae55e4dbbece15f3780a3dfaf3" [[package]] name = "bytesize" -version = "1.3.0" +version = "1.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3e368af43e418a04d52505cf3dbc23dda4e3407ae2fa99fd0e4f308ce546acc" +checksum = "2e93abca9e28e0a1b9877922aacb20576e05d4679ffa78c3d6dc22a26a216659" [[package]] name = "cast" @@ -424,7 +302,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.101", + "syn", ] [[package]] @@ -545,6 +423,22 @@ version = "0.8.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" +[[package]] +name = "crossterm" +version = "0.28.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "829d955a0bb380ef178a640b91779e3987da38c9aea133b20614cfed8cdea9c6" +dependencies = [ + "bitflags", + "crossterm_winapi", + "mio", + "parking_lot", + "rustix 0.38.37", + "signal-hook", + "signal-hook-mio", + "winapi", +] + [[package]] name = "crossterm_winapi" version = "0.9.1" @@ -627,19 +521,19 @@ dependencies = [ [[package]] name = "errno" -version = "0.3.9" +version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" +checksum = "976dd42dc7e85965fe702eb8164f21f450704bdde31faefd6471dba214cb594e" dependencies = [ "libc", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] name = "fancy-regex" -version = "0.13.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "531e46835a22af56d1e3b66f04844bed63158bc094a628bec1d321d9b4c44bf2" +checksum = "6e24cb5a94bcae1e5408b0effca5cd7172ea3c5755049c5f3af4cd283a165298" dependencies = [ "bit-set", "regex-automata", @@ -662,12 +556,6 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f81ec6369c545a7d40e4589b5597581fa1c441fe1cce96dd1de43159910a36a2" -[[package]] -name = "funty" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" - [[package]] name = "getrandom" version = "0.2.15" @@ -708,15 +596,6 @@ dependencies = [ "crunchy", ] -[[package]] -name = "hashbrown" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" -dependencies = [ - "ahash", -] - [[package]] name = "hashbrown" version = "0.15.0" @@ -793,12 +672,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.6.0" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" +checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e" dependencies = [ "equivalent", - "hashbrown 0.15.0", + "hashbrown", ] [[package]] @@ -826,9 +705,9 @@ checksum = "7655c9839580ee829dfacba1d1278c2b7883e50a277ff7541299489d6bdfdc45" [[package]] name = "is_debug" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06d198e9919d9822d5f7083ba8530e04de87841eaf21ead9af8f2304efd57c89" +checksum = "1fe266d2e243c931d8190177f20bf7f24eed45e96f39e87dc49a27b32d12d407" [[package]] name = "is_terminal_polyfill" @@ -877,9 +756,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "libc" -version = "0.2.159" +version = "0.2.172" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5" +checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa" [[package]] name = "libloading" @@ -918,6 +797,22 @@ version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" +[[package]] +name = "linux-raw-sys" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12" + +[[package]] +name = "lock_api" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +dependencies = [ + "autocfg", + "scopeguard", +] + [[package]] name = "log" version = "0.4.22" @@ -930,7 +825,7 @@ version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "234cf4f4a04dc1f57e24b96cc0cd600cf2af460d4161ac5ecdd0af8e1f3b2a38" dependencies = [ - "hashbrown 0.15.0", + "hashbrown", ] [[package]] @@ -959,9 +854,9 @@ checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "miette" -version = "7.2.0" +version = "7.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4edc8853320c2a0dab800fbda86253c8938f6ea88510dc92c5f1ed20e794afc1" +checksum = "5f98efec8807c63c752b5bd61f862c165c115b0a35685bdcfd9238c7aeb592b7" dependencies = [ "cfg-if", "miette-derive", @@ -971,19 +866,18 @@ dependencies = [ "supports-unicode", "terminal_size", "textwrap", - "thiserror 1.0.64", "unicode-width 0.1.14", ] [[package]] name = "miette-derive" -version = "7.2.0" +version = "7.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcf09caffaac8068c346b6df2a7fc27a177fd20b39421a39ce0a211bde679a6c" +checksum = "db5b29714e950dbb20d5e6f74f9dcec4edbcc1067bb7f8ed198c097b8c1a818b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.101", + "syn", ] [[package]] @@ -1001,6 +895,18 @@ dependencies = [ "adler2", ] +[[package]] +name = "mio" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" +dependencies = [ + "libc", + "log", + "wasi", + "windows-sys 0.52.0", +] + [[package]] name = "nix" version = "0.29.0" @@ -1043,9 +949,9 @@ dependencies = [ [[package]] name = "nu-cmd-lang" -version = "0.99.0" +version = "0.104.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27055f050baefe46ec1ee7311c0cba27ec8700e18c6ab00f68a745f957da9f3f" +checksum = "e66adfeda88f8e27bcb25d068d9e6e8b3a94c2bf988a9c30e8e3b2045867aefe" dependencies = [ "itertools 0.13.0", "nu-engine", @@ -1057,42 +963,41 @@ dependencies = [ [[package]] name = "nu-derive-value" -version = "0.99.0" +version = "0.104.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "733a3c36228f10968e82d5aacfc0269b050b5fdf359d1b9f34f3b3464f954f18" +checksum = "5fd0d8e358b6440d01fe4e617f180aea826bade72efb54f5dc1c22e0e8038b6f" dependencies = [ "heck", - "proc-macro-error", + "proc-macro-error2", "proc-macro2", "quote", - "syn 2.0.101", + "syn", ] [[package]] name = "nu-engine" -version = "0.99.0" +version = "0.104.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebb70da462cbfe52635826d2c3e73c9d381e181f39e3e19887b57252bd92d7b1" +checksum = "0c2b01483e3d09460375f0c0da7a83b6dc26fb319ca09c55d0665087b2d587c7" dependencies = [ "log", "nu-glob", "nu-path", "nu-protocol", "nu-utils", - "terminal_size", ] [[package]] name = "nu-glob" -version = "0.99.0" +version = "0.104.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bfe8f781a5bbc1d81c6ae9deb4406042c044f6e3d7157f6132a4d7802689f1c" +checksum = "202ce25889336061efea24e69d4e0de7147c15fd9892cdd70533500d47db8364" [[package]] name = "nu-parser" -version = "0.99.0" +version = "0.104.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd6b22646adbb8fff8949935ce86240a149f28d7f094d23f981145b404e25e94" +checksum = "cb0591ef4d4989c1930863d9d17d8fd2d70b03ec2d9caeca067e9626e05c49d9" dependencies = [ "bytesize", "chrono", @@ -1101,28 +1006,28 @@ dependencies = [ "nu-engine", "nu-path", "nu-protocol", + "nu-utils", "serde_json", ] [[package]] name = "nu-path" -version = "0.99.0" +version = "0.104.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a94dd32424ad75d665ad40add544dd3c35e66cbd147db18a6c0c7ac31ad48a6d" +checksum = "41c68c7c06898a5c4c9f10038da63759661cb8ac8f301ce7d159173a595c8258" dependencies = [ "dirs", "omnipath", "pwd", + "ref-cast", ] [[package]] name = "nu-protocol" -version = "0.99.0" +version = "0.104.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d113bafbe48178fdddaace7a2e783be73d66a71c2b732dd052c195eb8780e24" +checksum = "ab657b1947f1fad3c5052cb210fa311744736a4800a966ae21c4bc63de7c60ab" dependencies = [ - "brotli", - "byte-unit", "bytes", "chrono", "chrono-humanize", @@ -1133,26 +1038,31 @@ dependencies = [ "indexmap", "log", "lru", + "memchr", "miette", "nix", "nu-derive-value", + "nu-glob", "nu-path", "nu-system", "nu-utils", "num-format", "os_pipe", - "rmp-serde", "serde", - "thiserror 1.0.64", + "serde_json", + "strum", + "strum_macros", + "thiserror 2.0.12", "typetag", + "web-time", "windows-sys 0.48.0", ] [[package]] name = "nu-system" -version = "0.99.0" +version = "0.104.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbcabdb319f6126b1662181fdd4f30ddb1750e5a47378e1f757ac9cb3167eca3" +checksum = "f47094aaab4f1e3a86c3960400d82a50fcabde907f964ae095963ec95669577a" dependencies = [ "chrono", "itertools 0.13.0", @@ -1162,24 +1072,27 @@ dependencies = [ "mach2", "nix", "ntapi", - "once_cell", "procfs", "sysinfo", - "windows 0.54.0", + "web-time", + "windows 0.56.0", ] [[package]] name = "nu-utils" -version = "0.99.0" +version = "0.104.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e0dfcc946f4ee4d158d1db7bfa2a8aec2a35dba97af63bfbc3e61e771893797" +checksum = "327999b774d78b301a6b68c33d312a1a8047c59fb8971b6552ebf823251f1481" dependencies = [ + "crossterm", "crossterm_winapi", + "fancy-regex", "log", "lscolors", "nix", "num-format", "serde", + "serde_json", "strip-ansi-escapes", "sys-locale", "unicase", @@ -1198,6 +1111,7 @@ dependencies = [ "nu-cmd-lang", "nu-parser", "nu-protocol", + "nuon", "rayon", "thiserror 2.0.12", ] @@ -1236,6 +1150,18 @@ dependencies = [ "libc", ] +[[package]] +name = "nuon" +version = "0.104.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ad155fee37ed58420483d38c40cd9bea88160e281e1d04c1592525c8f8da9a5" +dependencies = [ + "nu-engine", + "nu-parser", + "nu-protocol", + "nu-utils", +] + [[package]] name = "omnipath" version = "0.1.6" @@ -1277,10 +1203,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fb37767f6569cd834a413442455e0f066d0d522de8630436e2a1761d9726ba56" [[package]] -name = "paste" -version = "1.0.15" +name = "parking_lot" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets 0.52.6", +] [[package]] name = "plotters" @@ -1317,44 +1260,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" [[package]] -name = "ppv-lite86" -version = "0.2.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" -dependencies = [ - "zerocopy", -] - -[[package]] -name = "proc-macro-crate" -version = "3.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ecf48c7ca261d60b74ab1a7b20da18bede46776b2e55535cb958eb595c5fa7b" -dependencies = [ - "toml_edit", -] - -[[package]] -name = "proc-macro-error" -version = "1.0.4" +name = "proc-macro-error-attr2" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +checksum = "96de42df36bb9bba5542fe9f1a054b8cc87e172759a1868aa05c1f3acc89dfc5" dependencies = [ - "proc-macro-error-attr", "proc-macro2", "quote", - "version_check", ] [[package]] -name = "proc-macro-error-attr" -version = "1.0.4" +name = "proc-macro-error2" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +checksum = "11ec05c52be0a07b08061f7dd003e7d7092e0472bc731b4af7bb1ef876109802" dependencies = [ + "proc-macro-error-attr2", "proc-macro2", "quote", - "version_check", + "syn", ] [[package]] @@ -1368,50 +1292,29 @@ dependencies = [ [[package]] name = "procfs" -version = "0.16.0" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "731e0d9356b0c25f16f33b5be79b1c57b562f141ebfcdb0ad8ac2c13a24293b4" +checksum = "cc5b72d8145275d844d4b5f6d4e1eef00c8cd889edb6035c21675d1bb1f45c9f" dependencies = [ "bitflags", "chrono", "flate2", "hex", - "lazy_static", "procfs-core", - "rustix", + "rustix 0.38.37", ] [[package]] name = "procfs-core" -version = "0.16.0" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d3554923a69f4ce04c4a754260c338f505ce22642d3830e049a399fc2059a29" +checksum = "239df02d8349b06fc07398a3a1697b06418223b1c7725085e801e7c0fc6a12ec" dependencies = [ "bitflags", "chrono", "hex", ] -[[package]] -name = "ptr_meta" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0738ccf7ea06b608c10564b31debd4f5bc5e197fc8bfe088f68ae5ce81e7a4f1" -dependencies = [ - "ptr_meta_derive", -] - -[[package]] -name = "ptr_meta_derive" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16b845dbfca988fa33db069c0e230574d15a3088f147a87b64c7589eb662c9ac" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "pure-rust-locales" version = "0.8.1" @@ -1437,42 +1340,6 @@ dependencies = [ "proc-macro2", ] -[[package]] -name = "radium" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" - -[[package]] -name = "rand" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" -dependencies = [ - "libc", - "rand_chacha", - "rand_core", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core", -] - -[[package]] -name = "rand_core" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -dependencies = [ - "getrandom", -] - [[package]] name = "rayon" version = "1.10.0" @@ -1493,6 +1360,15 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "redox_syscall" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2f103c6d277498fbceb16e84d317e2a400f160f46904d5f5410848c829511a3" +dependencies = [ + "bitflags", +] + [[package]] name = "redox_users" version = "0.4.6" @@ -1504,6 +1380,26 @@ dependencies = [ "thiserror 1.0.64", ] +[[package]] +name = "ref-cast" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a0ae411dbe946a674d89546582cea4ba2bb8defac896622d6496f14c23ba5cf" +dependencies = [ + "ref-cast-impl", +] + +[[package]] +name = "ref-cast-impl" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1165225c21bff1f3bbce98f5a1f889949bc902d3575308cc7b0de30b4f6d27c7" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "regex" version = "1.11.0" @@ -1533,82 +1429,6 @@ version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" -[[package]] -name = "rend" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71fe3824f5629716b1589be05dacd749f6aa084c87e00e016714a8cdfccc997c" -dependencies = [ - "bytecheck", -] - -[[package]] -name = "rkyv" -version = "0.7.45" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9008cd6385b9e161d8229e1f6549dd23c3d022f132a2ea37ac3a10ac4935779b" -dependencies = [ - "bitvec", - "bytecheck", - "bytes", - "hashbrown 0.12.3", - "ptr_meta", - "rend", - "rkyv_derive", - "seahash", - "tinyvec", - "uuid", -] - -[[package]] -name = "rkyv_derive" -version = "0.7.45" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "503d1d27590a2b0a3a4ca4c94755aa2875657196ecbf401a42eff41d7de532c0" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "rmp" -version = "0.8.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "228ed7c16fa39782c3b3468e974aec2795e9089153cd08ee2e9aefb3613334c4" -dependencies = [ - "byteorder", - "num-traits", - "paste", -] - -[[package]] -name = "rmp-serde" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52e599a477cf9840e92f2cde9a7189e67b42c57532749bf90aea6ec10facd4db" -dependencies = [ - "byteorder", - "rmp", - "serde", -] - -[[package]] -name = "rust_decimal" -version = "1.36.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b082d80e3e3cc52b2ed634388d436fe1f4de6af5786cc2de9ba9737527bdf555" -dependencies = [ - "arrayvec", - "borsh", - "bytes", - "num-traits", - "rand", - "rkyv", - "serde", - "serde_json", -] - [[package]] name = "rustc-hash" version = "1.1.0" @@ -1624,10 +1444,29 @@ dependencies = [ "bitflags", "errno", "libc", - "linux-raw-sys", + "linux-raw-sys 0.4.14", "windows-sys 0.52.0", ] +[[package]] +name = "rustix" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c71e83d6afe7ff64890ec6b71d6a69bb8a610ab78ce364b3352876bb4c801266" +dependencies = [ + "bitflags", + "errno", + "libc", + "linux-raw-sys 0.9.4", + "windows-sys 0.59.0", +] + +[[package]] +name = "rustversion" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eded382c5f5f786b989652c49544c4877d9f015cc22e145a5ea8ea66c2921cd2" + [[package]] name = "ryu" version = "1.0.18" @@ -1644,10 +1483,10 @@ dependencies = [ ] [[package]] -name = "seahash" -version = "4.1.0" +name = "scopeguard" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "serde" @@ -1666,7 +1505,7 @@ checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.101", + "syn", ] [[package]] @@ -1683,13 +1522,14 @@ dependencies = [ [[package]] name = "shadow-rs" -version = "0.35.1" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2311e39772c00391875f40e34d43efef247b23930143a70ca5fbec9505937420" +checksum = "6d5625ed609cf66d7e505e7d487aca815626dc4ebb6c0dd07637ca61a44651a6" dependencies = [ "const_format", "is_debug", "time", + "tzdb", ] [[package]] @@ -1699,16 +1539,40 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] -name = "simdutf8" -version = "0.1.5" +name = "signal-hook" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8621587d4798caf8eb44879d42e56b9a93ea5dcd315a6487c357130095b62801" +dependencies = [ + "libc", + "signal-hook-registry", +] + +[[package]] +name = "signal-hook-mio" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" +checksum = "34db1a06d485c9142248b7a054f034b349b212551f3dfd19c94d45a754a217cd" +dependencies = [ + "libc", + "mio", + "signal-hook", +] [[package]] -name = "smawk" -version = "0.3.2" +name = "signal-hook-registry" +version = "1.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7c388c1b5e93756d0c740965c41e8822f866621d41acbdf6336a6a168f8840c" +checksum = "9203b8055f63a2a00e2f593bb0510367fe707d7ff1e5c872de2f537b339e5410" +dependencies = [ + "libc", +] + +[[package]] +name = "smallvec" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8917285742e9f3e1683f0a9c4e6b57960b7314d0b08d30d1ecd426713ee2eee9" [[package]] name = "strip-ansi-escapes" @@ -1725,6 +1589,25 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" +[[package]] +name = "strum" +version = "0.26.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" + +[[package]] +name = "strum_macros" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "rustversion", + "syn", +] + [[package]] name = "supports-color" version = "3.0.1" @@ -1746,17 +1629,6 @@ version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7401a30af6cb5818bb64852270bb722533397edcfc7344954a38f420819ece2" -[[package]] -name = "syn" -version = "1.0.109" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - [[package]] name = "syn" version = "2.0.101" @@ -1768,18 +1640,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "syn_derive" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1329189c02ff984e9736652b1631330da25eaa6bc639089ed4915d25446cbe7b" -dependencies = [ - "proc-macro-error", - "proc-macro2", - "quote", - "syn 2.0.101", -] - [[package]] name = "sys-locale" version = "0.3.1" @@ -1791,25 +1651,18 @@ dependencies = [ [[package]] name = "sysinfo" -version = "0.30.13" +version = "0.33.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a5b4ddaee55fb2bea2bf0e5000747e5f5c0de765e5a5ff87f4cd106439f4bb3" +checksum = "4fc858248ea01b66f19d8e8a6d55f41deaf91e9d495246fd01368d99935c6c01" dependencies = [ - "cfg-if", "core-foundation-sys", "libc", + "memchr", "ntapi", - "once_cell", "rayon", - "windows 0.52.0", + "windows 0.54.0", ] -[[package]] -name = "tap" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" - [[package]] name = "termcolor" version = "1.4.1" @@ -1821,12 +1674,12 @@ dependencies = [ [[package]] name = "terminal_size" -version = "0.3.0" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21bebf2b7c9e0a515f6e0f8c51dc0f8e4696391e6f1ff30379559f8365fb0df7" +checksum = "45c6481c4829e4cc63825e62c49186a34538b7b2750b73b266581ffb612fb5ed" dependencies = [ - "rustix", - "windows-sys 0.48.0", + "rustix 1.0.7", + "windows-sys 0.59.0", ] [[package]] @@ -1835,7 +1688,6 @@ version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "23d434d3f8967a09480fb04132ebe0a3e088c173e6d0ee7897abbdf4eab0f8b9" dependencies = [ - "smawk", "unicode-linebreak", "unicode-width 0.1.14", ] @@ -1866,7 +1718,7 @@ checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.101", + "syn", ] [[package]] @@ -1877,7 +1729,7 @@ checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.101", + "syn", ] [[package]] @@ -1923,38 +1775,6 @@ dependencies = [ "serde_json", ] -[[package]] -name = "tinyvec" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" -dependencies = [ - "tinyvec_macros", -] - -[[package]] -name = "tinyvec_macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" - -[[package]] -name = "toml_datetime" -version = "0.6.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" - -[[package]] -name = "toml_edit" -version = "0.22.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" -dependencies = [ - "indexmap", - "toml_datetime", - "winnow", -] - [[package]] name = "typeid" version = "1.0.2" @@ -1982,18 +1802,41 @@ checksum = "70b20a22c42c8f1cd23ce5e34f165d4d37038f5b663ad20fb6adbdf029172483" dependencies = [ "proc-macro2", "quote", - "syn 2.0.101", + "syn", ] [[package]] -name = "unicase" -version = "2.7.0" +name = "tz-rs" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89" +checksum = "e1450bf2b99397e72070e7935c89facaa80092ac812502200375f1f7d33c71a1" + +[[package]] +name = "tzdb" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0be2ea5956f295449f47c0b825c5e109022ff1a6a53bb4f77682a87c2341fbf5" dependencies = [ - "version_check", + "iana-time-zone", + "tz-rs", + "tzdb_data", ] +[[package]] +name = "tzdb_data" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c4c81d75033770e40fbd3643ce7472a1a9fd301f90b7139038228daf8af03ec" +dependencies = [ + "tz-rs", +] + +[[package]] +name = "unicase" +version = "2.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539" + [[package]] name = "unicode-ident" version = "1.0.13" @@ -2024,30 +1867,12 @@ version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" -[[package]] -name = "utf8-width" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86bd8d4e895da8537e5315b8254664e6b769c4ff3db18321b297a1e7004392e3" - [[package]] name = "utf8parse" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" -[[package]] -name = "uuid" -version = "1.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8c5f0a0af699448548ad1a2fbf920fb4bee257eae39953ba95cb84891a0446a" - -[[package]] -name = "version_check" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" - [[package]] name = "vte" version = "0.11.1" @@ -2106,7 +1931,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.101", + "syn", "wasm-bindgen-shared", ] @@ -2128,7 +1953,7 @@ checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68" dependencies = [ "proc-macro2", "quote", - "syn 2.0.101", + "syn", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -2149,6 +1974,16 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "web-time" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + [[package]] name = "winapi" version = "0.3.9" @@ -2182,21 +2017,21 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "windows" -version = "0.52.0" +version = "0.54.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0be" +checksum = "9252e5725dbed82865af151df558e754e4a3c2c30818359eb17465f1346a1b49" dependencies = [ - "windows-core 0.52.0", + "windows-core 0.54.0", "windows-targets 0.52.6", ] [[package]] name = "windows" -version = "0.54.0" +version = "0.56.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9252e5725dbed82865af151df558e754e4a3c2c30818359eb17465f1346a1b49" +checksum = "1de69df01bdf1ead2f4ac895dc77c9351aefff65b2f3db429a343f9cbf05e132" dependencies = [ - "windows-core 0.54.0", + "windows-core 0.56.0", "windows-targets 0.52.6", ] @@ -2219,6 +2054,40 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "windows-core" +version = "0.56.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4698e52ed2d08f8658ab0c39512a7c00ee5fe2688c65f8c0a4f06750d729f2a6" +dependencies = [ + "windows-implement", + "windows-interface", + "windows-result", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-implement" +version = "0.56.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6fc35f58ecd95a9b71c4f2329b911016e6bec66b3f2e6a4aad86bd2e99e2f9b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "windows-interface" +version = "0.56.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08990546bf4edef8f431fa6326e032865f27138718c587dc21bc0265bbcb57cc" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "windows-result" version = "0.1.2" @@ -2375,42 +2244,3 @@ name = "windows_x86_64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" - -[[package]] -name = "winnow" -version = "0.6.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b" -dependencies = [ - "memchr", -] - -[[package]] -name = "wyz" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" -dependencies = [ - "tap", -] - -[[package]] -name = "zerocopy" -version = "0.7.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" -dependencies = [ - "byteorder", - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.101", -] diff --git a/Cargo.toml b/Cargo.toml index 72576b3..230b84e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,9 +19,10 @@ colored = "2" env_logger = "0.10.0" ignore = "0.4" log = "0.4.17" -nu-cmd-lang = "0.99.0" -nu-parser = "0.99.0" -nu-protocol = "0.99.0" +nu-cmd-lang = "0.104.0" +nu-parser = "0.104.0" +nu-protocol = "0.104.0" +nuon = "0.104.0" rayon = "1.10" thiserror = "2" diff --git a/README.md b/README.md index 8bb8651..0f93e2a 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ [discord-url]: https://discord.gg/NtAbbGn [ci-badge]: https://github.com/nushell/nufmt/actions/workflows/main.yml/badge.svg [ci-url]: https://github.com/nushell/nufmt/actions/workflows/main.yml -[nushell-badge]: https://img.shields.io/badge/nushell-v0.103.0-green +[nushell-badge]: https://img.shields.io/badge/nushell-v0.104.0-green [nushell-url]: https://crates.io/crates/nu diff --git a/scripts/update-nushell-version b/scripts/update-nushell-version index 11dc8c2..acf3d19 100755 --- a/scripts/update-nushell-version +++ b/scripts/update-nushell-version @@ -10,10 +10,14 @@ def main [ | str replace 'https://img.shields.io/badge/nushell-v\d+\.\d+\.\d+-green' $"https://img.shields.io/badge/nushell-v($version)-green" | save --force README.md + log info "updating the `nu-cmd-lang` dependency" + cargo add $"nu-cmd-lang@($version)" log info "updating the `nu-parser` dependency" cargo add $"nu-parser@($version)" log info "updating the `nu-protocol` dependency" cargo add $"nu-protocol@($version)" + log info "updating the `nuon` dependency" + cargo add $"nuon@($version)" log warning "do not forget to commit and push this :wink:" } diff --git a/src/config.rs b/src/config.rs index 4a539ed..b7a2eac 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,17 +1,22 @@ //! Keeps all the options, tweaks and dials of the configuration. +use std::convert::TryFrom; + +use crate::config_error::ConfigError; +use nu_protocol::Value; + #[derive(Debug, Clone, PartialEq, Eq)] pub struct Config { - pub tab_spaces: usize, - pub max_width: usize, + pub indent: usize, + pub line_length: usize, pub margin: usize, } impl Default for Config { fn default() -> Self { Config { - tab_spaces: 4, - max_width: 80, + indent: 4, + line_length: 80, margin: 1, } } @@ -20,9 +25,101 @@ impl Default for Config { impl Config { pub fn new(tab_spaces: usize, max_width: usize, margin: usize) -> Self { Config { - tab_spaces, - max_width, + indent: tab_spaces, + line_length: max_width, margin, } } } + +impl TryFrom for Config { + type Error = ConfigError; + + fn try_from(value: Value) -> Result { + let mut config = Config::default(); + match value { + Value::String { val, .. } => { + if !val.is_empty() { + return Err(ConfigError::InvalidFormat); + }; + } + Value::Record { val: record, .. } => { + for (key, value) in record.iter() { + match key.as_str() { + "indent" => { + let indent: usize = match value { + Value::Int { val, .. } => { + if *val <= 0 { + return Err(ConfigError::InvalidOptionValue( + key.to_string(), + value.get_type().to_string(), + "a positive number", + )); + } + *val as usize + } + other => { + return Err(ConfigError::InvalidOptionType( + key.to_string(), + other.get_type().to_string(), + "number", + )); + } + }; + config.indent = indent; + } + "line_length" => { + let line_length: usize = match value { + Value::Int { val, .. } => { + if *val <= 0 { + return Err(ConfigError::InvalidOptionValue( + key.to_string(), + value.get_type().to_string(), + "a positive number", + )); + } + *val as usize + } + other => { + return Err(ConfigError::InvalidOptionType( + key.to_string(), + other.get_type().to_string(), + "number", + )); + } + }; + config.line_length = line_length; + } + "margin" => { + let margin: usize = match value { + Value::Int { val, .. } => { + if *val <= 0 { + return Err(ConfigError::InvalidOptionValue( + key.to_string(), + value.get_type().to_string(), + "a positive number", + )); + } + *val as usize + } + other => { + return Err(ConfigError::InvalidOptionType( + key.to_string(), + other.get_type().to_string(), + "number", + )); + } + }; + config.margin = margin; + } + unknown => return Err(ConfigError::UnknownOption(unknown.to_string())), + } + } + } + _ => { + return Err(ConfigError::InvalidFormat); + } + } + Ok(config) + } +} diff --git a/src/lib.rs b/src/lib.rs index e9ddadd..536dd98 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -10,6 +10,7 @@ use std::io::Write; use std::path::PathBuf; pub mod config; +pub mod config_error; pub mod format_error; mod formatting; diff --git a/src/main.rs b/src/main.rs index 7d6fcf5..22559b3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,8 +5,10 @@ use colored::*; use ignore::{DirEntry, WalkBuilder}; use log::{info, trace}; use nu_formatter::config::Config; +use nu_formatter::config_error::ConfigError; use nu_formatter::{CheckOutcome, FormatOutcome}; use rayon::iter::{IntoParallelIterator, ParallelIterator}; +use std::convert::TryFrom; use std::{ io::{self, Write}, path::{Path, PathBuf}, @@ -85,12 +87,13 @@ fn main() { let config = match cli.config { None => Config::default(), - Some(input_cli) => { - todo!( - "cannot read from {:?} Reading a config from file not implemented!", - input_cli - ) - } + Some(cli_config) => match read_config(&cli_config) { + Ok(config) => config, + Err(err) => { + eprintln!("{}", err); + return exit_with_code(ExitCode::Failure); + } + }, }; let exit_code = if cli.stdin { @@ -109,6 +112,12 @@ fn main() { exit_with_code(exit_code); } +fn read_config(path: &PathBuf) -> Result { + let content = std::fs::read_to_string(path)?; + let content_nuon = nuon::from_nuon(&content, None)?; + Config::try_from(content_nuon) +} + /// format a string passed via stdin and output it directly to stdout fn format_string(string: String, options: &Config) -> ExitCode { match nu_formatter::format_string(&string, options) { From 1f446e71ade6468c219d6472ec8a3a0e5acc6b60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Riegel?= Date: Sat, 3 May 2025 14:32:20 +0200 Subject: [PATCH 14/30] cargo update --- Cargo.lock | 456 +++++++++++++++++++++++++------------------- src/config_error.rs | 27 +++ 2 files changed, 291 insertions(+), 192 deletions(-) create mode 100644 src/config_error.rs diff --git a/Cargo.lock b/Cargo.lock index 65f9bc6..4cf43d8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -19,9 +19,9 @@ dependencies = [ [[package]] name = "allocator-api2" -version = "0.2.18" +version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" +checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" [[package]] name = "android-tzdata" @@ -46,9 +46,9 @@ checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" [[package]] name = "anstream" -version = "0.6.15" +version = "0.6.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526" +checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" dependencies = [ "anstyle", "anstyle-parse", @@ -61,36 +61,37 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.8" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" +checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" [[package]] name = "anstyle-parse" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb" +checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.1.1" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a" +checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] name = "anstyle-wincon" -version = "3.0.4" +version = "3.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8" +checksum = "ca3534e77181a9cc07539ad51f2141fe32f6c3ffd4df76db8ad92346b003ae4e" dependencies = [ "anstyle", - "windows-sys 0.52.0", + "once_cell", + "windows-sys 0.59.0", ] [[package]] @@ -140,9 +141,9 @@ checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" [[package]] name = "bitflags" -version = "2.6.0" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" +checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd" [[package]] name = "bstr" @@ -156,15 +157,15 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.16.0" +version = "3.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" +checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf" [[package]] name = "bytes" -version = "1.7.2" +version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "428d9aa8fbc0670b7b8d6030a7fadd0f86151cae55e4dbbece15f3780a3dfaf3" +checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" [[package]] name = "bytesize" @@ -180,9 +181,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" -version = "1.1.30" +version = "1.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b16803a61b81d9eabb7eae2588776c4c1e584b738ede45fdbb4c972cec1e9945" +checksum = "8691782945451c1c383942c4874dbe63814f61cb57ef773cda2972682b7bb3c0" dependencies = [ "shlex", ] @@ -210,16 +211,16 @@ checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" [[package]] name = "chrono" -version = "0.4.38" +version = "0.4.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" +checksum = "c469d952047f47f91b68d1cba3f10d63c11d73e4636f24f08daf0278abf01c4d" dependencies = [ "android-tzdata", "iana-time-zone", "num-traits", "pure-rust-locales", "serde", - "windows-targets 0.52.6", + "windows-link", ] [[package]] @@ -271,9 +272,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.20" +version = "4.5.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b97f376d85a664d5837dbae44bf546e6477a679ff6610010f17276f686d867e8" +checksum = "eccb054f56cbd38340b380d4a8e69ef1f02f1af43db2f0cc817a4774d80ae071" dependencies = [ "clap_builder", "clap_derive", @@ -281,9 +282,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.20" +version = "4.5.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19bc80abd44e4bed93ca373a0704ccbd1b710dc5749406201bb018272808dc54" +checksum = "efd9466fac8543255d3b1fcad4762c5e116ffe808c8a3043d4263cd4fd4862a2" dependencies = [ "anstream", "anstyle", @@ -295,9 +296,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.18" +version = "4.5.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab" +checksum = "09176aae279615badda0765c0c0b3f6ed53f4709118af73cf4655d85d1530cd7" dependencies = [ "heck", "proc-macro2", @@ -307,15 +308,15 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.7.2" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" +checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" [[package]] name = "colorchoice" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" +checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" [[package]] name = "colored" @@ -329,18 +330,18 @@ dependencies = [ [[package]] name = "const_format" -version = "0.2.33" +version = "0.2.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50c655d81ff1114fb0dcdea9225ea9f0cc712a6f8d189378e82bdf62a473a64b" +checksum = "126f97965c8ad46d6d9163268ff28432e8f6a1196a55578867832e3049df63dd" dependencies = [ "const_format_proc_macros", ] [[package]] name = "const_format_proc_macros" -version = "0.2.33" +version = "0.2.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eff1a44b93f47b1bac19a27932f5c591e43d1ba357ee4f61526c8a25603f0eb1" +checksum = "1d57c2eccfb16dbac1f4e61e206105db5820c9d26c3c472bc17c774259ef7744" dependencies = [ "proc-macro2", "quote", @@ -400,9 +401,9 @@ dependencies = [ [[package]] name = "crossbeam-deque" -version = "0.8.5" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" +checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" dependencies = [ "crossbeam-epoch", "crossbeam-utils", @@ -419,9 +420,9 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.20" +version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" [[package]] name = "crossterm" @@ -433,7 +434,7 @@ dependencies = [ "crossterm_winapi", "mio", "parking_lot", - "rustix 0.38.37", + "rustix 0.38.44", "signal-hook", "signal-hook-mio", "winapi", @@ -450,15 +451,15 @@ dependencies = [ [[package]] name = "crunchy" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" +checksum = "43da5946c66ffcc7745f48db692ffbb10a83bfe0afd96235c5c2a4fb23994929" [[package]] name = "deranged" -version = "0.3.11" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" +checksum = "9c9e6a11ca8224451684bc0d7d5a7adbf8f2fd6887261a1cfc3c0432f9d4068e" dependencies = [ "powerfmt", ] @@ -486,9 +487,9 @@ dependencies = [ [[package]] name = "either" -version = "1.13.0" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" +checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" [[package]] name = "env_logger" @@ -505,15 +506,15 @@ dependencies = [ [[package]] name = "equivalent" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" [[package]] name = "erased-serde" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24e2389d65ab4fab27dc2a5de7b191e1f6617d1f1c8855c0dc569c94a4cbb18d" +checksum = "e004d887f51fcb9fef17317a2f3525c887d8aa3f4f50fed920816a688284a5b7" dependencies = [ "serde", "typeid", @@ -542,9 +543,9 @@ dependencies = [ [[package]] name = "flate2" -version = "1.0.34" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1b589b4dc103969ad3cf85c950899926ec64300a1a46d76c03a6072957036f0" +checksum = "7ced92e76e966ca2fd84c8f7aa01a4aea65b0eb6648d72f7c8f3e2764a67fece" dependencies = [ "crc32fast", "miniz_oxide", @@ -552,15 +553,15 @@ dependencies = [ [[package]] name = "foldhash" -version = "0.1.3" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f81ec6369c545a7d40e4589b5597581fa1c441fe1cce96dd1de43159910a36a2" +checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" [[package]] name = "getrandom" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" dependencies = [ "cfg-if", "libc", @@ -569,9 +570,9 @@ dependencies = [ [[package]] name = "glob" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" +checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2" [[package]] name = "globset" @@ -588,9 +589,9 @@ dependencies = [ [[package]] name = "half" -version = "2.4.1" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6dd08c532ae367adf81c312a4580bc67f1d0fe8bc9c460520283f4c0ff277888" +checksum = "459196ed295495a68f7d7fe1d84f6c4b7ff0e21fe3017b2f283c6fac3ad803c9" dependencies = [ "cfg-if", "crunchy", @@ -598,9 +599,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.15.0" +version = "0.15.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb" +checksum = "84b26c544d002229e640969970a2e74021aadf6e2f96372b9c58eff97de08eb3" dependencies = [ "allocator-api2", "equivalent", @@ -615,9 +616,9 @@ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "hermit-abi" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" +checksum = "fbd780fe5cc30f81464441920d82ac8740e2e46b29a6fad543ddd075229ce37e" [[package]] name = "hex" @@ -627,22 +628,23 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "humantime" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" +checksum = "9b112acc8b3adf4b107a8ec20977da0273a8c386765a3ec0229bd500a1443f9f" [[package]] name = "iana-time-zone" -version = "0.1.61" +version = "0.1.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220" +checksum = "b0c919e5debc312ad217002b8048a17b7d83f80703865bbfcfebb0458b0b27d8" dependencies = [ "android_system_properties", "core-foundation-sys", "iana-time-zone-haiku", "js-sys", + "log", "wasm-bindgen", - "windows-core 0.52.0", + "windows-core 0.61.0", ] [[package]] @@ -682,19 +684,22 @@ dependencies = [ [[package]] name = "inventory" -version = "0.3.15" +version = "0.3.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f958d3d68f4167080a18141e10381e7634563984a537f2a49a30fd8e53ac5767" +checksum = "ab08d7cd2c5897f2c949e5383ea7c7db03fb19130ffcfbf7eda795137ae3cb83" +dependencies = [ + "rustversion", +] [[package]] name = "is-terminal" -version = "0.4.13" +version = "0.4.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "261f68e344040fbd0edea105bef17c66edf46f984ddb1115b775ce31be948f4b" +checksum = "e04d7f318608d35d4b61ddd75cbdaee86b023ebe2bd5a66ee0915f0bf93095a9" dependencies = [ "hermit-abi", "libc", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -735,16 +740,17 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.11" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" +checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" [[package]] name = "js-sys" -version = "0.3.72" +version = "0.3.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a88f1bda2bd75b0452a14784937d796722fdebfe50df998aeb3f0b7603019a9" +checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" dependencies = [ + "once_cell", "wasm-bindgen", ] @@ -762,9 +768,9 @@ checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa" [[package]] name = "libloading" -version = "0.8.5" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" +checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34" dependencies = [ "cfg-if", "windows-targets 0.52.6", @@ -793,9 +799,9 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.4.14" +version = "0.4.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" +checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" [[package]] name = "linux-raw-sys" @@ -815,9 +821,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.22" +version = "0.4.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" +checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" [[package]] name = "lru" @@ -888,9 +894,9 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" -version = "0.8.0" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" +checksum = "3be647b768db090acb35d5ec5db2b0e1f1de11133ca123b9eacf5137868f892a" dependencies = [ "adler2", ] @@ -1170,15 +1176,15 @@ checksum = "80adb31078122c880307e9cdfd4e3361e6545c319f9b9dcafcb03acd3b51a575" [[package]] name = "once_cell" -version = "1.20.2" +version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" [[package]] name = "oorandom" -version = "11.1.4" +version = "11.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b410bbe7e14ab526a0e86877eb47c6996a2bd7746f027ba551028c925390e4e9" +checksum = "d6790f58c7ff633d8771f42965289203411a5e5c68388703c06e14f24770b41e" [[package]] name = "option-ext" @@ -1198,9 +1204,9 @@ dependencies = [ [[package]] name = "owo-colors" -version = "4.1.0" +version = "4.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb37767f6569cd834a413442455e0f066d0d522de8630436e2a1761d9726ba56" +checksum = "1036865bb9422d3300cf723f657c2851d0e9ab12567854b1f4eba3d77decf564" [[package]] name = "parking_lot" @@ -1301,7 +1307,7 @@ dependencies = [ "flate2", "hex", "procfs-core", - "rustix 0.38.37", + "rustix 0.38.44", ] [[package]] @@ -1328,14 +1334,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72c71c0c79b9701efe4e1e4b563b2016dd4ee789eb99badcb09d61ac4b92e4a2" dependencies = [ "libc", - "thiserror 1.0.64", + "thiserror 1.0.69", ] [[package]] name = "quote" -version = "1.0.37" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" dependencies = [ "proc-macro2", ] @@ -1377,7 +1383,7 @@ checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" dependencies = [ "getrandom", "libredox", - "thiserror 1.0.64", + "thiserror 1.0.69", ] [[package]] @@ -1402,9 +1408,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.11.0" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38200e5ee88914975b69f657f0801b6f6dccafd44fd9326302a4aaeecfacb1d8" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" dependencies = [ "aho-corasick", "memchr", @@ -1414,9 +1420,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.8" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "368758f23274712b504848e9d5a6f010445cc8b87a7cdb4d7cbee666c1288da3" +checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" dependencies = [ "aho-corasick", "memchr", @@ -1437,15 +1443,15 @@ checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" [[package]] name = "rustix" -version = "0.38.37" +version = "0.38.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811" +checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" dependencies = [ "bitflags", "errno", "libc", - "linux-raw-sys 0.4.14", - "windows-sys 0.52.0", + "linux-raw-sys 0.4.15", + "windows-sys 0.59.0", ] [[package]] @@ -1469,9 +1475,9 @@ checksum = "eded382c5f5f786b989652c49544c4877d9f015cc22e145a5ea8ea66c2921cd2" [[package]] name = "ryu" -version = "1.0.18" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" +checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" [[package]] name = "same-file" @@ -1490,18 +1496,18 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "serde" -version = "1.0.210" +version = "1.0.219" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" +checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.210" +version = "1.0.219" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" +checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" dependencies = [ "proc-macro2", "quote", @@ -1510,9 +1516,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.128" +version = "1.0.140" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8" +checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373" dependencies = [ "itoa", "memchr", @@ -1576,9 +1582,9 @@ checksum = "8917285742e9f3e1683f0a9c4e6b57960b7314d0b08d30d1ecd426713ee2eee9" [[package]] name = "strip-ansi-escapes" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55ff8ef943b384c414f54aefa961dd2bd853add74ec75e7ac74cf91dba62bcfa" +checksum = "2a8f8038e7e7969abb3f1b7c2a811225e9296da208539e0f79c5251d6cac0025" dependencies = [ "vte", ] @@ -1610,18 +1616,18 @@ dependencies = [ [[package]] name = "supports-color" -version = "3.0.1" +version = "3.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8775305acf21c96926c900ad056abeef436701108518cf890020387236ac5a77" +checksum = "c64fc7232dd8d2e4ac5ce4ef302b1d81e0b80d055b9d77c7c4f51f6aa4c867d6" dependencies = [ "is_ci", ] [[package]] name = "supports-hyperlinks" -version = "3.0.0" +version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c0a1e5168041f5f3ff68ff7d95dcb9c8749df29f6e7e89ada40dd4c9de404ee" +checksum = "804f44ed3c63152de6a9f90acbea1a110441de43006ea51bcce8f436196a288b" [[package]] name = "supports-unicode" @@ -1642,9 +1648,9 @@ dependencies = [ [[package]] name = "sys-locale" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e801cf239ecd6ccd71f03d270d67dd53d13e90aab208bf4b8fe4ad957ea949b0" +checksum = "8eab9a99a024a169fe8a903cf9d4a3b3601109bcc13bd9e3c6fff259138626c4" dependencies = [ "libc", ] @@ -1660,7 +1666,7 @@ dependencies = [ "memchr", "ntapi", "rayon", - "windows 0.54.0", + "windows 0.57.0", ] [[package]] @@ -1684,21 +1690,21 @@ dependencies = [ [[package]] name = "textwrap" -version = "0.16.1" +version = "0.16.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23d434d3f8967a09480fb04132ebe0a3e088c173e6d0ee7897abbdf4eab0f8b9" +checksum = "c13547615a44dc9c452a8a534638acdf07120d4b6847c8178705da06306a3057" dependencies = [ "unicode-linebreak", - "unicode-width 0.1.14", + "unicode-width 0.2.0", ] [[package]] name = "thiserror" -version = "1.0.64" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" dependencies = [ - "thiserror-impl 1.0.64", + "thiserror-impl 1.0.69", ] [[package]] @@ -1712,9 +1718,9 @@ dependencies = [ [[package]] name = "thiserror-impl" -version = "1.0.64" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", @@ -1734,9 +1740,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.36" +version = "0.3.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" +checksum = "8a7619e19bc266e0f9c5e6686659d394bc57973859340060a69221e57dbc0c40" dependencies = [ "deranged", "itoa", @@ -1751,15 +1757,15 @@ dependencies = [ [[package]] name = "time-core" -version = "0.1.2" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" +checksum = "c9e9a38711f559d9e3ce1cdb06dd7c5b8ea546bc90052da6d06bb76da74bb07c" [[package]] name = "time-macros" -version = "0.2.18" +version = "0.2.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" +checksum = "3526739392ec93fd8b359c8e98514cb3e8e021beb4e5f597b00a0221f8ed8a49" dependencies = [ "num-conv", "time-core", @@ -1777,15 +1783,15 @@ dependencies = [ [[package]] name = "typeid" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e13db2e0ccd5e14a544e8a246ba2312cd25223f616442d7f2cb0e3db614236e" +checksum = "bc7d623258602320d5c55d1bc22793b57daff0ec7efc270ea7d55ce1d5f5471c" [[package]] name = "typetag" -version = "0.2.18" +version = "0.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52ba3b6e86ffe0054b2c44f2d86407388b933b16cb0a70eea3929420db1d9bbe" +checksum = "73f22b40dd7bfe8c14230cf9702081366421890435b2d625fa92b4acc4c3de6f" dependencies = [ "erased-serde", "inventory", @@ -1796,9 +1802,9 @@ dependencies = [ [[package]] name = "typetag-impl" -version = "0.2.18" +version = "0.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70b20a22c42c8f1cd23ce5e34f165d4d37038f5b663ad20fb6adbdf029172483" +checksum = "35f5380909ffc31b4de4f4bdf96b877175a016aa2ca98cee39fcfd8c4d53d952" dependencies = [ "proc-macro2", "quote", @@ -1839,9 +1845,9 @@ checksum = "75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539" [[package]] name = "unicode-ident" -version = "1.0.13" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" +checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" [[package]] name = "unicode-linebreak" @@ -1875,22 +1881,11 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "vte" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5022b5fbf9407086c180e9557be968742d839e68346af7792b8592489732197" -dependencies = [ - "utf8parse", - "vte_generate_state_changes", -] - -[[package]] -name = "vte_generate_state_changes" -version = "0.1.2" +version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e369bee1b05d510a7b4ed645f5faa90619e05437111783ea5848f28d97d3c2e" +checksum = "231fdcd7ef3037e8330d8e17e61011a2c244126acc0a982f4040ac3f9f0bc077" dependencies = [ - "proc-macro2", - "quote", + "memchr", ] [[package]] @@ -1911,24 +1906,24 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.95" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "128d1e363af62632b8eb57219c8fd7877144af57558fb2ef0368d0087bddeb2e" +checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" dependencies = [ "cfg-if", "once_cell", + "rustversion", "wasm-bindgen-macro", ] [[package]] name = "wasm-bindgen-backend" -version = "0.2.95" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb6dd4d3ca0ddffd1dd1c9c04f94b868c37ff5fac97c30b97cff2d74fce3a358" +checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" dependencies = [ "bumpalo", "log", - "once_cell", "proc-macro2", "quote", "syn", @@ -1937,9 +1932,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.95" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e79384be7f8f5a9dd5d7167216f022090cf1f9ec128e6e6a482a2cb5c5422c56" +checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -1947,9 +1942,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.95" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68" +checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" dependencies = [ "proc-macro2", "quote", @@ -1960,15 +1955,18 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.95" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65fc09f10666a9f147042251e0dda9c18f166ff7de300607007e96bdebc1068d" +checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" +dependencies = [ + "unicode-ident", +] [[package]] name = "web-sys" -version = "0.3.72" +version = "0.3.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6488b90108c040df0fe62fa815cbdee25124641df01814dd7282749234c6112" +checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2" dependencies = [ "js-sys", "wasm-bindgen", @@ -2017,53 +2015,59 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "windows" -version = "0.54.0" +version = "0.56.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9252e5725dbed82865af151df558e754e4a3c2c30818359eb17465f1346a1b49" +checksum = "1de69df01bdf1ead2f4ac895dc77c9351aefff65b2f3db429a343f9cbf05e132" dependencies = [ - "windows-core 0.54.0", + "windows-core 0.56.0", "windows-targets 0.52.6", ] [[package]] name = "windows" -version = "0.56.0" +version = "0.57.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1de69df01bdf1ead2f4ac895dc77c9351aefff65b2f3db429a343f9cbf05e132" +checksum = "12342cb4d8e3b046f3d80effd474a7a02447231330ef77d71daa6fbc40681143" dependencies = [ - "windows-core 0.56.0", + "windows-core 0.57.0", "windows-targets 0.52.6", ] [[package]] name = "windows-core" -version = "0.52.0" +version = "0.56.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +checksum = "4698e52ed2d08f8658ab0c39512a7c00ee5fe2688c65f8c0a4f06750d729f2a6" dependencies = [ + "windows-implement 0.56.0", + "windows-interface 0.56.0", + "windows-result 0.1.2", "windows-targets 0.52.6", ] [[package]] name = "windows-core" -version = "0.54.0" +version = "0.57.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12661b9c89351d684a50a8a643ce5f608e20243b9fb84687800163429f161d65" +checksum = "d2ed2439a290666cd67ecce2b0ffaad89c2a56b976b736e6ece670297897832d" dependencies = [ - "windows-result", + "windows-implement 0.57.0", + "windows-interface 0.57.0", + "windows-result 0.1.2", "windows-targets 0.52.6", ] [[package]] name = "windows-core" -version = "0.56.0" +version = "0.61.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4698e52ed2d08f8658ab0c39512a7c00ee5fe2688c65f8c0a4f06750d729f2a6" +checksum = "4763c1de310c86d75a878046489e2e5ba02c649d185f21c67d4cf8a56d098980" dependencies = [ - "windows-implement", - "windows-interface", - "windows-result", - "windows-targets 0.52.6", + "windows-implement 0.60.0", + "windows-interface 0.59.1", + "windows-link", + "windows-result 0.3.2", + "windows-strings", ] [[package]] @@ -2077,6 +2081,28 @@ dependencies = [ "syn", ] +[[package]] +name = "windows-implement" +version = "0.57.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9107ddc059d5b6fbfbffdfa7a7fe3e22a226def0b2608f72e9d552763d3e1ad7" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "windows-implement" +version = "0.60.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "windows-interface" version = "0.56.0" @@ -2088,6 +2114,34 @@ dependencies = [ "syn", ] +[[package]] +name = "windows-interface" +version = "0.57.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29bee4b38ea3cde66011baa44dba677c432a78593e202392d1e9070cf2a7fca7" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "windows-interface" +version = "0.59.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "windows-link" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38" + [[package]] name = "windows-result" version = "0.1.2" @@ -2097,6 +2151,24 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "windows-result" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c64fd11a4fd95df68efcfee5f44a294fe71b8bc6a91993e2791938abcc712252" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-strings" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a2ba9642430ee452d5a7aa78d72907ebe8cfda358e8cb7918a2050581322f97" +dependencies = [ + "windows-link", +] + [[package]] name = "windows-sys" version = "0.48.0" diff --git a/src/config_error.rs b/src/config_error.rs new file mode 100644 index 0000000..6a7c0f9 --- /dev/null +++ b/src/config_error.rs @@ -0,0 +1,27 @@ +use thiserror::Error; + +#[derive(Clone, Debug, Error, PartialEq, Eq)] +pub enum ConfigError { + #[error("Failed read the configuration file: {0}")] + IOError(String), + #[error("The configuration is not valid nuon record")] + InvalidFormat, + #[error("Unknown configuration option: {0}")] + UnknownOption(String), + #[error("Invalid type for '{0}': got {1}, expected {2}")] + InvalidOptionType(String, String, &'static str), + #[error("Invalid value for '{0}': got {1}, expected {2}")] + InvalidOptionValue(String, String, &'static str), +} + +impl From for ConfigError { + fn from(value: std::io::Error) -> Self { + ConfigError::IOError(value.to_string()) + } +} + +impl From for ConfigError { + fn from(_value: nu_protocol::ShellError) -> Self { + ConfigError::InvalidFormat + } +} From ebc6d7921221f11012d30a7c0ec2969c53f58c85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Riegel?= Date: Sat, 3 May 2025 14:56:58 +0200 Subject: [PATCH 15/30] fix error --- src/config.rs | 6 +++--- src/config_error.rs | 8 ++++---- src/main.rs | 10 ++++++---- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/src/config.rs b/src/config.rs index b7a2eac..cbc4812 100644 --- a/src/config.rs +++ b/src/config.rs @@ -52,7 +52,7 @@ impl TryFrom for Config { if *val <= 0 { return Err(ConfigError::InvalidOptionValue( key.to_string(), - value.get_type().to_string(), + format!("{}", val), "a positive number", )); } @@ -74,7 +74,7 @@ impl TryFrom for Config { if *val <= 0 { return Err(ConfigError::InvalidOptionValue( key.to_string(), - value.get_type().to_string(), + format!("{}", val), "a positive number", )); } @@ -96,7 +96,7 @@ impl TryFrom for Config { if *val <= 0 { return Err(ConfigError::InvalidOptionValue( key.to_string(), - value.get_type().to_string(), + format!("{}", val), "a positive number", )); } diff --git a/src/config_error.rs b/src/config_error.rs index 6a7c0f9..d36ebff 100644 --- a/src/config_error.rs +++ b/src/config_error.rs @@ -4,13 +4,13 @@ use thiserror::Error; pub enum ConfigError { #[error("Failed read the configuration file: {0}")] IOError(String), - #[error("The configuration is not valid nuon record")] + #[error("The configuration is not a valid nuon record")] InvalidFormat, - #[error("Unknown configuration option: {0}")] + #[error("Found unknown configuration option: {0}")] UnknownOption(String), - #[error("Invalid type for '{0}': got {1}, expected {2}")] + #[error("Found invalid type for option '{0}': got {1}, expected {2}")] InvalidOptionType(String, String, &'static str), - #[error("Invalid value for '{0}': got {1}, expected {2}")] + #[error("Found invalid value for option '{0}': got {1}, expected {2}")] InvalidOptionValue(String, String, &'static str), } diff --git a/src/main.rs b/src/main.rs index 22559b3..9ebccc8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -90,12 +90,14 @@ fn main() { Some(cli_config) => match read_config(&cli_config) { Ok(config) => config, Err(err) => { - eprintln!("{}", err); + eprintln!("{}: {}", "error".bright_red(), &err); return exit_with_code(ExitCode::Failure); } }, }; + dbg!(&config.line_length); + let exit_code = if cli.stdin { let stdin_input = io::stdin().lines().map(|x| x.unwrap()).collect(); format_string(stdin_input, &config) @@ -126,7 +128,7 @@ fn format_string(string: String, options: &Config) -> ExitCode { ExitCode::Success } Err(err) => { - println!("{}: {}", "Could not format stdin".red(), err); + eprintln!("{}: {}", "Could not format stdin".red(), err); ExitCode::Failure } } @@ -187,7 +189,7 @@ fn exit_from_check(results: &[(PathBuf, CheckOutcome)]) -> ExitCode { } CheckOutcome::Failure(reason) => { failures += 1; - println!( + eprintln!( "{}: {} {}: {}", "error".bright_red(), "Failed to check".bold(), @@ -247,7 +249,7 @@ fn exit_from_format(results: &[(PathBuf, FormatOutcome)]) -> ExitCode { FormatOutcome::Reformatted => reformatted += 1, FormatOutcome::Failure(reason) => { failures += 1; - println!( + eprintln!( "{}: {} {}: {}", "error".bright_red(), "Failed to format".bold(), From ccd40cfa5ccca25de131bb9459072c04e8004ec4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Riegel?= Date: Sat, 3 May 2025 15:02:27 +0200 Subject: [PATCH 16/30] extract fn to refactor --- src/config.rs | 82 ++++++++++++++++----------------------------------- 1 file changed, 25 insertions(+), 57 deletions(-) diff --git a/src/config.rs b/src/config.rs index cbc4812..bb90711 100644 --- a/src/config.rs +++ b/src/config.rs @@ -47,69 +47,15 @@ impl TryFrom for Config { for (key, value) in record.iter() { match key.as_str() { "indent" => { - let indent: usize = match value { - Value::Int { val, .. } => { - if *val <= 0 { - return Err(ConfigError::InvalidOptionValue( - key.to_string(), - format!("{}", val), - "a positive number", - )); - } - *val as usize - } - other => { - return Err(ConfigError::InvalidOptionType( - key.to_string(), - other.get_type().to_string(), - "number", - )); - } - }; + let indent = parse_value_to_usize(key, value)?; config.indent = indent; } "line_length" => { - let line_length: usize = match value { - Value::Int { val, .. } => { - if *val <= 0 { - return Err(ConfigError::InvalidOptionValue( - key.to_string(), - format!("{}", val), - "a positive number", - )); - } - *val as usize - } - other => { - return Err(ConfigError::InvalidOptionType( - key.to_string(), - other.get_type().to_string(), - "number", - )); - } - }; + let line_length = parse_value_to_usize(key, value)?; config.line_length = line_length; } "margin" => { - let margin: usize = match value { - Value::Int { val, .. } => { - if *val <= 0 { - return Err(ConfigError::InvalidOptionValue( - key.to_string(), - format!("{}", val), - "a positive number", - )); - } - *val as usize - } - other => { - return Err(ConfigError::InvalidOptionType( - key.to_string(), - other.get_type().to_string(), - "number", - )); - } - }; + let margin = parse_value_to_usize(key, value)?; config.margin = margin; } unknown => return Err(ConfigError::UnknownOption(unknown.to_string())), @@ -123,3 +69,25 @@ impl TryFrom for Config { Ok(config) } } + +fn parse_value_to_usize(key: &str, value: &Value) -> Result { + match value { + Value::Int { val, .. } => { + if *val <= 0 { + return Err(ConfigError::InvalidOptionValue( + key.to_string(), + format!("{}", val), + "a positive number", + )); + } + Ok(*val as usize) + } + other => { + return Err(ConfigError::InvalidOptionType( + key.to_string(), + other.get_type().to_string(), + "number", + )); + } + } +} From f8849ba7350296978113f3719e5f36bea8eee352 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Riegel?= Date: Sat, 3 May 2025 15:44:04 +0200 Subject: [PATCH 17/30] look for config_file in parents directories --- src/config.rs | 12 +++++------- src/main.rs | 28 +++++++++++++++++++++++----- 2 files changed, 28 insertions(+), 12 deletions(-) diff --git a/src/config.rs b/src/config.rs index bb90711..d5e13c7 100644 --- a/src/config.rs +++ b/src/config.rs @@ -82,12 +82,10 @@ fn parse_value_to_usize(key: &str, value: &Value) -> Result } Ok(*val as usize) } - other => { - return Err(ConfigError::InvalidOptionType( - key.to_string(), - other.get_type().to_string(), - "number", - )); - } + other => Err(ConfigError::InvalidOptionType( + key.to_string(), + other.get_type().to_string(), + "number", + )), } } diff --git a/src/main.rs b/src/main.rs index 9ebccc8..b7d0001 100644 --- a/src/main.rs +++ b/src/main.rs @@ -14,6 +14,8 @@ use std::{ path::{Path, PathBuf}, }; +const DEFAULT_CONFIG_FILE: &str = "nufmt.nuon"; + /// The possible exit codes enum ExitCode { /// nufmt terminates successfully, regardless of whether files or stdin were formatted. @@ -85,7 +87,8 @@ fn main() { trace!("recieved cli.stdin: {:?}", cli.stdin); trace!("recieved cli.config: {:?}", cli.config); - let config = match cli.config { + let config_file = cli.config.or(find_in_parent_dirs(DEFAULT_CONFIG_FILE)); + let config = match config_file { None => Config::default(), Some(cli_config) => match read_config(&cli_config) { Ok(config) => config, @@ -136,7 +139,7 @@ fn format_string(string: String, options: &Config) -> ExitCode { /// check a list of files, possibly one fn check_files(files: Vec, options: &Config) -> Vec<(PathBuf, CheckOutcome)> { - let (target_files, invalid_paths) = discover_files(files); + let (target_files, invalid_paths) = discover_nu_files(files); let mut results = target_files .into_par_iter() .map(|file| { @@ -155,7 +158,7 @@ fn check_files(files: Vec, options: &Config) -> Vec<(PathBuf, CheckOutc /// format a list of files, possibly one, and modify them in place fn format_files(files: Vec, options: &Config) -> Vec<(PathBuf, FormatOutcome)> { - let (target_files, invalid_paths) = discover_files(files); + let (target_files, invalid_paths) = discover_nu_files(files); let mut results = target_files .into_par_iter() .map(|file| { @@ -294,7 +297,7 @@ fn exit_from_format(results: &[(PathBuf, FormatOutcome)]) -> ExitCode { /// Return the different files to analyze, taking only files with .nu extension and discarding files in .nufmtignore /// and the invalid paths provided -fn discover_files(paths: Vec) -> (Vec, Vec) { +fn discover_nu_files(paths: Vec) -> (Vec, Vec) { let mut valid_paths: Vec = vec![]; let mut invalid_paths: Vec = vec![]; @@ -310,7 +313,6 @@ fn discover_files(paths: Vec) -> (Vec, Vec) { .iter() .flat_map(|path| { WalkBuilder::new(path) - .add_custom_ignore_filename(".nufmtignore") .build() .filter_map(Result::ok) .filter(is_nu_file) @@ -339,6 +341,22 @@ fn make_relative(path: &Path) -> String { .to_string() } +/// Search for `filename` in current or any parent directories. +/// If `start_dir` is not provided, the current directory is used +fn find_in_parent_dirs(filename: &str) -> Option { + let start_dir = std::env::current_dir().unwrap_or(PathBuf::from(".")); + + let mut dir = Some(start_dir.as_path()); + while let Some(current) = dir { + let candidate = current.join(filename); + if candidate.exists() { + return Some(candidate); + } + dir = current.parent(); + } + None +} + #[cfg(test)] mod tests { use super::*; From e324ba16a7d937392444e8c75a8fd0822b1ad88f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Riegel?= Date: Sun, 4 May 2025 11:29:10 +0200 Subject: [PATCH 18/30] refactor FileDiagnostic and combine check and format to remove duplicates --- src/config.rs | 35 +++++++++ src/config_error.rs | 8 ++ src/lib.rs | 73 +++++++----------- src/main.rs | 184 +++++++++++++++++++------------------------- 4 files changed, 147 insertions(+), 153 deletions(-) diff --git a/src/config.rs b/src/config.rs index d5e13c7..15cd491 100644 --- a/src/config.rs +++ b/src/config.rs @@ -10,6 +10,7 @@ pub struct Config { pub indent: usize, pub line_length: usize, pub margin: usize, + pub excludes: Vec, } impl Default for Config { @@ -18,6 +19,7 @@ impl Default for Config { indent: 4, line_length: 80, margin: 1, + excludes: vec![], } } } @@ -28,6 +30,7 @@ impl Config { indent: tab_spaces, line_length: max_width, margin, + excludes: vec![], } } } @@ -58,6 +61,10 @@ impl TryFrom for Config { let margin = parse_value_to_usize(key, value)?; config.margin = margin; } + "exclude" => { + let excludes = parse_excludes(value)?; + config.excludes = excludes; + } unknown => return Err(ConfigError::UnknownOption(unknown.to_string())), } } @@ -89,3 +96,31 @@ fn parse_value_to_usize(key: &str, value: &Value) -> Result )), } } + +fn parse_excludes(value: &Value) -> Result, ConfigError> { + match value { + Value::List { vals, .. } => { + let mut excludes = vec![]; + for val in vals { + match val { + Value::String { val, .. } => { + excludes.push(val.clone()); + } + other => { + return Err(ConfigError::InvalidOptionType( + "excludes".to_string(), + other.get_type().to_string(), + "list", + )); + } + } + } + Ok(excludes) + } + other => Err(ConfigError::InvalidOptionType( + "excludes".to_string(), + other.get_type().to_string(), + "list", + )), + } +} diff --git a/src/config_error.rs b/src/config_error.rs index d36ebff..8b0d5e6 100644 --- a/src/config_error.rs +++ b/src/config_error.rs @@ -12,6 +12,8 @@ pub enum ConfigError { InvalidOptionType(String, String, &'static str), #[error("Found invalid value for option '{0}': got {1}, expected {2}")] InvalidOptionValue(String, String, &'static str), + #[error("Found an invalid exclude pattern")] + InvalidExcludePattern, } impl From for ConfigError { @@ -25,3 +27,9 @@ impl From for ConfigError { ConfigError::InvalidFormat } } + +impl From for ConfigError { + fn from(_value: ignore::Error) -> Self { + ConfigError::InvalidExcludePattern + } +} diff --git a/src/lib.rs b/src/lib.rs index 536dd98..cd536fe 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -14,79 +14,58 @@ pub mod config_error; pub mod format_error; mod formatting; -/// The possible outcome of checking a file -#[derive(Debug, Clone, PartialEq, Eq)] -pub enum CheckOutcome { - /// File is already correctly formatted - AlreadyFormatted, - /// File would be reformatted if check mode was off - NeedsFormatting, - /// An error occurred while trying to access or write to the file - Failure(String), -} - /// The possible outcome of checking or formatting a file #[derive(Debug, Clone, PartialEq, Eq)] -pub enum FormatOutcome { +pub enum FileDiagnostic { /// File was left unchanged, as it is already correctly formatted AlreadyFormatted, /// File was formatted successfully - Reformatted, + /// In check mode, file would be reformatted if check mode was off + ReformattedOrWouldFormat, /// An error occurred while trying to access or write to the file Failure(String), } -/// check a Nushell file -pub fn check_single_file(file: PathBuf, config: &Config) -> (PathBuf, CheckOutcome) { +/// format or check a Nushell file in place +/// only check the file (do not write) in check mode +pub fn format_single_file( + file: PathBuf, + config: &Config, + check: bool, +) -> (PathBuf, FileDiagnostic) { let contents = match std::fs::read(&file) { Ok(content) => content, Err(err) => { - return (file, CheckOutcome::Failure(err.to_string())); + return (file, FileDiagnostic::Failure(err.to_string())); } }; let formatted_bytes = add_newline_at_end_of_file(match format_inner(&contents, config) { Ok(bytes) => bytes, Err(err) => { - return (file, CheckOutcome::Failure(err.to_string())); + return (file, FileDiagnostic::Failure(err.to_string())); } }); if formatted_bytes == contents { - (file, CheckOutcome::AlreadyFormatted) - } else { - (file, CheckOutcome::NeedsFormatting) + debug!("File is already formatted correctly."); + return (file, FileDiagnostic::AlreadyFormatted); } -} - -/// format a Nushell file in place -pub fn format_single_file(file: PathBuf, config: &Config) -> (PathBuf, FormatOutcome) { - let contents = match std::fs::read(&file) { - Ok(content) => content, - Err(err) => { - return (file, FormatOutcome::Failure(err.to_string())); - } - }; - let formatted_bytes = add_newline_at_end_of_file(match format_inner(&contents, config) { - Ok(bytes) => bytes, - Err(err) => { - return (file, FormatOutcome::Failure(err.to_string())); + if !check { + let mut writer = match File::create(&file) { + Ok(file) => file, + Err(err) => { + return (file, FileDiagnostic::Failure(err.to_string())); + } + }; + let file_bytes = formatted_bytes.as_slice(); + if let Err(err) = writer.write_all(file_bytes) { + return (file, FileDiagnostic::Failure(err.to_string())); } - }); - - if formatted_bytes == contents { - debug!("File is already formatted correctly."); - return (file, FormatOutcome::AlreadyFormatted); + debug!("File formatted."); } - - let mut writer = File::create(&file).unwrap(); - let file_bytes = formatted_bytes.as_slice(); - writer - .write_all(file_bytes) - .expect("something went wrong writing"); - debug!("File formatted."); - (file, FormatOutcome::Reformatted) + (file, FileDiagnostic::ReformattedOrWouldFormat) } /// format a string of Nushell code diff --git a/src/main.rs b/src/main.rs index b7d0001..49ed533 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,11 +2,11 @@ use clap::Parser; use colored::*; -use ignore::{DirEntry, WalkBuilder}; +use ignore::{overrides::OverrideBuilder, DirEntry, WalkBuilder}; use log::{info, trace}; use nu_formatter::config::Config; use nu_formatter::config_error::ConfigError; -use nu_formatter::{CheckOutcome, FormatOutcome}; +use nu_formatter::FileDiagnostic; use rayon::iter::{IntoParallelIterator, ParallelIterator}; use std::convert::TryFrom; use std::{ @@ -104,15 +104,22 @@ fn main() { let exit_code = if cli.stdin { let stdin_input = io::stdin().lines().map(|x| x.unwrap()).collect(); format_string(stdin_input, &config) - } else if cli.check { - let results = check_files(cli.files, &config); - exit_from_check(&results) } else { - let results = format_files(cli.files, &config); - exit_from_format(&results) + let (target_files, invalid_files) = match discover_nu_files(cli.files, &config.excludes) { + Ok(files) => files, + Err(err) => { + eprintln!("{}: {}", "error".bright_red(), err); + return exit_with_code(ExitCode::Failure); + } + }; + let mut results = handle_invalid_file(invalid_files); + results.extend(format_files(target_files, &config, cli.check)); + display_diagnostic_and_compute_exit_code(&results, cli.check) }; - std::io::stdout().flush().unwrap(); + std::io::stdout() + .flush() + .expect("Unexpected error occurred when flushing stdout"); exit_with_code(exit_code); } @@ -137,65 +144,66 @@ fn format_string(string: String, options: &Config) -> ExitCode { } } -/// check a list of files, possibly one -fn check_files(files: Vec, options: &Config) -> Vec<(PathBuf, CheckOutcome)> { - let (target_files, invalid_paths) = discover_nu_files(files); - let mut results = target_files - .into_par_iter() - .map(|file| { - info!("checking file: {:?}", &file); - nu_formatter::check_single_file(file, options) - }) - .collect::>(); - for path in invalid_paths { +fn handle_invalid_file(files: Vec) -> Vec<(PathBuf, FileDiagnostic)> { + let mut results: Vec<(PathBuf, FileDiagnostic)> = vec![]; + for file in files { results.push(( - path, - CheckOutcome::Failure("cannot find the file specified".to_string()), + file, + FileDiagnostic::Failure("cannot find the file specified".to_string()), )); } results } /// format a list of files, possibly one, and modify them in place -fn format_files(files: Vec, options: &Config) -> Vec<(PathBuf, FormatOutcome)> { - let (target_files, invalid_paths) = discover_nu_files(files); - let mut results = target_files +/// if check mode is on, only check the files but do not modify them in place +fn format_files( + files: Vec, + options: &Config, + check: bool, +) -> Vec<(PathBuf, FileDiagnostic)> { + files .into_par_iter() .map(|file| { info!("formatting file: {:?}", &file); - nu_formatter::format_single_file(file, options) + nu_formatter::format_single_file(file, options, check) }) - .collect::>(); - for path in invalid_paths { - results.push(( - path, - FormatOutcome::Failure("cannot find the file specified".to_string()), - )); - } - results + .collect() } /// Display results and return the appropriate exit code after formatting in check mode -fn exit_from_check(results: &[(PathBuf, CheckOutcome)]) -> ExitCode { +fn display_diagnostic_and_compute_exit_code( + results: &[(PathBuf, FileDiagnostic)], + check: bool, +) -> ExitCode { let mut already_formatted: usize = 0; - let mut need_formatting: usize = 0; + let mut reformatted_or_would_reformat: usize = 0; let mut failures: usize = 0; let mut at_least_one_failure = false; let mut warning_messages: Vec = vec![]; + let file_failed_msg = if check { + "Failed to check" + } else { + "Failed to format" + }; + for (file, result) in results { match result { - CheckOutcome::AlreadyFormatted => already_formatted += 1, - CheckOutcome::NeedsFormatting => { - need_formatting += 1; - warning_messages.push(format!("Would reformat: {}", make_relative(file).bold())); + FileDiagnostic::AlreadyFormatted => already_formatted += 1, + FileDiagnostic::ReformattedOrWouldFormat => { + reformatted_or_would_reformat += 1; + if check { + warning_messages + .push(format!("Would reformat: {}", make_relative(file).bold())); + }; } - CheckOutcome::Failure(reason) => { + FileDiagnostic::Failure(reason) => { failures += 1; eprintln!( "{}: {} {}: {}", "error".bright_red(), - "Failed to check".bold(), + file_failed_msg.bold(), make_relative(file).bold(), &reason ); @@ -208,7 +216,7 @@ fn exit_from_check(results: &[(PathBuf, CheckOutcome)]) -> ExitCode { println!("{}", msg); } - if already_formatted + need_formatting + failures == 0 { + if already_formatted + reformatted_or_would_reformat + failures == 0 { print!( "{}: no Nushell files found under the given path(s)", "warning".bright_yellow(), @@ -216,11 +224,21 @@ fn exit_from_check(results: &[(PathBuf, CheckOutcome)]) -> ExitCode { return ExitCode::Success; } - if need_formatting > 0 { + if reformatted_or_would_reformat > 0 { + let msg = if check { + "would be reformatted" + } else { + "were formatted" + }; println!( - "{} file{} would be reformatted", - need_formatting, - if need_formatting == 1 { "" } else { "s" } + "{} file{} {}", + reformatted_or_would_reformat, + if reformatted_or_would_reformat == 1 { + "" + } else { + "s" + }, + msg, ); } if already_formatted > 0 { @@ -232,72 +250,19 @@ fn exit_from_check(results: &[(PathBuf, CheckOutcome)]) -> ExitCode { }; if at_least_one_failure { ExitCode::Failure - } else if need_formatting > 0 { + } else if reformatted_or_would_reformat > 0 { ExitCode::CheckFailed } else { ExitCode::Success } } -/// Display results and return the appropriate exit code after formatting in format mode -fn exit_from_format(results: &[(PathBuf, FormatOutcome)]) -> ExitCode { - let mut left_unchanged: usize = 0; - let mut reformatted: usize = 0; - let mut failures: usize = 0; - let mut at_least_one_failure = false; - - for (file, result) in results { - match result { - FormatOutcome::AlreadyFormatted => left_unchanged += 1, - FormatOutcome::Reformatted => reformatted += 1, - FormatOutcome::Failure(reason) => { - failures += 1; - eprintln!( - "{}: {} {}: {}", - "error".bright_red(), - "Failed to format".bold(), - make_relative(file).bold(), - &reason - ); - at_least_one_failure = true; - } - } - } - - if left_unchanged + reformatted + failures == 0 { - print!( - "{}: no Nushell files found under the given path(s)", - "warning".bright_yellow(), - ); - return ExitCode::Success; - } - - if reformatted > 0 { - println!( - "{} file{} were reformatted", - reformatted, - if reformatted == 1 { "" } else { "s" } - ); - } - - if left_unchanged > 0 { - println!( - "{} file{} already formatted", - left_unchanged, - if left_unchanged == 1 { "" } else { "s" } - ); - }; - - if at_least_one_failure { - ExitCode::Failure - } else { - ExitCode::Success - } -} - -/// Return the different files to analyze, taking only files with .nu extension and discarding files in .nufmtignore +/// Return the different files to analyze, taking only files with .nu extension and discarding files excluded in the config /// and the invalid paths provided -fn discover_nu_files(paths: Vec) -> (Vec, Vec) { +fn discover_nu_files( + paths: Vec, + excludes: &Vec, +) -> Result<(Vec, Vec), ConfigError> { let mut valid_paths: Vec = vec![]; let mut invalid_paths: Vec = vec![]; @@ -309,10 +274,17 @@ fn discover_nu_files(paths: Vec) -> (Vec, Vec) { } } + let mut overrides = OverrideBuilder::new("."); + for pattern in excludes { + overrides.add(&format!("!{}", pattern))?; + } + let overrides = overrides.build()?; + let nu_files = valid_paths .iter() .flat_map(|path| { WalkBuilder::new(path) + .overrides(overrides.clone()) .build() .filter_map(Result::ok) .filter(is_nu_file) @@ -321,7 +293,7 @@ fn discover_nu_files(paths: Vec) -> (Vec, Vec) { }) .collect(); - (nu_files, invalid_paths) + Ok((nu_files, invalid_paths)) } /// Return whether a DirEntry is a .nu file or not From 479d04b33351b92c0e214a0cef5f959d7c46eed2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Riegel?= Date: Sun, 4 May 2025 12:51:55 +0200 Subject: [PATCH 19/30] add tests --- Cargo.lock | 285 +++++++++++++++++++++++++++++++++++++++++++++++++- Cargo.toml | 3 + src/config.rs | 8 +- src/main.rs | 43 +++++++- tests/main.rs | 64 ++++++++++++ 5 files changed, 392 insertions(+), 11 deletions(-) create mode 100644 tests/main.rs diff --git a/Cargo.lock b/Cargo.lock index 4cf43d8..bc84270 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -100,6 +100,22 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" +[[package]] +name = "assert_cmd" +version = "2.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bd389a4b2970a01282ee455294913c0a43724daedcd1a24c3eb0ec1c1320b66" +dependencies = [ + "anstyle", + "bstr", + "doc-comment", + "libc", + "predicates", + "predicates-core", + "predicates-tree", + "wait-timeout", +] + [[package]] name = "autocfg" version = "1.4.0" @@ -152,6 +168,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "234113d19d0d7d613b40e86fb654acf958910802bcceab913a4f9e7cda03b1a4" dependencies = [ "memchr", + "regex-automata", "serde", ] @@ -464,6 +481,12 @@ dependencies = [ "powerfmt", ] +[[package]] +name = "difflib" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6184e33543162437515c2e2b48714794e37845ec9851711914eec9d308f6ebe8" + [[package]] name = "dirs" version = "5.0.1" @@ -485,6 +508,12 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "doc-comment" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" + [[package]] name = "either" version = "1.15.0" @@ -541,6 +570,12 @@ dependencies = [ "regex-syntax", ] +[[package]] +name = "fastrand" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" + [[package]] name = "flate2" version = "1.1.1" @@ -557,6 +592,49 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" +[[package]] +name = "futures-core" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" + +[[package]] +name = "futures-macro" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "futures-task" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" + +[[package]] +name = "futures-timer" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24" + +[[package]] +name = "futures-util" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" +dependencies = [ + "futures-core", + "futures-macro", + "futures-task", + "pin-project-lite", + "pin-utils", + "slab", +] + [[package]] name = "getrandom" version = "0.2.16" @@ -565,7 +643,19 @@ checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" dependencies = [ "cfg-if", "libc", - "wasi", + "wasi 0.11.0+wasi-snapshot-preview1", +] + +[[package]] +name = "getrandom" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73fea8450eea4bac3940448fb7ae50d91f034f941199fcd9d909a5a07aa455f0" +dependencies = [ + "cfg-if", + "libc", + "r-efi", + "wasi 0.14.2+wasi-0.2.4", ] [[package]] @@ -909,7 +999,7 @@ checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" dependencies = [ "libc", "log", - "wasi", + "wasi 0.11.0+wasi-snapshot-preview1", "windows-sys 0.52.0", ] @@ -1108,6 +1198,7 @@ dependencies = [ name = "nufmt" version = "0.1.0" dependencies = [ + "assert_cmd", "clap", "colored", "criterion", @@ -1119,6 +1210,8 @@ dependencies = [ "nu-protocol", "nuon", "rayon", + "rstest", + "tempfile", "thiserror 2.0.12", ] @@ -1231,6 +1324,18 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "pin-project-lite" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + [[package]] name = "plotters" version = "0.3.7" @@ -1265,6 +1370,42 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" +[[package]] +name = "predicates" +version = "3.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5d19ee57562043d37e82899fade9a22ebab7be9cef5026b07fda9cdd4293573" +dependencies = [ + "anstyle", + "difflib", + "predicates-core", +] + +[[package]] +name = "predicates-core" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "727e462b119fe9c93fd0eb1429a5f7647394014cf3c04ab2c0350eeb09095ffa" + +[[package]] +name = "predicates-tree" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72dd2d6d381dfb73a193c7fca536518d7caee39fc8503f74e7dc0be0531b425c" +dependencies = [ + "predicates-core", + "termtree", +] + +[[package]] +name = "proc-macro-crate" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edce586971a4dfaa28950c6f18ed55e0406c1ab88bbce2c6f6293a7aaba73d35" +dependencies = [ + "toml_edit", +] + [[package]] name = "proc-macro-error-attr2" version = "2.0.0" @@ -1346,6 +1487,12 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "r-efi" +version = "5.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5" + [[package]] name = "rayon" version = "1.10.0" @@ -1381,7 +1528,7 @@ version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" dependencies = [ - "getrandom", + "getrandom 0.2.16", "libredox", "thiserror 1.0.69", ] @@ -1435,12 +1582,57 @@ version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" +[[package]] +name = "relative-path" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba39f3699c378cd8970968dcbff9c43159ea4cfbd88d43c00b22f2ef10a435d2" + +[[package]] +name = "rstest" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fc39292f8613e913f7df8fa892b8944ceb47c247b78e1b1ae2f09e019be789d" +dependencies = [ + "futures-timer", + "futures-util", + "rstest_macros", + "rustc_version", +] + +[[package]] +name = "rstest_macros" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f168d99749d307be9de54d23fd226628d99768225ef08f6ffb52e0182a27746" +dependencies = [ + "cfg-if", + "glob", + "proc-macro-crate", + "proc-macro2", + "quote", + "regex", + "relative-path", + "rustc_version", + "syn", + "unicode-ident", +] + [[package]] name = "rustc-hash" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + [[package]] name = "rustix" version = "0.38.44" @@ -1494,6 +1686,12 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +[[package]] +name = "semver" +version = "1.0.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0" + [[package]] name = "serde" version = "1.0.219" @@ -1574,6 +1772,15 @@ dependencies = [ "libc", ] +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + [[package]] name = "smallvec" version = "1.15.0" @@ -1669,6 +1876,19 @@ dependencies = [ "windows 0.57.0", ] +[[package]] +name = "tempfile" +version = "3.19.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7437ac7763b9b123ccf33c338a5cc1bac6f69b45a136c19bdd8a65e3916435bf" +dependencies = [ + "fastrand", + "getrandom 0.3.2", + "once_cell", + "rustix 1.0.7", + "windows-sys 0.59.0", +] + [[package]] name = "termcolor" version = "1.4.1" @@ -1688,6 +1908,12 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "termtree" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f50febec83f5ee1df3015341d8bd429f2d1cc62bcba7ea2076759d315084683" + [[package]] name = "textwrap" version = "0.16.2" @@ -1781,6 +2007,23 @@ dependencies = [ "serde_json", ] +[[package]] +name = "toml_datetime" +version = "0.6.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3da5db5a963e24bc68be8b17b6fa82814bb22ee8660f192bb182771d498f09a3" + +[[package]] +name = "toml_edit" +version = "0.22.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "310068873db2c5b3e7659d2cc35d21855dbafa50d1ce336397c666e3cb08137e" +dependencies = [ + "indexmap", + "toml_datetime", + "winnow", +] + [[package]] name = "typeid" version = "1.0.3" @@ -1888,6 +2131,15 @@ dependencies = [ "memchr", ] +[[package]] +name = "wait-timeout" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ac3b126d3914f9849036f826e054cbabdc8519970b8998ddaf3b5bd3c65f11" +dependencies = [ + "libc", +] + [[package]] name = "walkdir" version = "2.5.0" @@ -1904,6 +2156,15 @@ version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +[[package]] +name = "wasi" +version = "0.14.2+wasi-0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" +dependencies = [ + "wit-bindgen-rt", +] + [[package]] name = "wasm-bindgen" version = "0.2.100" @@ -2316,3 +2577,21 @@ name = "windows_x86_64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "winnow" +version = "0.7.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9fb597c990f03753e08d3c29efbfcf2019a003b4bf4ba19225c158e1549f0f3" +dependencies = [ + "memchr", +] + +[[package]] +name = "wit-bindgen-rt" +version = "0.39.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" +dependencies = [ + "bitflags", +] diff --git a/Cargo.toml b/Cargo.toml index 230b84e..1e3bba0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,7 +27,10 @@ rayon = "1.10" thiserror = "2" [dev-dependencies] +assert_cmd = "2" criterion = "0.5.1" +rstest = "0.25" +tempfile = "3" [features] default = ["bin"] diff --git a/src/config.rs b/src/config.rs index 15cd491..b4cb598 100644 --- a/src/config.rs +++ b/src/config.rs @@ -41,11 +41,7 @@ impl TryFrom for Config { fn try_from(value: Value) -> Result { let mut config = Config::default(); match value { - Value::String { val, .. } => { - if !val.is_empty() { - return Err(ConfigError::InvalidFormat); - }; - } + Value::Nothing { .. } => (), Value::Record { val: record, .. } => { for (key, value) in record.iter() { match key.as_str() { @@ -72,7 +68,7 @@ impl TryFrom for Config { _ => { return Err(ConfigError::InvalidFormat); } - } + }; Ok(config) } } diff --git a/src/main.rs b/src/main.rs index 49ed533..ecd0b53 100644 --- a/src/main.rs +++ b/src/main.rs @@ -99,8 +99,6 @@ fn main() { }, }; - dbg!(&config.line_length); - let exit_code = if cli.stdin { let stdin_input = io::stdin().lines().map(|x| x.unwrap()).collect(); format_string(stdin_input, &config) @@ -332,10 +330,51 @@ fn find_in_parent_dirs(filename: &str) -> Option { #[cfg(test)] mod tests { use super::*; + use rstest::rstest; + use std::fs; + use tempfile::tempdir; #[test] fn clap_cli_construction() { use clap::CommandFactory; Cli::command().debug_assert(); } + + #[test] + fn read_valid_config_empty() { + let dir = tempdir().unwrap(); + let config_file = dir.path().join("nufmt.nuon"); + fs::write(&config_file, "").unwrap(); + + let config = read_config(&config_file).expect("Config should be valid"); + assert_eq!(config, Config::default()); + } + + #[rstest] + #[case(r#"{line_length: 120, exclude: ["a*nu", "b*.nu"]}"#)] + fn read_valid_config(#[case] config_content: &str) { + let dir = tempdir().unwrap(); + let config_file = dir.path().join("nufmt.nuon"); + fs::write(&config_file, config_content).unwrap(); + + let config = read_config(&config_file).expect("Config should be valid"); + assert_eq!(config.line_length, 120 as usize); + assert_eq!(config.excludes.len(), 2 as usize); + } + + #[rstest] + #[case(r#"some string"#)] + #[case(r#"{unknown: 1}"#)] + #[case(r#"{line_length: -1}"#)] + #[case(r#"{line_length: "120"}"#)] + #[case(r#"{exclude: "a*nu"}"#)] + #[case(r#"{exclude: ["a*nu", 1]}"#)] + fn read_invalid_config(#[case] config_content: &str) { + let dir = tempdir().unwrap(); + let config_file = dir.path().join("nufmt.nuon"); + fs::write(&config_file, config_content).unwrap(); + + let config = read_config(&config_file); + assert!(config.is_err()); + } } diff --git a/tests/main.rs b/tests/main.rs new file mode 100644 index 0000000..428356c --- /dev/null +++ b/tests/main.rs @@ -0,0 +1,64 @@ +use std::{fs, process::Command}; +use tempfile::tempdir; + +const INVALID: &str = "# beginning of script comment + +let one = 1 +"; +const VALID: &str = "# beginning of script comment +let one = 1 +"; + +#[test] +fn test_exit_with_failure_on_invalid_config() { + let dir = tempdir().unwrap(); + let config_file = dir.path().join("nufmt.nuon"); + fs::write(&config_file, r#"{unknown: 1}"#).unwrap(); + + let output = Command::new("target/debug/nufmt") + .arg("--config") + .arg(config_file.to_str().unwrap()) + .arg(dir.path().to_str().unwrap()) + .output() + .unwrap(); + let stderr = String::from_utf8_lossy(&output.stderr); + + assert!(stderr.contains("error")); + assert_eq!(output.status.code(), Some(2)); +} + +#[test] +fn test_warning_is_displayed_when_no_files_are_detected() { + let dir = tempdir().unwrap(); + + let output = Command::new("target/debug/nufmt") + .arg("--check") + .arg(dir.path().to_str().unwrap()) + .output() + .unwrap(); + let stdout = String::from_utf8_lossy(&output.stdout); + + assert!(stdout.contains("warning")); + assert_eq!(output.status.code(), Some(0)); +} + +#[test] +fn test_warning_is_displayed_when_no_files_are_detected_with_excluded_files() { + let dir = tempdir().unwrap(); + let config_file = dir.path().join("nufmt.nuon"); + let file_a = dir.path().join("a.nu"); + fs::write(&config_file, r#"{exclude: ["a*"]}"#).unwrap(); + fs::write(&file_a, INVALID).unwrap(); + + let output = Command::new("target/debug/nufmt") + .arg("--config") + .arg(config_file.to_str().unwrap()) + .arg("--check") + .arg(dir.path().to_str().unwrap()) + .output() + .unwrap(); + let stdout = String::from_utf8_lossy(&output.stdout); + + assert!(stdout.contains("warning")); + assert_eq!(output.status.code(), Some(0)); +} From 812580f0c055184c880a78a2b0aa1b9d2d0fb32c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Riegel?= Date: Sun, 4 May 2025 12:55:09 +0200 Subject: [PATCH 20/30] more tests --- tests/main.rs | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/tests/main.rs b/tests/main.rs index 428356c..bcd4563 100644 --- a/tests/main.rs +++ b/tests/main.rs @@ -10,7 +10,7 @@ let one = 1 "; #[test] -fn test_exit_with_failure_on_invalid_config() { +fn failure_with_invalid_config() { let dir = tempdir().unwrap(); let config_file = dir.path().join("nufmt.nuon"); fs::write(&config_file, r#"{unknown: 1}"#).unwrap(); @@ -28,7 +28,32 @@ fn test_exit_with_failure_on_invalid_config() { } #[test] -fn test_warning_is_displayed_when_no_files_are_detected() { +fn failure_with_invalid_config_file() { + let output = Command::new("target/debug/nufmt") + .arg("--config") + .arg("path/that/does/not/exist/nufmt.nuon") + .output() + .unwrap(); + let stderr = String::from_utf8_lossy(&output.stderr); + + assert!(stderr.contains("error")); + assert_eq!(output.status.code(), Some(2)); +} + +#[test] +fn failure_with_invalid_file_to_format() { + let output = Command::new("target/debug/nufmt") + .arg("path/that/does/not/exist/a.nu") + .output() + .unwrap(); + let stderr = String::from_utf8_lossy(&output.stderr); + + assert!(stderr.contains("error")); + assert_eq!(output.status.code(), Some(2)); +} + +#[test] +fn warning_when_no_files_are_detected() { let dir = tempdir().unwrap(); let output = Command::new("target/debug/nufmt") @@ -43,7 +68,7 @@ fn test_warning_is_displayed_when_no_files_are_detected() { } #[test] -fn test_warning_is_displayed_when_no_files_are_detected_with_excluded_files() { +fn warning_is_displayed_when_no_files_are_detected_with_excluded_files() { let dir = tempdir().unwrap(); let config_file = dir.path().join("nufmt.nuon"); let file_a = dir.path().join("a.nu"); From fb993d0d57f33000667905e1c499aac4ee3fd51b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Riegel?= Date: Sun, 4 May 2025 13:03:11 +0200 Subject: [PATCH 21/30] more tests and fix exit code when not checking --- src/main.rs | 2 +- tests/main.rs | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/src/main.rs b/src/main.rs index ecd0b53..bf72e5d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -248,7 +248,7 @@ fn display_diagnostic_and_compute_exit_code( }; if at_least_one_failure { ExitCode::Failure - } else if reformatted_or_would_reformat > 0 { + } else if check && reformatted_or_would_reformat > 0 { ExitCode::CheckFailed } else { ExitCode::Success diff --git a/tests/main.rs b/tests/main.rs index bcd4563..a1bee14 100644 --- a/tests/main.rs +++ b/tests/main.rs @@ -87,3 +87,52 @@ fn warning_is_displayed_when_no_files_are_detected_with_excluded_files() { assert!(stdout.contains("warning")); assert_eq!(output.status.code(), Some(0)); } + +#[test] +fn files_are_reformatted() { + let dir = tempdir().unwrap(); + let config_file = dir.path().join("nufmt.nuon"); + let file_a = dir.path().join("a.nu"); + let file_b = dir.path().join("b.nu"); + fs::write(&config_file, r#"{exclude: ["a*"]}"#).unwrap(); + fs::write(&file_a, INVALID).unwrap(); + fs::write(&file_b, INVALID).unwrap(); + + let output = Command::new("target/debug/nufmt") + .arg("--config") + .arg(config_file.to_str().unwrap()) + .arg(dir.path().to_str().unwrap()) + .output() + .unwrap(); + + assert_eq!(output.status.code(), Some(0)); + let file_a_content = fs::read_to_string(file_a).unwrap(); + let file_b_content = fs::read_to_string(file_b).unwrap(); + assert_eq!(file_a_content.as_str(), INVALID); + assert_eq!(file_b_content.as_str(), VALID); +} + +#[test] +fn files_are_checked() { + let dir = tempdir().unwrap(); + let config_file = dir.path().join("nufmt.nuon"); + let file_a = dir.path().join("a.nu"); + let file_b = dir.path().join("b.nu"); + fs::write(&config_file, r#"{exclude: ["a*"]}"#).unwrap(); + fs::write(&file_a, INVALID).unwrap(); + fs::write(&file_b, INVALID).unwrap(); + + let output = Command::new("target/debug/nufmt") + .arg("--config") + .arg(config_file.to_str().unwrap()) + .arg("--check") + .arg(dir.path().to_str().unwrap()) + .output() + .unwrap(); + + assert_eq!(output.status.code(), Some(1)); + let file_a_content = fs::read_to_string(file_a).unwrap(); + let file_b_content = fs::read_to_string(file_b).unwrap(); + assert_eq!(file_a_content.as_str(), INVALID); + assert_eq!(file_b_content.as_str(), INVALID); +} From 251aaeeab9d14c3aaeb8c9fe1b1b369a552aafad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Riegel?= Date: Sun, 4 May 2025 13:20:05 +0200 Subject: [PATCH 22/30] more unit tests --- src/main.rs | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/src/main.rs b/src/main.rs index bf72e5d..8dd0acd 100644 --- a/src/main.rs +++ b/src/main.rs @@ -17,6 +17,7 @@ use std::{ const DEFAULT_CONFIG_FILE: &str = "nufmt.nuon"; /// The possible exit codes +#[derive(Debug, Clone, PartialEq, Eq)] enum ExitCode { /// nufmt terminates successfully, regardless of whether files or stdin were formatted. Success, @@ -377,4 +378,34 @@ mod tests { let config = read_config(&config_file); assert!(config.is_err()); } + + #[rstest] + #[case(vec![ + (PathBuf::from("a.nu"), FileDiagnostic::AlreadyFormatted), + (PathBuf::from("b.nu"), FileDiagnostic::AlreadyFormatted),], false, ExitCode::Success)] + #[case(vec![ + (PathBuf::from("a.nu"), FileDiagnostic::AlreadyFormatted), + (PathBuf::from("b.nu"), FileDiagnostic::AlreadyFormatted),], true, ExitCode::Success)] + #[case(vec![ + (PathBuf::from("a.nu"), FileDiagnostic::AlreadyFormatted), + (PathBuf::from("b.nu"), FileDiagnostic::ReformattedOrWouldFormat),], false, ExitCode::Success)] + #[case(vec![ + (PathBuf::from("a.nu"), FileDiagnostic::AlreadyFormatted), + (PathBuf::from("b.nu"), FileDiagnostic::ReformattedOrWouldFormat),], true, ExitCode::CheckFailed)] + #[case(vec![ + (PathBuf::from("a.nu"), FileDiagnostic::AlreadyFormatted), + (PathBuf::from("b.nu"), FileDiagnostic::ReformattedOrWouldFormat), + (PathBuf::from("c.nu"), FileDiagnostic::Failure("some error".to_string())),], false, ExitCode::Failure)] + #[case(vec![ + (PathBuf::from("a.nu"), FileDiagnostic::AlreadyFormatted), + (PathBuf::from("b.nu"), FileDiagnostic::ReformattedOrWouldFormat), + (PathBuf::from("c.nu"), FileDiagnostic::Failure("some error".to_string())),], true, ExitCode::Failure)] + fn exit_code( + #[case] results: Vec<(PathBuf, FileDiagnostic)>, + #[case] check: bool, + #[case] expected: ExitCode, + ) { + let exit_code = display_diagnostic_and_compute_exit_code(&results, check); + assert_eq!(exit_code, expected); + } } From 7707e88afcab3898c5c518eb4f4d86ba71f1056a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Riegel?= Date: Sun, 4 May 2025 13:45:44 +0200 Subject: [PATCH 23/30] remove unused dep --- Cargo.lock | 72 ------------------------------------------------------ Cargo.toml | 1 - 2 files changed, 73 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bc84270..5aead09 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -100,22 +100,6 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" -[[package]] -name = "assert_cmd" -version = "2.0.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bd389a4b2970a01282ee455294913c0a43724daedcd1a24c3eb0ec1c1320b66" -dependencies = [ - "anstyle", - "bstr", - "doc-comment", - "libc", - "predicates", - "predicates-core", - "predicates-tree", - "wait-timeout", -] - [[package]] name = "autocfg" version = "1.4.0" @@ -168,7 +152,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "234113d19d0d7d613b40e86fb654acf958910802bcceab913a4f9e7cda03b1a4" dependencies = [ "memchr", - "regex-automata", "serde", ] @@ -481,12 +464,6 @@ dependencies = [ "powerfmt", ] -[[package]] -name = "difflib" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6184e33543162437515c2e2b48714794e37845ec9851711914eec9d308f6ebe8" - [[package]] name = "dirs" version = "5.0.1" @@ -508,12 +485,6 @@ dependencies = [ "windows-sys 0.48.0", ] -[[package]] -name = "doc-comment" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" - [[package]] name = "either" version = "1.15.0" @@ -1198,7 +1169,6 @@ dependencies = [ name = "nufmt" version = "0.1.0" dependencies = [ - "assert_cmd", "clap", "colored", "criterion", @@ -1370,33 +1340,6 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" -[[package]] -name = "predicates" -version = "3.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5d19ee57562043d37e82899fade9a22ebab7be9cef5026b07fda9cdd4293573" -dependencies = [ - "anstyle", - "difflib", - "predicates-core", -] - -[[package]] -name = "predicates-core" -version = "1.0.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "727e462b119fe9c93fd0eb1429a5f7647394014cf3c04ab2c0350eeb09095ffa" - -[[package]] -name = "predicates-tree" -version = "1.0.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72dd2d6d381dfb73a193c7fca536518d7caee39fc8503f74e7dc0be0531b425c" -dependencies = [ - "predicates-core", - "termtree", -] - [[package]] name = "proc-macro-crate" version = "3.3.0" @@ -1908,12 +1851,6 @@ dependencies = [ "windows-sys 0.59.0", ] -[[package]] -name = "termtree" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f50febec83f5ee1df3015341d8bd429f2d1cc62bcba7ea2076759d315084683" - [[package]] name = "textwrap" version = "0.16.2" @@ -2131,15 +2068,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "wait-timeout" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09ac3b126d3914f9849036f826e054cbabdc8519970b8998ddaf3b5bd3c65f11" -dependencies = [ - "libc", -] - [[package]] name = "walkdir" version = "2.5.0" diff --git a/Cargo.toml b/Cargo.toml index 1e3bba0..f8aebc1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,7 +27,6 @@ rayon = "1.10" thiserror = "2" [dev-dependencies] -assert_cmd = "2" criterion = "0.5.1" rstest = "0.25" tempfile = "3" From 5c0d6e3383fa23a66590f0e624da0d974fa2693e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Riegel?= Date: Sun, 4 May 2025 14:04:51 +0200 Subject: [PATCH 24/30] fix clippy and move clippy config from workflow to code --- .github/workflows/main.yml | 8 -------- benches/file-format-bench.rs | 2 +- src/main.rs | 14 +++++++++++--- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 9ccb8a8..829427f 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -35,14 +35,6 @@ jobs: --all-targets \ --no-deps \ --workspace \ - -- \ - -D warnings \ - -D rustdoc::broken_intra_doc_links \ - -W clippy::explicit_iter_loop \ - -W clippy::explicit_into_iter_loop \ - -W clippy::semicolon_if_nothing_returned \ - -W clippy::doc_markdown \ - -W clippy::manual_let_else test: name: test rust files diff --git a/benches/file-format-bench.rs b/benches/file-format-bench.rs index c2e7765..d1fd8b1 100644 --- a/benches/file-format-bench.rs +++ b/benches/file-format-bench.rs @@ -4,7 +4,7 @@ use std::path::PathBuf; fn criterion_benchmark(c: &mut Criterion) { c.bench_function("Format massive nu", |b| { - b.iter(|| format_single_file(&PathBuf::from("./benches/example.nu"), &Config::default())); + b.iter(|| format_single_file(PathBuf::from("./benches/example.nu"), &Config::default(), false)); }); } diff --git a/src/main.rs b/src/main.rs index 8dd0acd..b8ef4b9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,12 @@ #![doc = include_str!("../README.md")] +#![deny(warnings, rustdoc::broken_intra_doc_links)] +#![warn( + clippy::explicit_iter_loop, + clippy::explicit_into_iter_loop, + clippy::semicolon_if_nothing_returned, + clippy::doc_markdown, + clippy::manual_let_else +)] use clap::Parser; use colored::*; @@ -295,7 +303,7 @@ fn discover_nu_files( Ok((nu_files, invalid_paths)) } -/// Return whether a DirEntry is a .nu file or not +/// Return whether a `DirEntry` is a .nu file or not fn is_nu_file(entry: &DirEntry) -> bool { entry.file_type().map(|ft| ft.is_file()).unwrap_or(false) && entry.path().extension().is_some_and(|ext| ext == "nu") @@ -359,8 +367,8 @@ mod tests { fs::write(&config_file, config_content).unwrap(); let config = read_config(&config_file).expect("Config should be valid"); - assert_eq!(config.line_length, 120 as usize); - assert_eq!(config.excludes.len(), 2 as usize); + assert_eq!(config.line_length, 120_usize); + assert_eq!(config.excludes.len(), 2_usize); } #[rstest] From b2ee7f3901f4d807839ea3a9fb8ea385ada70dd5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Riegel?= Date: Sun, 4 May 2025 14:05:30 +0200 Subject: [PATCH 25/30] cargo fmt --- benches/file-format-bench.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/benches/file-format-bench.rs b/benches/file-format-bench.rs index d1fd8b1..c48fff9 100644 --- a/benches/file-format-bench.rs +++ b/benches/file-format-bench.rs @@ -4,7 +4,13 @@ use std::path::PathBuf; fn criterion_benchmark(c: &mut Criterion) { c.bench_function("Format massive nu", |b| { - b.iter(|| format_single_file(PathBuf::from("./benches/example.nu"), &Config::default(), false)); + b.iter(|| { + format_single_file( + PathBuf::from("./benches/example.nu"), + &Config::default(), + false, + ) + }); }); } From c2e75c182fa16aef7979406741c4e28839f70839 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Riegel?= Date: Mon, 5 May 2025 00:10:31 +0200 Subject: [PATCH 26/30] replace colored by nu-ansi-term --- Cargo.lock | 18 +----------------- Cargo.toml | 2 +- src/main.rs | 36 +++++++++++++++++++++--------------- 3 files changed, 23 insertions(+), 33 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5aead09..bd358fb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -318,16 +318,6 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" -[[package]] -name = "colored" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "117725a109d387c937a1533ce01b450cbde6b88abceea8473c4d7a85853cda3c" -dependencies = [ - "lazy_static", - "windows-sys 0.59.0", -] - [[package]] name = "const_format" version = "0.2.34" @@ -815,12 +805,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "lazy_static" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" - [[package]] name = "libc" version = "0.2.172" @@ -1170,11 +1154,11 @@ name = "nufmt" version = "0.1.0" dependencies = [ "clap", - "colored", "criterion", "env_logger", "ignore", "log", + "nu-ansi-term", "nu-cmd-lang", "nu-parser", "nu-protocol", diff --git a/Cargo.toml b/Cargo.toml index f8aebc1..0d13171 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,10 +15,10 @@ categories = ["command-line-utilities"] [dependencies] clap = { version = "4.3.0", optional = true, features = ["unicode", "derive"] } -colored = "2" env_logger = "0.10.0" ignore = "0.4" log = "0.4.17" +nu-ansi-term = "0.50.1" nu-cmd-lang = "0.104.0" nu-parser = "0.104.0" nu-protocol = "0.104.0" diff --git a/src/main.rs b/src/main.rs index b8ef4b9..e2f64c8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -9,9 +9,9 @@ )] use clap::Parser; -use colored::*; use ignore::{overrides::OverrideBuilder, DirEntry, WalkBuilder}; use log::{info, trace}; +use nu_ansi_term::{Color, Style}; use nu_formatter::config::Config; use nu_formatter::config_error::ConfigError; use nu_formatter::FileDiagnostic; @@ -102,7 +102,7 @@ fn main() { Some(cli_config) => match read_config(&cli_config) { Ok(config) => config, Err(err) => { - eprintln!("{}: {}", "error".bright_red(), &err); + eprintln!("{}: {}", Color::LightRed.paint("error"), &err); return exit_with_code(ExitCode::Failure); } }, @@ -115,7 +115,7 @@ fn main() { let (target_files, invalid_files) = match discover_nu_files(cli.files, &config.excludes) { Ok(files) => files, Err(err) => { - eprintln!("{}: {}", "error".bright_red(), err); + eprintln!("{}: {}", Color::LightRed.paint("error"), err); return exit_with_code(ExitCode::Failure); } }; @@ -145,7 +145,11 @@ fn format_string(string: String, options: &Config) -> ExitCode { ExitCode::Success } Err(err) => { - eprintln!("{}: {}", "Could not format stdin".red(), err); + eprintln!( + "{}: {}", + Color::LightRed.paint("Could not format stdin"), + err + ); ExitCode::Failure } } @@ -198,20 +202,22 @@ fn display_diagnostic_and_compute_exit_code( for (file, result) in results { match result { FileDiagnostic::AlreadyFormatted => already_formatted += 1, - FileDiagnostic::ReformattedOrWouldFormat => { + FileDiagnostic::Reformatted => { reformatted_or_would_reformat += 1; if check { - warning_messages - .push(format!("Would reformat: {}", make_relative(file).bold())); + warning_messages.push(format!( + "Would reformat: {}", + Style::new().bold().paint(make_relative(file)) + )); }; } FileDiagnostic::Failure(reason) => { failures += 1; eprintln!( "{}: {} {}: {}", - "error".bright_red(), - file_failed_msg.bold(), - make_relative(file).bold(), + Color::LightRed.paint("error"), + Style::new().bold().paint(file_failed_msg), + Style::new().bold().paint(make_relative(file)), &reason ); at_least_one_failure = true; @@ -226,7 +232,7 @@ fn display_diagnostic_and_compute_exit_code( if already_formatted + reformatted_or_would_reformat + failures == 0 { print!( "{}: no Nushell files found under the given path(s)", - "warning".bright_yellow(), + Color::LightYellow.paint("warning"), ); return ExitCode::Success; } @@ -396,17 +402,17 @@ mod tests { (PathBuf::from("b.nu"), FileDiagnostic::AlreadyFormatted),], true, ExitCode::Success)] #[case(vec![ (PathBuf::from("a.nu"), FileDiagnostic::AlreadyFormatted), - (PathBuf::from("b.nu"), FileDiagnostic::ReformattedOrWouldFormat),], false, ExitCode::Success)] + (PathBuf::from("b.nu"), FileDiagnostic::Reformatted),], false, ExitCode::Success)] #[case(vec![ (PathBuf::from("a.nu"), FileDiagnostic::AlreadyFormatted), - (PathBuf::from("b.nu"), FileDiagnostic::ReformattedOrWouldFormat),], true, ExitCode::CheckFailed)] + (PathBuf::from("b.nu"), FileDiagnostic::Reformatted),], true, ExitCode::CheckFailed)] #[case(vec![ (PathBuf::from("a.nu"), FileDiagnostic::AlreadyFormatted), - (PathBuf::from("b.nu"), FileDiagnostic::ReformattedOrWouldFormat), + (PathBuf::from("b.nu"), FileDiagnostic::Reformatted), (PathBuf::from("c.nu"), FileDiagnostic::Failure("some error".to_string())),], false, ExitCode::Failure)] #[case(vec![ (PathBuf::from("a.nu"), FileDiagnostic::AlreadyFormatted), - (PathBuf::from("b.nu"), FileDiagnostic::ReformattedOrWouldFormat), + (PathBuf::from("b.nu"), FileDiagnostic::Reformatted), (PathBuf::from("c.nu"), FileDiagnostic::Failure("some error".to_string())),], true, ExitCode::Failure)] fn exit_code( #[case] results: Vec<(PathBuf, FileDiagnostic)>, From 7639b67894876624918b530e9ccc64236ae15d13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Riegel?= Date: Mon, 5 May 2025 00:13:09 +0200 Subject: [PATCH 27/30] some renamings --- src/lib.rs | 8 ++++---- src/main.rs | 18 +++++++++--------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index cd536fe..34ca844 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -21,7 +21,7 @@ pub enum FileDiagnostic { AlreadyFormatted, /// File was formatted successfully /// In check mode, file would be reformatted if check mode was off - ReformattedOrWouldFormat, + Reformatted, /// An error occurred while trying to access or write to the file Failure(String), } @@ -31,7 +31,7 @@ pub enum FileDiagnostic { pub fn format_single_file( file: PathBuf, config: &Config, - check: bool, + check_mode: bool, ) -> (PathBuf, FileDiagnostic) { let contents = match std::fs::read(&file) { Ok(content) => content, @@ -52,7 +52,7 @@ pub fn format_single_file( return (file, FileDiagnostic::AlreadyFormatted); } - if !check { + if !check_mode { let mut writer = match File::create(&file) { Ok(file) => file, Err(err) => { @@ -65,7 +65,7 @@ pub fn format_single_file( } debug!("File formatted."); } - (file, FileDiagnostic::ReformattedOrWouldFormat) + (file, FileDiagnostic::Reformatted) } /// format a string of Nushell code diff --git a/src/main.rs b/src/main.rs index e2f64c8..10e06c5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -171,13 +171,13 @@ fn handle_invalid_file(files: Vec) -> Vec<(PathBuf, FileDiagnostic)> { fn format_files( files: Vec, options: &Config, - check: bool, + check_mode: bool, ) -> Vec<(PathBuf, FileDiagnostic)> { files .into_par_iter() .map(|file| { info!("formatting file: {:?}", &file); - nu_formatter::format_single_file(file, options, check) + nu_formatter::format_single_file(file, options, check_mode) }) .collect() } @@ -185,7 +185,7 @@ fn format_files( /// Display results and return the appropriate exit code after formatting in check mode fn display_diagnostic_and_compute_exit_code( results: &[(PathBuf, FileDiagnostic)], - check: bool, + check_mode: bool, ) -> ExitCode { let mut already_formatted: usize = 0; let mut reformatted_or_would_reformat: usize = 0; @@ -193,7 +193,7 @@ fn display_diagnostic_and_compute_exit_code( let mut at_least_one_failure = false; let mut warning_messages: Vec = vec![]; - let file_failed_msg = if check { + let file_failed_msg = if check_mode { "Failed to check" } else { "Failed to format" @@ -204,7 +204,7 @@ fn display_diagnostic_and_compute_exit_code( FileDiagnostic::AlreadyFormatted => already_formatted += 1, FileDiagnostic::Reformatted => { reformatted_or_would_reformat += 1; - if check { + if check_mode { warning_messages.push(format!( "Would reformat: {}", Style::new().bold().paint(make_relative(file)) @@ -238,7 +238,7 @@ fn display_diagnostic_and_compute_exit_code( } if reformatted_or_would_reformat > 0 { - let msg = if check { + let msg = if check_mode { "would be reformatted" } else { "were formatted" @@ -263,7 +263,7 @@ fn display_diagnostic_and_compute_exit_code( }; if at_least_one_failure { ExitCode::Failure - } else if check && reformatted_or_would_reformat > 0 { + } else if check_mode && reformatted_or_would_reformat > 0 { ExitCode::CheckFailed } else { ExitCode::Success @@ -416,10 +416,10 @@ mod tests { (PathBuf::from("c.nu"), FileDiagnostic::Failure("some error".to_string())),], true, ExitCode::Failure)] fn exit_code( #[case] results: Vec<(PathBuf, FileDiagnostic)>, - #[case] check: bool, + #[case] check_mode: bool, #[case] expected: ExitCode, ) { - let exit_code = display_diagnostic_and_compute_exit_code(&results, check); + let exit_code = display_diagnostic_and_compute_exit_code(&results, check_mode); assert_eq!(exit_code, expected); } } From 36867ddb9ec1bc43b78edee87c2152fd04bd1436 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Riegel?= Date: Thu, 8 May 2025 22:50:05 +0200 Subject: [PATCH 28/30] replace --check by --dry-run, and create Mode enum --- README.md | 2 +- src/lib.rs | 41 ++++++++++++++++++++++++++--------------- src/main.rs | 18 ++++++++++++------ tests/main.rs | 6 +++--- 4 files changed, 42 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index 0f93e2a..e8a3a79 100644 --- a/README.md +++ b/README.md @@ -60,7 +60,7 @@ nufmt my-file1.nu my-file2.nu my-file3.nu ### Options -- `--check` if you just want to check files without formatting them. It cannot be combined with stdin. +- `--dry-run` if you just want to check files without formatting them. It cannot be combined with stdin. - `-s` or `--stdin` formats from `stdin`, returns to `stdout` as a String. It cannot be used combined with `files`. - `-c` or `--config` pass the config file path. Sample: diff --git a/src/lib.rs b/src/lib.rs index 34ca844..5f4353f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -14,24 +14,30 @@ pub mod config_error; pub mod format_error; mod formatting; -/// The possible outcome of checking or formatting a file +/// Possible modes the formatter can run on +#[derive(Debug, Clone, Default, PartialEq, Eq)] +pub enum Mode { + #[default] + Normal, + DryRun, +} + +/// The possible outcome of formatting a file #[derive(Debug, Clone, PartialEq, Eq)] pub enum FileDiagnostic { /// File was left unchanged, as it is already correctly formatted AlreadyFormatted, /// File was formatted successfully - /// In check mode, file would be reformatted if check mode was off Reformatted, /// An error occurred while trying to access or write to the file Failure(String), } -/// format or check a Nushell file in place -/// only check the file (do not write) in check mode +/// format a Nushell file in place. Do not write in dry-run mode. pub fn format_single_file( file: PathBuf, config: &Config, - check_mode: bool, + mode: &Mode, ) -> (PathBuf, FileDiagnostic) { let contents = match std::fs::read(&file) { Ok(content) => content, @@ -52,19 +58,24 @@ pub fn format_single_file( return (file, FileDiagnostic::AlreadyFormatted); } - if !check_mode { - let mut writer = match File::create(&file) { - Ok(file) => file, - Err(err) => { + match mode { + Mode::DryRun => { + debug!("File not formatted because running in dry run, but would be reformatted in normal mode."); + } + Mode::Normal => { + let mut writer = match File::create(&file) { + Ok(file) => file, + Err(err) => { + return (file, FileDiagnostic::Failure(err.to_string())); + } + }; + let file_bytes = formatted_bytes.as_slice(); + if let Err(err) = writer.write_all(file_bytes) { return (file, FileDiagnostic::Failure(err.to_string())); } - }; - let file_bytes = formatted_bytes.as_slice(); - if let Err(err) = writer.write_all(file_bytes) { - return (file, FileDiagnostic::Failure(err.to_string())); + debug!("File formatted."); } - debug!("File formatted."); - } + }; (file, FileDiagnostic::Reformatted) } diff --git a/src/main.rs b/src/main.rs index 10e06c5..1ca5488 100644 --- a/src/main.rs +++ b/src/main.rs @@ -15,6 +15,7 @@ use nu_ansi_term::{Color, Style}; use nu_formatter::config::Config; use nu_formatter::config_error::ConfigError; use nu_formatter::FileDiagnostic; +use nu_formatter::Mode; use rayon::iter::{IntoParallelIterator, ParallelIterator}; use std::convert::TryFrom; use std::{ @@ -65,11 +66,11 @@ struct Cli { conflicts_with = "stdin", help = "Avoid writing any formatted files back; instead, exit with a non-zero status code if any files would have been modified, and zero otherwise" )] - check: bool, + dry_run: bool, #[arg( long, - conflicts_with = "check", + conflicts_with = "dry_run", conflicts_with = "files", help = "A string of Nushell directly given to the formatter" )] @@ -119,9 +120,14 @@ fn main() { return exit_with_code(ExitCode::Failure); } }; + let mode = if cli.dry_run { + Mode::DryRun + } else { + Mode::default() + }; let mut results = handle_invalid_file(invalid_files); - results.extend(format_files(target_files, &config, cli.check)); - display_diagnostic_and_compute_exit_code(&results, cli.check) + results.extend(format_files(target_files, &config, &mode)); + display_diagnostic_and_compute_exit_code(&results, cli.dry_run) }; std::io::stdout() @@ -171,13 +177,13 @@ fn handle_invalid_file(files: Vec) -> Vec<(PathBuf, FileDiagnostic)> { fn format_files( files: Vec, options: &Config, - check_mode: bool, + mode: &Mode, ) -> Vec<(PathBuf, FileDiagnostic)> { files .into_par_iter() .map(|file| { info!("formatting file: {:?}", &file); - nu_formatter::format_single_file(file, options, check_mode) + nu_formatter::format_single_file(file, options, mode) }) .collect() } diff --git a/tests/main.rs b/tests/main.rs index a1bee14..c19811d 100644 --- a/tests/main.rs +++ b/tests/main.rs @@ -57,7 +57,7 @@ fn warning_when_no_files_are_detected() { let dir = tempdir().unwrap(); let output = Command::new("target/debug/nufmt") - .arg("--check") + .arg("--dry-run") .arg(dir.path().to_str().unwrap()) .output() .unwrap(); @@ -78,7 +78,7 @@ fn warning_is_displayed_when_no_files_are_detected_with_excluded_files() { let output = Command::new("target/debug/nufmt") .arg("--config") .arg(config_file.to_str().unwrap()) - .arg("--check") + .arg("--dry-run") .arg(dir.path().to_str().unwrap()) .output() .unwrap(); @@ -125,7 +125,7 @@ fn files_are_checked() { let output = Command::new("target/debug/nufmt") .arg("--config") .arg(config_file.to_str().unwrap()) - .arg("--check") + .arg("--dry-run") .arg(dir.path().to_str().unwrap()) .output() .unwrap(); From 5b580141cffbe08db31c8c7324bfb692c27a064a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Riegel?= Date: Thu, 8 May 2025 22:52:54 +0200 Subject: [PATCH 29/30] fix Mode in benches --- benches/file-format-bench.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/benches/file-format-bench.rs b/benches/file-format-bench.rs index c48fff9..922504b 100644 --- a/benches/file-format-bench.rs +++ b/benches/file-format-bench.rs @@ -1,5 +1,5 @@ use criterion::{criterion_group, criterion_main, Criterion}; -use nu_formatter::{config::Config, format_single_file}; +use nu_formatter::{Mode, config::Config, format_single_file}; use std::path::PathBuf; fn criterion_benchmark(c: &mut Criterion) { @@ -8,7 +8,7 @@ fn criterion_benchmark(c: &mut Criterion) { format_single_file( PathBuf::from("./benches/example.nu"), &Config::default(), - false, + &Mode::Normal, ) }); }); From b32204b9914ebb14fa2081dec45deb53d9e52b01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Riegel?= Date: Thu, 8 May 2025 22:53:44 +0200 Subject: [PATCH 30/30] cargo fmt --- benches/file-format-bench.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/benches/file-format-bench.rs b/benches/file-format-bench.rs index 922504b..6751bda 100644 --- a/benches/file-format-bench.rs +++ b/benches/file-format-bench.rs @@ -1,5 +1,5 @@ use criterion::{criterion_group, criterion_main, Criterion}; -use nu_formatter::{Mode, config::Config, format_single_file}; +use nu_formatter::{config::Config, format_single_file, Mode}; use std::path::PathBuf; fn criterion_benchmark(c: &mut Criterion) {