forked from extern/nushell
Compare commits
978 Commits
Author | SHA1 | Date | |
---|---|---|---|
0bdb6e735a | |||
7933e01e77 | |||
b443a2d713 | |||
7a28ababd1 | |||
ddb9d3a864 | |||
186b75a848 | |||
8cedd2ee5b | |||
2e4b0b0b17 | |||
9f42d7693f | |||
3424334ce5 | |||
c68d236fd7 | |||
7c6e82c990 | |||
eb5d0d295b | |||
2eae5a2a89 | |||
595c9f2999 | |||
70d63e34e9 | |||
83ac65ced3 | |||
be140382cf | |||
d320ffe742 | |||
fbc6f01cfb | |||
3008434c0f | |||
5fbea31d15 | |||
f70c6d5d48 | |||
71e7eb7cfc | |||
339ec46961 | |||
fe53c37654 | |||
06857fbc52 | |||
1c830b5c95 | |||
a74145961e | |||
91698b2657 | |||
40fd8070a9 | |||
4d5f1f6023 | |||
bc2d65cd2e | |||
1a0b339897 | |||
8d3a937413 | |||
e85e1b2c9e | |||
c8aa8cb842 | |||
88c4473283 | |||
f4d9975dab | |||
6e8b768d79 | |||
cdb0eeafa2 | |||
388fc24191 | |||
b3c021899c | |||
bff50c6987 | |||
111fcf188e | |||
015693aea7 | |||
03a52f1988 | |||
372f6c16b3 | |||
c04da4c232 | |||
a070cb8154 | |||
bf4273776f | |||
95ca3ed4fa | |||
54c0603263 | |||
c598cd4255 | |||
2bb03d9813 | |||
9c41f581a9 | |||
6231367bc8 | |||
a7d7098b1a | |||
90aeb700ea | |||
9dfc647386 | |||
f992f5de95 | |||
946f7256e4 | |||
57d425d929 | |||
dd36bf07f4 | |||
406fb8d1d9 | |||
2d4a225e2a | |||
db218e06dc | |||
17e8a5ce38 | |||
07db14f72e | |||
412831cb9c | |||
f4dc79f4ba | |||
9cb573b3b4 | |||
ce106bfda9 | |||
a3ffc4baf0 | |||
3c3637b674 | |||
bcecd08825 | |||
55f99073ad | |||
008c60651c | |||
63667d9e46 | |||
08b770719c | |||
e0d27ebf84 | |||
0756145caf | |||
036860770b | |||
aa1ef39da3 | |||
7c8969d4ea | |||
87d58535ff | |||
1060ba2206 | |||
0401087175 | |||
f8dc06ef49 | |||
282cb46ff1 | |||
a3ff5f1246 | |||
5bb822dcd4 | |||
00b3c2036a | |||
3163b0d362 | |||
21f48577ae | |||
11e4410d1c | |||
27a950d28e | |||
f3d056110a | |||
b39c2e2f75 | |||
7cf3c6eb95 | |||
cdec0254ec | |||
02f3330812 | |||
6f013d0225 | |||
1f06f57de3 | |||
0f405f24c7 | |||
5a8128dd30 | |||
50616cc62c | |||
9d345cab07 | |||
59ab11e932 | |||
df302d4bac | |||
6bbfd0f4f6 | |||
943e0045e7 | |||
62a5250554 | |||
9043970e97 | |||
d32c9ce1b6 | |||
73d8478678 | |||
bab58576b4 | |||
41212c1ad1 | |||
4a6122905b | |||
15986c598a | |||
078342442d | |||
8855c54391 | |||
5dfc81a157 | |||
c42d97fb97 | |||
13314ad1e7 | |||
ff6026ca79 | |||
c6c6c0f295 | |||
1cca5557b1 | |||
76208110b9 | |||
56dd0282f0 | |||
c01b602b86 | |||
d6f46236e9 | |||
104b30142f | |||
f3a885d920 | |||
60445b0559 | |||
01d6287a8f | |||
0462b2db80 | |||
4cb399ed70 | |||
7ef9f7702f | |||
44a1686a76 | |||
15c6d24178 | |||
3b84e3ccfe | |||
da7d6beb22 | |||
f012eb7bdd | |||
f966394b63 | |||
889d2bb378 | |||
a2c4e485ba | |||
8860d8de8d | |||
d7b768ee9f | |||
6ea8e42331 | |||
1b784cb77a | |||
4a0ec1207c | |||
ffb2fedca9 | |||
382b1ba85f | |||
3b42655b51 | |||
e43e906f86 | |||
e51d9d0935 | |||
f57489ed92 | |||
503e521820 | |||
c317094947 | |||
243df63978 | |||
05ff102e09 | |||
cd30fac050 | |||
f589d3c795 | |||
51879d022e | |||
2260b3dda3 | |||
aa64442453 | |||
129ee45944 | |||
2fe7d105b0 | |||
136c8acba6 | |||
e92d4b2ccb | |||
6e91c96dd7 | |||
7801c03e2d | |||
763bbe1c01 | |||
0f67569cc3 | |||
0ea3527544 | |||
20dfca073f | |||
a3679f0f4e | |||
e75fdc2865 | |||
4be88ff572 | |||
992789af26 | |||
b822e13f12 | |||
cd058db046 | |||
1b3143d3d4 | |||
e31ed66610 | |||
7f18ff10b2 | |||
65ae24fbf1 | |||
b54ce921dd | |||
4935129c5a | |||
7614ce4b49 | |||
9d34ec9153 | |||
fd92271884 | |||
cea8fab307 | |||
2d44b7d296 | |||
faccb0627f | |||
a9cd6b4f7a | |||
81691e07c6 | |||
26f40dcabc | |||
3820fef801 | |||
392ff286b2 | |||
b6824d8b88 | |||
e09160e80d | |||
8ba5388438 | |||
30b6eac03d | |||
17ad07ce27 | |||
53911ebecd | |||
bc309705a9 | |||
1de80aeac3 | |||
1eaaf368ee | |||
36e40ebb85 | |||
3f600c5b82 | |||
fbd980f8b0 | |||
7d383421c6 | |||
aed386b3cd | |||
540cc4016e | |||
1b3a09495d | |||
b7af34371b | |||
105762e1c3 | |||
2706ae076d | |||
07ceec3e0b | |||
72fd1b047f | |||
178b6d4d8d | |||
d160e834eb | |||
3e8b9e7e8b | |||
c34ebfe739 | |||
571b33a11c | |||
07b90f4b4b | |||
f1630da2cc | |||
16751b5dee | |||
29ec9a436a | |||
6a7c00eaef | |||
82b24d9beb | |||
a317072e4e | |||
5b701cd197 | |||
8f035616a0 | |||
81f8ba9e4c | |||
380ab19910 | |||
4329629ee9 | |||
39fde52d8e | |||
0611f56776 | |||
8923e91e39 | |||
d6e6811bb9 | |||
f24bc5c826 | |||
c209d0d487 | |||
74dddc880d | |||
f3c41bbdf1 | |||
c45ddc8f22 | |||
84a98995bf | |||
ed83449514 | |||
9eda573a43 | |||
4f91d2512a | |||
2f5eeab567 | |||
f9fbb0eb3c | |||
43fbf4345d | |||
8262c2dd33 | |||
0e86430ea3 | |||
fc1301c92d | |||
e913e26c01 | |||
5ce4b12cc1 | |||
94429d781f | |||
321629a693 | |||
f21405399c | |||
305ca11eb5 | |||
9b1ff9b566 | |||
a0ed6ea3c8 | |||
4a6529973e | |||
9a02fac0e5 | |||
2c6a9e9e48 | |||
d91b735442 | |||
7d3025176f | |||
74111dddb7 | |||
74b0e4e541 | |||
587bb13be5 | |||
79d3237bf5 | |||
f8d44e732b | |||
0d2044e72e | |||
1bb301aafa | |||
5635b8378d | |||
294c2c600d | |||
b4c639a5d9 | |||
e7b37bee08 | |||
d32e97b812 | |||
81affaa584 | |||
f2d54f201d | |||
0373006710 | |||
ec2e35ad81 | |||
821ee5e726 | |||
5ed1ed54a6 | |||
96ef478fbc | |||
3f60c9d416 | |||
ed39377840 | |||
e250a3f213 | |||
3a99456371 | |||
bd6d8189f8 | |||
452b5c58e8 | |||
d1ebc55ed7 | |||
f20f3f56c7 | |||
65008bb912 | |||
d21389d549 | |||
f858a127ad | |||
de12393eaf | |||
b2c53a0967 | |||
65546646a7 | |||
ee8cd671cb | |||
d4df70c53f | |||
43ead45db6 | |||
22d2360c4b | |||
d38b8cf851 | |||
43cf52275b | |||
104b7824f5 | |||
a9293f62a8 | |||
0b210ce5bf | |||
38225d0dba | |||
473b6f727c | |||
63039666b0 | |||
a4a1588fbc | |||
4eafb22d5b | |||
aa09967173 | |||
7c40aed738 | |||
6c0bf6e0ab | |||
20e891db6e | |||
38b5979881 | |||
8422d40e2c | |||
de1c4e6c88 | |||
648d4865b1 | |||
7d4fec4db3 | |||
0f7e73646f | |||
bd6ca75032 | |||
341cc1ea63 | |||
2716bb020f | |||
193b00764b | |||
8ca678440a | |||
439889dcef | |||
5ec6bac7d9 | |||
af2ec60980 | |||
f0ca0312f3 | |||
3317b137e5 | |||
c2c10e2bc0 | |||
d2eb6f6646 | |||
1ad9d6f199 | |||
f8d337ad29 | |||
47150efc14 | |||
3e14de158b | |||
e18892000a | |||
c8671c719f | |||
0412c3a2f8 | |||
ef3e8eb778 | |||
fb8cfeb70d | |||
4d70255696 | |||
77c34acb03 | |||
e72bc8ea8b | |||
a882e640e4 | |||
c09d866a77 | |||
4467e59122 | |||
9c096d320a | |||
93ae5043cc | |||
b134394319 | |||
b163775112 | |||
8bd035f51d | |||
9f15017032 | |||
81fec11f88 | |||
8a6a688131 | |||
77a4de31fa | |||
09e88d127e | |||
7ff5734d5d | |||
1d19595996 | |||
7d115da782 | |||
b066775630 | |||
8bb6bcb6eb | |||
20031861b9 | |||
eb297d3b8f | |||
8faa0126eb | |||
6aec03708f | |||
2f7b1e4282 | |||
7492131142 | |||
3c6ee63e59 | |||
45ad18f654 | |||
01829f04d5 | |||
cc1c471877 | |||
de14f9fce8 | |||
6c3ed1dbc2 | |||
cf0fa3141a | |||
539e232f3c | |||
9ed889ccbb | |||
872e26b524 | |||
5bfff0c39b | |||
0505a9d6f7 | |||
9181a046ec | |||
1b0eaac470 | |||
e54cd98a9c | |||
f3eb4fb24e | |||
04854d5d99 | |||
124a814f4d | |||
2e1670fcb8 | |||
7d2747ea9a | |||
36f2b09cad | |||
be51aad9ad | |||
97695b74dd | |||
9d84e47214 | |||
9fb9adb6b4 | |||
91e6d31dc6 | |||
9a1c537854 | |||
2476c8d579 | |||
27e59ea49c | |||
27882efd6b | |||
5e98751c66 | |||
8dec2da564 | |||
27272d3754 | |||
f689434bbc | |||
03728c1868 | |||
ce771903e5 | |||
c78bce2af4 | |||
0b3c9b760e | |||
7e7eba8f4d | |||
a77c222db0 | |||
149961e8f1 | |||
caf3015e66 | |||
459bfdd783 | |||
a2f1cca85c | |||
c09b4b045f | |||
94d81445eb | |||
94744c626c | |||
e62a2509ae | |||
417ac4b69e | |||
b7bf31df99 | |||
a7a0f48286 | |||
1bf0f7110a | |||
ad53eb4e76 | |||
c81d20a069 | |||
08df76486d | |||
fe3753ea68 | |||
abf671da1b | |||
91b4d27931 | |||
310897897e | |||
8ba917b704 | |||
219da892b2 | |||
bbb4cc7d5f | |||
9d04a7cc40 | |||
70d0ae7b42 | |||
ce9e4a61e7 | |||
af8e2f6961 | |||
093b9c1c5b | |||
348d75112f | |||
3c7b1ba854 | |||
b7a8758845 | |||
3812037e2a | |||
c5fdbdb8a1 | |||
c15b5df674 | |||
00f0fd2873 | |||
7269cf7427 | |||
83d82a09b2 | |||
64345b2985 | |||
9c23d78513 | |||
ff92123d93 | |||
e1357a9541 | |||
3b7aa5124c | |||
ce947d70b0 | |||
caed87c125 | |||
e12ba5be8f | |||
d52e087453 | |||
982ebacddd | |||
ee2f54fbb0 | |||
4f5c0314cf | |||
542a3995ea | |||
4af0dbe441 | |||
78ccd4181c | |||
680aeb12c2 | |||
ddcf0b4f5f | |||
74e60fbef8 | |||
b4c783f23d | |||
6f6d2abdac | |||
b123f35d4b | |||
02d6614ae2 | |||
20de0ea01f | |||
9f352ace23 | |||
48cbc5b23c | |||
aa495f4d74 | |||
0d8768b827 | |||
0d076d97be | |||
5b5c33a86f | |||
12f34cc698 | |||
ac116f4f7c | |||
6617731d5b | |||
f7d5ddbc07 | |||
ba778eaff9 | |||
1801c006ec | |||
7a124518c3 | |||
1183d28b15 | |||
1da6ac8de7 | |||
2b89ddfb9e | |||
29734a1dce | |||
def33206d9 | |||
6aad0b8443 | |||
9891e5ab81 | |||
7113c702ff | |||
54edf571af | |||
f85968aba4 | |||
440f553aa8 | |||
a492b019fe | |||
2941740df6 | |||
f0b638063d | |||
0377efdc16 | |||
3d89d2961c | |||
8c240ca3fd | |||
85cd03f899 | |||
3480cdb3b4 | |||
fec83e5164 | |||
837d12decd | |||
ffa536bea3 | |||
3f8448da0d | |||
8ce73d838e | |||
574cd1101a | |||
15481b7be1 | |||
60b7da8ea7 | |||
3dd48bf831 | |||
2de7792939 | |||
a1f26d947d | |||
09e3f9c11b | |||
898b99d7c2 | |||
c7b9db0523 | |||
95ea3fcf4e | |||
7d41ac54b5 | |||
c720cc00e3 | |||
f99d38ead4 | |||
08fe603e81 | |||
cbba37a6b1 | |||
b8964bd320 | |||
630ff2495f | |||
51b8b0538a | |||
ccb6dc264e | |||
e6bdef696d | |||
3c2666a2df | |||
707af3f3ca | |||
480467447e | |||
d7d2a7ee77 | |||
9623a255c4 | |||
db3b2595e6 | |||
112e5d096f | |||
484d8c26ac | |||
df7a3a4863 | |||
70ac2381c5 | |||
d7e7f48aaa | |||
8d5b1ad233 | |||
639a316677 | |||
0c9a62aeec | |||
0a0be19bed | |||
1c95bf05dc | |||
1e3549571c | |||
44b7e07569 | |||
a96836facb | |||
85a5ed70b1 | |||
6acb2a9f9c | |||
5ff94004c6 | |||
a8e2801e0b | |||
c9310265fe | |||
4017f67855 | |||
3659e51163 | |||
72e6222992 | |||
2cf7249794 | |||
0beb067211 | |||
a54afd1747 | |||
f6b82e4c0c | |||
1b42438e8f | |||
7fbd6ce232 | |||
4ad249694f | |||
60dbca8bc6 | |||
17855d37a4 | |||
c9db3c498b | |||
8a6c700478 | |||
f4dfdab4e4 | |||
88c1b1dc6f | |||
6bb277baaa | |||
91bea7fb2a | |||
dc4421c07d | |||
fe993fa0ff | |||
2b88f1eed0 | |||
17d2a27350 | |||
19767ad551 | |||
ab915f1c44 | |||
0afda5c466 | |||
417916d2da | |||
4922028d69 | |||
52e71cad18 | |||
9382a7e64a | |||
da31eac735 | |||
579c7ff6d6 | |||
6551498b7b | |||
074a76c9d4 | |||
53cb40d8f6 | |||
4b8d0d62eb | |||
ea10d4dc0e | |||
b11a4535bd | |||
970cc3c24d | |||
d0d56deaf1 | |||
ea3b3e42c4 | |||
4dfebae136 | |||
d629686a4b | |||
189877e4dd | |||
a215997dcd | |||
6fe211fdbe | |||
f326680cad | |||
c2eefece0e | |||
7838dac689 | |||
39489a75aa | |||
e4ed8c94ad | |||
c57c0eb371 | |||
b35549adac | |||
4edc7422cd | |||
3fca94cf66 | |||
206998a41a | |||
1f3f3d3105 | |||
5ca075e38b | |||
dbefbcb046 | |||
9dc58247e5 | |||
3c9a0e0e1a | |||
127381497c | |||
53cfa09cd2 | |||
bee7c5639c | |||
f05c7d6792 | |||
4c2796f11c | |||
58b7800172 | |||
62e6cc4dae | |||
095e5ac69f | |||
149ccc4fd3 | |||
f47349c1a0 | |||
540e93aa3a | |||
b15bb2c667 | |||
191cc96b14 | |||
ba8383ae2f | |||
ae74ba5bb0 | |||
2dcbf78385 | |||
11ef007491 | |||
f61144006f | |||
45201cb284 | |||
d4240ffb4d | |||
7e2d701725 | |||
4d3e7efe25 | |||
35522ec6d8 | |||
aea11cf742 | |||
d1167151fc | |||
6b2a7d6793 | |||
4a2172a7f2 | |||
8e3b7e2373 | |||
1d3483b590 | |||
1277bfe0fb | |||
cf2c19706e | |||
0ca7aaa56f | |||
7c541000a1 | |||
1878bb8a54 | |||
d900d8b4c7 | |||
da6d6467f3 | |||
99d5dae83a | |||
4ce6a9c9f7 | |||
24ba0d93c7 | |||
f6f9507141 | |||
160bd7c535 | |||
d992086192 | |||
fa53d59aee | |||
21896b200c | |||
c9c9112155 | |||
6f13bf8b51 | |||
f770409a60 | |||
77c2e4200e | |||
207f9ece5a | |||
df9ff44956 | |||
ffd92362b0 | |||
448b1a4848 | |||
eecda3ecba | |||
159cf27e39 | |||
07151b8360 | |||
9da896ad4e | |||
84628f298d | |||
4cdaed1ad4 | |||
6c5da7d5a7 | |||
7427ea51df | |||
7913ae76f8 | |||
90b358d60b | |||
ee301f9f54 | |||
8be14a891d | |||
ffaf17945d | |||
28fe31d565 | |||
e2b9370f10 | |||
452f96a836 | |||
ea24571c22 | |||
1b2fdf7c1e | |||
35c0eb0059 | |||
19f97e6471 | |||
42489c1aab | |||
085973e2db | |||
b14fd12e47 | |||
98d826d1d6 | |||
b84c77d23a | |||
dcd97b6346 | |||
39fce1191f | |||
e8764911cb | |||
ede45e21de | |||
fd715e1775 | |||
0a9897c5ca | |||
60212611e5 | |||
6034de641a | |||
4591397fa3 | |||
6dad1c9be8 | |||
479f0a566e | |||
7a5fc82ee0 | |||
05e858fa94 | |||
1f05e98965 | |||
ab48d3a3f2 | |||
c6c4d4ddb1 | |||
a2b3e4c9d7 | |||
ab97459d0e | |||
5b706599e9 | |||
a2700308a7 | |||
3256b7adb3 | |||
1d0ed7e957 | |||
68cdeaf8ac | |||
b031d4cd77 | |||
030d73147e | |||
a449d2c005 | |||
6a8dddedc3 | |||
b0a02518f9 | |||
9e3d14cbbf | |||
8a9cdcab17 | |||
fa859f1461 | |||
7bd2fa1bfc | |||
1464feaab7 | |||
cf0efb811e | |||
35d576f540 | |||
225ef8e75d | |||
cc8872b4ee | |||
9ba2e75ac1 | |||
e8880a1a57 | |||
9b3a561e83 | |||
d5494e58a4 | |||
4a00887e9d | |||
95feb1ff16 | |||
3d912a2c1d | |||
556f4b2f12 | |||
2cb290b77b | |||
7fa09f59c2 | |||
246c9c06dc | |||
9773f8fbab | |||
9488c41dcd | |||
ca0183a136 | |||
3d5e31c55d | |||
8a29c9e6ab | |||
510ecaa77b | |||
113c2c380f | |||
bbde86c20d | |||
2dc78b2caf | |||
a69a0bc5ee | |||
e8bbd330e0 | |||
79a779dbea | |||
5491b54859 | |||
36c181706d | |||
f9d54c2f25 | |||
90f190e54a | |||
abfd417430 | |||
6e0cb6b809 | |||
9de1d9b782 | |||
ad3234a9a0 | |||
8504c7a8e6 | |||
8523ce3d01 | |||
2d8b558ac0 | |||
7d46f9e860 | |||
9e17b937c3 | |||
acdecdbb04 | |||
bf19dff602 | |||
a7e378d1c9 | |||
dd3c149615 | |||
ca0c6eaf58 | |||
ce2d247367 | |||
1a67ac6102 | |||
70ebe899c6 | |||
ed8896e828 | |||
00c5adda80 | |||
b514d93ffd | |||
5b7940b88c | |||
f5db3276b9 | |||
90daf0a486 | |||
423ccbe6c2 | |||
0d6b85b5bf | |||
6e932c471d | |||
ad18c7f61a | |||
6f5ddbd6ae | |||
138b5af82b | |||
1d77595576 | |||
f274df6753 | |||
2470e6dc24 | |||
339cf98dd1 | |||
2cde4da43f | |||
2cec8168c7 | |||
bf03b530c9 | |||
761cc3db14 | |||
3d147d1143 | |||
fa2c6ec227 | |||
4cde96bcc4 | |||
481722b80a | |||
a4fa5628ea | |||
c3abb3b687 | |||
60bfa277d0 | |||
9e167713b3 | |||
39e06bbc80 | |||
d870060018 | |||
213db54378 | |||
d1f70aff73 | |||
3fba30f2dc | |||
729051fdd2 | |||
605618bef8 | |||
8db21ddf99 | |||
1f9d5f9f89 | |||
5d47ad386e | |||
2c4777d2b5 | |||
8d21c7383e | |||
5ef70c5f01 | |||
2983fc1dea | |||
f81dbee5f9 | |||
6d0ea5eda4 | |||
2ae7528328 | |||
40ca353c48 | |||
ebce7231a2 | |||
58a32490c5 | |||
f393938515 | |||
e5d67d5481 | |||
b6db233c73 | |||
0b2f3a4924 | |||
31dd643642 | |||
7df48110ab | |||
ffdde542c7 | |||
c87fa14fc8 | |||
6638fe4ab3 | |||
f1e8c433c2 | |||
f050908084 | |||
9810df25b4 | |||
f730296e45 | |||
fcc41af899 | |||
a42cf7bf6e | |||
4576570275 | |||
e0a13de943 | |||
b94b38b4f4 | |||
4d2b0f43f5 | |||
a07817e0e0 | |||
b6ec98ce64 | |||
012d8f3d6f | |||
b283b83fe2 | |||
696c986db1 | |||
846e487663 | |||
55fb1f8dda | |||
3e72c3eca9 | |||
a7d4a8b065 | |||
7ca95ba9dd | |||
f82cc4291f | |||
abac7cf746 | |||
2c65b2fc2f | |||
21ad06b1e1 | |||
94752a3004 | |||
a1b30fda75 | |||
8e95508353 | |||
2bae2b57ee | |||
dfe452bbc4 | |||
34c042c4fc | |||
3827ded43f | |||
6d30acf542 | |||
4ebab3474b | |||
9aab884db0 | |||
f59b78a764 | |||
14f6b49483 | |||
162c8b4274 | |||
b502954558 | |||
247a4417ff | |||
1cdfe358c2 | |||
1dc1b0d071 | |||
570a0ac275 | |||
1d64d90419 | |||
3750a04cfc | |||
34292b282a | |||
5313fc5568 | |||
505fadd6d1 | |||
716517c13f | |||
738675259e | |||
87a99bbabf | |||
e32291d0d7 | |||
3e699db57c | |||
91093f2ab2 | |||
69492a10fe | |||
ce0113eb19 | |||
ca11dc2031 | |||
b77effa434 | |||
3514c77aac | |||
9a31a6c296 | |||
d51e12c69d | |||
8445cda291 | |||
bbe7d68659 | |||
628da27122 | |||
033cae2464 | |||
bc91c7f8b1 | |||
8ff418dc00 | |||
8da82c79b8 | |||
8940e57cf3 | |||
9761621879 | |||
30187e0311 | |||
7639fac1e7 | |||
f911e63765 | |||
04d2371cd6 | |||
472ff74904 | |||
ec0bc00253 | |||
12e3806349 | |||
dda4a707a7 | |||
0e14ba86ae | |||
de930daf33 | |||
3c89cb7e98 | |||
9735c3fcea | |||
376809aa2a | |||
a75c90cc42 | |||
c967f15e7c | |||
b0d7daa0d6 | |||
e9673c31ea | |||
a3b4d47b4e | |||
722e192c14 | |||
9814eeae30 | |||
a0f0372839 | |||
93a1a0604e | |||
cce5b5bb5e | |||
dd74657385 | |||
439700b87c | |||
5a355683ad | |||
ac15989bbb | |||
6e05f5c8da | |||
25750f8bb0 | |||
6ebf6f8a8f | |||
f5afbe8984 | |||
d5656d221b | |||
9c4f94fed5 | |||
45d514a4cb | |||
88fded8c64 | |||
108f66941b | |||
a85f2b9fa1 | |||
af2439e880 | |||
5d34e3a37d | |||
236e9ac81e | |||
190ca32161 | |||
c80907b7e6 | |||
19772f82aa | |||
4e59d30c83 | |||
f69f0b9c62 | |||
1b863cbb2b | |||
721a7b159d | |||
b777cf9008 | |||
ad8589e5a2 | |||
b36bda24fa | |||
5a72f6db56 | |||
b7c426e952 | |||
ea86d14673 | |||
8af4713237 | |||
a0d716054f | |||
4570d8a065 | |||
8a8f512506 | |||
bd2be874c1 | |||
651589164a | |||
f893ef03d6 | |||
ba602c4629 | |||
4fb298aae0 | |||
c811cbe821 | |||
62e705079e | |||
6e135cbc74 | |||
f6cf6f6768 | |||
aa9685e9a3 | |||
9593007fea | |||
bb794dcfec | |||
add48d873b | |||
6babefbb00 | |||
e32ac882de | |||
cc7186c37b | |||
668d3a4392 | |||
8bdc715e3e | |||
877bbcd931 | |||
c67d4a6eff | |||
12cedddd68 | |||
9de0b27867 |
@ -1,20 +1,29 @@
|
||||
variables:
|
||||
lkg-rust-nightly: "2019-08-08"
|
||||
|
||||
trigger:
|
||||
- master
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
linux-nightly:
|
||||
linux-stable:
|
||||
image: ubuntu-16.04
|
||||
toolchain: nightly-$(lkg-rust-nightly)
|
||||
macos-nightly:
|
||||
image: macos-10.13
|
||||
toolchain: nightly-$(lkg-rust-nightly)
|
||||
windows-nightly:
|
||||
style: 'unflagged'
|
||||
macos-stable:
|
||||
image: macos-10.14
|
||||
style: 'unflagged'
|
||||
windows-stable:
|
||||
image: vs2017-win2016
|
||||
toolchain: nightly-$(lkg-rust-nightly)
|
||||
style: 'unflagged'
|
||||
linux-nightly-canary:
|
||||
image: ubuntu-16.04
|
||||
style: 'canary'
|
||||
macos-nightly-canary:
|
||||
image: macos-10.14
|
||||
style: 'canary'
|
||||
windows-nightly-canary:
|
||||
image: vs2017-win2016
|
||||
style: 'canary'
|
||||
fmt:
|
||||
image: ubuntu-16.04
|
||||
style: 'fmt'
|
||||
|
||||
pool:
|
||||
vmImage: $(image)
|
||||
@ -22,14 +31,23 @@ pool:
|
||||
steps:
|
||||
- bash: |
|
||||
set -e
|
||||
curl https://sh.rustup.rs -sSf | sh -s -- -y --no-modify-path --default-toolchain none
|
||||
if [ -e /etc/debian_version ]
|
||||
then
|
||||
sudo apt-get -y install libxcb-composite0-dev libx11-dev
|
||||
fi
|
||||
curl https://sh.rustup.rs -sSf | sh -s -- -y --no-modify-path --default-toolchain "stable"
|
||||
export PATH=$HOME/.cargo/bin:$PATH
|
||||
rustup install --no-self-update $(toolchain)
|
||||
rustup default $(toolchain)
|
||||
rustup update
|
||||
rustc -Vv
|
||||
echo "##vso[task.prependpath]$HOME/.cargo/bin"
|
||||
rustup component add rustfmt --toolchain "stable"
|
||||
displayName: Install Rust
|
||||
- bash: RUSTFLAGS="-D warnings" cargo build
|
||||
displayName: Build source
|
||||
- bash: cargo test
|
||||
- bash: RUSTFLAGS="-D warnings" cargo test --all-features
|
||||
condition: eq(variables['style'], 'unflagged')
|
||||
displayName: Run tests
|
||||
- bash: NUSHELL_ENABLE_ALL_FLAGS=1 RUSTFLAGS="-D warnings" cargo test --all-features
|
||||
condition: eq(variables['style'], 'canary')
|
||||
displayName: Run tests
|
||||
- bash: cargo fmt --all -- --check
|
||||
condition: eq(variables['style'], 'fmt')
|
||||
displayName: Lint
|
||||
|
@ -0,0 +1,3 @@
|
||||
[build]
|
||||
|
||||
#rustflags = ["--cfg", "coloring_in_tokens"]
|
165
.circleci/config.yml
Normal file
165
.circleci/config.yml
Normal file
@ -0,0 +1,165 @@
|
||||
# CircleCI 2.0 configuration file
|
||||
#
|
||||
# Check https://circleci.com/docs/2.0/configuration-reference/ for more details
|
||||
# See https://circleci.com/docs/2.0/config-intro/#section=configuration for spec
|
||||
#
|
||||
version: 2.1
|
||||
|
||||
# Commands
|
||||
|
||||
commands:
|
||||
|
||||
pull_cache:
|
||||
description: Pulls Quay.io docker images (latest) for our cache
|
||||
parameters:
|
||||
tag:
|
||||
type: string
|
||||
default: "devel"
|
||||
steps:
|
||||
- run: echo "Tag is << parameters.tag >>"
|
||||
- run: docker pull quay.io/nushell/nu:<< parameters.tag >>
|
||||
- run: docker pull quay.io/nushell/nu-base:<< parameters.tag >>
|
||||
|
||||
orbs:
|
||||
# https://circleci.com/orbs/registry/orb/circleci/docker
|
||||
docker: circleci/docker@0.5.13
|
||||
|
||||
workflows:
|
||||
version: 2.0
|
||||
|
||||
# This builds on all pull requests to test, and ignores master
|
||||
build_without_deploy:
|
||||
jobs:
|
||||
- docker/publish:
|
||||
deploy: false
|
||||
image: nushell/nu-base
|
||||
tag: latest
|
||||
dockerfile: docker/Dockerfile.nu-base
|
||||
extra_build_args: --cache-from=quay.io/nushell/nu-base:devel
|
||||
filters:
|
||||
branches:
|
||||
ignore:
|
||||
- master
|
||||
before_build:
|
||||
- pull_cache
|
||||
after_build:
|
||||
- run:
|
||||
name: Build Multistage (smaller) container
|
||||
command: |
|
||||
docker build -f docker/Dockerfile -t quay.io/nushell/nu .
|
||||
- run:
|
||||
name: Preview Docker Tag for Nushell Build
|
||||
command: |
|
||||
DOCKER_TAG=$(docker run quay.io/nushell/nu --version | cut -d' ' -f2)
|
||||
echo "Version that would be used for Docker tag is v${DOCKER_TAG}"
|
||||
- run:
|
||||
name: Test Executable
|
||||
command: |
|
||||
docker run --rm quay.io/nushell/nu-base --help
|
||||
docker run --rm quay.io/nushell/nu --help
|
||||
|
||||
# workflow publishes to Docker Hub, with each job having different triggers
|
||||
build_with_deploy:
|
||||
jobs:
|
||||
|
||||
# Deploy versioned and latest images on tags (releases) only - builds --release.
|
||||
- docker/publish:
|
||||
image: nushell/nu-base
|
||||
registry: quay.io
|
||||
tag: latest
|
||||
dockerfile: docker/Dockerfile.nu-base
|
||||
extra_build_args: --cache-from=quay.io/nushell/nu-base:latest,quay.io/nushell/nu:latest --build-arg RELEASE=true
|
||||
filters:
|
||||
branches:
|
||||
ignore: /.*/
|
||||
tags:
|
||||
only: /^v.*/
|
||||
before_build:
|
||||
- run: docker pull quay.io/nushell/nu:latest
|
||||
- run: docker pull quay.io/nushell/nu-base:latest
|
||||
after_build:
|
||||
- run:
|
||||
name: Build Multistage (smaller) container
|
||||
command: |
|
||||
docker build -f docker/Dockerfile -t quay.io/nushell/nu .
|
||||
- run:
|
||||
name: Test Executable
|
||||
command: |
|
||||
docker run --rm quay.io/nushell/nu --help
|
||||
docker run --rm quay.io/nushell/nu-base --help
|
||||
- run:
|
||||
name: Publish Docker Tag with Nushell Version
|
||||
command: |
|
||||
DOCKER_TAG=$(docker run quay.io/nushell/nu --version | cut -d' ' -f2)
|
||||
echo "Version for Docker tag is ${DOCKER_TAG}"
|
||||
docker tag quay.io/nushell/nu-base:latest quay.io/nushell/nu-base:${DOCKER_TAG}
|
||||
docker tag quay.io/nushell/nu:latest quay.io/nushell/nu:${DOCKER_TAG}
|
||||
docker push quay.io/nushell/nu-base
|
||||
docker push quay.io/nushell/nu
|
||||
|
||||
|
||||
# publish devel to Docker Hub on merge to master (doesn't build --release)
|
||||
build_with_deploy_devel:
|
||||
jobs:
|
||||
|
||||
# Deploy devel tag on merge to master
|
||||
- docker/publish:
|
||||
image: nushell/nu-base
|
||||
registry: quay.io
|
||||
tag: devel
|
||||
dockerfile: docker/Dockerfile.nu-base
|
||||
extra_build_args: --cache-from=quay.io/nushell/nu-base:devel
|
||||
before_build:
|
||||
- pull_cache
|
||||
filters:
|
||||
branches:
|
||||
only: master
|
||||
after_build:
|
||||
- run:
|
||||
name: Build Multistage (smaller) container
|
||||
command: |
|
||||
docker build --build-arg FROMTAG=devel -f docker/Dockerfile -t quay.io/nushell/nu:devel .
|
||||
- run:
|
||||
name: Test Executable
|
||||
command: |
|
||||
docker run --rm quay.io/nushell/nu:devel --help
|
||||
docker run --rm quay.io/nushell/nu-base:devel --help
|
||||
- run:
|
||||
name: Publish Development Docker Tags
|
||||
command: |
|
||||
docker push quay.io/nushell/nu-base:devel
|
||||
docker push quay.io/nushell/nu:devel
|
||||
|
||||
nightly:
|
||||
triggers:
|
||||
- schedule:
|
||||
cron: "0 0 * * *"
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
jobs:
|
||||
- docker/publish:
|
||||
image: nushell/nu-base
|
||||
registry: quay.io
|
||||
tag: nightly
|
||||
dockerfile: docker/Dockerfile.nu-base
|
||||
extra_build_args: --cache-from=quay.io/nushell/nu-base:nightly --build-arg RELEASE=true
|
||||
before_build:
|
||||
- run: docker pull quay.io/nushell/nu:nightly
|
||||
- run: docker pull quay.io/nushell/nu-base:nightly
|
||||
after_build:
|
||||
- run:
|
||||
name: Build Multistage (smaller) container
|
||||
command: |
|
||||
docker build -f docker/Dockerfile -t quay.io/nushell/nu:nightly .
|
||||
- run:
|
||||
name: Test Executable
|
||||
command: |
|
||||
docker run --rm quay.io/nushell/nu:nightly --help
|
||||
docker run --rm quay.io/nushell/nu-base:nightly --help
|
||||
- run:
|
||||
name: Publish Nightly Nushell Containers
|
||||
command: |
|
||||
docker push quay.io/nushell/nu-base:nightly
|
||||
docker push quay.io/nushell/nu:nightly
|
@ -4,6 +4,11 @@ root = true
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = false
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = false
|
||||
end_of_line = lf
|
||||
end_of_line = lf
|
||||
|
||||
[*.{yml,yaml}]
|
||||
indent_size = 2
|
||||
charset = utf-8
|
||||
insert_final_newline = true
|
30
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
30
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
**To Reproduce**
|
||||
Steps to reproduce the behavior:
|
||||
1.
|
||||
2.
|
||||
3.
|
||||
|
||||
**Expected behavior**
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
**Screenshots**
|
||||
If applicable, add screenshots to help explain your problem.
|
||||
|
||||
**Configuration (please complete the following information):**
|
||||
- OS: [e.g. Windows]
|
||||
- Version [e.g. 0.4.0]
|
||||
- Optional features (if any)
|
||||
|
||||
Add any other context about the problem here.
|
20
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
20
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||
|
||||
**Describe the solution you'd like**
|
||||
A clear and concise description of what you want to happen.
|
||||
|
||||
**Describe alternatives you've considered**
|
||||
A clear and concise description of any alternative solutions or features you've considered.
|
||||
|
||||
**Additional context**
|
||||
Add any other context or screenshots about the feature request here.
|
118
.github/workflows/docker-publish.yml
vendored
Normal file
118
.github/workflows/docker-publish.yml
vendored
Normal file
@ -0,0 +1,118 @@
|
||||
name: Publish consumable Docker images
|
||||
|
||||
on:
|
||||
push:
|
||||
tags: ['v?[0-9]+.[0-9]+.[0-9]+*']
|
||||
|
||||
jobs:
|
||||
compile:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
arch:
|
||||
- x86_64-unknown-linux-musl
|
||||
- x86_64-unknown-linux-gnu
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- name: Install rust-embedded/cross
|
||||
env: { VERSION: v0.1.16 }
|
||||
run: >-
|
||||
wget -nv https://github.com/rust-embedded/cross/releases/download/${VERSION}/cross-${VERSION}-x86_64-unknown-linux-gnu.tar.gz
|
||||
-O- | sudo tar xz -C /usr/local/bin/
|
||||
- name: compile for specific target
|
||||
env: { arch: '${{ matrix.arch }}' }
|
||||
run: |
|
||||
cross build --target ${{ matrix.arch }} --release
|
||||
# leave only the executable file
|
||||
rm -rd target/${{ matrix.arch }}/release/{*/*,*.d,*.rlib,.fingerprint}
|
||||
find . -empty -delete
|
||||
- uses: actions/upload-artifact@master
|
||||
with:
|
||||
name: ${{ matrix.arch }}
|
||||
path: target/${{ matrix.arch }}/release
|
||||
|
||||
docker:
|
||||
name: Build and publish docker images
|
||||
needs: compile
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
DOCKER_REGISTRY: quay.io/nushell
|
||||
DOCKER_PASSWORD: ${{ secrets.DOCKER_REGISTRY }}
|
||||
DOCKER_USER: ${{ secrets.DOCKER_USER }}
|
||||
strategy:
|
||||
matrix:
|
||||
tag:
|
||||
- alpine
|
||||
- slim
|
||||
- debian
|
||||
- glibc-busybox
|
||||
- musl-busybox
|
||||
- musl-distroless
|
||||
- glibc-distroless
|
||||
- glibc
|
||||
- musl
|
||||
include:
|
||||
- { tag: alpine, base-image: alpine, arch: x86_64-unknown-linux-musl, plugin: true }
|
||||
- { tag: slim, base-image: 'debian:stable-slim', arch: x86_64-unknown-linux-gnu, plugin: true }
|
||||
- { tag: debian, base-image: debian, arch: x86_64-unknown-linux-gnu, plugin: true }
|
||||
- { tag: glibc-busybox, base-image: 'busybox:glibc', arch: x86_64-unknown-linux-gnu, use-patch: true }
|
||||
- { tag: musl-busybox, base-image: 'busybox:musl', arch: x86_64-unknown-linux-musl, }
|
||||
- { tag: musl-distroless, base-image: 'gcr.io/distroless/static', arch: x86_64-unknown-linux-musl, }
|
||||
- { tag: glibc-distroless, base-image: 'gcr.io/distroless/cc', arch: x86_64-unknown-linux-gnu, use-patch: true }
|
||||
- { tag: glibc, base-image: scratch, arch: x86_64-unknown-linux-gnu, }
|
||||
- { tag: musl, base-image: scratch, arch: x86_64-unknown-linux-musl, }
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- uses: actions/download-artifact@master
|
||||
with: { name: '${{ matrix.arch }}', path: target/release }
|
||||
- name: Build and publish exact version
|
||||
run: |-
|
||||
export DOCKER_TAG=${GITHUB_REF##*/}-${{ matrix.tag }}
|
||||
export NU_BINS=target/release/$( [ ${{ matrix.plugin }} = true ] && echo nu* || echo nu )
|
||||
export PATCH=$([ ${{ matrix.use-patch }} = true ] && echo .${{ matrix.tag }} || echo '')
|
||||
chmod +x $NU_BINS
|
||||
|
||||
echo ${DOCKER_PASSWORD} | docker login ${DOCKER_REGISTRY} -u ${DOCKER_USER} --password-stdin
|
||||
docker-compose --file docker/docker-compose.package.yml build
|
||||
docker-compose --file docker/docker-compose.package.yml push # exact version
|
||||
env:
|
||||
BASE_IMAGE: ${{ matrix.base-image }}
|
||||
|
||||
#region semantics tagging
|
||||
- name: Retag and push with suffixed version
|
||||
run: |-
|
||||
VERSION=${GITHUB_REF##*/}
|
||||
|
||||
latest_version=${VERSION%%%.*}-${{ matrix.tag }}
|
||||
latest_feature=${VERSION%%.*}-${{ matrix.tag }}
|
||||
latest_patch=${VERSION%.*}-${{ matrix.tag }}
|
||||
exact_version=${VERSION}-${{ matrix.tag }}
|
||||
|
||||
tags=( ${latest_version} ${latest_feature} ${latest_patch} ${exact_version} )
|
||||
|
||||
for tag in ${tags[@]}; do
|
||||
docker tag ${DOCKER_REGISTRY}/nu:${VERSION}-${{ matrix.tag }} ${DOCKER_REGISTRY}/nu:${tag}
|
||||
docker push ${DOCKER_REGISTRY}/nu:${tag}
|
||||
done
|
||||
|
||||
# latest version
|
||||
docker tag ${DOCKER_REGISTRY}/nu:${VERSION}-${{ matrix.tag }} ${DOCKER_REGISTRY}/nu:${{ matrix.tag }}
|
||||
docker push ${DOCKER_REGISTRY}/nu:${{ matrix.tag }}
|
||||
|
||||
- name: Retag and push debian as latest
|
||||
if: matrix.tag == 'debian'
|
||||
run: |-
|
||||
VERSION=${GITHUB_REF##*/}
|
||||
|
||||
# ${latest features} ${latest patch} ${exact version}
|
||||
tags=( ${VERSION%%.*} ${VERSION%.*} ${VERSION} )
|
||||
|
||||
for tag in ${tags[@]}; do
|
||||
docker tag ${DOCKER_REGISTRY}/nu:${VERSION}-${{ matrix.tag }} ${DOCKER_REGISTRY}/nu:${tag}
|
||||
docker push ${DOCKER_REGISTRY}/nu:${tag}
|
||||
done
|
||||
|
||||
# latest version
|
||||
docker tag ${DOCKER_REGISTRY}/nu:${{ matrix.tag }} ${DOCKER_REGISTRY}/nu:latest
|
||||
docker push ${DOCKER_REGISTRY}/nu:latest
|
||||
#endregion semantics tagging
|
10
.gitignore
vendored
10
.gitignore
vendored
@ -1,4 +1,12 @@
|
||||
/target
|
||||
/scratch
|
||||
**/*.rs.bk
|
||||
history.txt
|
||||
tests/fixtures/nuplayground
|
||||
tests/fixtures/nuplayground
|
||||
|
||||
# Debian/Ubuntu
|
||||
debian/.debhelper/
|
||||
debian/debhelper-build-stamp
|
||||
debian/files
|
||||
debian/nu.substvars
|
||||
debian/nu/
|
||||
|
7
.gitpod.Dockerfile
vendored
Normal file
7
.gitpod.Dockerfile
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
FROM gitpod/workspace-full
|
||||
USER root
|
||||
RUN apt-get update && apt-get install -y libssl-dev \
|
||||
libxcb-composite0-dev \
|
||||
pkg-config \
|
||||
curl \
|
||||
rustc
|
21
.gitpod.yml
Normal file
21
.gitpod.yml
Normal file
@ -0,0 +1,21 @@
|
||||
image:
|
||||
file: .gitpod.Dockerfile
|
||||
tasks:
|
||||
- init: cargo install nu
|
||||
command: nu
|
||||
github:
|
||||
prebuilds:
|
||||
# enable for the master/default branch (defaults to true)
|
||||
master: true
|
||||
# enable for all branches in this repo (defaults to false)
|
||||
branches: true
|
||||
# enable for pull requests coming from this repo (defaults to true)
|
||||
pullRequests: true
|
||||
# enable for pull requests coming from forks (defaults to false)
|
||||
pullRequestsFromForks: true
|
||||
# add a "Review in Gitpod" button as a comment to pull requests (defaults to true)
|
||||
addComment: true
|
||||
# add a "Review in Gitpod" button to pull requests (defaults to false)
|
||||
addBadge: false
|
||||
# add a label once the prebuild is ready to pull requests (defaults to false)
|
||||
addLabel: prebuilt-in-gitpod
|
76
CODE_OF_CONDUCT.md
Normal file
76
CODE_OF_CONDUCT.md
Normal file
@ -0,0 +1,76 @@
|
||||
# Contributor Covenant Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
In the interest of fostering an open and welcoming environment, we as
|
||||
contributors and maintainers pledge to make participation in our project and
|
||||
our community a harassment-free experience for everyone, regardless of age, body
|
||||
size, disability, ethnicity, sex characteristics, gender identity and expression,
|
||||
level of experience, education, socio-economic status, nationality, personal
|
||||
appearance, race, religion, or sexual identity and orientation.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to creating a positive environment
|
||||
include:
|
||||
|
||||
* Using welcoming and inclusive language
|
||||
* Being respectful of differing viewpoints and experiences
|
||||
* Gracefully accepting constructive criticism
|
||||
* Focusing on what is best for the community
|
||||
* Showing empathy towards other community members
|
||||
|
||||
Examples of unacceptable behavior by participants include:
|
||||
|
||||
* The use of sexualized language or imagery and unwelcome sexual attention or
|
||||
advances
|
||||
* Trolling, insulting/derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or electronic
|
||||
address, without explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a
|
||||
professional setting
|
||||
|
||||
## Our Responsibilities
|
||||
|
||||
Project maintainers are responsible for clarifying the standards of acceptable
|
||||
behavior and are expected to take appropriate and fair corrective action in
|
||||
response to any instances of unacceptable behavior.
|
||||
|
||||
Project maintainers have the right and responsibility to remove, edit, or
|
||||
reject comments, commits, code, wiki edits, issues, and other contributions
|
||||
that are not aligned to this Code of Conduct, or to ban temporarily or
|
||||
permanently any contributor for other behaviors that they deem inappropriate,
|
||||
threatening, offensive, or harmful.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies within all project spaces, and it also applies when
|
||||
an individual is representing the project or its community in public spaces.
|
||||
Examples of representing a project or community include using an official
|
||||
project e-mail address, posting via an official social media account, or acting
|
||||
as an appointed representative at an online or offline event. Representation of
|
||||
a project may be further defined and clarified by project maintainers.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||
reported by contacting the project team at wycats@gmail.com. All
|
||||
complaints will be reviewed and investigated and will result in a response that
|
||||
is deemed necessary and appropriate to the circumstances. The project team is
|
||||
obligated to maintain confidentiality with regard to the reporter of an incident.
|
||||
Further details of specific enforcement policies may be posted separately.
|
||||
|
||||
Project maintainers who do not follow or enforce the Code of Conduct in good
|
||||
faith may face temporary or permanent repercussions as determined by other
|
||||
members of the project's leadership.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
|
||||
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
|
||||
|
||||
[homepage]: https://www.contributor-covenant.org
|
||||
|
||||
For answers to common questions about this code of conduct, see
|
||||
https://www.contributor-covenant.org/faq
|
3232
Cargo.lock
generated
3232
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
171
Cargo.toml
171
Cargo.toml
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "nu"
|
||||
version = "0.2.0"
|
||||
version = "0.6.0"
|
||||
authors = ["Yehuda Katz <wycats@gmail.com>", "Jonathan Turner <jonathan.d.turner@gmail.com>", "Andrés N. Robalino <andres@androbtech.com>"]
|
||||
description = "A shell for the GitHub era"
|
||||
license = "MIT"
|
||||
@ -8,89 +8,120 @@ edition = "2018"
|
||||
readme = "README.md"
|
||||
default-run = "nu"
|
||||
repository = "https://github.com/nushell/nushell"
|
||||
homepage = "http://nushell.sh"
|
||||
homepage = "https://www.nushell.sh"
|
||||
documentation = "https://book.nushell.sh"
|
||||
|
||||
[workspace]
|
||||
|
||||
members = ["crates/nu-source"]
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
rustyline = "5.0.2"
|
||||
sysinfo = "0.9"
|
||||
chrono = { version = "0.4.7", features = ["serde"] }
|
||||
chrono-tz = "0.5.1"
|
||||
derive-new = "0.5.7"
|
||||
nu-source = { version = "0.1.0", path = "./crates/nu-source" }
|
||||
|
||||
rustyline = "5.0.4"
|
||||
chrono = { version = "0.4.9", features = ["serde"] }
|
||||
derive-new = "0.5.8"
|
||||
prettytable-rs = "0.8.0"
|
||||
itertools = "0.8.0"
|
||||
ansi_term = "0.12.0"
|
||||
nom = "5.0.0"
|
||||
itertools = "0.8.1"
|
||||
ansi_term = "0.12.1"
|
||||
nom = "5.0.1"
|
||||
dunce = "1.0.0"
|
||||
indexmap = { version = "1.0.2", features = ["serde-1"] }
|
||||
indexmap = { version = "1.3.0", features = ["serde-1"] }
|
||||
chrono-humanize = "0.0.11"
|
||||
byte-unit = "3.0.1"
|
||||
ordered-float = {version = "1.0.2", features = ["serde"]}
|
||||
prettyprint = "0.7.0"
|
||||
futures-preview = { version = "=0.3.0-alpha.18", features = ["compat", "io-compat"] }
|
||||
futures-sink-preview = "=0.3.0-alpha.18"
|
||||
futures-async-stream = "0.1.0-alpha.1"
|
||||
async-trait = "0.1.10"
|
||||
byte-unit = "3.0.3"
|
||||
base64 = "0.11"
|
||||
futures-preview = { version = "=0.3.0-alpha.19", features = ["compat", "io-compat"] }
|
||||
async-stream = "0.1.2"
|
||||
futures_codec = "0.2.5"
|
||||
num-traits = "0.2.8"
|
||||
term = "0.5.2"
|
||||
bytes = "0.4.12"
|
||||
log = "0.4.8"
|
||||
pretty_env_logger = "0.3.1"
|
||||
serde = { version = "1.0.98", features = ["derive"] }
|
||||
serde_json = "1.0.40"
|
||||
serde = { version = "1.0.102", features = ["derive"] }
|
||||
bson = { version = "0.14.0", features = ["decimal128"] }
|
||||
serde_json = "1.0.41"
|
||||
serde-hjson = "0.9.1"
|
||||
serde_yaml = "0.8"
|
||||
serde_bytes = "0.11.2"
|
||||
getset = "0.0.7"
|
||||
logos = "0.10.0-rc2"
|
||||
logos-derive = "0.10.0-rc2"
|
||||
language-reporting = "0.3.1"
|
||||
getset = "0.0.9"
|
||||
language-reporting = "0.4.0"
|
||||
app_dirs = "1.2.1"
|
||||
csv = "1.1"
|
||||
toml = "0.5.3"
|
||||
toml-query = "0.9.2"
|
||||
toml = "0.5.5"
|
||||
clap = "2.33.0"
|
||||
enum_derive = "0.1.7"
|
||||
adhoc_derive = "0.1.2"
|
||||
lazy_static = "1.3.0"
|
||||
git2 = { version = "0.9.2", default_features = false }
|
||||
git2 = { version = "0.10.1", default_features = false }
|
||||
dirs = "2.0.2"
|
||||
glob = "0.3.0"
|
||||
ctrlc = "3.1.3"
|
||||
ptree = "0.2"
|
||||
reqwest = "0.9"
|
||||
roxmltree = "0.7.0"
|
||||
nom5_locate = "0.1.1"
|
||||
derive_more = "0.15.0"
|
||||
enum-utils = "0.1.1"
|
||||
surf = "1.0.3"
|
||||
url = "2.1.0"
|
||||
roxmltree = "0.7.2"
|
||||
nom_locate = "1.0.0"
|
||||
nom-tracable = "0.4.1"
|
||||
unicode-xid = "0.2.0"
|
||||
serde_ini = "0.2.0"
|
||||
subprocess = "0.1.18"
|
||||
mime = "0.3.13"
|
||||
regex = "1.2.1"
|
||||
pretty-hex = "0.1.0"
|
||||
neso = "0.5.0"
|
||||
crossterm = "0.10.2"
|
||||
mime = "0.3.14"
|
||||
pretty-hex = "0.1.1"
|
||||
hex = "0.4"
|
||||
tempfile = "3.1.0"
|
||||
image = "0.22.1"
|
||||
semver = "0.9.0"
|
||||
uuid = {version = "0.7.4", features = [ "v4", "serde" ]}
|
||||
syntect = "3.2.0"
|
||||
strip-ansi-escapes = "0.1.0"
|
||||
onig_sys = "=69.1.0"
|
||||
heim = "0.0.6"
|
||||
which = "2.0.1"
|
||||
battery = "0.7.4"
|
||||
which = "3.1"
|
||||
textwrap = {version = "0.11.0", features = ["term_size"]}
|
||||
unicode-width = "0.1.6"
|
||||
shellexpand = "1.0.0"
|
||||
futures-timer = "2.0.0"
|
||||
pin-utils = "0.1.0-alpha.4"
|
||||
num-bigint = { version = "0.2.3", features = ["serde"] }
|
||||
bigdecimal = { version = "0.1.0", features = ["serde"] }
|
||||
natural = "0.3.0"
|
||||
serde_urlencoded = "0.6.1"
|
||||
sublime_fuzzy = "0.6"
|
||||
trash = "1.0.0"
|
||||
regex = "1"
|
||||
cfg-if = "0.1"
|
||||
strip-ansi-escapes = "0.1.0"
|
||||
calamine = "0.16"
|
||||
umask = "0.1"
|
||||
futures-util = "0.3.0"
|
||||
pretty = "0.5.2"
|
||||
termcolor = "1.0.5"
|
||||
console = "0.9.1"
|
||||
|
||||
neso = { version = "0.5.0", optional = true }
|
||||
crossterm = { version = "0.10.2", optional = true }
|
||||
syntect = {version = "3.2.0", optional = true }
|
||||
onig_sys = {version = "=69.1.0", optional = true }
|
||||
heim = {version = "0.0.8", optional = true }
|
||||
battery = {version = "0.7.4", optional = true }
|
||||
rawkey = {version = "0.1.2", optional = true }
|
||||
clipboard = {version = "0.5", optional = true }
|
||||
ptree = {version = "0.2" }
|
||||
image = { version = "0.22.2", default_features = false, features = ["png_codec", "jpeg"], optional = true }
|
||||
starship = { version = "0.26.4", optional = true}
|
||||
|
||||
[features]
|
||||
default = ["textview", "sys", "ps"]
|
||||
raw-key = ["rawkey", "neso"]
|
||||
textview = ["syntect", "onig_sys", "crossterm"]
|
||||
binaryview = ["image", "crossterm"]
|
||||
sys = ["heim", "battery"]
|
||||
ps = ["heim"]
|
||||
starship-prompt = ["starship"]
|
||||
# trace = ["nom-tracable/trace"]
|
||||
|
||||
[dependencies.rusqlite]
|
||||
version = "0.20.0"
|
||||
features = ["bundled", "blob"]
|
||||
|
||||
[dev-dependencies]
|
||||
pretty_assertions = "0.6.1"
|
||||
tempdir = "0.3.7"
|
||||
|
||||
[build-dependencies]
|
||||
toml = "0.5.5"
|
||||
serde = { version = "1.0.102", features = ["derive"] }
|
||||
|
||||
[lib]
|
||||
name = "nu"
|
||||
@ -105,13 +136,29 @@ name = "nu_plugin_sum"
|
||||
path = "src/plugins/sum.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "nu_plugin_add"
|
||||
path = "src/plugins/add.rs"
|
||||
name = "nu_plugin_average"
|
||||
path = "src/plugins/average.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "nu_plugin_embed"
|
||||
path = "src/plugins/embed.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "nu_plugin_insert"
|
||||
path = "src/plugins/insert.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "nu_plugin_edit"
|
||||
path = "src/plugins/edit.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "nu_plugin_format"
|
||||
path = "src/plugins/format.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "nu_plugin_parse"
|
||||
path = "src/plugins/parse.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "nu_plugin_str"
|
||||
path = "src/plugins/str.rs"
|
||||
@ -120,21 +167,39 @@ path = "src/plugins/str.rs"
|
||||
name = "nu_plugin_skip"
|
||||
path = "src/plugins/skip.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "nu_plugin_match"
|
||||
path = "src/plugins/match.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "nu_plugin_sys"
|
||||
path = "src/plugins/sys.rs"
|
||||
required-features = ["sys"]
|
||||
|
||||
[[bin]]
|
||||
name = "nu_plugin_ps"
|
||||
path = "src/plugins/ps.rs"
|
||||
required-features = ["ps"]
|
||||
|
||||
[[bin]]
|
||||
name = "nu_plugin_tree"
|
||||
path = "src/plugins/tree.rs"
|
||||
required-features = ["tree"]
|
||||
|
||||
[[bin]]
|
||||
name = "nu_plugin_binaryview"
|
||||
path = "src/plugins/binaryview.rs"
|
||||
required-features = ["binaryview"]
|
||||
|
||||
[[bin]]
|
||||
name = "nu_plugin_textview"
|
||||
path = "src/plugins/textview.rs"
|
||||
required-features = ["textview"]
|
||||
|
||||
[[bin]]
|
||||
name = "nu_plugin_docker"
|
||||
path = "src/plugins/docker.rs"
|
||||
required-features = ["docker"]
|
||||
|
||||
[[bin]]
|
||||
name = "nu"
|
||||
|
@ -4,21 +4,12 @@ command = "lalrpop"
|
||||
args = ["src/parser/parser.lalrpop"]
|
||||
|
||||
[tasks.baseline]
|
||||
dependencies = ["lalrpop"]
|
||||
|
||||
[tasks.build]
|
||||
command = "cargo"
|
||||
args = ["build"]
|
||||
dependencies = ["lalrpop"]
|
||||
args = ["build", "--bins"]
|
||||
|
||||
[tasks.run]
|
||||
command = "cargo"
|
||||
args = ["run", "--release"]
|
||||
dependencies = ["baseline"]
|
||||
|
||||
[tasks.release]
|
||||
command = "cargo"
|
||||
args = ["build", "--release"]
|
||||
args = ["run"]
|
||||
dependencies = ["baseline"]
|
||||
|
||||
[tasks.test]
|
||||
|
263
README.md
263
README.md
@ -1,78 +1,135 @@
|
||||
[](https://dev.azure.com/nushell/nushell/_build/latest?definitionId=2&branchName=master) [](https://discord.gg/NtAbbGn)
|
||||
|
||||
[](https://crates.io/crates/nu)
|
||||
[](https://dev.azure.com/nushell/nushell/_build/latest?definitionId=2&branchName=master)
|
||||
[](https://discord.gg/NtAbbGn)
|
||||
[](https://changelog.com/podcast/363)
|
||||
|
||||
|
||||
# Nu Shell
|
||||
|
||||
A modern, GitHub-era shell written in Rust
|
||||
A modern shell for the GitHub era.
|
||||
|
||||

|
||||

|
||||
|
||||
# Status
|
||||
|
||||
This project has reached a minimum-viable product level of quality. While contributors dogfood it as their daily driver, it may be instable for some commands. Future releases will work fill out missing features and improve stability. Its design is also subject to change as it matures.
|
||||
This project has reached a minimum-viable product level of quality. While contributors dogfood it as their daily driver, it may be unstable for some commands. Future releases will work to fill out missing features and improve stability. Its design is also subject to change as it matures.
|
||||
|
||||
Nu comes with a set of built-in commands (listed below). If a command is unknown, the command will shell-out and execute it (using cmd on Windows or bash on Linux and MacOS), correctly passing through stdin, stdout and stderr, so things like your daily git workflows and even `vim` will work just fine.
|
||||
Nu comes with a set of built-in commands (listed below). If a command is unknown, the command will shell-out and execute it (using cmd on Windows or bash on Linux and macOS), correctly passing through stdin, stdout, and stderr, so things like your daily git workflows and even `vim` will work just fine.
|
||||
|
||||
There is also a [book](https://book.nushell.sh) about Nu, currently in progress.
|
||||
# Learning more
|
||||
|
||||
There are a few good resources to learn about Nu. There is a [book](https://book.nushell.sh) about Nu that is currently in progress. The book focuses on using Nu and its core concepts.
|
||||
|
||||
If you're a developer who would like to contribute to Nu, we're also working on a [book for developers](https://github.com/nushell/contributor-book/tree/master/en) to help you get started. There are also [good first issues](https://github.com/nushell/nushell/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22) to help you dive in.
|
||||
|
||||
We also have an active [Discord](https://discord.gg/NtAbbGn) and [Twitter](https://twitter.com/nu_shell) if you'd like to come and chat with us.
|
||||
|
||||
Try it in Gitpod.
|
||||
|
||||
[](https://gitpod.io/#https://github.com/nushell/nushell)
|
||||
|
||||
# Installation
|
||||
|
||||
Up-to-date installation instructions can be found in the [installation chapter of the book](https://book.nushell.sh/en/installation).
|
||||
## Local
|
||||
|
||||
Up-to-date installation instructions can be found in the [installation chapter of the book](https://book.nushell.sh/en/installation). **Windows users**: please note that Nu works on Windows 10 and does not currently have Windows 7/8.1 support.
|
||||
|
||||
To build Nu, you will need to use the **latest stable (1.39 or later)** version of the compiler.
|
||||
|
||||
Required dependencies:
|
||||
|
||||
* libssl
|
||||
* on macOS (via homebrew): `brew install openssl`
|
||||
* on Linux (on Debian/Ubuntu): `apt install libssl-dev`
|
||||
* pkg-config and libssl (only needed on Linux)
|
||||
* on Debian/Ubuntu: `apt install pkg-config libssl-dev`
|
||||
|
||||
Optional dependencies:
|
||||
|
||||
* To use Nu with all possible optional features enabled, you'll also need the following:
|
||||
* on Linux (on Debian/Ubuntu): `apt install libxcb-composite0-dev libx11-dev`
|
||||
|
||||
To install Nu via cargo:
|
||||
To install Nu via cargo (make sure you have installed [rustup](https://rustup.rs/) and the latest stable compiler via `rustup install stable`):
|
||||
|
||||
```
|
||||
cargo install nu
|
||||
```
|
||||
|
||||
You can also install Nu with all the bells and whistles:
|
||||
You can also install Nu with all the bells and whistles (be sure to have installed the [dependencies](https://book.nushell.sh/en/installation#dependencies) for your platform):
|
||||
|
||||
```
|
||||
cargo install nu --features rawkey,clipboard
|
||||
cargo install nu --all-features
|
||||
```
|
||||
|
||||
The following optional features are currently supported:
|
||||
## Docker
|
||||
|
||||
* **rawkey** - direct keyboard input, which creates a smoother experience in viewing text and binaries
|
||||
* **clipboard** - integration with the native clipboard via the `clip` command
|
||||
If you want to pull a pre-built container, you can browse tags for the [nushell organization](https://quay.io/organization/nushell)
|
||||
on Quay.io. Pulling a container would come down to:
|
||||
|
||||
```bash
|
||||
$ docker pull quay.io/nushell/nu
|
||||
$ docker pull quay.io/nushell/nu-base
|
||||
```
|
||||
|
||||
Both "nu-base" and "nu" provide the nu binary, however nu-base also includes the source code at `/code`
|
||||
in the container and all dependencies.
|
||||
|
||||
Optionally, you can also build the containers locally using the [dockerfiles provided](docker):
|
||||
To build the base image:
|
||||
|
||||
```bash
|
||||
$ docker build -f docker/Dockerfile.nu-base -t nushell/nu-base .
|
||||
```
|
||||
|
||||
And then to build the smaller container (using a Multistage build):
|
||||
|
||||
```bash
|
||||
$ docker build -f docker/Dockerfile -t nushell/nu .
|
||||
```
|
||||
|
||||
Either way, you can run either container as follows:
|
||||
|
||||
```bash
|
||||
$ docker run -it nushell/nu-base
|
||||
$ docker run -it nushell/nu
|
||||
/> exit
|
||||
```
|
||||
|
||||
The second container is a bit smaller if the size is important to you.
|
||||
|
||||
## Packaging status
|
||||
|
||||
[](https://repology.org/project/nushell/versions)
|
||||
|
||||
### Fedora
|
||||
|
||||
[COPR repo](https://copr.fedorainfracloud.org/coprs/atim/nushell/): `sudo dnf copr enable atim/nushell -y && sudo dnf install nushell -y`
|
||||
|
||||
# Philosophy
|
||||
|
||||
Nu draws inspiration from projects like PowerShell, functional programming languages, and modern cli tools. Rather than thinking of files and services as raw streams of text, Nu looks at each input as something with structure. For example, when you list the contents of a directory, what you get back in a list of objects, where each object represents an item in that directory. These values can be piped through a series of steps, in a series of commands called a 'pipeline'.
|
||||
Nu draws inspiration from projects like PowerShell, functional programming languages, and modern CLI tools. Rather than thinking of files and services as raw streams of text, Nu looks at each input as something with structure. For example, when you list the contents of a directory, what you get back is a table of rows, where each row represents an item in that directory. These values can be piped through a series of steps, in a series of commands called a 'pipeline'.
|
||||
|
||||
## Pipelines
|
||||
|
||||
In Unix, it's common to pipe between commands to split up a sophisticated command over multiple steps. Nu takes this a step further and builds heavily on the idea of _pipelines_. Just as the Unix philosophy, Nu allows commands to output from stdout and read from stdin. Additionally, commands can output structured data (you can think of this as a third kind of stream). Commands that work in the pipeline fit into one of three categories
|
||||
In Unix, it's common to pipe between commands to split up a sophisticated command over multiple steps. Nu takes this a step further and builds heavily on the idea of _pipelines_. Just as the Unix philosophy, Nu allows commands to output from stdout and read from stdin. Additionally, commands can output structured data (you can think of this as a third kind of stream). Commands that work in the pipeline fit into one of three categories:
|
||||
|
||||
* Commands that produce a stream (eg, `ls`)
|
||||
* Commands that filter a stream (eg, `where type == "Directory"`)
|
||||
* Commands that consumes the output of the pipeline (eg, `autoview`)
|
||||
* Commands that consume the output of the pipeline (eg, `autoview`)
|
||||
|
||||
Commands are separated by the pipe symbol (`|`) to denote a pipeline flowing left to right.
|
||||
|
||||
```
|
||||
/home/jonathan/Source/nushell(master)> ls | where type == "Directory" | autoview
|
||||
--------+-----------+----------+--------+--------------+----------------
|
||||
name | type | readonly | size | accessed | modified
|
||||
--------+-----------+----------+--------+--------------+----------------
|
||||
target | Directory | | 4.1 KB | 19 hours ago | 19 hours ago
|
||||
images | Directory | | 4.1 KB | 2 weeks ago | a week ago
|
||||
tests | Directory | | 4.1 KB | 2 weeks ago | 18 minutes ago
|
||||
docs | Directory | | 4.1 KB | a week ago | a week ago
|
||||
.git | Directory | | 4.1 KB | 2 weeks ago | 25 minutes ago
|
||||
src | Directory | | 4.1 KB | 2 weeks ago | 25 minutes ago
|
||||
.cargo | Directory | | 4.1 KB | 2 weeks ago | 2 weeks ago
|
||||
-----------+-----------+----------+--------+--------------+----------------
|
||||
━━━━┯━━━━━━━━━━━┯━━━━━━━━━━━┯━━━━━━━━━━┯━━━━━━━━┯━━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━━
|
||||
# │ name │ type │ readonly │ size │ accessed │ modified
|
||||
────┼───────────┼───────────┼──────────┼────────┼──────────────┼────────────────
|
||||
0 │ .azure │ Directory │ │ 4.1 KB │ 2 months ago │ a day ago
|
||||
1 │ target │ Directory │ │ 4.1 KB │ 3 days ago │ 3 days ago
|
||||
2 │ images │ Directory │ │ 4.1 KB │ 2 months ago │ 2 weeks ago
|
||||
3 │ tests │ Directory │ │ 4.1 KB │ 2 months ago │ 37 minutes ago
|
||||
4 │ tmp │ Directory │ │ 4.1 KB │ 2 weeks ago │ 2 weeks ago
|
||||
5 │ src │ Directory │ │ 4.1 KB │ 2 months ago │ 37 minutes ago
|
||||
6 │ assets │ Directory │ │ 4.1 KB │ a month ago │ a month ago
|
||||
7 │ docs │ Directory │ │ 4.1 KB │ 2 months ago │ 2 months ago
|
||||
━━━━┷━━━━━━━━━━━┷━━━━━━━━━━━┷━━━━━━━━━━┷━━━━━━━━┷━━━━━━━━━━━━━━┷━━━━━━━━━━━━━━━━
|
||||
```
|
||||
|
||||
Because most of the time you'll want to see the output of a pipeline, `autoview` is assumed. We could have also written the above:
|
||||
@ -84,15 +141,16 @@ Because most of the time you'll want to see the output of a pipeline, `autoview`
|
||||
Being able to use the same commands and compose them differently is an important philosophy in Nu. For example, we could use the built-in `ps` command as well to get a list of the running processes, using the same `where` as above.
|
||||
|
||||
```text
|
||||
C:\Code\nushell(master)> ps | where cpu > 0
|
||||
------------------ +-----+-------+-------+----------
|
||||
name | cmd | cpu | pid | status
|
||||
------------------ +-----+-------+-------+----------
|
||||
msedge.exe | - | 0.77 | 26472 | Runnable
|
||||
nu.exe | - | 7.83 | 15473 | Runnable
|
||||
SearchIndexer.exe | - | 82.17 | 23476 | Runnable
|
||||
BlueJeans.exe | - | 4.54 | 10000 | Runnable
|
||||
-------------------+-----+-------+-------+----------
|
||||
/home/jonathan/Source/nushell(master)> ps | where cpu > 0
|
||||
━━━┯━━━━━━━┯━━━━━━━━━━━━━━━━━┯━━━━━━━━━━┯━━━━━━━━━━
|
||||
# │ pid │ name │ status │ cpu
|
||||
───┼───────┼─────────────────┼──────────┼──────────
|
||||
0 │ 992 │ chrome │ Sleeping │ 6.988768
|
||||
1 │ 4240 │ chrome │ Sleeping │ 5.645982
|
||||
2 │ 13973 │ qemu-system-x86 │ Sleeping │ 4.996551
|
||||
3 │ 15746 │ nu │ Sleeping │ 84.59905
|
||||
━━━┷━━━━━━━┷━━━━━━━━━━━━━━━━━┷━━━━━━━━━━┷━━━━━━━━━━
|
||||
|
||||
```
|
||||
|
||||
## Opening files
|
||||
@ -101,36 +159,55 @@ Nu can load file and URL contents as raw text or as structured data (if it recog
|
||||
|
||||
```
|
||||
/home/jonathan/Source/nushell(master)> open Cargo.toml
|
||||
-----------------+------------------+-----------------
|
||||
dependencies | dev-dependencies | package
|
||||
-----------------+------------------+-----------------
|
||||
[object Object] | [object Object] | [object Object]
|
||||
-----------------+------------------+-----------------
|
||||
━━━━━━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━━━━
|
||||
bin │ dependencies │ dev-dependencies
|
||||
──────────────────┼────────────────┼──────────────────
|
||||
[table: 12 rows] │ [table: 1 row] │ [table: 1 row]
|
||||
━━━━━━━━━━━━━━━━━━┷━━━━━━━━━━━━━━━━┷━━━━━━━━━━━━━━━━━━
|
||||
```
|
||||
|
||||
We can pipeline this into a command that gets the contents of one of the columns:
|
||||
|
||||
```
|
||||
/home/jonathan/Source/nushell(master)> open Cargo.toml | get package
|
||||
-------------+----------------------------+---------+---------+------+---------
|
||||
authors | description | edition | license | name | version
|
||||
-------------+----------------------------+---------+---------+------+---------
|
||||
[list List] | A shell for the GitHub era | 2018 | MIT | nu | 0.2.0
|
||||
-------------+----------------------------+---------+---------+------+---------
|
||||
━━━━━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━━━━━━━━━━━━━━┯━━━━━━━━━┯━━━━━━━━━┯━━━━━━┯━━━━━━━━━
|
||||
authors │ description │ edition │ license │ name │ version
|
||||
─────────────────┼────────────────────────────┼─────────┼─────────┼──────┼─────────
|
||||
[table: 3 rows] │ A shell for the GitHub era │ 2018 │ MIT │ nu │ 0.6.0
|
||||
━━━━━━━━━━━━━━━━━┷━━━━━━━━━━━━━━━━━━━━━━━━━━━━┷━━━━━━━━━┷━━━━━━━━━┷━━━━━━┷━━━━━━━━━
|
||||
```
|
||||
|
||||
Finally, we can use commands outside of Nu once we have the data we want:
|
||||
|
||||
```
|
||||
/home/jonathan/Source/nushell(master)> open Cargo.toml | get package.version | echo $it
|
||||
0.2.0
|
||||
0.6.0
|
||||
```
|
||||
|
||||
Here we use the variable `$it` to refer to the value being piped to the external command.
|
||||
|
||||
## Configuration
|
||||
|
||||
Nu has early support for configuring the shell. It currently supports the following settings:
|
||||
|
||||
| Variable | Type | Description |
|
||||
| ------------- | ------------- | ----- |
|
||||
| path | table of strings | PATH to use to find binaries |
|
||||
| env | row | the environment variables to pass to external commands |
|
||||
| ctrlc_exit | boolean | whether or not to exit Nu after multiple ctrl-c presses |
|
||||
| table_mode | "light" or other | enable lightweight or normal tables |
|
||||
| edit_mode | "vi" or "emacs" | changes line editing to "vi" or "emacs" mode |
|
||||
|
||||
To set one of these variables, you can use `config --set`. For example:
|
||||
|
||||
```
|
||||
> config --set [edit_mode "vi"]
|
||||
> config --set [path $nu:path]
|
||||
```
|
||||
|
||||
## Shells
|
||||
|
||||
By default, Nu will work inside of a single directory and allow you to navigate around your filesystem. Sometimes, you'll want to work in multiple directories at the same time. For this, Nu offers a way of adding additional working directories that you can jump between.
|
||||
Nu will work inside of a single directory and allow you to navigate around your filesystem by default. Nu also offers a way of adding additional working directories that you can jump between, allowing you to work in multiple directories at the same time.
|
||||
|
||||
To do so, use the `enter` command, which will allow you create a new "shell" and enter it at the specified path. You can toggle between this new shell and the original shell with the `p` (for previous) and `n` (for next), allowing you to navigate around a ring buffer of shells. Once you're done with a shell, you can `exit` it and remove it from the ring buffer.
|
||||
|
||||
@ -138,11 +215,11 @@ Finally, to get a list of all the current shells, you can use the `shells` comma
|
||||
|
||||
## Plugins
|
||||
|
||||
Nu supports plugins that offer additional functionality to the shell and follow the same object model that built-in commands use. This allows you to extend nu for your needs.
|
||||
Nu supports plugins that offer additional functionality to the shell and follow the same structured data model that built-in commands use. This allows you to extend nu for your needs.
|
||||
|
||||
There are a few examples in the `plugins` directory.
|
||||
|
||||
Plugins are binaries that are available in your path and follow a "nu_plugin_*" naming convention. These binaries interact with nu via a simple JSON-RPC protocol where the command identifies itself and passes along its configuration, which then makes it available for use. If the plugin is a filter, data streams to it one element at a time, and it can stream data back in return via stdin/stdout. If the plugin is a sink, it is given the full vector of final data and is given free reign over stdin/stdout to use as it pleases.
|
||||
Plugins are binaries that are available in your path and follow a `nu_plugin_*` naming convention. These binaries interact with nu via a simple JSON-RPC protocol where the command identifies itself and passes along its configuration, which then makes it available for use. If the plugin is a filter, data streams to it one element at a time, and it can stream data back in return via stdin/stdout. If the plugin is a sink, it is given the full vector of final data and is given free reign over stdin/stdout to use as it pleases.
|
||||
|
||||
# Goals
|
||||
|
||||
@ -154,9 +231,9 @@ Nu adheres closely to a set of goals that make up its design philosophy. As feat
|
||||
|
||||
* Nu's workflow and tools should have the usability in day-to-day experience of using a shell in 2019 (and beyond).
|
||||
|
||||
* Nu views data as both structured and unstructured. It is an object shell like PowerShell.
|
||||
* Nu views data as both structured and unstructured. It is a structured shell like PowerShell.
|
||||
|
||||
* Finally, Nu views data functionally. Rather than using mutation, pipelines act as a mean to load, change, and save data without mutable state.
|
||||
* Finally, Nu views data functionally. Rather than using mutation, pipelines act as a means to load, change, and save data without mutable state.
|
||||
|
||||
# Commands
|
||||
## Initial commands
|
||||
@ -164,14 +241,23 @@ Nu adheres closely to a set of goals that make up its design philosophy. As feat
|
||||
| ------------- | ------------- |
|
||||
| cd path | Change to a new path |
|
||||
| cp source path | Copy files |
|
||||
| date (--utc) | Get the current datetime |
|
||||
| fetch url | Fetch contents from a url and retrieve data as a table if possible |
|
||||
| help | Display help information about commands |
|
||||
| ls (path) | View the contents of the current or given path |
|
||||
| mkdir path | Make directories, creates intermediary directories as required. |
|
||||
| mv source target | Move files or directories. |
|
||||
| date (--utc) | Get the current datetime |
|
||||
| open filename | Load a file into a cell, convert to table if possible (avoid by appending '--raw') |
|
||||
| post url body (--user <user>) (--password <password>) | Post content to a url and retrieve data as a table if possible |
|
||||
| ps | View current processes |
|
||||
| sys | View information about the current system |
|
||||
| open {filename or url} | Load a file into a cell, convert to table if possible (avoid by appending '--raw') |
|
||||
| which filename | Finds a program file. |
|
||||
| rm {file or directory} | Remove a file, (for removing directory append '--recursive') |
|
||||
| version | Display Nu version |
|
||||
|
||||
## Shell commands
|
||||
| command | description |
|
||||
| ------- | ----------- |
|
||||
| exit (--now) | Exit the current shell (or all shells) |
|
||||
| enter (path) | Create a new shell and begin at this path |
|
||||
| p | Go to previous shell |
|
||||
@ -181,39 +267,61 @@ Nu adheres closely to a set of goals that make up its design philosophy. As feat
|
||||
## Filters on tables (structured data)
|
||||
| command | description |
|
||||
| ------------- | ------------- |
|
||||
| pick ...columns | Down-select table to only these columns |
|
||||
| reject ...columns | Remove the given columns from the table |
|
||||
| get column-or-column-path | Open given cells as text |
|
||||
| sort-by ...columns | Sort by the given columns |
|
||||
| where condition | Filter table to match the condition |
|
||||
| inc (field) | Increment a value or version. Optional use the field of a table |
|
||||
| add field value | Add a new field to the table |
|
||||
| sum | Sum a column of values |
|
||||
| edit field value | Edit an existing field to have a new value |
|
||||
| skip amount | Skip a number of rows |
|
||||
| append row-data | Append a row to the end of the table |
|
||||
| compact ...columns | Remove rows where given columns are empty |
|
||||
| count | Show the total number of rows |
|
||||
| default column row-data | Sets a default row's column if missing |
|
||||
| edit column-or-column-path value | Edit an existing column to have a new value |
|
||||
| embed column | Creates a new table of one column with the given name, and places the current table inside of it |
|
||||
| first amount | Show only the first number of rows |
|
||||
| nth row-number | Return only the selected row |
|
||||
| str (field) | Apply string function. Optional use the field of a table |
|
||||
| format pattern | Format table row data as a string following the given pattern |
|
||||
| get column-or-column-path | Open column and get data from the corresponding cells |
|
||||
| group-by column | Creates a new table with the data from the table rows grouped by the column given |
|
||||
| histogram column ...column-names | Creates a new table with a histogram based on the column name passed in, optionally give the frequency column name
|
||||
| inc (column-or-column-path) | Increment a value or version. Optionally use the column of a table |
|
||||
| insert column-or-column-path value | Insert a new column to the table |
|
||||
| last amount | Show only the last number of rows |
|
||||
| nth ...row-numbers | Return only the selected rows |
|
||||
| pick ...columns | Down-select table to only these columns |
|
||||
| pivot --header-row <headers> | Pivot the tables, making columns into rows and vice versa |
|
||||
| prepend row-data | Prepend a row to the beginning of the table |
|
||||
| reject ...columns | Remove the given columns from the table |
|
||||
| reverse | Reverses the table. |
|
||||
| skip amount | Skip a number of rows |
|
||||
| skip-while condition | Skips rows while the condition matches |
|
||||
| split-by column | Creates a new table with the data from the inner tables splitted by the column given |
|
||||
| sort-by ...columns | Sort by the given columns |
|
||||
| str (column) | Apply string function. Optionally use the column of a table |
|
||||
| sum | Sum a column of values |
|
||||
| tags | Read the tags (metadata) for values |
|
||||
| from-array | Expand an array/list into rows |
|
||||
| to-array | Collapse rows into a single list |
|
||||
| to-bson | Convert table into .bson binary data |
|
||||
| to-csv | Convert table into .csv text |
|
||||
| to-json | Convert table into .json text |
|
||||
| to-sqlite | Convert table to sqlite .db binary data |
|
||||
| to-toml | Convert table into .toml text |
|
||||
| to-tsv | Convert table into .tsv text |
|
||||
| to-url | Convert table to a urlencoded string |
|
||||
| to-yaml | Convert table into .yaml text |
|
||||
| to-csv | Convert table into .csv text |
|
||||
| where condition | Filter table to match the condition |
|
||||
|
||||
## Filters on text (unstructured data)
|
||||
| command | description |
|
||||
| ------------- | ------------- |
|
||||
| from-bson | Parse binary data as .bson and create table |
|
||||
| from-csv | Parse text as .csv and create table |
|
||||
| from-ini | Parse text as .ini and create table |
|
||||
| from-json | Parse text as .json and create table |
|
||||
| from-sqlite | Parse binary data as sqlite .db and create table |
|
||||
| from-ssv --minimum-spaces <minimum number of spaces to count as a separator> | Parse text as space-separated values and create table |
|
||||
| from-toml | Parse text as .toml and create table |
|
||||
| from-tsv | Parse text as .tsv and create table |
|
||||
| from-url | Parse urlencoded string and create a table |
|
||||
| from-xml | Parse text as .xml and create a table |
|
||||
| from-yaml | Parse text as a .yaml/.yml and create a table |
|
||||
| lines | Split single string into rows, one per line |
|
||||
| parse pattern | Convert text to a table by matching the given pattern |
|
||||
| size | Gather word count statistics on the text |
|
||||
| split-column sep ...fields | Split row contents across multiple columns via the separator |
|
||||
| split-column sep ...column-names | Split row contents across multiple columns via the separator, optionally give the columns names |
|
||||
| split-row sep | Split row contents over multiple rows via the separator |
|
||||
| trim | Trim leading and following whitespace from text data |
|
||||
| {external-command} $it | Run external command with given arguments, replacing $it with each row text |
|
||||
@ -222,13 +330,12 @@ Nu adheres closely to a set of goals that make up its design philosophy. As feat
|
||||
| command | description |
|
||||
| ------------- | ------------- |
|
||||
| autoview | View the contents of the pipeline as a table or list |
|
||||
| binaryview | Autoview of binary data |
|
||||
| clip | Copy the contents of the pipeline to the copy/paste buffer |
|
||||
| binaryview | Autoview of binary data (optional feature) |
|
||||
| clip | Copy the contents of the pipeline to the copy/paste buffer (optional feature) |
|
||||
| save filename | Save the contents of the pipeline to a file |
|
||||
| table | View the contents of the pipeline as a table |
|
||||
| textview | Autoview of text data |
|
||||
| tree | View the contents of the pipeline as a tree |
|
||||
| vtable | View the contents of the pipeline as a vertical (rotated) table |
|
||||
| tree | View the contents of the pipeline as a tree (optional feature) |
|
||||
|
||||
# License
|
||||
|
||||
|
48
TODO.md
Normal file
48
TODO.md
Normal file
@ -0,0 +1,48 @@
|
||||
This pattern is extremely repetitive and can be abstracted:
|
||||
|
||||
```rs
|
||||
let args = args.evaluate_once(registry)?;
|
||||
let tag = args.name_tag();
|
||||
let input = args.input;
|
||||
|
||||
let stream = async_stream! {
|
||||
let values: Vec<Value> = input.values.collect().await;
|
||||
|
||||
let mut concat_string = String::new();
|
||||
let mut latest_tag: Option<Tag> = None;
|
||||
|
||||
for value in values {
|
||||
latest_tag = Some(value_tag.clone());
|
||||
let value_span = value.tag.span;
|
||||
|
||||
match &value.value {
|
||||
UntaggedValue::Primitive(Primitive::String(s)) => {
|
||||
concat_string.push_str(&s);
|
||||
concat_string.push_str("\n");
|
||||
}
|
||||
_ => yield Err(ShellError::labeled_error_with_secondary(
|
||||
"Expected a string from pipeline",
|
||||
"requires string input",
|
||||
name_span,
|
||||
"value originates from here",
|
||||
value_span,
|
||||
)),
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Mandatory and Optional in parse_command
|
||||
|
||||
trace_remaining?
|
||||
|
||||
select_fields and select_fields take unnecessary Tag
|
||||
|
||||
Value#value should be Value#untagged
|
||||
|
||||
Unify dictionary building, probably around a macro
|
||||
|
||||
sys plugin in own crate
|
||||
|
||||
textview in own crate
|
39
build.rs
Normal file
39
build.rs
Normal file
@ -0,0 +1,39 @@
|
||||
use serde::Deserialize;
|
||||
use std::collections::HashMap;
|
||||
use std::collections::HashSet;
|
||||
use std::env;
|
||||
use std::path::Path;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct Feature {
|
||||
#[allow(unused)]
|
||||
description: String,
|
||||
enabled: bool,
|
||||
}
|
||||
|
||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let input = env::var("CARGO_MANIFEST_DIR").unwrap();
|
||||
let all_on = env::var("NUSHELL_ENABLE_ALL_FLAGS").is_ok();
|
||||
let flags: HashSet<String> = env::var("NUSHELL_ENABLE_FLAGS")
|
||||
.map(|s| s.split(",").map(|s| s.to_string()).collect())
|
||||
.unwrap_or_else(|_| HashSet::new());
|
||||
|
||||
if all_on && !flags.is_empty() {
|
||||
println!(
|
||||
"cargo:warning={}",
|
||||
"Both NUSHELL_ENABLE_ALL_FLAGS and NUSHELL_ENABLE_FLAGS were set. You don't need both."
|
||||
);
|
||||
}
|
||||
|
||||
let path = Path::new(&input).join("features.toml");
|
||||
|
||||
let toml: HashMap<String, Feature> = toml::from_str(&std::fs::read_to_string(path)?)?;
|
||||
|
||||
for (key, value) in toml.iter() {
|
||||
if value.enabled == true || all_on || flags.contains(key) {
|
||||
println!("cargo:rustc-cfg={}", key);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
20
crates/nu-source/Cargo.toml
Normal file
20
crates/nu-source/Cargo.toml
Normal file
@ -0,0 +1,20 @@
|
||||
[package]
|
||||
name = "nu-source"
|
||||
version = "0.1.0"
|
||||
authors = ["Yehuda Katz <wycats@gmail.com>"]
|
||||
edition = "2018"
|
||||
description = "A source string characterizer for Nushell"
|
||||
license = "MIT"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
|
||||
serde = { version = "1.0.102", features = ["derive"] }
|
||||
derive-new = "0.5.8"
|
||||
getset = "0.0.9"
|
||||
nom_locate = "1.0.0"
|
||||
nom-tracable = "0.4.1"
|
||||
language-reporting = "0.4.0"
|
||||
termcolor = "1.0.5"
|
||||
pretty = "0.5.2"
|
15
crates/nu-source/src/lib.rs
Normal file
15
crates/nu-source/src/lib.rs
Normal file
@ -0,0 +1,15 @@
|
||||
mod meta;
|
||||
mod pretty;
|
||||
mod term_colored;
|
||||
mod text;
|
||||
mod tracable;
|
||||
|
||||
pub use self::meta::{
|
||||
span_for_spanned_list, tag_for_tagged_list, AnchorLocation, HasFallibleSpan, HasSpan, HasTag,
|
||||
Span, Spanned, SpannedItem, Tag, Tagged, TaggedItem,
|
||||
};
|
||||
pub use self::pretty::{
|
||||
b, DebugDoc, DebugDocBuilder, PrettyDebug, PrettyDebugWithSource, ShellAnnotation,
|
||||
};
|
||||
pub use self::text::Text;
|
||||
pub use self::tracable::{nom_input, NomSpan, TracableContext};
|
655
crates/nu-source/src/meta.rs
Normal file
655
crates/nu-source/src/meta.rs
Normal file
@ -0,0 +1,655 @@
|
||||
use crate::pretty::{b, DebugDocBuilder, PrettyDebugWithSource};
|
||||
use crate::text::Text;
|
||||
use crate::tracable::TracableContext;
|
||||
|
||||
use derive_new::new;
|
||||
use getset::Getters;
|
||||
use serde::Deserialize;
|
||||
use serde::Serialize;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
pub enum AnchorLocation {
|
||||
Url(String),
|
||||
File(String),
|
||||
Source(Text),
|
||||
}
|
||||
|
||||
pub trait HasTag {
|
||||
fn tag(&self) -> Tag;
|
||||
}
|
||||
|
||||
#[derive(new, Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Serialize, Deserialize, Hash)]
|
||||
pub struct Spanned<T> {
|
||||
pub span: Span,
|
||||
pub item: T,
|
||||
}
|
||||
|
||||
impl<T> Spanned<T> {
|
||||
pub fn map<U>(self, input: impl FnOnce(T) -> U) -> Spanned<U> {
|
||||
let span = self.span;
|
||||
|
||||
let mapped = input(self.item);
|
||||
mapped.spanned(span)
|
||||
}
|
||||
}
|
||||
|
||||
impl Spanned<String> {
|
||||
pub fn items<'a, U>(
|
||||
items: impl Iterator<Item = &'a Spanned<String>>,
|
||||
) -> impl Iterator<Item = &'a str> {
|
||||
items.into_iter().map(|item| &item.item[..])
|
||||
}
|
||||
}
|
||||
|
||||
impl Spanned<String> {
|
||||
pub fn borrow_spanned(&self) -> Spanned<&str> {
|
||||
let span = self.span;
|
||||
self.item[..].spanned(span)
|
||||
}
|
||||
}
|
||||
|
||||
pub trait SpannedItem: Sized {
|
||||
fn spanned(self, span: impl Into<Span>) -> Spanned<Self> {
|
||||
Spanned {
|
||||
item: self,
|
||||
span: span.into(),
|
||||
}
|
||||
}
|
||||
|
||||
fn spanned_unknown(self) -> Spanned<Self> {
|
||||
Spanned {
|
||||
item: self,
|
||||
span: Span::unknown(),
|
||||
}
|
||||
}
|
||||
}
|
||||
impl<T> SpannedItem for T {}
|
||||
|
||||
impl<T> std::ops::Deref for Spanned<T> {
|
||||
type Target = T;
|
||||
|
||||
fn deref(&self) -> &T {
|
||||
&self.item
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(new, Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Serialize, Deserialize, Hash)]
|
||||
pub struct Tagged<T> {
|
||||
pub tag: Tag,
|
||||
pub item: T,
|
||||
}
|
||||
|
||||
impl Tagged<String> {
|
||||
pub fn borrow_spanned(&self) -> Spanned<&str> {
|
||||
let span = self.tag.span;
|
||||
self.item[..].spanned(span)
|
||||
}
|
||||
|
||||
pub fn borrow_tagged(&self) -> Tagged<&str> {
|
||||
self.item[..].tagged(self.tag.clone())
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Tagged<Vec<T>> {
|
||||
pub fn items(&self) -> impl Iterator<Item = &T> {
|
||||
self.item.iter()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> HasTag for Tagged<T> {
|
||||
fn tag(&self) -> Tag {
|
||||
self.tag.clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<Path> for Tagged<PathBuf> {
|
||||
fn as_ref(&self) -> &Path {
|
||||
self.item.as_ref()
|
||||
}
|
||||
}
|
||||
|
||||
pub trait TaggedItem: Sized {
|
||||
fn tagged(self, tag: impl Into<Tag>) -> Tagged<Self> {
|
||||
Tagged {
|
||||
item: self,
|
||||
tag: tag.into(),
|
||||
}
|
||||
}
|
||||
|
||||
// For now, this is a temporary facility. In many cases, there are other useful spans that we
|
||||
// could be using, such as the original source spans of JSON or Toml files, but we don't yet
|
||||
// have the infrastructure to make that work.
|
||||
fn tagged_unknown(self) -> Tagged<Self> {
|
||||
Tagged {
|
||||
item: self,
|
||||
tag: Tag {
|
||||
span: Span::unknown(),
|
||||
anchor: None,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> TaggedItem for T {}
|
||||
|
||||
impl<T> std::ops::Deref for Tagged<T> {
|
||||
type Target = T;
|
||||
|
||||
fn deref(&self) -> &T {
|
||||
&self.item
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Tagged<T> {
|
||||
pub fn map<U>(self, input: impl FnOnce(T) -> U) -> Tagged<U> {
|
||||
let tag = self.tag();
|
||||
|
||||
let mapped = input(self.item);
|
||||
mapped.tagged(tag)
|
||||
}
|
||||
|
||||
pub fn map_anchored(self, anchor: &Option<AnchorLocation>) -> Tagged<T> {
|
||||
let mut tag = self.tag;
|
||||
|
||||
tag.anchor = anchor.clone();
|
||||
|
||||
Tagged {
|
||||
item: self.item,
|
||||
tag: tag,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn transpose(&self) -> Tagged<&T> {
|
||||
Tagged {
|
||||
item: &self.item,
|
||||
tag: self.tag.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn tag(&self) -> Tag {
|
||||
self.tag.clone()
|
||||
}
|
||||
|
||||
pub fn span(&self) -> Span {
|
||||
self.tag.span
|
||||
}
|
||||
|
||||
pub fn anchor(&self) -> Option<AnchorLocation> {
|
||||
self.tag.anchor.clone()
|
||||
}
|
||||
|
||||
pub fn anchor_name(&self) -> Option<String> {
|
||||
match self.tag.anchor {
|
||||
Some(AnchorLocation::File(ref file)) => Some(file.clone()),
|
||||
Some(AnchorLocation::Url(ref url)) => Some(url.clone()),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn item(&self) -> &T {
|
||||
&self.item
|
||||
}
|
||||
|
||||
pub fn into_parts(self) -> (T, Tag) {
|
||||
(self.item, self.tag)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&Tag> for Tag {
|
||||
fn from(input: &Tag) -> Tag {
|
||||
input.clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> From<nom_locate::LocatedSpanEx<&str, T>> for Span {
|
||||
fn from(input: nom_locate::LocatedSpanEx<&str, T>) -> Span {
|
||||
Span::new(input.offset, input.offset + input.fragment.len())
|
||||
}
|
||||
}
|
||||
|
||||
impl<T>
|
||||
From<(
|
||||
nom_locate::LocatedSpanEx<T, u64>,
|
||||
nom_locate::LocatedSpanEx<T, u64>,
|
||||
)> for Span
|
||||
{
|
||||
fn from(
|
||||
input: (
|
||||
nom_locate::LocatedSpanEx<T, u64>,
|
||||
nom_locate::LocatedSpanEx<T, u64>,
|
||||
),
|
||||
) -> Span {
|
||||
Span {
|
||||
start: input.0.offset,
|
||||
end: input.1.offset,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<(usize, usize)> for Span {
|
||||
fn from(input: (usize, usize)) -> Span {
|
||||
Span::new(input.0, input.1)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&std::ops::Range<usize>> for Span {
|
||||
fn from(input: &std::ops::Range<usize>) -> Span {
|
||||
Span {
|
||||
start: input.start,
|
||||
end: input.end,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(
|
||||
Debug, Clone, PartialEq, Eq, Ord, PartialOrd, Serialize, Deserialize, Hash, Getters, new,
|
||||
)]
|
||||
pub struct Tag {
|
||||
pub anchor: Option<AnchorLocation>,
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
impl From<Span> for Tag {
|
||||
fn from(span: Span) -> Self {
|
||||
Tag { anchor: None, span }
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&Span> for Tag {
|
||||
fn from(span: &Span) -> Self {
|
||||
Tag {
|
||||
anchor: None,
|
||||
span: *span,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<(usize, usize, TracableContext)> for Tag {
|
||||
fn from((start, end, _context): (usize, usize, TracableContext)) -> Self {
|
||||
Tag {
|
||||
anchor: None,
|
||||
span: Span::new(start, end),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<(usize, usize, AnchorLocation)> for Tag {
|
||||
fn from((start, end, anchor): (usize, usize, AnchorLocation)) -> Self {
|
||||
Tag {
|
||||
anchor: Some(anchor),
|
||||
span: Span::new(start, end),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<(usize, usize, Option<AnchorLocation>)> for Tag {
|
||||
fn from((start, end, anchor): (usize, usize, Option<AnchorLocation>)) -> Self {
|
||||
Tag {
|
||||
anchor,
|
||||
span: Span::new(start, end),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<nom_locate::LocatedSpanEx<&str, TracableContext>> for Tag {
|
||||
fn from(input: nom_locate::LocatedSpanEx<&str, TracableContext>) -> Tag {
|
||||
Tag {
|
||||
anchor: None,
|
||||
span: Span::new(input.offset, input.offset + input.fragment.len()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Tag> for Span {
|
||||
fn from(tag: Tag) -> Self {
|
||||
tag.span
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&Tag> for Span {
|
||||
fn from(tag: &Tag) -> Self {
|
||||
tag.span
|
||||
}
|
||||
}
|
||||
|
||||
impl Tag {
|
||||
pub fn unknown_anchor(span: Span) -> Tag {
|
||||
Tag { anchor: None, span }
|
||||
}
|
||||
|
||||
pub fn for_char(pos: usize, anchor: AnchorLocation) -> Tag {
|
||||
Tag {
|
||||
anchor: Some(anchor),
|
||||
span: Span {
|
||||
start: pos,
|
||||
end: pos + 1,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn unknown_span(anchor: AnchorLocation) -> Tag {
|
||||
Tag {
|
||||
anchor: Some(anchor),
|
||||
span: Span::unknown(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn unknown() -> Tag {
|
||||
Tag {
|
||||
anchor: None,
|
||||
span: Span::unknown(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn anchor(&self) -> Option<AnchorLocation> {
|
||||
self.anchor.clone()
|
||||
}
|
||||
|
||||
pub fn until(&self, other: impl Into<Tag>) -> Tag {
|
||||
let other = other.into();
|
||||
debug_assert!(
|
||||
self.anchor == other.anchor,
|
||||
"Can only merge two tags with the same anchor"
|
||||
);
|
||||
|
||||
Tag {
|
||||
span: Span::new(self.span.start, other.span.end),
|
||||
anchor: self.anchor.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn until_option(&self, other: Option<impl Into<Tag>>) -> Tag {
|
||||
match other {
|
||||
Some(other) => {
|
||||
let other = other.into();
|
||||
debug_assert!(
|
||||
self.anchor == other.anchor,
|
||||
"Can only merge two tags with the same anchor"
|
||||
);
|
||||
|
||||
Tag {
|
||||
span: Span::new(self.span.start, other.span.end),
|
||||
anchor: self.anchor.clone(),
|
||||
}
|
||||
}
|
||||
None => self.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn slice<'a>(&self, source: &'a str) -> &'a str {
|
||||
self.span.slice(source)
|
||||
}
|
||||
|
||||
pub fn string<'a>(&self, source: &'a str) -> String {
|
||||
self.span.slice(source).to_string()
|
||||
}
|
||||
|
||||
pub fn tagged_slice<'a>(&self, source: &'a str) -> Tagged<&'a str> {
|
||||
self.span.slice(source).tagged(self)
|
||||
}
|
||||
|
||||
pub fn tagged_string<'a>(&self, source: &'a str) -> Tagged<String> {
|
||||
self.span.slice(source).to_string().tagged(self)
|
||||
}
|
||||
|
||||
pub fn anchor_name(&self) -> Option<String> {
|
||||
match self.anchor {
|
||||
Some(AnchorLocation::File(ref file)) => Some(file.clone()),
|
||||
Some(AnchorLocation::Url(ref url)) => Some(url.clone()),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
pub fn tag_for_tagged_list(mut iter: impl Iterator<Item = Tag>) -> Tag {
|
||||
let first = iter.next();
|
||||
|
||||
let first = match first {
|
||||
None => return Tag::unknown(),
|
||||
Some(first) => first,
|
||||
};
|
||||
|
||||
let last = iter.last();
|
||||
|
||||
match last {
|
||||
None => first,
|
||||
Some(last) => first.until(last),
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
pub fn span_for_spanned_list(mut iter: impl Iterator<Item = Span>) -> Span {
|
||||
let first = iter.next();
|
||||
|
||||
let first = match first {
|
||||
None => return Span::unknown(),
|
||||
Some(first) => first,
|
||||
};
|
||||
|
||||
let last = iter.last();
|
||||
|
||||
match last {
|
||||
None => first,
|
||||
Some(last) => first.until(last),
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Ord, PartialOrd, Serialize, Deserialize, Hash)]
|
||||
pub struct Span {
|
||||
start: usize,
|
||||
end: usize,
|
||||
}
|
||||
|
||||
impl From<&Span> for Span {
|
||||
fn from(span: &Span) -> Span {
|
||||
*span
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Option<Span>> for Span {
|
||||
fn from(input: Option<Span>) -> Span {
|
||||
match input {
|
||||
None => Span::new(0, 0),
|
||||
Some(span) => span,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Span {
|
||||
pub fn unknown() -> Span {
|
||||
Span::new(0, 0)
|
||||
}
|
||||
|
||||
pub fn new(start: usize, end: usize) -> Span {
|
||||
assert!(
|
||||
end >= start,
|
||||
"Can't create a Span whose end < start, start={}, end={}",
|
||||
start,
|
||||
end
|
||||
);
|
||||
|
||||
Span { start, end }
|
||||
}
|
||||
|
||||
pub fn for_char(pos: usize) -> Span {
|
||||
Span {
|
||||
start: pos,
|
||||
end: pos + 1,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn until(&self, other: impl Into<Span>) -> Span {
|
||||
let other = other.into();
|
||||
|
||||
Span::new(self.start, other.end)
|
||||
}
|
||||
|
||||
pub fn until_option(&self, other: Option<impl Into<Span>>) -> Span {
|
||||
match other {
|
||||
Some(other) => {
|
||||
let other = other.into();
|
||||
|
||||
Span::new(self.start, other.end)
|
||||
}
|
||||
None => *self,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn string<'a>(&self, source: &'a str) -> String {
|
||||
self.slice(source).to_string()
|
||||
}
|
||||
|
||||
pub fn spanned_slice<'a>(&self, source: &'a str) -> Spanned<&'a str> {
|
||||
self.slice(source).spanned(*self)
|
||||
}
|
||||
|
||||
pub fn spanned_string<'a>(&self, source: &'a str) -> Spanned<String> {
|
||||
self.slice(source).to_string().spanned(*self)
|
||||
}
|
||||
|
||||
pub fn start(&self) -> usize {
|
||||
self.start
|
||||
}
|
||||
|
||||
pub fn end(&self) -> usize {
|
||||
self.end
|
||||
}
|
||||
|
||||
pub fn is_unknown(&self) -> bool {
|
||||
self.start == 0 && self.end == 0
|
||||
}
|
||||
|
||||
pub fn slice<'a>(&self, source: &'a str) -> &'a str {
|
||||
&source[self.start..self.end]
|
||||
}
|
||||
}
|
||||
|
||||
impl language_reporting::ReportingSpan for Span {
|
||||
fn with_start(&self, start: usize) -> Self {
|
||||
Span::new(start, self.end)
|
||||
}
|
||||
|
||||
fn with_end(&self, end: usize) -> Self {
|
||||
Span::new(self.start, end)
|
||||
}
|
||||
|
||||
fn start(&self) -> usize {
|
||||
self.start
|
||||
}
|
||||
|
||||
fn end(&self) -> usize {
|
||||
self.end
|
||||
}
|
||||
}
|
||||
|
||||
pub trait HasSpan: PrettyDebugWithSource {
|
||||
fn span(&self) -> Span;
|
||||
}
|
||||
|
||||
pub trait HasFallibleSpan: PrettyDebugWithSource {
|
||||
fn maybe_span(&self) -> Option<Span>;
|
||||
}
|
||||
|
||||
impl<T: HasSpan> HasFallibleSpan for T {
|
||||
fn maybe_span(&self) -> Option<Span> {
|
||||
Some(HasSpan::span(self))
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> HasSpan for Spanned<T>
|
||||
where
|
||||
Spanned<T>: PrettyDebugWithSource,
|
||||
{
|
||||
fn span(&self) -> Span {
|
||||
self.span
|
||||
}
|
||||
}
|
||||
|
||||
impl PrettyDebugWithSource for Option<Span> {
|
||||
fn pretty_debug(&self, source: &str) -> DebugDocBuilder {
|
||||
match self {
|
||||
None => b::description("no span"),
|
||||
Some(span) => span.pretty_debug(source),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl HasFallibleSpan for Option<Span> {
|
||||
fn maybe_span(&self) -> Option<Span> {
|
||||
*self
|
||||
}
|
||||
}
|
||||
|
||||
impl PrettyDebugWithSource for Span {
|
||||
fn pretty_debug(&self, source: &str) -> DebugDocBuilder {
|
||||
b::typed(
|
||||
"spanned",
|
||||
b::keyword("for") + b::space() + b::description(format!("{:?}", source)),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl HasSpan for Span {
|
||||
fn span(&self) -> Span {
|
||||
*self
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> PrettyDebugWithSource for Option<Spanned<T>>
|
||||
where
|
||||
Spanned<T>: PrettyDebugWithSource,
|
||||
{
|
||||
fn pretty_debug(&self, source: &str) -> DebugDocBuilder {
|
||||
match self {
|
||||
None => b::description("nothing"),
|
||||
Some(v) => v.pretty_debug(source),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> HasFallibleSpan for Option<Spanned<T>>
|
||||
where
|
||||
Spanned<T>: PrettyDebugWithSource,
|
||||
{
|
||||
fn maybe_span(&self) -> Option<Span> {
|
||||
match self {
|
||||
None => None,
|
||||
Some(value) => Some(value.span),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> PrettyDebugWithSource for Option<Tagged<T>>
|
||||
where
|
||||
Tagged<T>: PrettyDebugWithSource,
|
||||
{
|
||||
fn pretty_debug(&self, source: &str) -> DebugDocBuilder {
|
||||
match self {
|
||||
None => b::description("nothing"),
|
||||
Some(d) => d.pretty_debug(source),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> HasFallibleSpan for Option<Tagged<T>>
|
||||
where
|
||||
Tagged<T>: PrettyDebugWithSource,
|
||||
{
|
||||
fn maybe_span(&self) -> Option<Span> {
|
||||
match self {
|
||||
None => None,
|
||||
Some(value) => Some(value.tag.span),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> HasSpan for Tagged<T>
|
||||
where
|
||||
Tagged<T>: PrettyDebugWithSource,
|
||||
{
|
||||
fn span(&self) -> Span {
|
||||
self.tag.span
|
||||
}
|
||||
}
|
495
crates/nu-source/src/pretty.rs
Normal file
495
crates/nu-source/src/pretty.rs
Normal file
@ -0,0 +1,495 @@
|
||||
use crate::term_colored::TermColored;
|
||||
use crate::text::Text;
|
||||
use derive_new::new;
|
||||
use pretty::{BoxAllocator, DocAllocator};
|
||||
use std::hash::Hash;
|
||||
use termcolor::{Color, ColorSpec};
|
||||
|
||||
#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd, Hash)]
|
||||
pub enum ShellStyle {
|
||||
Delimiter,
|
||||
Key,
|
||||
Value,
|
||||
Equals,
|
||||
Kind,
|
||||
Keyword,
|
||||
Operator,
|
||||
Variable,
|
||||
Primitive,
|
||||
Opaque,
|
||||
Description,
|
||||
Error,
|
||||
}
|
||||
|
||||
impl From<ShellAnnotation> for ColorSpec {
|
||||
fn from(ann: ShellAnnotation) -> ColorSpec {
|
||||
match ann.style {
|
||||
ShellStyle::Delimiter => ColorSpec::new()
|
||||
.set_fg(Some(Color::White))
|
||||
.set_intense(false)
|
||||
.clone(),
|
||||
ShellStyle::Key => ColorSpec::new()
|
||||
.set_fg(Some(Color::Black))
|
||||
.set_intense(true)
|
||||
.clone(),
|
||||
ShellStyle::Value => ColorSpec::new()
|
||||
.set_fg(Some(Color::White))
|
||||
.set_intense(true)
|
||||
.clone(),
|
||||
ShellStyle::Equals => ColorSpec::new()
|
||||
.set_fg(Some(Color::Black))
|
||||
.set_intense(true)
|
||||
.clone(),
|
||||
ShellStyle::Kind => ColorSpec::new().set_fg(Some(Color::Cyan)).clone(),
|
||||
ShellStyle::Variable => ColorSpec::new()
|
||||
.set_fg(Some(Color::Green))
|
||||
.set_intense(true)
|
||||
.clone(),
|
||||
ShellStyle::Keyword => ColorSpec::new().set_fg(Some(Color::Magenta)).clone(),
|
||||
ShellStyle::Operator => ColorSpec::new().set_fg(Some(Color::Yellow)).clone(),
|
||||
ShellStyle::Primitive => ColorSpec::new()
|
||||
.set_fg(Some(Color::Green))
|
||||
.set_intense(true)
|
||||
.clone(),
|
||||
ShellStyle::Opaque => ColorSpec::new()
|
||||
.set_fg(Some(Color::Yellow))
|
||||
.set_intense(true)
|
||||
.clone(),
|
||||
ShellStyle::Description => ColorSpec::new()
|
||||
.set_fg(Some(Color::Black))
|
||||
.set_intense(true)
|
||||
.clone(),
|
||||
ShellStyle::Error => ColorSpec::new()
|
||||
.set_fg(Some(Color::Red))
|
||||
.set_intense(true)
|
||||
.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Eq, Ord, PartialEq, PartialOrd, Hash, new)]
|
||||
pub struct ShellAnnotation {
|
||||
style: ShellStyle,
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for ShellAnnotation {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "{:?}", self.style)
|
||||
}
|
||||
}
|
||||
|
||||
impl ShellAnnotation {
|
||||
pub fn style(style: impl Into<ShellStyle>) -> ShellAnnotation {
|
||||
ShellAnnotation {
|
||||
style: style.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub type PrettyDebugDoc =
|
||||
pretty::Doc<'static, pretty::BoxDoc<'static, ShellAnnotation>, ShellAnnotation>;
|
||||
|
||||
pub type PrettyDebugDocBuilder = pretty::DocBuilder<'static, pretty::BoxAllocator, ShellAnnotation>;
|
||||
|
||||
pub use self::DebugDocBuilder as b;
|
||||
|
||||
#[derive(Clone, new)]
|
||||
pub struct DebugDocBuilder {
|
||||
pub inner: PrettyDebugDocBuilder,
|
||||
}
|
||||
|
||||
impl PrettyDebug for DebugDocBuilder {
|
||||
fn pretty(&self) -> DebugDocBuilder {
|
||||
self.clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::Add for DebugDocBuilder {
|
||||
type Output = DebugDocBuilder;
|
||||
|
||||
fn add(self, rhs: DebugDocBuilder) -> DebugDocBuilder {
|
||||
DebugDocBuilder::new(self.inner.append(rhs.inner))
|
||||
}
|
||||
}
|
||||
|
||||
impl DebugDocBuilder {
|
||||
pub fn from_doc(doc: DebugDoc) -> DebugDocBuilder {
|
||||
DebugDocBuilder {
|
||||
inner: BoxAllocator.nil().append(doc),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn blank() -> DebugDocBuilder {
|
||||
BoxAllocator.nil().into()
|
||||
}
|
||||
|
||||
pub fn delimiter(string: impl std::fmt::Display) -> DebugDocBuilder {
|
||||
DebugDocBuilder::styled(string, ShellStyle::Delimiter)
|
||||
}
|
||||
|
||||
pub fn key(string: impl std::fmt::Display) -> DebugDocBuilder {
|
||||
DebugDocBuilder::styled(string, ShellStyle::Key)
|
||||
}
|
||||
|
||||
pub fn value(string: impl std::fmt::Display) -> DebugDocBuilder {
|
||||
DebugDocBuilder::styled(string, ShellStyle::Value)
|
||||
}
|
||||
|
||||
pub fn as_value(self) -> DebugDocBuilder {
|
||||
self.inner
|
||||
.annotate(ShellAnnotation::style(ShellStyle::Value))
|
||||
.into()
|
||||
}
|
||||
|
||||
pub fn equals() -> DebugDocBuilder {
|
||||
DebugDocBuilder::styled("=", ShellStyle::Equals)
|
||||
}
|
||||
|
||||
pub fn kind(string: impl std::fmt::Display) -> DebugDocBuilder {
|
||||
DebugDocBuilder::styled(string, ShellStyle::Kind)
|
||||
}
|
||||
|
||||
pub fn as_kind(self) -> DebugDocBuilder {
|
||||
self.inner
|
||||
.annotate(ShellAnnotation::style(ShellStyle::Kind))
|
||||
.into()
|
||||
}
|
||||
|
||||
pub fn typed(kind: &str, value: DebugDocBuilder) -> DebugDocBuilder {
|
||||
b::delimit("(", b::kind(kind) + b::space() + value.group(), ")").group()
|
||||
}
|
||||
|
||||
pub fn subtyped(
|
||||
kind: &str,
|
||||
subkind: impl std::fmt::Display,
|
||||
value: DebugDocBuilder,
|
||||
) -> DebugDocBuilder {
|
||||
b::delimit(
|
||||
"(",
|
||||
(b::kind(kind) + b::delimit("[", b::kind(format!("{}", subkind)), "]")).group()
|
||||
+ b::space()
|
||||
+ value.group(),
|
||||
")",
|
||||
)
|
||||
.group()
|
||||
}
|
||||
|
||||
pub fn keyword(string: impl std::fmt::Display) -> DebugDocBuilder {
|
||||
DebugDocBuilder::styled(string, ShellStyle::Keyword)
|
||||
}
|
||||
|
||||
pub fn var(string: impl std::fmt::Display) -> DebugDocBuilder {
|
||||
DebugDocBuilder::styled(string, ShellStyle::Variable)
|
||||
}
|
||||
|
||||
pub fn operator(string: impl std::fmt::Display) -> DebugDocBuilder {
|
||||
DebugDocBuilder::styled(string, ShellStyle::Operator)
|
||||
}
|
||||
|
||||
pub fn primitive(string: impl std::fmt::Display) -> DebugDocBuilder {
|
||||
DebugDocBuilder::styled(format!("{}", string), ShellStyle::Primitive)
|
||||
}
|
||||
|
||||
pub fn opaque(string: impl std::fmt::Display) -> DebugDocBuilder {
|
||||
DebugDocBuilder::styled(string, ShellStyle::Opaque)
|
||||
}
|
||||
|
||||
pub fn description(string: impl std::fmt::Display) -> DebugDocBuilder {
|
||||
DebugDocBuilder::styled(string, ShellStyle::Description)
|
||||
}
|
||||
|
||||
pub fn error(string: impl std::fmt::Display) -> DebugDocBuilder {
|
||||
DebugDocBuilder::styled(string, ShellStyle::Error)
|
||||
}
|
||||
|
||||
pub fn delimit(start: &str, doc: DebugDocBuilder, end: &str) -> DebugDocBuilder {
|
||||
DebugDocBuilder::delimiter(start) + doc + DebugDocBuilder::delimiter(end)
|
||||
}
|
||||
|
||||
pub fn preceded(before: DebugDocBuilder, body: DebugDocBuilder) -> DebugDocBuilder {
|
||||
if body.is_empty() {
|
||||
body
|
||||
} else {
|
||||
before + body
|
||||
}
|
||||
}
|
||||
|
||||
pub fn surrounded_option(
|
||||
before: Option<DebugDocBuilder>,
|
||||
builder: Option<DebugDocBuilder>,
|
||||
after: Option<DebugDocBuilder>,
|
||||
) -> DebugDocBuilder {
|
||||
match builder {
|
||||
None => DebugDocBuilder::blank(),
|
||||
Some(b) => b::option(before) + b + b::option(after),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn preceded_option(
|
||||
before: Option<DebugDocBuilder>,
|
||||
builder: Option<DebugDocBuilder>,
|
||||
) -> DebugDocBuilder {
|
||||
DebugDocBuilder::surrounded_option(before, builder, None)
|
||||
}
|
||||
|
||||
pub fn option(builder: Option<DebugDocBuilder>) -> DebugDocBuilder {
|
||||
match builder {
|
||||
None => DebugDocBuilder::blank(),
|
||||
Some(b) => b,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn space() -> DebugDocBuilder {
|
||||
BoxAllocator.space().into()
|
||||
}
|
||||
|
||||
pub fn newline() -> DebugDocBuilder {
|
||||
BoxAllocator.newline().into()
|
||||
}
|
||||
|
||||
pub fn is_empty(&self) -> bool {
|
||||
match &self.inner.1 {
|
||||
pretty::Doc::Nil => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn or(self, doc: DebugDocBuilder) -> DebugDocBuilder {
|
||||
if self.is_empty() {
|
||||
doc
|
||||
} else {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
pub fn group(self) -> DebugDocBuilder {
|
||||
self.inner.group().into()
|
||||
}
|
||||
|
||||
pub fn nest(self) -> DebugDocBuilder {
|
||||
self.inner.nest(1).group().into()
|
||||
}
|
||||
|
||||
pub fn intersperse_with_source<'a, T: PrettyDebugWithSource + 'a>(
|
||||
list: impl IntoIterator<Item = &'a T>,
|
||||
separator: DebugDocBuilder,
|
||||
source: &str,
|
||||
) -> DebugDocBuilder {
|
||||
BoxAllocator
|
||||
.intersperse(
|
||||
list.into_iter().filter_map(|item| {
|
||||
let item = item.pretty_debug(source);
|
||||
if item.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(item)
|
||||
}
|
||||
}),
|
||||
separator,
|
||||
)
|
||||
.into()
|
||||
}
|
||||
|
||||
pub fn intersperse<T: PrettyDebug>(
|
||||
list: impl IntoIterator<Item = T>,
|
||||
separator: DebugDocBuilder,
|
||||
) -> DebugDocBuilder {
|
||||
BoxAllocator
|
||||
.intersperse(
|
||||
list.into_iter().filter_map(|item| {
|
||||
let item = item.pretty();
|
||||
if item.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(item)
|
||||
}
|
||||
}),
|
||||
separator,
|
||||
)
|
||||
.into()
|
||||
}
|
||||
|
||||
pub fn list(list: impl IntoIterator<Item = DebugDocBuilder>) -> DebugDocBuilder {
|
||||
let mut result: DebugDocBuilder = BoxAllocator.nil().into();
|
||||
|
||||
for item in list {
|
||||
result = result + item;
|
||||
}
|
||||
|
||||
result.into()
|
||||
}
|
||||
|
||||
fn styled(string: impl std::fmt::Display, style: ShellStyle) -> DebugDocBuilder {
|
||||
BoxAllocator
|
||||
.text(string.to_string())
|
||||
.annotate(ShellAnnotation::style(style))
|
||||
.into()
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::Deref for DebugDocBuilder {
|
||||
type Target = PrettyDebugDocBuilder;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.inner
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd, new)]
|
||||
pub struct DebugDoc {
|
||||
pub inner: PrettyDebugDoc,
|
||||
}
|
||||
|
||||
pub trait PrettyDebugWithSource: Sized {
|
||||
fn pretty_debug(&self, source: &str) -> DebugDocBuilder;
|
||||
|
||||
// This is a transitional convenience method
|
||||
fn debug(&self, source: impl Into<Text>) -> String
|
||||
where
|
||||
Self: Clone,
|
||||
{
|
||||
self.clone().debuggable(source).display()
|
||||
}
|
||||
|
||||
fn debuggable(self, source: impl Into<Text>) -> DebuggableWithSource<Self> {
|
||||
DebuggableWithSource {
|
||||
inner: self,
|
||||
source: source.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: PrettyDebug> PrettyDebugWithSource for T {
|
||||
fn pretty_debug(&self, _source: &str) -> DebugDocBuilder {
|
||||
self.pretty()
|
||||
}
|
||||
}
|
||||
|
||||
pub struct DebuggableWithSource<T: PrettyDebugWithSource> {
|
||||
inner: T,
|
||||
source: Text,
|
||||
}
|
||||
|
||||
impl<T> PrettyDebug for DebuggableWithSource<T>
|
||||
where
|
||||
T: PrettyDebugWithSource,
|
||||
{
|
||||
fn pretty(&self) -> DebugDocBuilder {
|
||||
self.inner.pretty_debug(&self.source)
|
||||
}
|
||||
}
|
||||
|
||||
impl PrettyDebug for DebugDoc {
|
||||
fn pretty(&self) -> DebugDocBuilder {
|
||||
DebugDocBuilder::new(BoxAllocator.nil().append(self.inner.clone()))
|
||||
}
|
||||
}
|
||||
|
||||
pub trait PrettyDebug {
|
||||
fn pretty(&self) -> DebugDocBuilder;
|
||||
|
||||
fn to_doc(&self) -> DebugDoc {
|
||||
DebugDoc::new(self.pretty().into())
|
||||
}
|
||||
|
||||
fn pretty_doc(&self) -> PrettyDebugDoc {
|
||||
let builder = self.pretty();
|
||||
builder.inner.into()
|
||||
}
|
||||
|
||||
fn pretty_builder(&self) -> PrettyDebugDocBuilder {
|
||||
let doc = self.pretty();
|
||||
doc.inner
|
||||
}
|
||||
|
||||
/// A convenience method that prints out the document without colors in
|
||||
/// 70 columns. Generally, you should use plain_string or colored_string
|
||||
/// if possible, but display() can be useful for trace lines and things
|
||||
/// like that, where you don't have control over the terminal.
|
||||
fn display(&self) -> String {
|
||||
self.plain_string(70)
|
||||
}
|
||||
|
||||
fn plain_string(&self, width: usize) -> String {
|
||||
let doc = self.pretty_doc();
|
||||
let mut buffer = termcolor::Buffer::no_color();
|
||||
|
||||
doc.render_raw(width, &mut TermColored::new(&mut buffer))
|
||||
.unwrap();
|
||||
|
||||
String::from_utf8_lossy(buffer.as_slice()).to_string()
|
||||
}
|
||||
|
||||
fn colored_string(&self, width: usize) -> String {
|
||||
let doc = self.pretty_doc();
|
||||
let mut buffer = termcolor::Buffer::ansi();
|
||||
|
||||
doc.render_raw(width, &mut TermColored::new(&mut buffer))
|
||||
.unwrap();
|
||||
|
||||
String::from_utf8_lossy(buffer.as_slice()).to_string()
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<DebugDocBuilder> for PrettyDebugDocBuilder {
|
||||
fn into(self) -> DebugDocBuilder {
|
||||
DebugDocBuilder { inner: self }
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::Deref for DebugDoc {
|
||||
type Target = PrettyDebugDoc;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.inner
|
||||
}
|
||||
}
|
||||
|
||||
impl From<DebugDoc> for PrettyDebugDoc {
|
||||
fn from(input: DebugDoc) -> PrettyDebugDoc {
|
||||
input.inner
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<PrettyDebugDoc> for DebugDocBuilder {
|
||||
fn into(self) -> PrettyDebugDoc {
|
||||
self.inner.into()
|
||||
}
|
||||
}
|
||||
|
||||
fn hash_doc<H: std::hash::Hasher>(doc: &PrettyDebugDoc, state: &mut H) {
|
||||
match doc {
|
||||
pretty::Doc::Nil => 0u8.hash(state),
|
||||
pretty::Doc::Append(a, b) => {
|
||||
1u8.hash(state);
|
||||
hash_doc(&*a, state);
|
||||
hash_doc(&*b, state);
|
||||
}
|
||||
pretty::Doc::Group(a) => {
|
||||
2u8.hash(state);
|
||||
hash_doc(&*a, state);
|
||||
}
|
||||
pretty::Doc::Nest(a, b) => {
|
||||
3u8.hash(state);
|
||||
a.hash(state);
|
||||
hash_doc(&*b, state);
|
||||
}
|
||||
pretty::Doc::Space => 4u8.hash(state),
|
||||
pretty::Doc::Newline => 5u8.hash(state),
|
||||
pretty::Doc::Text(t) => {
|
||||
6u8.hash(state);
|
||||
t.hash(state);
|
||||
}
|
||||
pretty::Doc::Annotated(a, b) => {
|
||||
7u8.hash(state);
|
||||
a.hash(state);
|
||||
hash_doc(&*b, state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::hash::Hash for DebugDoc {
|
||||
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
|
||||
hash_doc(&self.inner, state);
|
||||
}
|
||||
}
|
51
crates/nu-source/src/term_colored.rs
Normal file
51
crates/nu-source/src/term_colored.rs
Normal file
@ -0,0 +1,51 @@
|
||||
use crate::pretty::ShellAnnotation;
|
||||
use pretty::{Render, RenderAnnotated};
|
||||
use std::io;
|
||||
use termcolor::WriteColor;
|
||||
|
||||
pub struct TermColored<'a, W> {
|
||||
color_stack: Vec<ShellAnnotation>,
|
||||
upstream: &'a mut W,
|
||||
}
|
||||
|
||||
impl<'a, W> TermColored<'a, W> {
|
||||
pub fn new(upstream: &'a mut W) -> TermColored<'a, W> {
|
||||
TermColored {
|
||||
color_stack: Vec::new(),
|
||||
upstream,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, W> Render for TermColored<'a, W>
|
||||
where
|
||||
W: io::Write,
|
||||
{
|
||||
type Error = io::Error;
|
||||
|
||||
fn write_str(&mut self, s: &str) -> io::Result<usize> {
|
||||
self.upstream.write(s.as_bytes())
|
||||
}
|
||||
|
||||
fn write_str_all(&mut self, s: &str) -> io::Result<()> {
|
||||
self.upstream.write_all(s.as_bytes())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, W> RenderAnnotated<ShellAnnotation> for TermColored<'a, W>
|
||||
where
|
||||
W: WriteColor,
|
||||
{
|
||||
fn push_annotation(&mut self, ann: &ShellAnnotation) -> Result<(), Self::Error> {
|
||||
self.color_stack.push(*ann);
|
||||
self.upstream.set_color(&(*ann).into())
|
||||
}
|
||||
|
||||
fn pop_annotation(&mut self) -> Result<(), Self::Error> {
|
||||
self.color_stack.pop();
|
||||
match self.color_stack.last() {
|
||||
Some(previous) => self.upstream.set_color(&(*previous).into()),
|
||||
None => self.upstream.reset(),
|
||||
}
|
||||
}
|
||||
}
|
@ -74,6 +74,12 @@ impl From<&str> for Text {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&Text> for Text {
|
||||
fn from(text: &Text) -> Self {
|
||||
text.clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl std::borrow::Borrow<str> for Text {
|
||||
fn borrow(&self) -> &str {
|
||||
&*self
|
||||
@ -213,7 +219,7 @@ impl Serialize for Text {
|
||||
}
|
||||
}
|
||||
|
||||
impl Deserialize<'de> for Text {
|
||||
impl<'de> Deserialize<'de> for Text {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
32
crates/nu-source/src/tracable.rs
Normal file
32
crates/nu-source/src/tracable.rs
Normal file
@ -0,0 +1,32 @@
|
||||
use derive_new::new;
|
||||
use nom_locate::LocatedSpanEx;
|
||||
use nom_tracable::{HasTracableInfo, TracableInfo};
|
||||
|
||||
pub type NomSpan<'a> = LocatedSpanEx<&'a str, TracableContext>;
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, new)]
|
||||
pub struct TracableContext {
|
||||
pub(crate) info: TracableInfo,
|
||||
}
|
||||
|
||||
impl HasTracableInfo for TracableContext {
|
||||
fn get_tracable_info(&self) -> TracableInfo {
|
||||
self.info
|
||||
}
|
||||
|
||||
fn set_tracable_info(self, info: TracableInfo) -> Self {
|
||||
TracableContext { info }
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::Deref for TracableContext {
|
||||
type Target = TracableInfo;
|
||||
|
||||
fn deref(&self) -> &TracableInfo {
|
||||
&self.info
|
||||
}
|
||||
}
|
||||
|
||||
pub fn nom_input(s: &str) -> NomSpan<'_> {
|
||||
LocatedSpanEx::new_extra(s, TracableContext::new(TracableInfo::new()))
|
||||
}
|
5
debian/changelog
vendored
Normal file
5
debian/changelog
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
nu (0.2.0-1) unstable; urgency=low
|
||||
|
||||
* Initial release
|
||||
|
||||
-- Jan Koprowski <jan.koprowski@gmail.com> Wed, 04 Sep 2019 21:38:44 +0200
|
1
debian/compat
vendored
Normal file
1
debian/compat
vendored
Normal file
@ -0,0 +1 @@
|
||||
10
|
18
debian/control
vendored
Normal file
18
debian/control
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
Source: nu
|
||||
Section: shells
|
||||
Priority: optional
|
||||
Maintainer: Jan Koprowski <jan.koprowski@gmail.com>
|
||||
Build-Depends: debhelper (>= 10)
|
||||
Standards-Version: 4.1.2
|
||||
Homepage: https://github.com/nushell/nushell
|
||||
Vcs-Git: https://github.com/nushell/nushell.git
|
||||
Vcs-Browser: https://github.com/nushell/nushell
|
||||
|
||||
Package: nu
|
||||
Architecture: any
|
||||
Depends: ${shlibs:Depends}, ${misc:Depends}
|
||||
Description: A modern shell for the GitHub era
|
||||
The goal of this project is to take the Unix
|
||||
philosophy of shells, where pipes connect simple
|
||||
commands together, and bring it to the modern
|
||||
style of development.
|
32
debian/copyright
vendored
Normal file
32
debian/copyright
vendored
Normal file
@ -0,0 +1,32 @@
|
||||
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
|
||||
Upstream-Name: nu
|
||||
Source: https://github.com/nushell/nushell
|
||||
|
||||
Files: *
|
||||
Copyright: 2019 Yehuda Katz
|
||||
2019 Jonathan Turner
|
||||
License: MIT
|
||||
|
||||
Files: debian/*
|
||||
Copyright: 2019 Yehuda Katz
|
||||
2019 Jonathan Turner
|
||||
License: MIT
|
||||
|
||||
License: MIT
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following conditions:
|
||||
.
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
.
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
11
debian/install
vendored
Normal file
11
debian/install
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
target/release/nu usr/bin
|
||||
target/release/nu_plugin_binaryview usr/bin
|
||||
target/release/nu_plugin_edit usr/bin
|
||||
target/release/nu_plugin_inc usr/bin
|
||||
target/release/nu_plugin_skip usr/bin
|
||||
target/release/nu_plugin_str usr/bin
|
||||
target/release/nu_plugin_sum usr/bin
|
||||
target/release/nu_plugin_sys usr/bin
|
||||
target/release/nu_plugin_textview usr/bin
|
||||
target/release/nu_plugin_tree usr/bin
|
||||
target/release/nu_plugin_docker usr/bin
|
8
debian/postinst
vendored
Normal file
8
debian/postinst
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
#! /bin/bash
|
||||
|
||||
if [ "$1" = configure ] && which add-shell >/dev/null
|
||||
then
|
||||
add-shell /usr/bin/nu
|
||||
fi
|
||||
|
||||
exit 0
|
17
debian/postrm
vendored
Normal file
17
debian/postrm
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
case "$1" in
|
||||
upgrade|failed-upgrade|abort-install|abort-upgrade)
|
||||
;;
|
||||
remove|purge|disappear)
|
||||
if which remove-shell >/dev/null && [ -f /etc/shells ]; then
|
||||
remove-shell /usr/bin/nu
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
echo "postrm called with unknown argument \`$1'" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
25
debian/rules
vendored
Executable file
25
debian/rules
vendored
Executable file
@ -0,0 +1,25 @@
|
||||
#!/usr/bin/make -f
|
||||
# See debhelper(7) (uncomment to enable)
|
||||
# output every command that modifies files on the build system.
|
||||
#export DH_VERBOSE = 1
|
||||
|
||||
|
||||
# see FEATURE AREAS in dpkg-buildflags(1)
|
||||
#export DEB_BUILD_MAINT_OPTIONS = hardening=+all
|
||||
|
||||
# see ENVIRONMENT in dpkg-buildflags(1)
|
||||
# package maintainers to append CFLAGS
|
||||
#export DEB_CFLAGS_MAINT_APPEND = -Wall -pedantic
|
||||
# package maintainers to append LDFLAGS
|
||||
#export DEB_LDFLAGS_MAINT_APPEND = -Wl,--as-needed
|
||||
|
||||
|
||||
%:
|
||||
dh $@
|
||||
|
||||
|
||||
# dh_make generated override targets
|
||||
# This is example for Cmake (See https://bugs.debian.org/641051 )
|
||||
#override_dh_auto_configure:
|
||||
# dh_auto_configure -- # -DCMAKE_LIBRARY_PATH=$(DEB_HOST_MULTIARCH)
|
||||
|
1
debian/source/format
vendored
Normal file
1
debian/source/format
vendored
Normal file
@ -0,0 +1 @@
|
||||
3.0 (quilt)
|
9
docker/Dockerfile
Normal file
9
docker/Dockerfile
Normal file
@ -0,0 +1,9 @@
|
||||
ARG FROMTAG=latest
|
||||
FROM quay.io/nushell/nu-base:${FROMTAG} as base
|
||||
FROM ubuntu:18.04
|
||||
COPY --from=base /usr/local/bin/nu /usr/local/bin/nu
|
||||
ENV DEBIAN_FRONTEND noninteractive
|
||||
RUN apt-get update && apt-get install -y libssl-dev \
|
||||
pkg-config
|
||||
ENTRYPOINT ["nu"]
|
||||
CMD ["-l", "info"]
|
25
docker/Dockerfile.nu-base
Normal file
25
docker/Dockerfile.nu-base
Normal file
@ -0,0 +1,25 @@
|
||||
FROM ubuntu:18.04
|
||||
|
||||
# docker build -f docker/Dockerfile.nu-base -t nushell/nu-base .
|
||||
# docker run -it nushell/nu-base
|
||||
|
||||
ENV DEBIAN_FRONTEND noninteractive
|
||||
RUN apt-get update && apt-get install -y libssl-dev \
|
||||
libxcb-composite0-dev \
|
||||
pkg-config \
|
||||
curl
|
||||
|
||||
ARG RELEASE=false
|
||||
WORKDIR /code
|
||||
RUN curl https://sh.rustup.rs -sSf | sh -s -- -y --no-modify-path --default-toolchain "stable"
|
||||
ENV PATH=/root/.cargo/bin:$PATH
|
||||
RUN rustup update
|
||||
COPY . /code
|
||||
RUN echo "##vso[task.prependpath]/root/.cargo/bin" && \
|
||||
rustc -Vv && \
|
||||
if $RELEASE; then cargo build --release; \
|
||||
cp target/release/nu /usr/local/bin; \
|
||||
else cargo build; \
|
||||
cp target/debug/nu /usr/local/bin; fi;
|
||||
ENTRYPOINT ["nu"]
|
||||
CMD ["-l", "info"]
|
7
docker/Package.Dockerfile
Normal file
7
docker/Package.Dockerfile
Normal file
@ -0,0 +1,7 @@
|
||||
ARG base
|
||||
FROM ${base}
|
||||
|
||||
ARG artifact
|
||||
COPY ${artifact} /bin/
|
||||
|
||||
ENTRYPOINT ["/bin/nu"]
|
15
docker/Package.glibc-busybox.Dockerfile
Normal file
15
docker/Package.glibc-busybox.Dockerfile
Normal file
@ -0,0 +1,15 @@
|
||||
ARG base
|
||||
FROM debian:stable-slim AS patch
|
||||
FROM ${base}
|
||||
|
||||
ARG artifact
|
||||
COPY ${artifact} /bin/
|
||||
|
||||
COPY --from=patch \
|
||||
/lib/x86_64-linux-gnu/libz.so.1 \
|
||||
/lib/x86_64-linux-gnu/libdl.so.2 \
|
||||
/lib/x86_64-linux-gnu/librt.so.1 \
|
||||
/lib/x86_64-linux-gnu/libgcc_s.so.1 \
|
||||
/lib/x86_64-linux-gnu/
|
||||
|
||||
ENTRYPOINT ["/bin/nu"]
|
12
docker/Package.glibc-distroless.Dockerfile
Normal file
12
docker/Package.glibc-distroless.Dockerfile
Normal file
@ -0,0 +1,12 @@
|
||||
ARG base
|
||||
FROM debian:stable-slim AS patch
|
||||
FROM ${base}
|
||||
|
||||
ARG artifact
|
||||
COPY ${artifact} /bin/
|
||||
|
||||
COPY --from=patch \
|
||||
/lib/x86_64-linux-gnu/libz.so.1 \
|
||||
/lib/x86_64-linux-gnu/
|
||||
|
||||
ENTRYPOINT ["/bin/nu"]
|
11
docker/docker-compose.package.yml
Normal file
11
docker/docker-compose.package.yml
Normal file
@ -0,0 +1,11 @@
|
||||
version: '3'
|
||||
|
||||
services:
|
||||
nushell:
|
||||
image: ${DOCKER_REGISTRY}/nu:${DOCKER_TAG}
|
||||
build:
|
||||
context: ..
|
||||
dockerfile: docker/Package${PATCH}.Dockerfile
|
||||
args:
|
||||
base: ${BASE_IMAGE}
|
||||
artifact: ${NU_BINS}
|
17
docker/packaging/Dockerfile.ubuntu-bionic
Normal file
17
docker/packaging/Dockerfile.ubuntu-bionic
Normal file
@ -0,0 +1,17 @@
|
||||
# docker build -f docker/packaging/Dockerfile.ubuntu-bionic .
|
||||
|
||||
ARG FROMTAG=latest
|
||||
FROM quay.io/nushell/nu-base:${FROMTAG}
|
||||
|
||||
RUN apt-get update && apt-get install -y \
|
||||
devscripts \
|
||||
debhelper
|
||||
|
||||
COPY debian /code/debian
|
||||
|
||||
RUN rustc -Vv && cargo build --release && \
|
||||
cp README.md debian/README.Debian && \
|
||||
debuild -b -us -uc -i && \
|
||||
dpkg -i ../nu_0.2.0-1_amd64.deb && \
|
||||
chsh -s /usr/bin/nu && \
|
||||
echo 'ls | get name | echo $it' | /usr/bin/nu
|
55
docker/packaging/README.md
Normal file
55
docker/packaging/README.md
Normal file
@ -0,0 +1,55 @@
|
||||
# Packaging
|
||||
|
||||
This directory contains docker images used for creating packages for different distribution.
|
||||
|
||||
## How to use this docker files?
|
||||
|
||||
Start with:
|
||||
|
||||
```bash
|
||||
$ docker build -f docker/packaging/Dockerfile.ubuntu-bionic -t nushell/package:ubuntu-bionic .
|
||||
```
|
||||
|
||||
after building the image please run container:
|
||||
|
||||
```bash
|
||||
$ docker run -td --rm --name nushell_package_ubuntu_bionic nushell/package:ubuntu-bionic
|
||||
```
|
||||
|
||||
and copy deb package from inside:
|
||||
|
||||
```bash
|
||||
$ docker cp nushell_package_ubuntu_bionic:/nu_0.2.0-1_amd64.deb .
|
||||
```
|
||||
|
||||
or shell inside, and test install:
|
||||
|
||||
```bash
|
||||
$ docker exec -it nushell_package_ubuntu_bionic bash
|
||||
$ dpkg -i /nu_0.2.0-1_amd64.deb
|
||||
|
||||
(Reading database ... 25656 files and directories currently installed.)
|
||||
Preparing to unpack /nu_0.2.0-1_amd64.deb ...
|
||||
Unpacking nu (0.2.0-1) over (0.2.0-1) ...
|
||||
Setting up nu (0.2.0-1) ...
|
||||
```
|
||||
|
||||
When you are finished, exit and stop the container. It will be removed since we
|
||||
used `--rm`.
|
||||
|
||||
```bash
|
||||
$ docker stop nushell_package_ubuntu_bionic
|
||||
```
|
||||
|
||||
## What should be done
|
||||
|
||||
* We should run sbuild command to create chroot and then install dpkg.
|
||||
For two reasons. First: we want to use the same tools as Ubuntu package builders
|
||||
to handle the cornercases. Second: we want to test dpkg requirements.
|
||||
https://github.com/nushell/nushell/issues/681
|
||||
|
||||
* File debian/changelog file should be generated based on git history.
|
||||
https://github.com/nushell/nushell/issues/682
|
||||
|
||||
* Building package and nu version should be parametrized.
|
||||
https://github.com/nushell/nushell/issues/683
|
25
docs/commands/README.md
Normal file
25
docs/commands/README.md
Normal file
@ -0,0 +1,25 @@
|
||||
# How do I get started?
|
||||
|
||||
Pick any command from the checklist and write a comment acknowledging you started work.
|
||||
|
||||
# Instructions for documenting a Nu command of your choosing
|
||||
|
||||
Name the file after the command, like so:
|
||||
|
||||
`command.md`
|
||||
|
||||
Example: If you want to add documentation for the Nu command `enter`, create a file named `enter.md`, write documentation, save it at `/docs/commands/[your_command_picked].md` as and create your pull request.
|
||||
|
||||
# What kind of documentation should I write?
|
||||
|
||||
Anything you want that you believe it *best* documents the command and the way you would like to see it. Here are some of our ideas of documentation we would *love* to see (feel free to add yours):
|
||||
|
||||
* Examples of using the command (max creativity welcomed!)
|
||||
* Description of the command.
|
||||
* Command usage.
|
||||
|
||||
# Anything else?
|
||||
|
||||
Of course! (These are drafts) so feel free to leave feedback and suggestions in the same file.
|
||||
|
||||
Happy Documenting.
|
28
docs/commands/add.md
Normal file
28
docs/commands/add.md
Normal file
@ -0,0 +1,28 @@
|
||||
# add
|
||||
|
||||
This command adds a column to any table output. The first parameter takes the heading, the second parameter takes the value for all the rows.
|
||||
|
||||
## Examples
|
||||
|
||||
```shell
|
||||
> ls | add is_on_a_computer yes_obviously
|
||||
━━━┯━━━━━━━━━━━━━━━━━━━━━━━━━━━━┯━━━━━━┯━━━━━━━━━━┯━━━━━━━━┯━━━━━━━━━━━┯━━━━━━━━━━━┯━━━━━━━━━━━━━━━━━━
|
||||
# │ name │ type │ readonly │ size │ accessed │ modified │ is_on_a_computer
|
||||
───┼────────────────────────────┼──────┼──────────┼────────┼───────────┼───────────┼──────────────────
|
||||
0 │ zeusiscrazy.txt │ File │ │ 556 B │ a day ago │ a day ago │ yes_obviously
|
||||
1 │ coww.txt │ File │ │ 24 B │ a day ago │ a day ago │ yes_obviously
|
||||
2 │ randomweirdstuff.txt │ File │ │ 197 B │ a day ago │ a day ago │ yes_obviously
|
||||
3 │ abaracadabra.txt │ File │ │ 401 B │ a day ago │ a day ago │ yes_obviously
|
||||
4 │ youshouldeatmorecereal.txt │ File │ │ 768 B │ a day ago │ a day ago │ yes_obviously
|
||||
━━━┷━━━━━━━━━━━━━━━━━━━━━━━━━━━━┷━━━━━━┷━━━━━━━━━━┷━━━━━━━━┷━━━━━━━━━━━┷━━━━━━━━━━━┷━━━━━━━━━━━━━━━━━━
|
||||
```
|
||||
|
||||
```shell
|
||||
> shells | add os linux_on_this_machine
|
||||
━━━┯━━━┯━━━━━━━━━━━━┯━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━━━━━━━━━
|
||||
# │ │ name │ path │ os
|
||||
───┼───┼────────────┼────────────────────────────────┼───────────────────────
|
||||
0 │ X │ filesystem │ /home/shaurya/stuff/expr/stuff │ linux_on_this_machine
|
||||
1 │ │ filesystem │ / │ linux_on_this_machine
|
||||
━━━┷━━━┷━━━━━━━━━━━━┷━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┷━━━━━━━━━━━━━━━━━━━━━━━
|
||||
```
|
53
docs/commands/append.md
Normal file
53
docs/commands/append.md
Normal file
@ -0,0 +1,53 @@
|
||||
# append
|
||||
This command allows you to append the given row to the table.
|
||||
|
||||
**Note**:
|
||||
- `append` does not change a file itself. If you want to save your changes, you need to run the `save` command
|
||||
- if you want to add something containing a whitespace character, you need to put it in quotation marks
|
||||
|
||||
## Examples
|
||||
|
||||
Let's add more cities to this table:
|
||||
|
||||
```shell
|
||||
> open cities.txt | lines
|
||||
━━━┯━━━━━━━━━━━━
|
||||
# │ <value>
|
||||
───┼────────────
|
||||
0 │ Canberra
|
||||
1 │ London
|
||||
2 │ Nairobi
|
||||
3 │ Washington
|
||||
━━━┷━━━━━━━━━━━━
|
||||
```
|
||||
|
||||
You can add a new row by using `append`:
|
||||
|
||||
```shell
|
||||
> open cities.txt | lines | append Beijing
|
||||
━━━┯━━━━━━━━━━━━
|
||||
# │ <value>
|
||||
───┼────────────
|
||||
0 │ Canberra
|
||||
1 │ London
|
||||
2 │ Nairobi
|
||||
3 │ Washington
|
||||
4 │ Beijing
|
||||
━━━┷━━━━━━━━━━━━
|
||||
```
|
||||
|
||||
It's not possible to add multiple rows at once, so you'll need to call `append` multiple times:
|
||||
|
||||
```shell
|
||||
> open cities.txt | lines | append Beijing | append "Buenos Aires"
|
||||
━━━┯━━━━━━━━━━━━━━
|
||||
# │ <value>
|
||||
───┼──────────────
|
||||
0 │ Canberra
|
||||
1 │ London
|
||||
2 │ Nairobi
|
||||
3 │ Washington
|
||||
4 │ Beijing
|
||||
5 │ Buenos Aires
|
||||
━━━┷━━━━━━━━━━━━━━
|
||||
```
|
45
docs/commands/average.md
Normal file
45
docs/commands/average.md
Normal file
@ -0,0 +1,45 @@
|
||||
# average
|
||||
This command allows you to calculate the average of values in a column.
|
||||
|
||||
## Examples
|
||||
To get the average of the file sizes in a directory, simply pipe the size column from the ls command to the average command.
|
||||
|
||||
```shell
|
||||
> ls | get size | average
|
||||
━━━━━━━━━
|
||||
<value>
|
||||
━━━━━━━━━
|
||||
2282.727272727273
|
||||
━━━━━━━━━
|
||||
```
|
||||
|
||||
```shell
|
||||
> pwd | split-row / | size | get chars | average
|
||||
━━━━━━━━━
|
||||
<value>
|
||||
━━━━━━━━━
|
||||
5.250000000000000
|
||||
━━━━━━━━━
|
||||
```
|
||||
|
||||
Note that average only works for integer and byte values. If the shell doesn't recognize the values in a column as one of those types, it will return an error.
|
||||
One way to solve this is to convert each row to an integer when possible and then pipe the result to `average`
|
||||
|
||||
```shell
|
||||
> open tests/fixtures/formats/caco3_plastics.csv | get tariff_item | average
|
||||
error: Unrecognized type in stream: Primitive(String("2509000000"))
|
||||
- shell:1:0
|
||||
1 | open tests/fixtures/formats/caco3_plastics.csv | get tariff_item | average
|
||||
| ^^^^ source
|
||||
```
|
||||
|
||||
```shell
|
||||
> open tests/fixtures/formats/caco3_plastics.csv | get tariff_item | str --to-int | average
|
||||
━━━━━━━━━━━━━━━━━━━
|
||||
<value>
|
||||
───────────────────
|
||||
3239404444.000000
|
||||
━━━━━━━━━━━━━━━━━━━
|
||||
```
|
||||
|
||||
|
33
docs/commands/cd.md
Normal file
33
docs/commands/cd.md
Normal file
@ -0,0 +1,33 @@
|
||||
# cd
|
||||
|
||||
If you didn't already know, the `cd` command is very simple. It stands for 'change directory' and it does exactly that. It changes the current directory to the one specified. If no directory is specified, it takes you to the home directory. Additionally, using `cd ..` takes you to the parent directory.
|
||||
|
||||
## Examples
|
||||
|
||||
```shell
|
||||
/home/username> cd Desktop
|
||||
/home/username/Desktop> now your current directory has been changed
|
||||
```
|
||||
|
||||
```shell
|
||||
/home/username/Desktop/nested/folders> cd ..
|
||||
/home/username/Desktop/nested> cd ..
|
||||
/home/username/Desktop> cd ../Documents/school_related
|
||||
/home/username/Documents/school_related> cd ../../..
|
||||
/home/>
|
||||
```
|
||||
|
||||
```shell
|
||||
/home/username/Desktop/super/duper/crazy/nested/folders> cd
|
||||
/home/username> cd ../../usr
|
||||
/usr> cd
|
||||
/home/username>
|
||||
```
|
||||
|
||||
Using `cd -` will take you to the previous directory:
|
||||
|
||||
```shell
|
||||
/home/username/Desktop/super/duper/crazy/nested/folders> cd
|
||||
/home/username> cd -
|
||||
/home/username/Desktop/super/duper/crazy/nested/folders> cd
|
||||
```
|
48
docs/commands/count.md
Normal file
48
docs/commands/count.md
Normal file
@ -0,0 +1,48 @@
|
||||
# count
|
||||
|
||||
This command counts the number of rows in a table.
|
||||
|
||||
## Examples -
|
||||
|
||||
```shell
|
||||
> ls
|
||||
━━━━┯━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┯━━━━━━━━━━━┯━━━━━━━━━━┯━━━━━━━━━┯━━━━━━━━━━━━━━┯━━━━━━━━━━━━━━┯━━━━━━━━━━━━━━
|
||||
# │ name │ type │ readonly │ size │ created │ accessed │ modified
|
||||
────┼──────────────────────────────┼───────────┼──────────┼─────────┼──────────────┼──────────────┼──────────────
|
||||
0 │ Desktop │ Directory │ │ 4.1 KB │ 2 months ago │ 2 months ago │ 2 months ago
|
||||
1 │ aur │ Directory │ │ 4.1 KB │ 4 hours ago │ 4 hours ago │ 4 hours ago
|
||||
...
|
||||
75 │ .emulator_console_auth_token │ File │ │ 16 B │ 2 months ago │ 2 months ago │ 2 months ago
|
||||
76 │ bin │ Directory │ │ 4.1 KB │ 2 months ago │ 2 months ago │ 2 months ago
|
||||
━━━━┷━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┷━━━━━━━━━━━┷━━━━━━━━━━┷━━━━━━━━━┷━━━━━━━━━━━━━━┷━━━━━━━━━━━━━━┷━━━━━━━━━━━━━━━
|
||||
> ls | count
|
||||
━━━━━━━━━
|
||||
<value>
|
||||
─────────
|
||||
77
|
||||
━━━━━━━━━
|
||||
> ls | get name | count
|
||||
━━━━━━━━━
|
||||
<value>
|
||||
─────────
|
||||
77
|
||||
━━━━━━━━━
|
||||
> ls | where type == File | count
|
||||
━━━━━━━━━
|
||||
<value>
|
||||
─────────
|
||||
29
|
||||
━━━━━━━━━
|
||||
> ls | where type == Directory | count
|
||||
━━━━━━━━━
|
||||
<value>
|
||||
─────────
|
||||
48
|
||||
━━━━━━━━━
|
||||
> ls | where size > 2KB | count
|
||||
━━━━━━━━━
|
||||
<value>
|
||||
─────────
|
||||
57
|
||||
━━━━━━━━━
|
||||
```
|
34
docs/commands/date.md
Normal file
34
docs/commands/date.md
Normal file
@ -0,0 +1,34 @@
|
||||
# date
|
||||
|
||||
Use `date` to get the current date and time. Defaults to local timezone but you can get it in UTC too.
|
||||
|
||||
## Flags
|
||||
|
||||
--utc
|
||||
Returns the current date and time in UTC
|
||||
|
||||
--local
|
||||
Returns the current date and time in your local timezone
|
||||
|
||||
## Examples
|
||||
|
||||
```shell
|
||||
> date
|
||||
━━━━━━┯━━━━━━━┯━━━━━┯━━━━━━┯━━━━━━━━┯━━━━━━━━┯━━━━━━━━━━
|
||||
year │ month │ day │ hour │ minute │ second │ timezone
|
||||
──────┼───────┼─────┼──────┼────────┼────────┼──────────
|
||||
2019 │ 9 │ 30 │ 21 │ 52 │ 30 │ -03:00
|
||||
━━━━━━┷━━━━━━━┷━━━━━┷━━━━━━┷━━━━━━━━┷━━━━━━━━┷━━━━━━━━━━
|
||||
> date --utc
|
||||
━━━━━━┯━━━━━━━┯━━━━━┯━━━━━━┯━━━━━━━━┯━━━━━━━━┯━━━━━━━━━━
|
||||
year │ month │ day │ hour │ minute │ second │ timezone
|
||||
──────┼───────┼─────┼──────┼────────┼────────┼──────────
|
||||
2019 │ 10 │ 1 │ 0 │ 52 │ 32 │ UTC
|
||||
━━━━━━┷━━━━━━━┷━━━━━┷━━━━━━┷━━━━━━━━┷━━━━━━━━┷━━━━━━━━━━
|
||||
> date --local
|
||||
━━━━━━┯━━━━━━━┯━━━━━┯━━━━━━┯━━━━━━━━┯━━━━━━━━┯━━━━━━━━━━
|
||||
year │ month │ day │ hour │ minute │ second │ timezone
|
||||
──────┼───────┼─────┼──────┼────────┼────────┼──────────
|
||||
2019 │ 9 │ 30 │ 21 │ 52 │ 34 │ -03:00
|
||||
━━━━━━┷━━━━━━━┷━━━━━┷━━━━━━┷━━━━━━━━┷━━━━━━━━┷━━━━━━━━━━
|
||||
```
|
12
docs/commands/echo.md
Normal file
12
docs/commands/echo.md
Normal file
@ -0,0 +1,12 @@
|
||||
# echo
|
||||
|
||||
Use `echo` to repeat arguments back to the user
|
||||
|
||||
## Examples
|
||||
|
||||
```shell
|
||||
> echo Hello world
|
||||
Hello world
|
||||
> echo "Hello, world!"
|
||||
Hello, world!
|
||||
```
|
45
docs/commands/edit.md
Normal file
45
docs/commands/edit.md
Normal file
@ -0,0 +1,45 @@
|
||||
# edit
|
||||
|
||||
Edits an existing column on a table. First parameter is the column to edit and the second parameter is the value to put.
|
||||
|
||||
## Examples
|
||||
|
||||
```shell
|
||||
> ls
|
||||
━━━┯━━━━━━━━━━━━━━━━━━━━━━━━━━━━┯━━━━━━┯━━━━━━━━━━┯━━━━━━━━┯━━━━━━━━━━━┯━━━━━━━━━━━
|
||||
# │ name │ type │ readonly │ size │ accessed │ modified
|
||||
───┼────────────────────────────┼──────┼──────────┼────────┼───────────┼───────────
|
||||
0 │ zeusiscrazy.txt │ File │ │ 556 B │ a day ago │ a day ago
|
||||
1 │ coww.txt │ File │ │ 24 B │ a day ago │ a day ago
|
||||
2 │ randomweirdstuff.txt │ File │ │ 197 B │ a day ago │ a day ago
|
||||
3 │ abaracadabra.txt │ File │ │ 401 B │ a day ago │ a day ago
|
||||
4 │ youshouldeatmorecereal.txt │ File │ │ 768 B │ a day ago │ a day ago
|
||||
━━━┷━━━━━━━━━━━━━━━━━━━━━━━━━━━━┷━━━━━━┷━━━━━━━━━━┷━━━━━━━━┷━━━━━━━━━━━┷━━━━━━━━━━━
|
||||
> ls | edit modified neverrrr
|
||||
━━━┯━━━━━━━━━━━━━━━━━━━━━━━━━━━━┯━━━━━━┯━━━━━━━━━━┯━━━━━━━━┯━━━━━━━━━━━┯━━━━━━━━━━
|
||||
# │ name │ type │ readonly │ size │ accessed │ modified
|
||||
───┼────────────────────────────┼──────┼──────────┼────────┼───────────┼──────────
|
||||
0 │ zeusiscrazy.txt │ File │ │ 556 B │ a day ago │ neverrrr
|
||||
1 │ coww.txt │ File │ │ 24 B │ a day ago │ neverrrr
|
||||
2 │ randomweirdstuff.txt │ File │ │ 197 B │ a day ago │ neverrrr
|
||||
3 │ abaracadabra.txt │ File │ │ 401 B │ a day ago │ neverrrr
|
||||
4 │ youshouldeatmorecereal.txt │ File │ │ 768 B │ a day ago │ neverrrr
|
||||
━━━┷━━━━━━━━━━━━━━━━━━━━━━━━━━━━┷━━━━━━┷━━━━━━━━━━┷━━━━━━━━┷━━━━━━━━━━━┷━━━━━━━━━━
|
||||
```
|
||||
|
||||
```shell
|
||||
> shells
|
||||
━━━┯━━━┯━━━━━━━━━━━━┯━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
# │ │ name │ path
|
||||
───┼───┼────────────┼────────────────────────────────
|
||||
0 │ X │ filesystem │ /home/username/stuff/expr/stuff
|
||||
1 │ │ filesystem │ /
|
||||
━━━┷━━━┷━━━━━━━━━━━━┷━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
> shells | edit " " X | edit path /
|
||||
━━━┯━━━┯━━━━━━━━━━━━┯━━━━━━
|
||||
# │ │ name │ path
|
||||
───┼───┼────────────┼──────
|
||||
0 │ X │ filesystem │ /
|
||||
1 │ X │ filesystem │ /
|
||||
━━━┷━━━┷━━━━━━━━━━━━┷━━━━━━
|
||||
```
|
39
docs/commands/enter.md
Normal file
39
docs/commands/enter.md
Normal file
@ -0,0 +1,39 @@
|
||||
# enter
|
||||
|
||||
This command creates a new shell and begin at this path.
|
||||
|
||||
## Examples
|
||||
|
||||
```shell
|
||||
/home/foobar> cat user.json
|
||||
{
|
||||
"Name": "Peter",
|
||||
"Age": 30,
|
||||
"Telephone": 88204828,
|
||||
"Country": "Singapore"
|
||||
}
|
||||
/home/foobar> enter user.json
|
||||
/> ls
|
||||
━━━━━━━┯━━━━━┯━━━━━━━━━━━┯━━━━━━━━━━━
|
||||
Name │ Age │ Telephone │ Country
|
||||
───────┼─────┼───────────┼───────────
|
||||
Peter │ 30 │ 88204828 │ Singapore
|
||||
━━━━━━━┷━━━━━┷━━━━━━━━━━━┷━━━━━━━━━━━
|
||||
/> exit
|
||||
/home/foobar>
|
||||
```
|
||||
|
||||
It also provides the ability to work with multiple directories at the same time. This command will allow you to create a new "shell" and enter it at the specified path. You can toggle between this new shell and the original shell with the `p` (for previous) and `n` (for next), allowing you to navigate around a ring buffer of shells. Once you're done with a shell, you can `exit` it and remove it from the ring buffer.
|
||||
|
||||
```shell
|
||||
/> enter /tmp
|
||||
/tmp> enter /usr
|
||||
/usr> enter /bin
|
||||
/bin> enter /opt
|
||||
/opt> p
|
||||
/bin> p
|
||||
/usr> p
|
||||
/tmp> p
|
||||
/> n
|
||||
/tmp>
|
||||
```
|
27
docs/commands/env.md
Normal file
27
docs/commands/env.md
Normal file
@ -0,0 +1,27 @@
|
||||
# env
|
||||
|
||||
The `env` command prints to terminal the environment of nushell
|
||||
|
||||
This includes
|
||||
- cwd : the path to the current working the directory (`cwd`),
|
||||
- home : the path to the home directory
|
||||
- config : the path to the config file for nushell
|
||||
- history : the path to the nushell command history
|
||||
- temp : the path to the temp file
|
||||
- vars : descriptor variable for the table
|
||||
|
||||
`env` does not take any arguments, and ignores any arguments given.
|
||||
|
||||
|
||||
## Examples -
|
||||
|
||||
|
||||
```shell
|
||||
/home/username/mynushell/docs/commands(master)> env
|
||||
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┯━━━━━━┯━━━━━━━━━━━━━━━━
|
||||
cwd │ home │ config │ history │ temp │ vars
|
||||
────────────────────────────────────────┼────────────────┼───────────────────────────────────────┼────────────────────────────────────────────┼──────┼────────────────
|
||||
/home/username/mynushell/docs/commands │ /home/username │ /home/username/.config/nu/config.toml │ /home/username/.local/share/nu/history.txt │ /tmp │ [table: 1 row]
|
||||
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┷━━━━━━━━━━━━━━━━┷━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┷━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┷━━━━━━┷━━━━━━━━━━━━━━━━
|
||||
```
|
||||
|
30
docs/commands/exit.md
Normal file
30
docs/commands/exit.md
Normal file
@ -0,0 +1,30 @@
|
||||
# exit
|
||||
|
||||
Exits the nu shell. If you have multiple nu shells, use `exit --now` to exit all of them.
|
||||
|
||||
## Examples
|
||||
|
||||
```shell
|
||||
> exit
|
||||
```
|
||||
|
||||
```
|
||||
/home/username/stuff/books> shells
|
||||
---+---+------------+----------------------------
|
||||
# | | name | path
|
||||
---+---+------------+----------------------------
|
||||
0 | | filesystem | /home/username/stuff/notes
|
||||
1 | | filesystem | /home/username/stuff/videos
|
||||
2 | X | filesystem | /home/username/stuff/books
|
||||
---+---+------------+----------------------------
|
||||
/home/username/stuff/books> exit
|
||||
/home/username/stuff/videos> shells
|
||||
---+---+------------+----------------------------
|
||||
# | | name | path
|
||||
---+---+------------+----------------------------
|
||||
0 | | filesystem | /home/username/stuff/notes
|
||||
1 | X | filesystem | /home/username/stuff/videos
|
||||
---+---+------------+----------------------------
|
||||
/home/username/stuff/videos> exit --now
|
||||
exits both the shells
|
||||
```
|
32
docs/commands/fetch.md
Normal file
32
docs/commands/fetch.md
Normal file
@ -0,0 +1,32 @@
|
||||
# fetch
|
||||
|
||||
This command loads from a URL into a cell, convert it to table if possible (avoid by appending `--raw` flag)
|
||||
|
||||
## Examples
|
||||
|
||||
```shell
|
||||
> fetch http://headers.jsontest.com
|
||||
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┯━━━━━━━━┯━━━━━━━━━━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
X-Cloud-Trace-Context │ Accept │ Host │ Content-Length │ user-agent
|
||||
───────────────────────────────────────────────────────┼────────┼──────────────────────┼────────────────┼─────────────────────────
|
||||
aeee1a8abf08820f6fe19d114dc3bb87/16772233176633589121 │ */* │ headers.jsontest.com │ 0 │ curl/7.54.0 isahc/0.7.1
|
||||
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┷━━━━━━━━┷━━━━━━━━━━━━━━━━━━━━━━┷━━━━━━━━━━━━━━━━┷━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
> fetch http://headers.jsontest.com --raw
|
||||
{
|
||||
"X-Cloud-Trace-Context": "aeee1a8abf08820f6fe19d114dc3bb87/16772233176633589121",
|
||||
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3",
|
||||
"Upgrade-Insecure-Requests": "1",
|
||||
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36",
|
||||
"Host": "headers.jsontest.com",
|
||||
"Accept-Language": "en-GB,en-US;q=0.9,en;q=0.8"
|
||||
}
|
||||
```
|
||||
|
||||
```shell
|
||||
> fetch https://www.jonathanturner.org/feed.xml
|
||||
━━━━━━━━━━━━━━━━
|
||||
rss
|
||||
────────────────
|
||||
[table: 1 row]
|
||||
━━━━━━━━━━━━━━━━
|
||||
```
|
28
docs/commands/first.md
Normal file
28
docs/commands/first.md
Normal file
@ -0,0 +1,28 @@
|
||||
# first
|
||||
|
||||
Use `first` to retrieve the first "n" rows of a table. `first` has a required amount parameter that indicates how many rows you would like returned. If more than one row is returned, an index column will be included showing the row number.
|
||||
|
||||
## Examples
|
||||
|
||||
```shell
|
||||
> ps | first 1
|
||||
━━━━━━━┯━━━━━━━━━━━━━━┯━━━━━━━━━┯━━━━━━━━━━━━━━━━━━━
|
||||
pid │ name │ status │ cpu
|
||||
───────┼──────────────┼─────────┼───────────────────
|
||||
60358 │ nu_plugin_ps │ Running │ 5.399802999999999
|
||||
━━━━━━━┷━━━━━━━━━━━━━━┷━━━━━━━━━┷━━━━━━━━━━━━━━━━━━━
|
||||
```
|
||||
|
||||
```shell
|
||||
> ps | first 5
|
||||
━━━┯━━━━━━━┯━━━━━━━━━━━━━━┯━━━━━━━━━┯━━━━━━━━━━━━━━━━━━━
|
||||
# │ pid │ name │ status │ cpu
|
||||
───┼───────┼──────────────┼─────────┼───────────────────
|
||||
0 │ 60754 │ nu_plugin_ps │ Running │ 4.024156000000000
|
||||
1 │ 60107 │ quicklookd │ Running │ 0.000000000000000
|
||||
2 │ 59356 │ nu │ Running │ 0.000000000000000
|
||||
3 │ 59216 │ zsh │ Running │ 0.000000000000000
|
||||
4 │ 59162 │ vim │ Running │ 0.000000000000000
|
||||
━━━┷━━━━━━━┷━━━━━━━━━━━━━━┷━━━━━━━━━┷━━━━━━━━━━━━━━━━━━━
|
||||
```
|
||||
|
116
docs/commands/from-csv.md
Normal file
116
docs/commands/from-csv.md
Normal file
@ -0,0 +1,116 @@
|
||||
# from-csv
|
||||
|
||||
Converts csv data into table. Use this when nushell cannot dertermine the input file extension.
|
||||
|
||||
## Example
|
||||
|
||||
Let's say we have the following file :
|
||||
|
||||
```shell
|
||||
> cat pets.txt
|
||||
animal, name, age
|
||||
cat, Tom, 7
|
||||
dog, Alfred, 10
|
||||
chameleon, Linda, 1
|
||||
```
|
||||
|
||||
`pets.txt` is actually a .csv file but it has the .txt extension, `open` is not able to convert it into a table :
|
||||
|
||||
```shell
|
||||
> open pets.txt
|
||||
animal, name, age
|
||||
cat, Tom, 7
|
||||
dog, Alfred, 10
|
||||
chameleon, Linda, 1
|
||||
```
|
||||
|
||||
To get a table from `pets.txt` we need to use the `from-csv` command :
|
||||
|
||||
```shell
|
||||
> open pets.txt | from-csv
|
||||
━━━┯━━━━━━━━━━━┯━━━━━━━━━┯━━━━━━
|
||||
# │ animal │ name │ age
|
||||
───┼───────────┼─────────┼──────
|
||||
0 │ cat │ Tom │ 7
|
||||
1 │ dog │ Alfred │ 10
|
||||
2 │ chameleon │ Linda │ 1
|
||||
━━━┷━━━━━━━━━━━┷━━━━━━━━━┷━━━━━━
|
||||
```
|
||||
|
||||
To ignore the csv headers use `--headerless` :
|
||||
|
||||
```shell
|
||||
━━━┯━━━━━━━━━━━┯━━━━━━━━━┯━━━━━━━━━
|
||||
# │ Column1 │ Column2 │ Column3
|
||||
───┼───────────┼─────────┼─────────
|
||||
0 │ dog │ Alfred │ 10
|
||||
1 │ chameleon │ Linda │ 1
|
||||
━━━┷━━━━━━━━━━━┷━━━━━━━━━┷━━━━━━━━━
|
||||
```
|
||||
|
||||
To split on a character other than ',' use `--separator` :
|
||||
|
||||
```shell
|
||||
> open pets.txt
|
||||
animal; name; age
|
||||
cat; Tom; 7
|
||||
dog; Alfred; 10
|
||||
chameleon; Linda; 1
|
||||
```
|
||||
|
||||
```shell
|
||||
> open pets.txt | from-csv --separator ';'
|
||||
━━━┯━━━━━━━━━━━┯━━━━━━━━━┯━━━━━━
|
||||
# │ animal │ name │ age
|
||||
───┼───────────┼─────────┼──────
|
||||
0 │ cat │ Tom │ 7
|
||||
1 │ dog │ Alfred │ 10
|
||||
2 │ chameleon │ Linda │ 1
|
||||
━━━┷━━━━━━━━━━━┷━━━━━━━━━┷━━━━━━
|
||||
```
|
||||
|
||||
To use this command to open a csv with separators other than a comma, use the `--raw` switch of `open` to open the csv, othewise the csv will enter `from-csv` as a table split on commas rather than raw text.
|
||||
|
||||
```shell
|
||||
> mv pets.txt pets.csv
|
||||
> open pets.csv | from-csv --separator ';'
|
||||
error: Expected a string from pipeline
|
||||
- shell:1:16
|
||||
1 | open pets.csv | from-csv --separator ';'
|
||||
| ^^^^^^^^ requires string input
|
||||
- shell:1:0
|
||||
1 | open pets.csv | from-csv --separator ';'
|
||||
| value originates from here
|
||||
|
||||
> open pets.csv --raw | from-csv --separator ';'
|
||||
━━━┯━━━━━━━━━━━┯━━━━━━━━━┯━━━━━━
|
||||
# │ animal │ name │ age
|
||||
───┼───────────┼─────────┼──────
|
||||
0 │ cat │ Tom │ 7
|
||||
1 │ dog │ Alfred │ 10
|
||||
2 │ chameleon │ Linda │ 1
|
||||
━━━┷━━━━━━━━━━━┷━━━━━━━━━┷━━━━━━
|
||||
```
|
||||
|
||||
The string '\t' can be used to separate on tabs. Note that this is the same as using the from-tsv command.
|
||||
|
||||
Newlines '\n' are not acceptable separators.
|
||||
|
||||
Note that separators are currently provided as strings and need to be wrapped in quotes.
|
||||
|
||||
```shell
|
||||
> open pets.csv --raw | from-csv --separator ;
|
||||
- shell:1:43
|
||||
1 | open pets.csv --raw | from-csv --separator ;
|
||||
| ^
|
||||
```
|
||||
|
||||
It is also considered an error to use a separator greater than one char :
|
||||
|
||||
```shell
|
||||
> open pets.txt | from-csv --separator '123'
|
||||
error: Expected a single separator char from --separator
|
||||
- shell:1:37
|
||||
1 | open pets.txt | from-csv --separator '123'
|
||||
| ^^^^^ requires a single character string input
|
||||
```
|
23
docs/commands/from-toml.md
Normal file
23
docs/commands/from-toml.md
Normal file
@ -0,0 +1,23 @@
|
||||
# from-toml
|
||||
Converts toml data into table. Use this when nushell cannot dertermine the input file extension.
|
||||
|
||||
## Example
|
||||
Let's say we have the following Rust .lock file :
|
||||
```shell
|
||||
> open Cargo.lock
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing. [[package]] name = "adler32" version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
...
|
||||
```
|
||||
|
||||
The "Cargo.lock" file is actually a .toml file, but the file extension isn't .toml. That's okay, we can use the `from-toml` command :
|
||||
|
||||
|
||||
```shell
|
||||
> open Cargo.lock | from-toml
|
||||
━━━━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━━━━━
|
||||
metadata │ package
|
||||
────────────────┼───────────────────
|
||||
[table: 1 row] │ [table: 154 rows]
|
||||
━━━━━━━━━━━━━━━━┷━━━━━━━━━━━━━━━━━━━
|
||||
```
|
72
docs/commands/group-by.md
Normal file
72
docs/commands/group-by.md
Normal file
@ -0,0 +1,72 @@
|
||||
# group-by
|
||||
|
||||
This command creates a new table with the data from the table rows grouped by the column given.
|
||||
|
||||
## Examples
|
||||
|
||||
Let's say we have this table of all countries in the world sorted by their population:
|
||||
|
||||
```shell
|
||||
> open countries_by_population.json | from-json | first 10
|
||||
━━━┯━━━━━━┯━━━━━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━━━┯━━━━━━━━
|
||||
# │ rank │ country or area │ UN continental region │ UN statistical region │ population 2018 │ population 2019 │ change
|
||||
───┼──────┼─────────────────┼───────────────────────┼───────────────────────┼─────────────────┼─────────────────┼────────
|
||||
0 │ 1 │ China │ Asia │ Eastern Asia │ 1,427,647,786 │ 1,433,783,686 │ +0.4%
|
||||
1 │ 2 │ India │ Asia │ Southern Asia │ 1,352,642,280 │ 1,366,417,754 │ +1.0%
|
||||
2 │ 3 │ United States │ Americas │ Northern America │ 327,096,265 │ 329,064,917 │ +0.6%
|
||||
3 │ 4 │ Indonesia │ Asia │ South-eastern Asia │ 267,670,543 │ 270,625,568 │ +1.1%
|
||||
4 │ 5 │ Pakistan │ Asia │ Southern Asia │ 212,228,286 │ 216,565,318 │ +2.0%
|
||||
5 │ 6 │ Brazil │ Americas │ South America │ 209,469,323 │ 211,049,527 │ +0.8%
|
||||
6 │ 7 │ Nigeria │ Africa │ Western Africa │ 195,874,683 │ 200,963,599 │ +2.6%
|
||||
7 │ 8 │ Bangladesh │ Asia │ Southern Asia │ 161,376,708 │ 163,046,161 │ +1.0%
|
||||
8 │ 9 │ Russia │ Europe │ Eastern Europe │ 145,734,038 │ 145,872,256 │ +0.1%
|
||||
9 │ 10 │ Mexico │ Americas │ Central America │ 126,190,788 │ 127,575,529 │ +1.1%
|
||||
━━━┷━━━━━━┷━━━━━━━━━━━━━━━━━┷━━━━━━━━━━━━━━━━━━━━━━━┷━━━━━━━━━━━━━━━━━━━━━━━┷━━━━━━━━━━━━━━━━━┷━━━━━━━━━━━━━━━━━┷━━━━━━━━
|
||||
```
|
||||
|
||||
Here we have listed only the first 10 lines. In total this table has got 233 rows which is to big to get information easily out of it.
|
||||
|
||||
We can use the `group-by` command on 'UN statistical region' to create a table per continental region.
|
||||
|
||||
```shell
|
||||
> open countries_by_population.json | from-json | group-by "UN continental region"
|
||||
━━━━━━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━━━━
|
||||
Asia │ Americas │ Africa │ Europe │ Oceania
|
||||
──────────────────┼──────────────────┼──────────────────┼──────────────────┼──────────────────
|
||||
[table: 51 rows] │ [table: 53 rows] │ [table: 58 rows] │ [table: 48 rows] │ [table: 23 rows]
|
||||
━━━━━━━━━━━━━━━━━━┷━━━━━━━━━━━━━━━━━━┷━━━━━━━━━━━━━━━━━━┷━━━━━━━━━━━━━━━━━━┷━━━━━━━━━━━━━━━━━━
|
||||
```
|
||||
|
||||
Now we can already get some informations like "which continental regions are there" and "how many countries are in each region".
|
||||
If we want to see only the countries in the continental region of Oceania we can type:
|
||||
|
||||
```shell
|
||||
> open countries_by_population.json | from-json | group-by "UN continental region" | get Oceania
|
||||
━━━━┯━━━━━━┯━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━━━┯━━━━━━━━
|
||||
# │ rank │ country or area │ UN continental region │ UN statistical region │ population 2018 │ population 2019 │ change
|
||||
────┼──────┼────────────────────────────────┼───────────────────────┼───────────────────────────┼─────────────────┼─────────────────┼────────
|
||||
0 │ 55 │ Australia │ Oceania │ Australia and New Zealand │ 24,898,152 │ 25,203,198 │ +1.2%
|
||||
1 │ 98 │ Papua New Guinea │ Oceania │ Melanesia │ 8,606,323 │ 8,776,109 │ +2.0%
|
||||
2 │ 125 │ New Zealand │ Oceania │ Australia and New Zealand │ 4,743,131 │ 4,783,063 │ +0.8%
|
||||
3 │ 161 │ Fiji │ Oceania │ Melanesia │ 883,483 │ 889,953 │ +0.7%
|
||||
4 │ 166 │ Solomon Islands │ Oceania │ Melanesia │ 652,857 │ 669,823 │ +2.6%
|
||||
5 │ 181 │ Vanuatu │ Oceania │ Melanesia │ 292,680 │ 299,882 │ +2.5%
|
||||
6 │ 183 │ New Caledonia │ Oceania │ Melanesia │ 279,993 │ 282,750 │ +1.0%
|
||||
7 │ 185 │ French Polynesia │ Oceania │ Polynesia │ 277,679 │ 279,287 │ +0.6%
|
||||
8 │ 188 │ Samoa │ Oceania │ Polynesia │ 196,129 │ 197,097 │ +0.5%
|
||||
9 │ 191 │ Guam │ Oceania │ Micronesia │ 165,768 │ 167,294 │ +0.9%
|
||||
10 │ 193 │ Kiribati │ Oceania │ Micronesia │ 115,847 │ 117,606 │ +1.5%
|
||||
11 │ 194 │ Federated States of Micronesia │ Oceania │ Micronesia │ 112,640 │ 113,815 │ +1.0%
|
||||
12 │ 196 │ Tonga │ Oceania │ Polynesia │ 110,589 │ 110,940 │ +0.3%
|
||||
13 │ 207 │ Marshall Islands │ Oceania │ Micronesia │ 58,413 │ 58,791 │ +0.6%
|
||||
14 │ 209 │ Northern Mariana Islands │ Oceania │ Micronesia │ 56,882 │ 56,188 │ −1.2%
|
||||
15 │ 210 │ American Samoa │ Oceania │ Polynesia │ 55,465 │ 55,312 │ −0.3%
|
||||
16 │ 221 │ Palau │ Oceania │ Micronesia │ 17,907 │ 18,008 │ +0.6%
|
||||
17 │ 222 │ Cook Islands │ Oceania │ Polynesia │ 17,518 │ 17,548 │ +0.2%
|
||||
18 │ 224 │ Tuvalu │ Oceania │ Polynesia │ 11,508 │ 11,646 │ +1.2%
|
||||
19 │ 225 │ Wallis and Futuna │ Oceania │ Polynesia │ 11,661 │ 11,432 │ −2.0%
|
||||
20 │ 226 │ Nauru │ Oceania │ Micronesia │ 10,670 │ 10,756 │ +0.8%
|
||||
21 │ 231 │ Niue │ Oceania │ Polynesia │ 1,620 │ 1,615 │ −0.3%
|
||||
22 │ 232 │ Tokelau │ Oceania │ Polynesia │ 1,319 │ 1,340 │ +1.6%
|
||||
━━━━┷━━━━━━┷━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┷━━━━━━━━━━━━━━━━━━━━━━━┷━━━━━━━━━━━━━━━━━━━━━━━━━━━┷━━━━━━━━━━━━━━━━━┷━━━━━━━━━━━━━━━━━┷━━━━━━━━
|
||||
```
|
47
docs/commands/help.md
Normal file
47
docs/commands/help.md
Normal file
@ -0,0 +1,47 @@
|
||||
# help
|
||||
|
||||
Use `help` for more information on a command.
|
||||
Use `help commands` to list all availble commands.
|
||||
Use `help <command name>` to display help about a particular command.
|
||||
|
||||
## Examples
|
||||
|
||||
```shell
|
||||
> help
|
||||
Welcome to Nushell.
|
||||
|
||||
Here are some tips to help you get started.
|
||||
* help commands - list all available commands
|
||||
* help <command name> - display help about a particular command
|
||||
|
||||
You can also learn more at https://book.nushell.sh
|
||||
```
|
||||
|
||||
```shell
|
||||
> help commands
|
||||
━━━━┯━━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
# │ name │ description
|
||||
────┼──────────────┼────────────────────────────────────────────────────────────────────────────────────────
|
||||
0 │ add │ Add a new field to the table.
|
||||
1 │ autoview │ View the contents of the pipeline as a table or list.
|
||||
2 │ cd │ Change to a new path.
|
||||
3 │ config │ Configuration management.
|
||||
4 │ cp │ Copy files.
|
||||
5 │ date │ Get the current datetime.
|
||||
...
|
||||
70 │ trim │ Trim leading and following whitespace from text data.
|
||||
71 │ version │ Display Nu version
|
||||
72 │ where │ Filter table to match the condition.
|
||||
73 │ which │ Finds a program file.
|
||||
━━━━┷━━━━━━━━━━━━━━┷━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
```
|
||||
|
||||
```shell
|
||||
> help cd
|
||||
Change to a new path.
|
||||
|
||||
Usage:
|
||||
> cd (directory)
|
||||
```
|
||||
|
||||
|
31
docs/commands/inc.md
Normal file
31
docs/commands/inc.md
Normal file
@ -0,0 +1,31 @@
|
||||
# inc
|
||||
|
||||
This command increments the value of variable by one.
|
||||
|
||||
## Examples
|
||||
|
||||
```shell
|
||||
> open rustfmt.toml
|
||||
---------
|
||||
edition
|
||||
---------
|
||||
2018
|
||||
---------
|
||||
> open rustfmt.toml | inc edition
|
||||
---------
|
||||
edition
|
||||
---------
|
||||
2019
|
||||
---------
|
||||
```
|
||||
|
||||
```shell
|
||||
> open Cargo.toml | get package.version
|
||||
0.1.3
|
||||
> open Cargo.toml | inc package.version --major | get package.version
|
||||
1.0.0
|
||||
> open Cargo.toml | inc package.version --minor | get package.version
|
||||
0.2.0
|
||||
> open Cargo.toml | inc package.version --patch | get package.version
|
||||
0.1.4
|
||||
```
|
29
docs/commands/last.md
Normal file
29
docs/commands/last.md
Normal file
@ -0,0 +1,29 @@
|
||||
# last
|
||||
|
||||
Use `last` to retrieve the last "n" rows of a table. `last` has a required amount parameter that indicates how many rows you would like returned. If more than one row is returned, an index column will be included showing the row number. `last` does not alter the order of the rows of the table.
|
||||
|
||||
## Examples
|
||||
|
||||
```shell
|
||||
> ps | last 1
|
||||
━━━━━┯━━━━━━━━━━━━━┯━━━━━━━━━┯━━━━━━━━━━━━━━━━━━━
|
||||
pid │ name │ status │ cpu
|
||||
─────┼─────────────┼─────────┼───────────────────
|
||||
121 │ loginwindow │ Running │ 0.000000000000000
|
||||
━━━━━┷━━━━━━━━━━━━━┷━━━━━━━━━┷━━━━━━━━━━━━━━━━━━━
|
||||
```
|
||||
|
||||
```shell
|
||||
> ps | last 5
|
||||
━━━┯━━━━━┯━━━━━━━━━━━━━━━━┯━━━━━━━━━┯━━━━━━━━━━━━━━━━━━━
|
||||
# │ pid │ name │ status │ cpu
|
||||
───┼─────┼────────────────┼─────────┼───────────────────
|
||||
0 │ 360 │ CommCenter │ Running │ 0.000000000000000
|
||||
1 │ 358 │ distnoted │ Running │ 0.000000000000000
|
||||
2 │ 356 │ UserEventAgent │ Running │ 0.000000000000000
|
||||
3 │ 354 │ cfprefsd │ Running │ 0.000000000000000
|
||||
4 │ 121 │ loginwindow │ Running │ 0.000000000000000
|
||||
━━━┷━━━━━┷━━━━━━━━━━━━━━━━┷━━━━━━━━━┷━━━━━━━━━━━━━━━━━━━
|
||||
```
|
||||
|
||||
|
28
docs/commands/lines.md
Normal file
28
docs/commands/lines.md
Normal file
@ -0,0 +1,28 @@
|
||||
# lines
|
||||
This command takes a string from a pipeline as input, and returns a table where each line of the input string is a row in the table. Empty lines are ignored. This command is capable of feeding other commands, such as `nth`, with its output.
|
||||
|
||||
## Usage
|
||||
```shell
|
||||
> [input-command] | lines
|
||||
```
|
||||
|
||||
## Examples
|
||||
Basic usage:
|
||||
```shell
|
||||
> printf "Hello\nWorld!\nLove, nushell." | lines
|
||||
━━━┯━━━━━━━━━━━━━━━━
|
||||
# │ value
|
||||
───┼────────────────
|
||||
0 │ Hello
|
||||
1 │ World!
|
||||
2 │ Love, nushell.
|
||||
━━━┷━━━━━━━━━━━━━━━━
|
||||
```
|
||||
|
||||
One useful application is piping the contents of file into `lines`. This example extracts a certain line from a given file.
|
||||
```shell
|
||||
> cat lines.md | lines | nth 6
|
||||
## Examples
|
||||
```
|
||||
|
||||
Similarly to this example, `lines` can be used to extract certain portions of or apply transformations to data returned by any program which returns a string.
|
31
docs/commands/nth.md
Normal file
31
docs/commands/nth.md
Normal file
@ -0,0 +1,31 @@
|
||||
# nth
|
||||
|
||||
This command returns the nth row of a table, starting from 0.
|
||||
If the number given is less than 0 or more than the number of rows, nothing is returned.
|
||||
|
||||
## Usage
|
||||
```shell
|
||||
> [input-command] | nth [row-number]
|
||||
```
|
||||
|
||||
## Examples
|
||||
```shell
|
||||
> ls
|
||||
━━━┯━━━━━━━━━━━━┯━━━━━━━━━━━┯━━━━━━━━━━┯━━━━━━━━┯━━━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━
|
||||
# │ name │ type │ readonly │ size │ accessed │ modified
|
||||
───┼────────────┼───────────┼──────────┼────────┼───────────────┼───────────────
|
||||
0 │ Cargo.toml │ File │ │ 239 B │ 2 minutes ago │ 2 minutes ago
|
||||
1 │ .git │ Directory │ │ 4.1 KB │ 2 minutes ago │ 2 minutes ago
|
||||
2 │ .gitignore │ File │ │ 19 B │ 2 minutes ago │ 2 minutes ago
|
||||
3 │ src │ Directory │ │ 4.1 KB │ 2 minutes ago │ 2 minutes ago
|
||||
━━━┷━━━━━━━━━━━━┷━━━━━━━━━━━┷━━━━━━━━━━┷━━━━━━━━┷━━━━━━━━━━━━━━━┷━━━━━━━━━━━━━━━
|
||||
|
||||
> ls | nth 0
|
||||
━━━━━━━━━━━━┯━━━━━━┯━━━━━━━━━━┯━━━━━━━━┯━━━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━
|
||||
name │ type │ readonly │ size │ accessed │ modified
|
||||
────────────┼──────┼──────────┼────────┼───────────────┼───────────────
|
||||
Cargo.toml │ File │ │ 239 B │ 2 minutes ago │ 2 minutes ago
|
||||
━━━━━━━━━━━━┷━━━━━━┷━━━━━━━━━━┷━━━━━━━━┷━━━━━━━━━━━━━━━┷━━━━━━━━━━━━━━━
|
||||
|
||||
> ls | nth 5
|
||||
```
|
95
docs/commands/open.md
Normal file
95
docs/commands/open.md
Normal file
@ -0,0 +1,95 @@
|
||||
# open
|
||||
|
||||
Loads a file into a cell, convert it to table if possible (avoid by appending `--raw` flag)
|
||||
|
||||
## Example
|
||||
|
||||
```shell
|
||||
> cat user.yaml
|
||||
- Name: Peter
|
||||
Age: 30
|
||||
Telephone: 88204828
|
||||
Country: Singapore
|
||||
- Name: Michael
|
||||
Age: 42
|
||||
Telephone: 44002010
|
||||
Country: Spain
|
||||
- Name: Will
|
||||
Age: 50
|
||||
Telephone: 99521080
|
||||
Country: Germany
|
||||
> open user.yaml
|
||||
━━━┯━━━━━━━━━┯━━━━━┯━━━━━━━━━━━┯━━━━━━━━━━━
|
||||
# │ Name │ Age │ Telephone │ Country
|
||||
───┼─────────┼─────┼───────────┼───────────
|
||||
0 │ Peter │ 30 │ 88204828 │ Singapore
|
||||
1 │ Michael │ 42 │ 44002010 │ Spain
|
||||
2 │ Will │ 50 │ 99521080 │ Germany
|
||||
━━━┷━━━━━━━━━┷━━━━━┷━━━━━━━━━━━┷━━━━━━━━━━━
|
||||
> open user.yaml --raw
|
||||
- Name: Peter
|
||||
Age: 30
|
||||
Telephone: 88204828
|
||||
Country: Singapore
|
||||
- Name: Michael
|
||||
Age: 42
|
||||
Telephone: 44002010
|
||||
Country: Spain
|
||||
- Name: Will
|
||||
Age: 50
|
||||
Telephone: 99521080
|
||||
Country: Germany
|
||||
```
|
||||
|
||||
```shell
|
||||
> cat user.json
|
||||
[
|
||||
{
|
||||
"Name": "Peter",
|
||||
"Age": 30,
|
||||
"Telephone": 88204828,
|
||||
"Country": "Singapore"
|
||||
},
|
||||
{
|
||||
"Name": "Michael",
|
||||
"Age": 42,
|
||||
"Telephone": 44002010,
|
||||
"Country": "Spain"
|
||||
},
|
||||
{
|
||||
"Name": "Will",
|
||||
"Age": 50,
|
||||
"Telephone": 99521080,
|
||||
"Country": "Germany"
|
||||
}
|
||||
]
|
||||
> open user.json
|
||||
━━━┯━━━━━━━━━┯━━━━━┯━━━━━━━━━━━┯━━━━━━━━━━━
|
||||
# │ Name │ Age │ Telephone │ Country
|
||||
───┼─────────┼─────┼───────────┼───────────
|
||||
0 │ Peter │ 30 │ 88204828 │ Singapore
|
||||
1 │ Michael │ 42 │ 44002010 │ Spain
|
||||
2 │ Will │ 50 │ 99521080 │ Germany
|
||||
━━━┷━━━━━━━━━┷━━━━━┷━━━━━━━━━━━┷━━━━━━━━━━━
|
||||
> open user.json --raw
|
||||
[
|
||||
{
|
||||
"Name": "Peter",
|
||||
"Age": 30,
|
||||
"Telephone": 88204828,
|
||||
"Country": "Singapore"
|
||||
},
|
||||
{
|
||||
"Name": "Michael",
|
||||
"Age": 42,
|
||||
"Telephone": 44002010,
|
||||
"Country": "Spain"
|
||||
},
|
||||
{
|
||||
"Name": "Will",
|
||||
"Age": 50,
|
||||
"Telephone": 99521080,
|
||||
"Country": "Germany"
|
||||
}
|
||||
]
|
||||
```
|
53
docs/commands/pick.md
Normal file
53
docs/commands/pick.md
Normal file
@ -0,0 +1,53 @@
|
||||
# pick
|
||||
|
||||
This command displays only the column names passed on to it.
|
||||
|
||||
## Examples
|
||||
|
||||
```shell
|
||||
> ls
|
||||
━━━┯━━━━━━━━━━━━━━━━━━━━━━━━━━━━┯━━━━━━┯━━━━━━━━━━┯━━━━━━━━┯━━━━━━━━━━━━━┯━━━━━━━━━━━━━┯━━━━━━━━━━━━━
|
||||
# │ name │ type │ readonly │ size │ created │ accessed │ modified
|
||||
───┼────────────────────────────┼──────┼──────────┼────────┼─────────────┼─────────────┼─────────────
|
||||
0 │ zeusiscrazy.txt │ File │ │ 556 B │ a month ago │ a month ago │ a month ago
|
||||
1 │ coww.txt │ File │ │ 24 B │ a month ago │ a month ago │ a month ago
|
||||
2 │ randomweirdstuff.txt │ File │ │ 197 B │ a month ago │ a month ago │ a month ago
|
||||
3 │ abaracadabra.txt │ File │ │ 401 B │ a month ago │ a month ago │ a month ago
|
||||
4 │ youshouldeatmorecereal.txt │ File │ │ 768 B │ a month ago │ a month ago │ a month ago
|
||||
━━━┷━━━━━━━━━━━━━━━━━━━━━━━━━━━━┷━━━━━━┷━━━━━━━━━━┷━━━━━━━━┷━━━━━━━━━━━━━┷━━━━━━━━━━━━━┷━━━━━━━━━━━━━
|
||||
> ls | pick name
|
||||
━━━┯━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
# │ name
|
||||
───┼────────────────────────────
|
||||
0 │ zeusiscrazy.txt
|
||||
1 │ coww.txt
|
||||
2 │ randomweirdstuff.txt
|
||||
3 │ abaracadabra.txt
|
||||
4 │ youshouldeatmorecereal.txt
|
||||
━━━┷━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
```
|
||||
|
||||
The order in which you put the column names matters:
|
||||
|
||||
```shell
|
||||
> ls | pick type name size
|
||||
━━━┯━━━━━━┯━━━━━━━━━━━━━━━━━━━━━━━━━━━━┯━━━━━━━━
|
||||
# │ type │ name │ size
|
||||
───┼──────┼────────────────────────────┼────────
|
||||
0 │ File │ zeusiscrazy.txt │ 556 B
|
||||
1 │ File │ coww.txt │ 24 B
|
||||
2 │ File │ randomweirdstuff.txt │ 197 B
|
||||
3 │ File │ abaracadabra.txt │ 401 B
|
||||
4 │ File │ youshouldeatmorecereal.txt │ 768 B
|
||||
━━━┷━━━━━━┷━━━━━━━━━━━━━━━━━━━━━━━━━━━━┷━━━━━━━━
|
||||
> ls | pick size type name
|
||||
━━━┯━━━━━━━━┯━━━━━━┯━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
# │ size │ type │ name
|
||||
───┼────────┼──────┼────────────────────────────
|
||||
0 │ 556 B │ File │ zeusiscrazy.txt
|
||||
1 │ 24 B │ File │ coww.txt
|
||||
2 │ 197 B │ File │ randomweirdstuff.txt
|
||||
3 │ 401 B │ File │ abaracadabra.txt
|
||||
4 │ 768 B │ File │ youshouldeatmorecereal.txt
|
||||
━━━┷━━━━━━━━┷━━━━━━┷━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
```
|
75
docs/commands/pivot.md
Normal file
75
docs/commands/pivot.md
Normal file
@ -0,0 +1,75 @@
|
||||
# pivot
|
||||
|
||||
Pivots the table contents so rows become columns and columns become rows.
|
||||
|
||||
## Examples
|
||||
|
||||
```sh
|
||||
> ls docs
|
||||
━━━┯━━━━━━━━━━━━━━━━━━━━┯━━━━━━━━━━━┯━━━━━━━━━━┯━━━━━━━━┯━━━━━━━━━━━━━┯━━━━━━━━━━━━━
|
||||
# │ name │ type │ readonly │ size │ accessed │ modified
|
||||
───┼────────────────────┼───────────┼──────────┼────────┼─────────────┼─────────────
|
||||
0 │ docs/commands │ Directory │ │ 4.1 KB │ an hour ago │ an hour ago
|
||||
1 │ docs/docker.md │ File │ │ 7.0 KB │ an hour ago │ a day ago
|
||||
2 │ docs/philosophy.md │ File │ │ 896 B │ an hour ago │ a day ago
|
||||
━━━┷━━━━━━━━━━━━━━━━━━━━┷━━━━━━━━━━━┷━━━━━━━━━━┷━━━━━━━━┷━━━━━━━━━━━━━┷━━━━━━━━━━━━━
|
||||
|
||||
> ls docs | pivot
|
||||
━━━┯━━━━━━━━━━┯━━━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━━━━━━
|
||||
# │ Column0 │ Column1 │ Column2 │ Column3
|
||||
───┼──────────┼───────────────┼────────────────┼────────────────────
|
||||
0 │ name │ docs/commands │ docs/docker.md │ docs/philosophy.md
|
||||
1 │ type │ Directory │ File │ File
|
||||
2 │ readonly │ │ │
|
||||
3 │ size │ 4.1 KB │ 7.0 KB │ 896 B
|
||||
4 │ accessed │ an hour ago │ an hour ago │ an hour ago
|
||||
5 │ modified │ an hour ago │ a day ago │ a day ago
|
||||
━━━┷━━━━━━━━━━┷━━━━━━━━━━━━━━━┷━━━━━━━━━━━━━━━━┷━━━━━━━━━━━━━━━━━━━━
|
||||
```
|
||||
|
||||
Use `--header-row` to treat the first row as column names:
|
||||
|
||||
```shell
|
||||
> ls docs | pivot --header-row
|
||||
━━━┯━━━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━━━━━━
|
||||
# │ docs/commands │ docs/docker.md │ docs/philosophy.md
|
||||
───┼───────────────┼────────────────┼────────────────────
|
||||
0 │ Directory │ File │ File
|
||||
1 │ │ │
|
||||
2 │ 4.1 KB │ 7.0 KB │ 896 B
|
||||
3 │ an hour ago │ an hour ago │ an hour ago
|
||||
4 │ an hour ago │ a day ago │ a day ago
|
||||
━━━┷━━━━━━━━━━━━━━━┷━━━━━━━━━━━━━━━━┷━━━━━━━━━━━━━━━━━━━━
|
||||
```
|
||||
|
||||
Use `--ignore-titles` to prevent pivoting the column names into values:
|
||||
|
||||
```shell
|
||||
> ls docs | pivot --ignore-titles
|
||||
━━━┯━━━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━━━━━━
|
||||
# │ Column0 │ Column1 │ Column2
|
||||
───┼───────────────┼────────────────┼────────────────────
|
||||
0 │ docs/commands │ docs/docker.md │ docs/philosophy.md
|
||||
1 │ Directory │ File │ File
|
||||
2 │ │ │
|
||||
3 │ 4.1 KB │ 7.0 KB │ 896 B
|
||||
4 │ an hour ago │ an hour ago │ an hour ago
|
||||
5 │ an hour ago │ a day ago │ a day ago
|
||||
━━━┷━━━━━━━━━━━━━━━┷━━━━━━━━━━━━━━━━┷━━━━━━━━━━━━━━━━━━━━
|
||||
```
|
||||
|
||||
Additional arguments are used as column names:
|
||||
|
||||
```shell
|
||||
> ls docs | pivot foo bar baz
|
||||
━━━┯━━━━━━━━━━┯━━━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━━━━━━
|
||||
# │ foo │ bar │ baz │ Column3
|
||||
───┼──────────┼───────────────┼────────────────┼────────────────────
|
||||
0 │ name │ docs/commands │ docs/docker.md │ docs/philosophy.md
|
||||
1 │ type │ Directory │ File │ File
|
||||
2 │ readonly │ │ │
|
||||
3 │ size │ 4.1 KB │ 7.0 KB │ 896 B
|
||||
4 │ accessed │ 2 hours ago │ 2 hours ago │ 2 hours ago
|
||||
5 │ modified │ 2 hours ago │ a day ago │ a day ago
|
||||
━━━┷━━━━━━━━━━┷━━━━━━━━━━━━━━━┷━━━━━━━━━━━━━━━━┷━━━━━━━━━━━━━━━━━━━━
|
||||
```
|
56
docs/commands/prepend.md
Normal file
56
docs/commands/prepend.md
Normal file
@ -0,0 +1,56 @@
|
||||
# prepend
|
||||
This command prepends the given row to the front of the table
|
||||
|
||||
**Note**:
|
||||
- `prepend` does not change a file itself. If you want to save your changes, you need to run the `save` command
|
||||
- if you want to add something containing a whitespace character, you need to put it in quotation marks
|
||||
|
||||
## Examples
|
||||
|
||||
Let's complete this table with the missing continents:
|
||||
|
||||
```shell
|
||||
> open continents.txt | lines
|
||||
━━━┯━━━━━━━━━━━━━━━
|
||||
# │ <value>
|
||||
───┼───────────────
|
||||
0 │ Africa
|
||||
1 │ South America
|
||||
2 │ Australia
|
||||
3 │ Europe
|
||||
4 │ Antarctica
|
||||
━━━┷━━━━━━━━━━━━━━━
|
||||
```
|
||||
|
||||
You can add a new row at the top by using `prepend`:
|
||||
|
||||
```shell
|
||||
> open continents.txt | lines | prepend Asia
|
||||
━━━┯━━━━━━━━━━━━━━━
|
||||
# │ <value>
|
||||
───┼───────────────
|
||||
0 │ Asia
|
||||
1 │ Africa
|
||||
2 │ South America
|
||||
3 │ Australia
|
||||
4 │ Europe
|
||||
5 │ Antarctica
|
||||
━━━┷━━━━━━━━━━━━━━━
|
||||
```
|
||||
|
||||
It's not possible to add multiple rows at once, so you'll need to call `prepend` multiple times:
|
||||
|
||||
```shell
|
||||
> open continents.txt | lines | prepend Asia | prepend "North America"
|
||||
━━━┯━━━━━━━━━━━━━━━
|
||||
# │ <value>
|
||||
───┼───────────────
|
||||
0 │ North America
|
||||
1 │ Asia
|
||||
2 │ Africa
|
||||
3 │ South America
|
||||
4 │ Australia
|
||||
5 │ Europe
|
||||
6 │ Antarctica
|
||||
━━━┷━━━━━━━━━━━━━━━
|
||||
```
|
38
docs/commands/reject.md
Normal file
38
docs/commands/reject.md
Normal file
@ -0,0 +1,38 @@
|
||||
# reject
|
||||
|
||||
This column removes or rejects the columns passed to it.
|
||||
|
||||
## Examples
|
||||
|
||||
```shell
|
||||
> ls
|
||||
━━━┯━━━━━━━━━━━━━━━━━━━━━━━━━━━━┯━━━━━━┯━━━━━━━━━━┯━━━━━━━━┯━━━━━━━━━━━━━┯━━━━━━━━━━━━━┯━━━━━━━━━━━━━
|
||||
# │ name │ type │ readonly │ size │ created │ accessed │ modified
|
||||
───┼────────────────────────────┼──────┼──────────┼────────┼─────────────┼─────────────┼─────────────
|
||||
0 │ zeusiscrazy.txt │ File │ │ 556 B │ a month ago │ a month ago │ a month ago
|
||||
1 │ coww.txt │ File │ │ 24 B │ a month ago │ a month ago │ a month ago
|
||||
2 │ randomweirdstuff.txt │ File │ │ 197 B │ a month ago │ a month ago │ a month ago
|
||||
3 │ abaracadabra.txt │ File │ │ 401 B │ a month ago │ a month ago │ a month ago
|
||||
4 │ youshouldeatmorecereal.txt │ File │ │ 768 B │ a month ago │ a month ago │ a month ago
|
||||
━━━┷━━━━━━━━━━━━━━━━━━━━━━━━━━━━┷━━━━━━┷━━━━━━━━━━┷━━━━━━━━┷━━━━━━━━━━━━━┷━━━━━━━━━━━━━┷━━━━━━━━━━━━━
|
||||
> ls | reject readonly
|
||||
━━━┯━━━━━━━━━━━━━━━━━━━━━━━━━━━━┯━━━━━━┯━━━━━━━━┯━━━━━━━━━━━━━┯━━━━━━━━━━━━━┯━━━━━━━━━━━━━
|
||||
# │ name │ type │ size │ created │ accessed │ modified
|
||||
───┼────────────────────────────┼──────┼────────┼─────────────┼─────────────┼─────────────
|
||||
0 │ zeusiscrazy.txt │ File │ 556 B │ a month ago │ a month ago │ a month ago
|
||||
1 │ coww.txt │ File │ 24 B │ a month ago │ a month ago │ a month ago
|
||||
2 │ randomweirdstuff.txt │ File │ 197 B │ a month ago │ a month ago │ a month ago
|
||||
3 │ abaracadabra.txt │ File │ 401 B │ a month ago │ a month ago │ a month ago
|
||||
4 │ youshouldeatmorecereal.txt │ File │ 768 B │ a month ago │ a month ago │ a month ago
|
||||
━━━┷━━━━━━━━━━━━━━━━━━━━━━━━━━━━┷━━━━━━┷━━━━━━━━┷━━━━━━━━━━━━━┷━━━━━━━━━━━━━┷━━━━━━━━━━━━━
|
||||
> ls | reject readonly accessed
|
||||
━━━┯━━━━━━━━━━━━━━━━━━━━━━━━━━━━┯━━━━━━┯━━━━━━━━┯━━━━━━━━━━━━━┯━━━━━━━━━━━━━
|
||||
# │ name │ type │ size │ created │ modified
|
||||
───┼────────────────────────────┼──────┼────────┼─────────────┼─────────────
|
||||
0 │ zeusiscrazy.txt │ File │ 556 B │ a month ago │ a month ago
|
||||
1 │ coww.txt │ File │ 24 B │ a month ago │ a month ago
|
||||
2 │ randomweirdstuff.txt │ File │ 197 B │ a month ago │ a month ago
|
||||
3 │ abaracadabra.txt │ File │ 401 B │ a month ago │ a month ago
|
||||
4 │ youshouldeatmorecereal.txt │ File │ 768 B │ a month ago │ a month ago
|
||||
━━━┷━━━━━━━━━━━━━━━━━━━━━━━━━━━━┷━━━━━━┷━━━━━━━━┷━━━━━━━━━━━━━┷━━━━━━━━━━━━━
|
||||
```
|
51
docs/commands/reverse.md
Normal file
51
docs/commands/reverse.md
Normal file
@ -0,0 +1,51 @@
|
||||
# reverse
|
||||
|
||||
This command reverses the order of the elements in a sorted table.
|
||||
|
||||
## Examples
|
||||
|
||||
```shell
|
||||
> ls | sort-by name
|
||||
━━━┯━━━━━━━━━━━━━━━━━━━━━━━━━━━━┯━━━━━━┯━━━━━━━━━━┯━━━━━━━━┯━━━━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━━
|
||||
# │ name │ type │ readonly │ size │ accessed │ modified
|
||||
───┼────────────────────────────┼──────┼──────────┼────────┼────────────────┼────────────────
|
||||
0 │ abaracadabra.txt │ File │ │ 401 B │ 23 minutes ago │ 16 minutes ago
|
||||
1 │ coww.txt │ File │ │ 24 B │ 22 minutes ago │ 17 minutes ago
|
||||
2 │ randomweirdstuff.txt │ File │ │ 197 B │ 21 minutes ago │ 18 minutes ago
|
||||
3 │ youshouldeatmorecereal.txt │ File │ │ 768 B │ 30 seconds ago │ now
|
||||
4 │ zeusiscrazy.txt │ File │ │ 556 B │ 22 minutes ago │ 18 minutes ago
|
||||
━━━┷━━━━━━━━━━━━━━━━━━━━━━━━━━━━┷━━━━━━┷━━━━━━━━━━┷━━━━━━━━┷━━━━━━━━━━━━━━━━┷━━━━━━━━━━━━━━━━
|
||||
> ls | sort-by name | reverse
|
||||
━━━┯━━━━━━━━━━━━━━━━━━━━━━━━━━━━┯━━━━━━┯━━━━━━━━━━┯━━━━━━━━┯━━━━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━━
|
||||
# │ name │ type │ readonly │ size │ accessed │ modified
|
||||
───┼────────────────────────────┼──────┼──────────┼────────┼────────────────┼────────────────
|
||||
0 │ zeusiscrazy.txt │ File │ │ 556 B │ 22 minutes ago │ 19 minutes ago
|
||||
1 │ youshouldeatmorecereal.txt │ File │ │ 768 B │ 39 seconds ago │ 18 seconds ago
|
||||
2 │ randomweirdstuff.txt │ File │ │ 197 B │ 21 minutes ago │ 18 minutes ago
|
||||
3 │ coww.txt │ File │ │ 24 B │ 22 minutes ago │ 18 minutes ago
|
||||
4 │ abaracadabra.txt │ File │ │ 401 B │ 23 minutes ago │ 16 minutes ago
|
||||
━━━┷━━━━━━━━━━━━━━━━━━━━━━━━━━━━┷━━━━━━┷━━━━━━━━━━┷━━━━━━━━┷━━━━━━━━━━━━━━━━┷━━━━━━━━━━━━━━━━
|
||||
```
|
||||
|
||||
```shell
|
||||
> ls | sort-by size
|
||||
━━━┯━━━━━━━━━━━━━━━━━━━━━━━━━━━━┯━━━━━━┯━━━━━━━━━━┯━━━━━━━━┯━━━━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━━
|
||||
# │ name │ type │ readonly │ size │ accessed │ modified
|
||||
───┼────────────────────────────┼──────┼──────────┼────────┼────────────────┼────────────────
|
||||
0 │ coww.txt │ File │ │ 24 B │ 22 minutes ago │ 18 minutes ago
|
||||
1 │ randomweirdstuff.txt │ File │ │ 197 B │ 21 minutes ago │ 18 minutes ago
|
||||
2 │ abaracadabra.txt │ File │ │ 401 B │ 23 minutes ago │ 16 minutes ago
|
||||
3 │ zeusiscrazy.txt │ File │ │ 556 B │ 22 minutes ago │ 19 minutes ago
|
||||
4 │ youshouldeatmorecereal.txt │ File │ │ 768 B │ a minute ago │ 26 seconds ago
|
||||
━━━┷━━━━━━━━━━━━━━━━━━━━━━━━━━━━┷━━━━━━┷━━━━━━━━━━┷━━━━━━━━┷━━━━━━━━━━━━━━━━┷━━━━━━━━━━━━━━━━
|
||||
> ls | sort-by size | reverse
|
||||
━━━┯━━━━━━━━━━━━━━━━━━━━━━━━━━━━┯━━━━━━┯━━━━━━━━━━┯━━━━━━━━┯━━━━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━━
|
||||
# │ name │ type │ readonly │ size │ accessed │ modified
|
||||
───┼────────────────────────────┼──────┼──────────┼────────┼────────────────┼────────────────
|
||||
0 │ youshouldeatmorecereal.txt │ File │ │ 768 B │ a minute ago │ 32 seconds ago
|
||||
1 │ zeusiscrazy.txt │ File │ │ 556 B │ 22 minutes ago │ 19 minutes ago
|
||||
2 │ abaracadabra.txt │ File │ │ 401 B │ 23 minutes ago │ 16 minutes ago
|
||||
3 │ randomweirdstuff.txt │ File │ │ 197 B │ 21 minutes ago │ 18 minutes ago
|
||||
4 │ coww.txt │ File │ │ 24 B │ 22 minutes ago │ 18 minutes ago
|
||||
━━━┷━━━━━━━━━━━━━━━━━━━━━━━━━━━━┷━━━━━━┷━━━━━━━━━━┷━━━━━━━━┷━━━━━━━━━━━━━━━━┷━━━━━━━━━━━━━━━━
|
||||
```
|
26
docs/commands/shells.md
Normal file
26
docs/commands/shells.md
Normal file
@ -0,0 +1,26 @@
|
||||
# shells
|
||||
|
||||
Lists all the active nu shells with a number/index, a name and the path. Also marks the current nu shell.
|
||||
|
||||
## Examples
|
||||
|
||||
```
|
||||
> shells
|
||||
---+---+------------+---------------
|
||||
# | | name | path
|
||||
---+---+------------+---------------
|
||||
0 | | filesystem | /usr
|
||||
1 | | filesystem | /home
|
||||
2 | X | filesystem | /home/username
|
||||
---+---+------------+---------------
|
||||
```
|
||||
|
||||
```
|
||||
/> shells
|
||||
---+---+-------------------------------------------------+------------------------------------
|
||||
# | | name | path
|
||||
---+---+-------------------------------------------------+------------------------------------
|
||||
0 | | filesystem | /Users/username/Code/nushell
|
||||
1 | X | {/Users/username/Code/nushell/Cargo.toml} | /
|
||||
---+---+-------------------------------------------------+------------------------------------
|
||||
```
|
20
docs/commands/size.md
Normal file
20
docs/commands/size.md
Normal file
@ -0,0 +1,20 @@
|
||||
# size
|
||||
|
||||
This commands gives word count statistics on any text.
|
||||
|
||||
## Examples -
|
||||
|
||||
```shell
|
||||
> open lalala.txt | size
|
||||
━━━━━━━┯━━━━━━━┯━━━━━━━┯━━━━━━━━━━━━
|
||||
lines │ words │ chars │ max length
|
||||
───────┼───────┼───────┼────────────
|
||||
4 │ 10 │ 72 │ 72
|
||||
━━━━━━━┷━━━━━━━┷━━━━━━━┷━━━━━━━━━━━━
|
||||
> open the_mysterious_affair_at_styles.txt | size
|
||||
━━━━━━━┯━━━━━━━┯━━━━━━━━┯━━━━━━━━━━━━
|
||||
lines │ words │ chars │ max length
|
||||
───────┼───────┼────────┼────────────
|
||||
8935 │ 62352 │ 349459 │ 361771
|
||||
━━━━━━━┷━━━━━━━┷━━━━━━━━┷━━━━━━━━━━━━
|
||||
```
|
56
docs/commands/sort-by.md
Normal file
56
docs/commands/sort-by.md
Normal file
@ -0,0 +1,56 @@
|
||||
|
||||
# env
|
||||
|
||||
The `sort-by` command sorts the table being displayed in the terminal by a chosen column(s).
|
||||
|
||||
`sort-by` takes multiple arguments (being the names of columns) sorting by each argument in order.
|
||||
|
||||
|
||||
## Examples -
|
||||
|
||||
```shell
|
||||
/home/example> ls | sort-by size
|
||||
━━━┯━━━━━━┯━━━━━━┯━━━━━━━━━━┯━━━━━━━━┯━━━━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━━
|
||||
# │ name │ type │ readonly │ size │ accessed │ modified
|
||||
───┼──────┼──────┼──────────┼────────┼────────────────┼────────────────
|
||||
0 │ az │ File │ │ 18 B │ 4 minutes ago │ 4 minutes ago
|
||||
1 │ a │ File │ │ 18 B │ 4 minutes ago │ 38 minutes ago
|
||||
2 │ ad │ File │ │ 18 B │ 4 minutes ago │ 4 minutes ago
|
||||
3 │ ac │ File │ │ 18 B │ 4 minutes ago │ 4 minutes ago
|
||||
4 │ ab │ File │ │ 18 B │ 4 minutes ago │ 4 minutes ago
|
||||
5 │ c │ File │ │ 102 B │ 35 minutes ago │ 35 minutes ago
|
||||
6 │ d │ File │ │ 189 B │ 35 minutes ago │ 34 minutes ago
|
||||
7 │ b │ File │ │ 349 B │ 35 minutes ago │ 35 minutes ago
|
||||
━━━┷━━━━━━┷━━━━━━┷━━━━━━━━━━┷━━━━━━━━┷━━━━━━━━━━━━━━━━┷━━━━━━━━━━━━━━━━
|
||||
```
|
||||
|
||||
```shell
|
||||
/home/example> ls | sort-by size name
|
||||
━━━┯━━━━━━┯━━━━━━┯━━━━━━━━━━┯━━━━━━━━┯━━━━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━━
|
||||
# │ name │ type │ readonly │ size │ accessed │ modified
|
||||
───┼──────┼──────┼──────────┼────────┼────────────────┼────────────────
|
||||
0 │ a │ File │ │ 18 B │ 4 minutes ago │ 39 minutes ago
|
||||
1 │ ab │ File │ │ 18 B │ 4 minutes ago │ 4 minutes ago
|
||||
2 │ ac │ File │ │ 18 B │ 4 minutes ago │ 4 minutes ago
|
||||
3 │ ad │ File │ │ 18 B │ 4 minutes ago │ 4 minutes ago
|
||||
4 │ az │ File │ │ 18 B │ 4 minutes ago │ 4 minutes ago
|
||||
5 │ c │ File │ │ 102 B │ 36 minutes ago │ 35 minutes ago
|
||||
6 │ d │ File │ │ 189 B │ 35 minutes ago │ 35 minutes ago
|
||||
7 │ b │ File │ │ 349 B │ 36 minutes ago │ 36 minutes ago
|
||||
```
|
||||
|
||||
```
|
||||
/home/example> ls | sort-by accessed
|
||||
━━━┯━━━━━━┯━━━━━━┯━━━━━━━━━━┯━━━━━━━━┯━━━━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━━
|
||||
# │ name │ type │ readonly │ size │ accessed │ modified
|
||||
───┼──────┼──────┼──────────┼────────┼────────────────┼────────────────
|
||||
0 │ b │ File │ │ 349 B │ 37 minutes ago │ 37 minutes ago
|
||||
1 │ c │ File │ │ 102 B │ 37 minutes ago │ 37 minutes ago
|
||||
2 │ d │ File │ │ 189 B │ 37 minutes ago │ 36 minutes ago
|
||||
3 │ a │ File │ │ 18 B │ 6 minutes ago │ 40 minutes ago
|
||||
4 │ ab │ File │ │ 18 B │ 6 minutes ago │ 6 minutes ago
|
||||
5 │ ac │ File │ │ 18 B │ 6 minutes ago │ 6 minutes ago
|
||||
6 │ ad │ File │ │ 18 B │ 5 minutes ago │ 5 minutes ago
|
||||
7 │ az │ File │ │ 18 B │ 5 minutes ago │ 5 minutes ago
|
||||
━━━┷━━━━━━┷━━━━━━┷━━━━━━━━━━┷━━━━━━━━┷━━━━━━━━━━━━━━━━┷━━━━━━━━━━━━━━━━
|
||||
```
|
50
docs/commands/str.md
Normal file
50
docs/commands/str.md
Normal file
@ -0,0 +1,50 @@
|
||||
# str
|
||||
|
||||
Consumes either a single value or a table and converts the provided data to a string and optionally applies a change.
|
||||
|
||||
## Examples
|
||||
|
||||
```shell
|
||||
> shells
|
||||
━━━┯━━━┯━━━━━━━━━━━━┯━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
# │ │ name │ path
|
||||
───┼───┼────────────┼────────────────────────────────
|
||||
0 │ X │ filesystem │ /home/TUX/stuff/expr/stuff
|
||||
1 │ │ filesystem │ /
|
||||
━━━┷━━━┷━━━━━━━━━━━━┷━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
> shells | str path --upcase
|
||||
━━━┯━━━┯━━━━━━━━━━━━┯━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
# │ │ name │ path
|
||||
───┼───┼────────────┼────────────────────────────────
|
||||
0 │ X │ filesystem │ /HOME/TUX/STUFF/EXPR/STUFF
|
||||
1 │ │ filesystem │ /
|
||||
━━━┷━━━┷━━━━━━━━━━━━┷━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
> shells | str path --downcase
|
||||
━━━┯━━━┯━━━━━━━━━━━━┯━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
# │ │ name │ path
|
||||
───┼───┼────────────┼────────────────────────────────
|
||||
0 │ X │ filesystem │ /home/tux/stuff/expr/stuff
|
||||
1 │ │ filesystem │ /
|
||||
━━━┷━━━┷━━━━━━━━━━━━┷━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
> shells | str # --substring "21, 99"
|
||||
━━━┯━━━┯━━━━━━━━━━━━┯━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
# │ │ name │ path
|
||||
───┼───┼────────────┼────────────────────────────────
|
||||
0 │ X │ filesystem │ stuff
|
||||
1 │ │ filesystem │
|
||||
━━━┷━━━┷━━━━━━━━━━━━┷━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
> shells | str # --substring "6,"
|
||||
━━━┯━━━┯━━━━━━━━━━━━┯━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
# │ │ name │ path
|
||||
───┼───┼────────────┼────────────────────────────────
|
||||
0 │ X │ filesystem │ TUX/stuff/expr/stuff
|
||||
1 │ │ filesystem │
|
||||
━━━┷━━━┷━━━━━━━━━━━━┷━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
|
||||
> echo "1, 2, 3" | split-row "," | str --to-int | sum
|
||||
━━━━━━━━━
|
||||
<value>
|
||||
─────────
|
||||
6
|
||||
━━━━━━━━━
|
||||
```
|
44
docs/commands/sum.md
Normal file
44
docs/commands/sum.md
Normal file
@ -0,0 +1,44 @@
|
||||
# sum
|
||||
This command allows you to calculate the sum of values in a column.
|
||||
|
||||
## Examples
|
||||
To get the sum of the file sizes in a directory, simply pipe the size column from the ls command to the sum command.
|
||||
|
||||
```shell
|
||||
> ls | get size | sum
|
||||
━━━━━━━━━
|
||||
value
|
||||
━━━━━━━━━
|
||||
51.0 MB
|
||||
━━━━━━━━━
|
||||
```
|
||||
|
||||
To get the sum of the characters that make up your present working directory.
|
||||
```shell
|
||||
> pwd | split-row / | size | get chars | sum
|
||||
━━━━━━━━━
|
||||
<value>
|
||||
━━━━━━━━━
|
||||
21
|
||||
━━━━━━━━━
|
||||
```
|
||||
|
||||
Note that sum only works for integer and byte values. If the shell doesn't recognize the values in a column as one of those types, it will return an error.
|
||||
One way to solve this is to convert each row to an integer when possible and then pipe the result to `sum`
|
||||
|
||||
```shell
|
||||
> open tests/fixtures/formats/caco3_plastics.csv | get tariff_item | sum
|
||||
error: Unrecognized type in stream: Primitive(String("2509000000"))
|
||||
- shell:1:0
|
||||
1 | open tests/fixtures/formats/caco3_plastics.csv | get tariff_item | sum
|
||||
| ^^^^ source
|
||||
```
|
||||
|
||||
```shell
|
||||
> open tests/fixtures/formats/caco3_plastics.csv | get tariff_item | str --to-int | sum
|
||||
━━━━━━━━━━━━━
|
||||
<value>
|
||||
─────────────
|
||||
29154639996
|
||||
━━━━━━━━━━━━━
|
||||
```
|
32
docs/commands/sys.md
Normal file
32
docs/commands/sys.md
Normal file
@ -0,0 +1,32 @@
|
||||
# sys
|
||||
|
||||
This command gives information about the system where nu is running on.
|
||||
|
||||
## Examples
|
||||
|
||||
```shell
|
||||
> sys
|
||||
━━━━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━━
|
||||
host │ cpu │ disks │ mem │ net │ battery
|
||||
────────────────┼────────────────┼─────────────────┼────────────────┼──────────────────┼────────────────
|
||||
[table: 1 row] │ [table: 1 row] │ [table: 3 rows] │ [table: 1 row] │ [table: 18 rows] │ [table: 1 row]
|
||||
━━━━━━━━━━━━━━━━┷━━━━━━━━━━━━━━━━┷━━━━━━━━━━━━━━━━━┷━━━━━━━━━━━━━━━━┷━━━━━━━━━━━━━━━━━━┷━━━━━━━━━━━━━━━━
|
||||
> sys | get host
|
||||
━━━━━━━━┯━━━━━━━━━┯━━━━━━━━━━━━━━┯━━━━━━━━┯━━━━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━━━━
|
||||
name │ release │ hostname │ arch │ uptime │ users
|
||||
────────┼─────────┼──────────────┼────────┼────────────────┼──────────────────
|
||||
Darwin │ 18.7.0 │ C02Y437GJGH6 │ x86_64 │ [table: 1 row] │ [table: 17 rows]
|
||||
━━━━━━━━┷━━━━━━━━━┷━━━━━━━━━━━━━━┷━━━━━━━━┷━━━━━━━━━━━━━━━━┷━━━━━━━━━━━━━━━━━━
|
||||
> sys | get cpu
|
||||
━━━━━━━┯━━━━━━━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━━━━━
|
||||
cores │ current ghz │ min ghz │ max ghz
|
||||
───────┼───────────────────┼───────────────────┼───────────────────
|
||||
12 │ 2.600000000000000 │ 2.600000000000000 │ 2.600000000000000
|
||||
━━━━━━━┷━━━━━━━━━━━━━━━━━━━┷━━━━━━━━━━━━━━━━━━━┷━━━━━━━━━━━━━━━━━━━
|
||||
> sys | get mem
|
||||
━━━━━━━━━┯━━━━━━━━━━┯━━━━━━━━━━━━┯━━━━━━━━━━━
|
||||
total │ free │ swap total │ swap free
|
||||
─────────┼──────────┼────────────┼───────────
|
||||
34.4 GB │ 545.0 MB │ 2.1 GB │ 723.0 MB
|
||||
━━━━━━━━━┷━━━━━━━━━━┷━━━━━━━━━━━━┷━━━━━━━━━━━
|
||||
```
|
47
docs/commands/tags.md
Normal file
47
docs/commands/tags.md
Normal file
@ -0,0 +1,47 @@
|
||||
# tags
|
||||
|
||||
The tags commands allows users to access the metadata of the previous value in
|
||||
the pipeline. This command may be run on multiple values of input as well.
|
||||
|
||||
As of writing this, the only metadata returned includes:
|
||||
|
||||
- `span`: the start and end indices of the previous value's substring location
|
||||
- `anchor`: the source where data was loaded from; this may not appear if the
|
||||
previous pipeline value didn't actually have a source (like trying to `open` a
|
||||
dir, or running `ls` on a dir)
|
||||
|
||||
## Examples
|
||||
|
||||
```shell
|
||||
> open README.md | tags
|
||||
━━━━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
span │ anchor
|
||||
────────────────┼──────────────────────────────────────────────────
|
||||
[table: 1 row] │ /Users/danielh/Projects/github/nushell/README.md
|
||||
━━━━━━━━━━━━━━━━┷━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
```
|
||||
|
||||
```shell
|
||||
> open README.md | tags | get span
|
||||
━━━━━━━┯━━━━━
|
||||
start │ end
|
||||
───────┼─────
|
||||
5 │ 14
|
||||
━━━━━━━┷━━━━━
|
||||
```
|
||||
|
||||
```shell
|
||||
> ls | tags | first 3 | get span
|
||||
━━━┯━━━━━━━┯━━━━━
|
||||
# │ start │ end
|
||||
───┼───────┼─────
|
||||
0 │ 0 │ 2
|
||||
1 │ 0 │ 2
|
||||
2 │ 0 │ 2
|
||||
━━━┷━━━━━━━┷━━━━━
|
||||
```
|
||||
|
||||
## Reference
|
||||
|
||||
More useful information on the `tags` command can be found by referencing [The
|
||||
Nu Book's entry on Metadata](https://book.nushell.sh/en/metadata)
|
114
docs/commands/to-csv.md
Normal file
114
docs/commands/to-csv.md
Normal file
@ -0,0 +1,114 @@
|
||||
# to-csv
|
||||
|
||||
Converts table data into csv text.
|
||||
|
||||
## Example
|
||||
|
||||
```shell
|
||||
> shells
|
||||
━━━┯━━━┯━━━━━━━━━━━━┯━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
# │ │ name │ path
|
||||
───┼───┼────────────┼────────────────────────
|
||||
0 │ X │ filesystem │ /home/shaurya
|
||||
1 │ │ filesystem │ /home/shaurya/Pictures
|
||||
2 │ │ filesystem │ /home/shaurya/Desktop
|
||||
━━━┷━━━┷━━━━━━━━━━━━┷━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
> shells | to-csv
|
||||
,name,path
|
||||
X,filesystem,/home/shaurya
|
||||
,filesystem,/home/shaurya/Pictures
|
||||
,filesystem,/home/shaurya/Desktop
|
||||
```
|
||||
|
||||
```shell
|
||||
> open caco3_plastics.csv
|
||||
━━━┯━━━━━━━━━━━━━━┯━━━━━━━━━━━━━━┯━━━━━━━━━━━━━┯━━━━━━━━━━━━━━┯━━━━━━━━━━┯━━━━━━━━━━━━┯━━━━━━━━━━━━┯━━━━━━━━━━━━┯━━━━━━━━━━━┯━━━━━━━━━━━┯━━━━━━━━━━━━━━
|
||||
# │ importer │ shipper │ tariff_item │ name │ origin │ shipped_at │ arrived_at │ net_weight │ fob_price │ cif_price │ cif_per_net_
|
||||
│ │ │ │ │ │ │ │ │ │ │ weight
|
||||
───┼──────────────┼──────────────┼─────────────┼──────────────┼──────────┼────────────┼────────────┼────────────┼───────────┼───────────┼──────────────
|
||||
0 │ PLASTICOS │ S A REVERTE │ 2509000000 │ CARBONATO DE │ SPAIN │ 18/03/2016 │ 17/04/2016 │ 81,000.00 │ 14,417.58 │ 18,252.34 │ 0.23
|
||||
│ RIVAL CIA │ │ │ CALCIO TIPO │ │ │ │ │ │ │
|
||||
│ LTDA │ │ │ CALCIPORE │ │ │ │ │ │ │
|
||||
│ │ │ │ 160 T AL │ │ │ │ │ │ │
|
||||
1 │ MEXICHEM │ OMYA ANDINA │ 2836500000 │ CARBONATO │ COLOMBIA │ 07/07/2016 │ 10/07/2016 │ 26,000.00 │ 7,072.00 │ 8,127.18 │ 0.31
|
||||
│ ECUADOR S.A. │ S A │ │ │ │ │ │ │ │ │
|
||||
2 │ PLASTIAZUAY │ SA REVERTE │ 2836500000 │ CARBONATO DE │ SPAIN │ 27/07/2016 │ 09/08/2016 │ 81,000.00 │ 8,100.00 │ 11,474.55 │ 0.14
|
||||
│ SA │ │ │ CALCIO │ │ │ │ │ │ │
|
||||
3 │ PLASTICOS │ AND │ 2836500000 │ CALCIUM │ TURKEY │ 04/10/2016 │ 11/11/2016 │ 100,000.00 │ 17,500.00 │ 22,533.75 │ 0.23
|
||||
│ RIVAL CIA │ ENDUSTRIYEL │ │ CARBONATE │ │ │ │ │ │ │
|
||||
│ LTDA │ HAMMADDELER │ │ ANADOLU │ │ │ │ │ │ │
|
||||
│ │ DIS TCARET │ │ ANDCARB CT-1 │ │ │ │ │ │ │
|
||||
│ │ LTD.STI. │ │ │ │ │ │ │ │ │
|
||||
4 │ QUIMICA │ SA REVERTE │ 2836500000 │ CARBONATO DE │ SPAIN │ 24/06/2016 │ 12/07/2016 │ 27,000.00 │ 3,258.90 │ 5,585.00 │ 0.21
|
||||
│ COMERCIAL │ │ │ CALCIO │ │ │ │ │ │ │
|
||||
│ QUIMICIAL │ │ │ │ │ │ │ │ │ │
|
||||
│ CIA. LTDA. │ │ │ │ │ │ │ │ │ │
|
||||
5 │ PICA │ OMYA ANDINA │ 3824909999 │ CARBONATO DE │ COLOMBIA │ 01/01/1900 │ 18/01/2016 │ 66,500.00 │ 12,635.00 │ 18,670.52 │ 0.28
|
||||
│ PLASTICOS │ S.A │ │ CALCIO │ │ │ │ │ │ │
|
||||
│ INDUSTRIALES │ │ │ │ │ │ │ │ │ │
|
||||
│ C.A. │ │ │ │ │ │ │ │ │ │
|
||||
6 │ PLASTIQUIM │ OMYA ANDINA │ 3824909999 │ CARBONATO DE │ COLOMBIA │ 01/01/1900 │ 25/10/2016 │ 33,000.00 │ 6,270.00 │ 9,999.00 │ 0.30
|
||||
│ S.A. │ S.A NIT │ │ CALCIO │ │ │ │ │ │ │
|
||||
│ │ 830.027.386- │ │ RECUBIERTO │ │ │ │ │ │ │
|
||||
│ │ 6 │ │ CON ACIDO │ │ │ │ │ │ │
|
||||
│ │ │ │ ESTEARICO │ │ │ │ │ │ │
|
||||
│ │ │ │ OMYA CARB 1T │ │ │ │ │ │ │
|
||||
│ │ │ │ CG BBS 1000 │ │ │ │ │ │ │
|
||||
7 │ QUIMICOS │ SIBELCO │ 3824909999 │ CARBONATO DE │ COLOMBIA │ 01/11/2016 │ 03/11/2016 │ 52,000.00 │ 8,944.00 │ 13,039.05 │ 0.25
|
||||
│ ANDINOS │ COLOMBIA SAS │ │ CALCIO │ │ │ │ │ │ │
|
||||
│ QUIMANDI │ │ │ RECUBIERTO │ │ │ │ │ │ │
|
||||
│ S.A. │ │ │ │ │ │ │ │ │ │
|
||||
8 │ TIGRE │ OMYA ANDINA │ 3824909999 │ CARBONATO DE │ COLOMBIA │ 01/01/1900 │ 28/10/2016 │ 66,000.00 │ 11,748.00 │ 18,216.00 │ 0.28
|
||||
│ ECUADOR S.A. │ S.A NIT │ │ CALCIO │ │ │ │ │ │ │
|
||||
│ ECUATIGRE │ 830.027.386- │ │ RECUBIERTO │ │ │ │ │ │ │
|
||||
│ │ 6 │ │ CON ACIDO │ │ │ │ │ │ │
|
||||
│ │ │ │ ESTEARICO │ │ │ │ │ │ │
|
||||
│ │ │ │ OMYACARB 1T │ │ │ │ │ │ │
|
||||
│ │ │ │ CG BPA 25 NO │ │ │ │ │ │ │
|
||||
━━━┷━━━━━━━━━━━━━━┷━━━━━━━━━━━━━━┷━━━━━━━━━━━━━┷━━━━━━━━━━━━━━┷━━━━━━━━━━┷━━━━━━━━━━━━┷━━━━━━━━━━━━┷━━━━━━━━━━━━┷━━━━━━━━━━━┷━━━━━━━━━━━┷━━━━━━━━━━━━━━
|
||||
> open caco3_plastics.csv | to-csv
|
||||
importer,shipper,tariff_item,name,origin,shipped_at,arrived_at,net_weight,fob_price,cif_price,cif_per_net_weight
|
||||
PLASTICOS RIVAL CIA LTDA,S A REVERTE,2509000000,CARBONATO DE CALCIO TIPO CALCIPORE 160 T AL,SPAIN,18/03/2016,17/04/2016,"81,000.00","14,417.58","18,252.34",0.23
|
||||
MEXICHEM ECUADOR S.A.,OMYA ANDINA S A,2836500000,CARBONATO,COLOMBIA,07/07/2016,10/07/2016,"26,000.00","7,072.00","8,127.18",0.31
|
||||
PLASTIAZUAY SA,SA REVERTE,2836500000,CARBONATO DE CALCIO,SPAIN,27/07/2016,09/08/2016,"81,000.00","8,100.00","11,474.55",0.14
|
||||
PLASTICOS RIVAL CIA LTDA,AND ENDUSTRIYEL HAMMADDELER DIS TCARET LTD.STI.,2836500000,CALCIUM CARBONATE ANADOLU ANDCARB CT-1,TURKEY,04/10/2016,11/11/2016,"100,000.00","17,500.00","22,533.75",0.23
|
||||
QUIMICA COMERCIAL QUIMICIAL CIA. LTDA.,SA REVERTE,2836500000,CARBONATO DE CALCIO,SPAIN,24/06/2016,12/07/2016,"27,000.00","3,258.90","5,585.00",0.21
|
||||
PICA PLASTICOS INDUSTRIALES C.A.,OMYA ANDINA S.A,3824909999,CARBONATO DE CALCIO,COLOMBIA,01/01/1900,18/01/2016,"66,500.00","12,635.00","18,670.52",0.28
|
||||
PLASTIQUIM S.A.,OMYA ANDINA S.A NIT 830.027.386-6,3824909999,CARBONATO DE CALCIO RECUBIERTO CON ACIDO ESTEARICO OMYA CARB 1T CG BBS 1000,COLOMBIA,01/01/1900,25/10/2016,"33,000.00","6,270.00","9,999.00",0.30
|
||||
QUIMICOS ANDINOS QUIMANDI S.A.,SIBELCO COLOMBIA SAS,3824909999,CARBONATO DE CALCIO RECUBIERTO,COLOMBIA,01/11/2016,03/11/2016,"52,000.00","8,944.00","13,039.05",0.25
|
||||
TIGRE ECUADOR S.A. ECUATIGRE,OMYA ANDINA S.A NIT 830.027.386-6,3824909999,CARBONATO DE CALCIO RECUBIERTO CON ACIDO ESTEARICO OMYACARB 1T CG BPA 25 NO,COLOMBIA,01/01/1900,28/10/2016,"66,000.00","11,748.00","18,216.00",0.28
|
||||
```
|
||||
|
||||
To use a character other than ',' to separate records, use `--separator` :
|
||||
|
||||
```shell
|
||||
> shells
|
||||
━━━┯━━━┯━━━━━━━━━━━━┯━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
# │ │ name │ path
|
||||
───┼───┼────────────┼────────────────────────
|
||||
0 │ X │ filesystem │ /home/shaurya
|
||||
1 │ │ filesystem │ /home/shaurya/Pictures
|
||||
2 │ │ filesystem │ /home/shaurya/Desktop
|
||||
━━━┷━━━┷━━━━━━━━━━━━┷━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
> shells | to-csv --separator ';'
|
||||
;name,path
|
||||
X;filesystem;/home/shaurya
|
||||
;filesystem;/home/shaurya/Pictures
|
||||
;filesystem;/home/shaurya/Desktop
|
||||
```
|
||||
|
||||
The string '\t' can be used to separate on tabs. Note that this is the same as using the to-tsv command.
|
||||
|
||||
Newlines '\n' are not acceptable separators.
|
||||
|
||||
Note that separators are currently provided as strings and need to be wrapped in quotes.
|
||||
|
||||
It is also considered an error to use a separator greater than one char :
|
||||
|
||||
```shell
|
||||
> open pets.txt | from-csv --separator '123'
|
||||
error: Expected a single separator char from --separator
|
||||
- shell:1:37
|
||||
1 | open pets.txt | from-csv --separator '123'
|
||||
| ^^^^^ requires a single character string input
|
||||
```
|
40
docs/commands/to-json.md
Normal file
40
docs/commands/to-json.md
Normal file
@ -0,0 +1,40 @@
|
||||
# to-json
|
||||
|
||||
Converts table data into json text.
|
||||
|
||||
## Example
|
||||
|
||||
```shell
|
||||
> shells
|
||||
━━━┯━━━┯━━━━━━━━━━━━┯━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
# │ │ name │ path
|
||||
───┼───┼────────────┼────────────────────────
|
||||
0 │ X │ filesystem │ /home/shaurya
|
||||
1 │ │ filesystem │ /home/shaurya/Pictures
|
||||
2 │ │ filesystem │ /home/shaurya/Desktop
|
||||
━━━┷━━━┷━━━━━━━━━━━━┷━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
> shells | to-json
|
||||
[{" ":"X","name":"filesystem","path":"/home/shaurya"},{" ":" ","name":"filesystem","path":"/home/shaurya/Pictures"},{" ":" ","name":"filesystem","path":"/home/shaurya/Desktop"}]
|
||||
```
|
||||
|
||||
```shell
|
||||
> open sgml_description.json
|
||||
━━━━━━━━━━━━━━━━
|
||||
glossary
|
||||
────────────────
|
||||
[table: 1 row]
|
||||
━━━━━━━━━━━━━━━━
|
||||
> open sgml_description.json | to-json
|
||||
{"glossary":{"title":"example glossary","GlossDiv":{"title":"S","GlossList":{"GlossEntry":{"ID":"SGML","SortAs":"SGML","GlossTerm":"Standard Generalized Markup Language","Acronym":"SGML","Abbrev":"ISO 8879:1986","Height":10,"GlossDef":{"para":"A meta-markup language, used to create markup languages such as DocBook.","GlossSeeAlso":["GML","XML"]},"Sections":[101,102],"GlossSee":"markup"}}}}}
|
||||
```
|
||||
We can also convert formats !
|
||||
```shell
|
||||
> open jonathan.xml
|
||||
━━━━━━━━━━━━━━━━
|
||||
rss
|
||||
────────────────
|
||||
[table: 1 row]
|
||||
━━━━━━━━━━━━━━━━
|
||||
> open jonathan.xml | to-json
|
||||
{"rss":[{"channel":[{"title":["Jonathan Turner"]},{"link":["http://www.jonathanturner.org"]},{"link":[]},{"item":[{"title":["Creating crossplatform Rust terminal apps"]},{"description":["<p><img src=\"/images/pikachu.jpg\" alt=\"Pikachu animation in Windows\" /></p>\n\n<p><em>Look Mom, Pikachu running in Windows CMD!</em></p>\n\n<p>Part of the adventure is not seeing the way ahead and going anyway.</p>\n"]},{"pubDate":["Mon, 05 Oct 2015 00:00:00 +0000"]},{"link":["http://www.jonathanturner.org/2015/10/off-to-new-adventures.html"]},{"guid":["http://www.jonathanturner.org/2015/10/off-to-new-adventures.html"]}]}]}]}
|
||||
```
|
112
docs/commands/to-toml.md
Normal file
112
docs/commands/to-toml.md
Normal file
@ -0,0 +1,112 @@
|
||||
# to-toml
|
||||
|
||||
Converts table data into toml text.
|
||||
|
||||
## Example
|
||||
|
||||
```shell
|
||||
> shells
|
||||
━━━┯━━━┯━━━━━━━━━━━━┯━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
# │ │ name │ path
|
||||
───┼───┼────────────┼────────────────────────
|
||||
0 │ X │ filesystem │ /home/shaurya
|
||||
1 │ │ filesystem │ /home/shaurya/Pictures
|
||||
2 │ │ filesystem │ /home/shaurya/Desktop
|
||||
━━━┷━━━┷━━━━━━━━━━━━┷━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
> shells | to-toml
|
||||
[[]]
|
||||
" " = "X"
|
||||
name = "filesystem"
|
||||
path = "/home/shaurya"
|
||||
|
||||
[[]]
|
||||
" " = " "
|
||||
name = "filesystem"
|
||||
path = "/home/shaurya/Pictures"
|
||||
|
||||
[[]]
|
||||
" " = " "
|
||||
name = "filesystem"
|
||||
path = "/home/shaurya/Desktop"
|
||||
|
||||
```
|
||||
|
||||
```shell
|
||||
> open cargo_sample.toml
|
||||
━━━━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━━
|
||||
dependencies │ dev-dependencies │ package
|
||||
────────────────┼──────────────────┼────────────────
|
||||
[table: 1 row] │ [table: 1 row] │ [table: 1 row]
|
||||
━━━━━━━━━━━━━━━━┷━━━━━━━━━━━━━━━━━━┷━━━━━━━━━━━━━━━━
|
||||
> open cargo_sample.toml | to-toml
|
||||
[dependencies]
|
||||
ansi_term = "0.11.0"
|
||||
app_dirs = "1.2.1"
|
||||
byte-unit = "2.1.0"
|
||||
bytes = "0.4.12"
|
||||
chrono-humanize = "0.0.11"
|
||||
chrono-tz = "0.5.1"
|
||||
clap = "2.33.0"
|
||||
conch-parser = "0.1.1"
|
||||
derive-new = "0.5.6"
|
||||
dunce = "1.0.0"
|
||||
futures-sink-preview = "0.3.0-alpha.16"
|
||||
futures_codec = "0.2.2"
|
||||
getset = "0.0.7"
|
||||
git2 = "0.8.0"
|
||||
itertools = "0.8.0"
|
||||
lalrpop-util = "0.17.0"
|
||||
language-reporting = "0.3.0"
|
||||
log = "0.4.6"
|
||||
logos = "0.10.0-rc2"
|
||||
logos-derive = "0.10.0-rc2"
|
||||
nom = "5.0.0-beta1"
|
||||
ordered-float = "1.0.2"
|
||||
pretty_env_logger = "0.3.0"
|
||||
prettyprint = "0.6.0"
|
||||
prettytable-rs = "0.8.0"
|
||||
regex = "1.1.6"
|
||||
rustyline = "4.1.0"
|
||||
serde = "1.0.91"
|
||||
serde_derive = "1.0.91"
|
||||
serde_json = "1.0.39"
|
||||
subprocess = "0.1.18"
|
||||
sysinfo = "0.8.4"
|
||||
term = "0.5.2"
|
||||
tokio-fs = "0.1.6"
|
||||
toml = "0.5.1"
|
||||
toml-query = "0.9.0"
|
||||
|
||||
[dependencies.chrono]
|
||||
features = ["serde"]
|
||||
version = "0.4.6"
|
||||
|
||||
[dependencies.cursive]
|
||||
default-features = false
|
||||
features = ["pancurses-backend"]
|
||||
version = "0.12.0"
|
||||
|
||||
[dependencies.futures-preview]
|
||||
features = ["compat", "io-compat"]
|
||||
version = "0.3.0-alpha.16"
|
||||
|
||||
[dependencies.indexmap]
|
||||
features = ["serde-1"]
|
||||
version = "1.0.2"
|
||||
|
||||
[dependencies.pancurses]
|
||||
features = ["win32a"]
|
||||
version = "0.16"
|
||||
|
||||
[dev-dependencies]
|
||||
pretty_assertions = "0.6.1"
|
||||
|
||||
[package]
|
||||
authors = ["Yehuda Katz <wycats@gmail.com>"]
|
||||
description = "A shell for the GitHub era"
|
||||
edition = "2018"
|
||||
license = "ISC"
|
||||
name = "nu"
|
||||
version = "0.1.1"
|
||||
|
||||
```
|
80
docs/commands/to-tsv.md
Normal file
80
docs/commands/to-tsv.md
Normal file
@ -0,0 +1,80 @@
|
||||
# to-tsv
|
||||
|
||||
Converts table data into tsv text.
|
||||
|
||||
## Example
|
||||
|
||||
```shell
|
||||
> shells
|
||||
━━━┯━━━┯━━━━━━━━━━━━┯━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
# │ │ name │ path
|
||||
───┼───┼────────────┼────────────────────────
|
||||
0 │ X │ filesystem │ /home/shaurya
|
||||
1 │ │ filesystem │ /home/shaurya/Pictures
|
||||
2 │ │ filesystem │ /home/shaurya/Desktop
|
||||
━━━┷━━━┷━━━━━━━━━━━━┷━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
> shells |to-tsv
|
||||
name path
|
||||
X filesystem /home/shaurya
|
||||
|
||||
```
|
||||
|
||||
```shell
|
||||
> open caco3_plastics.tsv
|
||||
━━━┯━━━━━━━━━━━━━━┯━━━━━━━━━━━━━━┯━━━━━━━━━━━━━┯━━━━━━━━━━━━━━┯━━━━━━━━━━┯━━━━━━━━━━━━┯━━━━━━━━━━━━┯━━━━━━━━━━━━┯━━━━━━━━━━━┯━━━━━━━━━━━┯━━━━━━━━━━━━━━
|
||||
# │ importer │ shipper │ tariff_item │ name │ origin │ shipped_at │ arrived_at │ net_weight │ fob_price │ cif_price │ cif_per_net_
|
||||
│ │ │ │ │ │ │ │ │ │ │ weight
|
||||
───┼──────────────┼──────────────┼─────────────┼──────────────┼──────────┼────────────┼────────────┼────────────┼───────────┼───────────┼──────────────
|
||||
0 │ PLASTICOS │ S A REVERTE │ 2509000000 │ CARBONATO DE │ SPAIN │ 18/03/2016 │ 17/04/2016 │ 81,000.00 │ 14,417.58 │ 18,252.34 │ 0.23
|
||||
│ RIVAL CIA │ │ │ CALCIO TIPO │ │ │ │ │ │ │
|
||||
│ LTDA │ │ │ CALCIPORE │ │ │ │ │ │ │
|
||||
│ │ │ │ 160 T AL │ │ │ │ │ │ │
|
||||
1 │ MEXICHEM │ OMYA ANDINA │ 2836500000 │ CARBONATO │ COLOMBIA │ 07/07/2016 │ 10/07/2016 │ 26,000.00 │ 7,072.00 │ 8,127.18 │ 0.31
|
||||
│ ECUADOR S.A. │ S A │ │ │ │ │ │ │ │ │
|
||||
2 │ PLASTIAZUAY │ SA REVERTE │ 2836500000 │ CARBONATO DE │ SPAIN │ 27/07/2016 │ 09/08/2016 │ 81,000.00 │ 8,100.00 │ 11,474.55 │ 0.14
|
||||
│ SA │ │ │ CALCIO │ │ │ │ │ │ │
|
||||
3 │ PLASTICOS │ AND │ 2836500000 │ CALCIUM │ TURKEY │ 04/10/2016 │ 11/11/2016 │ 100,000.00 │ 17,500.00 │ 22,533.75 │ 0.23
|
||||
│ RIVAL CIA │ ENDUSTRIYEL │ │ CARBONATE │ │ │ │ │ │ │
|
||||
│ LTDA │ HAMMADDELER │ │ ANADOLU │ │ │ │ │ │ │
|
||||
│ │ DIS TCARET │ │ ANDCARB CT-1 │ │ │ │ │ │ │
|
||||
│ │ LTD.STI. │ │ │ │ │ │ │ │ │
|
||||
4 │ QUIMICA │ SA REVERTE │ 2836500000 │ CARBONATO DE │ SPAIN │ 24/06/2016 │ 12/07/2016 │ 27,000.00 │ 3,258.90 │ 5,585.00 │ 0.21
|
||||
│ COMERCIAL │ │ │ CALCIO │ │ │ │ │ │ │
|
||||
│ QUIMICIAL │ │ │ │ │ │ │ │ │ │
|
||||
│ CIA. LTDA. │ │ │ │ │ │ │ │ │ │
|
||||
5 │ PICA │ OMYA ANDINA │ 3824909999 │ CARBONATO DE │ COLOMBIA │ 01/01/1900 │ 18/01/2016 │ 66,500.00 │ 12,635.00 │ 18,670.52 │ 0.28
|
||||
│ PLASTICOS │ S.A │ │ CALCIO │ │ │ │ │ │ │
|
||||
│ INDUSTRIALES │ │ │ │ │ │ │ │ │ │
|
||||
│ C.A. │ │ │ │ │ │ │ │ │ │
|
||||
6 │ PLASTIQUIM │ OMYA ANDINA │ 3824909999 │ CARBONATO DE │ COLOMBIA │ 01/01/1900 │ 25/10/2016 │ 33,000.00 │ 6,270.00 │ 9,999.00 │ 0.30
|
||||
│ S.A. │ S.A NIT │ │ CALCIO │ │ │ │ │ │ │
|
||||
│ │ 830.027.386- │ │ RECUBIERTO │ │ │ │ │ │ │
|
||||
│ │ 6 │ │ CON ACIDO │ │ │ │ │ │ │
|
||||
│ │ │ │ ESTEARICO │ │ │ │ │ │ │
|
||||
│ │ │ │ OMYA CARB 1T │ │ │ │ │ │ │
|
||||
│ │ │ │ CG BBS 1000 │ │ │ │ │ │ │
|
||||
7 │ QUIMICOS │ SIBELCO │ 3824909999 │ CARBONATO DE │ COLOMBIA │ 01/11/2016 │ 03/11/2016 │ 52,000.00 │ 8,944.00 │ 13,039.05 │ 0.25
|
||||
│ ANDINOS │ COLOMBIA SAS │ │ CALCIO │ │ │ │ │ │ │
|
||||
│ QUIMANDI │ │ │ RECUBIERTO │ │ │ │ │ │ │
|
||||
│ S.A. │ │ │ │ │ │ │ │ │ │
|
||||
8 │ TIGRE │ OMYA ANDINA │ 3824909999 │ CARBONATO DE │ COLOMBIA │ 01/01/1900 │ 28/10/2016 │ 66,000.00 │ 11,748.00 │ 18,216.00 │ 0.28
|
||||
│ ECUADOR S.A. │ S.A NIT │ │ CALCIO │ │ │ │ │ │ │
|
||||
│ ECUATIGRE │ 830.027.386- │ │ RECUBIERTO │ │ │ │ │ │ │
|
||||
│ │ 6 │ │ CON ACIDO │ │ │ │ │ │ │
|
||||
│ │ │ │ ESTEARICO │ │ │ │ │ │ │
|
||||
│ │ │ │ OMYACARB 1T │ │ │ │ │ │ │
|
||||
│ │ │ │ CG BPA 25 NO │ │ │ │ │ │ │
|
||||
━━━┷━━━━━━━━━━━━━━┷━━━━━━━━━━━━━━┷━━━━━━━━━━━━━┷━━━━━━━━━━━━━━┷━━━━━━━━━━┷━━━━━━━━━━━━┷━━━━━━━━━━━━┷━━━━━━━━━━━━┷━━━━━━━━━━━┷━━━━━━━━━━━┷━━━━━━━━━━━━━━
|
||||
> open caco3_plastics.tsv | to-tsv
|
||||
importer shipper tariff_item name origin shipped_at arrived_at net_weight fob_price cif_price cif_per_net_weight
|
||||
PLASTICOS RIVAL CIA LTDA S A REVERTE 2509000000 CARBONATO DE CALCIO TIPO CALCIPORE 160 T AL SPAIN 18/03/2016 17/04/2016 81,000.00 14,417.58 18,252.34 0.23
|
||||
MEXICHEM ECUADOR S.A. OMYA ANDINA S A 2836500000 CARBONATO COLOMBIA 07/07/2016 10/07/2016 26,000.00 7,072.00 8,127.18 0.31
|
||||
PLASTIAZUAY SA SA REVERTE 2836500000 CARBONATO DE CALCIO SPAIN 27/07/2016 09/08/2016 81,000.00 8,100.00 11,474.55 0.14
|
||||
PLASTICOS RIVAL CIA LTDA AND ENDUSTRIYEL HAMMADDELER DIS TCARET LTD.STI. 2836500000 CALCIUM CARBONATE ANADOLU ANDCARB CT-1 TURKEY 04/10/2016 11/11/2016 100,000.00 17,500.00 22,533.75 0.23
|
||||
QUIMICA COMERCIAL QUIMICIAL CIA. LTDA. SA REVERTE 2836500000 CARBONATO DE CALCIO SPAIN 24/06/2016 12/07/2016 27,000.00 3,258.90 5,585.00 0.21
|
||||
PICA PLASTICOS INDUSTRIALES C.A. OMYA ANDINA S.A 3824909999 CARBONATO DE CALCIO COLOMBIA 01/01/1900 18/01/2016 66,500.00 12,635.00 18,670.52 0.28
|
||||
PLASTIQUIM S.A. OMYA ANDINA S.A NIT 830.027.386-6 3824909999 CARBONATO DE CALCIO RECUBIERTO CON ACIDO ESTEARICO OMYA CARB 1T CG BBS 1000 COLOMBIA 01/01/1900 25/10/2016 33,000.00 6,270.00 9,999.00 0.30
|
||||
QUIMICOS ANDINOS QUIMANDI S.A. SIBELCO COLOMBIA SAS 3824909999 CARBONATO DE CALCIO RECUBIERTO COLOMBIA 01/11/2016 03/11/2016 52,000.00 8,944.00 13,039.05 0.25
|
||||
TIGRE ECUADOR S.A. ECUATIGRE OMYA ANDINA S.A NIT 830.027.386-6 3824909999 CARBONATO DE CALCIO RECUBIERTO CON ACIDO ESTEARICO OMYACARB 1T CG BPA 25 NO COLOMBIA 01/01/1900 28/10/2016 66,000.00 11,748.00 18,216.00 0.28
|
||||
|
||||
```
|
35
docs/commands/to-url.md
Normal file
35
docs/commands/to-url.md
Normal file
@ -0,0 +1,35 @@
|
||||
# to-url
|
||||
|
||||
Converts table data into url-formatted text.
|
||||
|
||||
## Example
|
||||
|
||||
```shell
|
||||
> shells
|
||||
━━━┯━━━┯━━━━━━━━━━━━┯━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
# │ │ name │ path
|
||||
───┼───┼────────────┼────────────────────────
|
||||
0 │ X │ filesystem │ /home/shaurya
|
||||
1 │ │ filesystem │ /home/shaurya/Pictures
|
||||
2 │ │ filesystem │ /home/shaurya/Desktop
|
||||
━━━┷━━━┷━━━━━━━━━━━━┷━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
> shells | to-url
|
||||
━━━┯━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
# │ value
|
||||
───┼───────────────────────────────────────────────────────
|
||||
0 │ +=X&name=filesystem&path=%2Fhome%2Fshaurya
|
||||
1 │ +=+&name=filesystem&path=%2Fhome%2Fshaurya%2FPictures
|
||||
2 │ +=+&name=filesystem&path=%2Fhome%2Fshaurya%2FDesktop
|
||||
━━━┷━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
```
|
||||
|
||||
```shell
|
||||
> open sample.url
|
||||
━━━━━━━━━━┯━━━━━━━━┯━━━━━━┯━━━━━━━━
|
||||
bread │ cheese │ meat │ fat
|
||||
──────────┼────────┼──────┼────────
|
||||
baguette │ comté │ ham │ butter
|
||||
━━━━━━━━━━┷━━━━━━━━┷━━━━━━┷━━━━━━━━
|
||||
> open sample.url | to-url
|
||||
bread=baguette&cheese=comt%C3%A9&meat=ham&fat=butter
|
||||
```
|
60
docs/commands/to-yaml.md
Normal file
60
docs/commands/to-yaml.md
Normal file
@ -0,0 +1,60 @@
|
||||
# to-yaml
|
||||
|
||||
Converts table data into yaml text.
|
||||
|
||||
## Example
|
||||
|
||||
```shell
|
||||
> shells
|
||||
━━━┯━━━┯━━━━━━━━━━━━┯━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
# │ │ name │ path
|
||||
───┼───┼────────────┼────────────────────────
|
||||
0 │ X │ filesystem │ /home/shaurya
|
||||
1 │ │ filesystem │ /home/shaurya/Pictures
|
||||
2 │ │ filesystem │ /home/shaurya/Desktop
|
||||
━━━┷━━━┷━━━━━━━━━━━━┷━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
> shells | to-yaml
|
||||
---
|
||||
- " ": X
|
||||
name: filesystem
|
||||
path: /home/shaurya
|
||||
- " ": " "
|
||||
name: filesystem
|
||||
path: /home/shaurya/Pictures
|
||||
- " ": " "
|
||||
name: filesystem
|
||||
path: /home/shaurya/Desktop
|
||||
```
|
||||
|
||||
```shell
|
||||
> open appveyor.yml
|
||||
━━━━━━━━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━━━┯━━━━━━━┯━━━━━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━━━
|
||||
image │ environment │ install │ build │ test_script │ cache
|
||||
────────────────────┼────────────────┼─────────────────┼───────┼─────────────────┼─────────────────
|
||||
Visual Studio 2017 │ [table: 1 row] │ [table: 5 rows] │ │ [table: 2 rows] │ [table: 2 rows]
|
||||
━━━━━━━━━━━━━━━━━━━━┷━━━━━━━━━━━━━━━━┷━━━━━━━━━━━━━━━━━┷━━━━━━━┷━━━━━━━━━━━━━━━━━┷━━━━━━━━━━━━━━━━━
|
||||
> open appveyor.yml | to-yaml
|
||||
---
|
||||
image: Visual Studio 2017
|
||||
environment:
|
||||
global:
|
||||
PROJECT_NAME: nushell
|
||||
RUST_BACKTRACE: 1
|
||||
matrix:
|
||||
- TARGET: x86_64-pc-windows-msvc
|
||||
CHANNEL: nightly
|
||||
BITS: 64
|
||||
install:
|
||||
- "set PATH=C:\\msys64\\mingw%BITS%\\bin;C:\\msys64\\usr\\bin;%PATH%"
|
||||
- "curl -sSf -o rustup-init.exe https://win.rustup.rs"
|
||||
- rustup-init.exe -y --default-host %TARGET% --default-toolchain %CHANNEL%-%TARGET%
|
||||
- "set PATH=%PATH%;C:\\Users\\appveyor\\.cargo\\bin"
|
||||
- "call \"C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\Community\\VC\\Auxiliary\\Build\\vcvars64.bat\""
|
||||
build: false
|
||||
test_script:
|
||||
- cargo build --verbose
|
||||
- cargo test --all --verbose
|
||||
cache:
|
||||
- target -> Cargo.lock
|
||||
- "C:\\Users\\appveyor\\.cargo\\registry -> Cargo.lock"
|
||||
```
|
12
docs/commands/trim.md
Normal file
12
docs/commands/trim.md
Normal file
@ -0,0 +1,12 @@
|
||||
# trim
|
||||
|
||||
Trim leading and following whitespace from text data
|
||||
|
||||
## Example
|
||||
|
||||
```shell
|
||||
> echo " Hello world"
|
||||
Hello world
|
||||
> echo " Hello world" | trim
|
||||
Hello world
|
||||
```
|
14
docs/commands/version.md
Normal file
14
docs/commands/version.md
Normal file
@ -0,0 +1,14 @@
|
||||
# version
|
||||
|
||||
Outputs the nushell version.
|
||||
|
||||
## Examples
|
||||
|
||||
```shell
|
||||
> version
|
||||
━━━━━━━━━
|
||||
version
|
||||
─────────
|
||||
0.3.0
|
||||
━━━━━━━━━
|
||||
```
|
34
docs/commands/where.md
Normal file
34
docs/commands/where.md
Normal file
@ -0,0 +1,34 @@
|
||||
# where
|
||||
|
||||
This command filters the content of a table based on a condition passed as a parameter, which must be a boolean expression making use of any of the table columns. Other commands such as `ls` are capable of feeding `where` with their output through pipelines.
|
||||
|
||||
## Usage
|
||||
```shell
|
||||
> [input-command] | where [condition]
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
```shell
|
||||
> ls | where size > 4kb
|
||||
----+----------------+------+----------+----------+----------------+----------------
|
||||
# | name | type | readonly | size | accessed | modified
|
||||
----+----------------+------+----------+----------+----------------+----------------
|
||||
0 | IMG_1291.jpg | File | | 115.5 KB | a month ago | 4 months ago
|
||||
1 | README.md | File | | 11.1 KB | 2 days ago | 2 days ago
|
||||
2 | IMG_1291.png | File | | 589.0 KB | a month ago | a month ago
|
||||
3 | IMG_1381.jpg | File | | 81.0 KB | a month ago | 4 months ago
|
||||
4 | butterfly.jpeg | File | | 4.2 KB | a month ago | a month ago
|
||||
5 | Cargo.lock | File | | 199.6 KB | 22 minutes ago | 22 minutes ago
|
||||
```
|
||||
|
||||
```shell
|
||||
> ps | where cpu > 10
|
||||
---+-------+----------+-------+-----------------------------
|
||||
# | pid | status | cpu | name
|
||||
---+-------+----------+-------+-----------------------------
|
||||
0 | 1992 | Sleeping | 44.52 | /usr/bin/gnome-shell
|
||||
1 | 1069 | Sleeping | 16.15 |
|
||||
2 | 24116 | Sleeping | 13.70 | /opt/google/chrome/chrome
|
||||
3 | 21976 | Sleeping | 12.67 | /usr/share/discord/Discord
|
||||
```
|
124
docs/docker.md
Normal file
124
docs/docker.md
Normal file
@ -0,0 +1,124 @@
|
||||
# Docker Guide
|
||||
|
||||
| tag | base image | plugins | package manager | libs & bins | size |
|
||||
| ------------------ | -------------------- | ------- | --------------- | ---------------------------------------------------------------- | ----------- |
|
||||
| `latest`, `debian` | `debian:latest` | yes | apt | **a lot**, including _glibc_ | ~(48+62) MB |
|
||||
| `slim` | `debian:stable-slim` | yes | apt | all `nu:debian` image but exclude [this list][.slimify-excludes] | ~(26+62) MB |
|
||||
| `alpine` | `alpine:latest` | yes | apk | all `nu:musl-busybox` image + libcrypto, libssl, libtls, libz | ~(3+61) MB |
|
||||
| `musl-busybox` | `busybox:musl` | no | — | GNU utils + _musl_ | ~(1+16) MB |
|
||||
| `glibc-busybox` | `busybox:glibc` | no | — | GNU utils + _glibc_ | ~(3+17) MB |
|
||||
| `musl-distroless` | `distroless/static` | no | — | see [here][distroless/base] | ~(2+16) MB |
|
||||
| `glibc-distroless` | `distroless/cc` | no | — | `distroless/static` with _glibc_ | ~(17+17) MB |
|
||||
| `glibc` | `scratch` | no | — | **only `nu` binary-executable** which depend on glibc runtime | ~17 MB |
|
||||
| `musl` | `scratch` | no | — | **only `nu` binary-executable** statically linked to musl | ~16 MB |
|
||||
|
||||
[.slimify-excludes]: https://github.com/debuerreotype/debuerreotype/blob/master/scripts/.slimify-excludes
|
||||
[distroless/base]: https://github.com/GoogleContainerTools/distroless/blob/master/base/README.md
|
||||
|
||||
## Image Variants
|
||||
|
||||
### `nu:<version>`
|
||||
This is the defacto image. If you are unsure about what your needs are, you probably want to use this one. It is designed to be used both as a throw away container (mount your source code and start the container to start your app), as well as the base to build other images off of.
|
||||
|
||||
<details><summary>example</summary>
|
||||
|
||||
Let say you create a plugin in Rust.
|
||||
- create a Dockerfile in your root project
|
||||
```dockerfile
|
||||
FROM nu:0.2
|
||||
|
||||
COPY /target/debug/nu_plugin_cowsay /bin/
|
||||
ENTRYPOINT ["nu"]
|
||||
```
|
||||
- build your project first then run it via docker
|
||||
```console
|
||||
cargo build
|
||||
docker run -it .
|
||||
```
|
||||
</details>
|
||||
|
||||
### `nu:<version>-slim`
|
||||
This image does not contain the common packages contained in the default tag and only contains the minimal packages needed to run `nu`. Unless you are working in an environment where only the `nu` image will be deployed and you have space constraints, it's highly recommended to use the alpine image if you aim for small image size. Only use this image if you really need **both** `glibc` and small image size.
|
||||
|
||||
### `nu:<version>-alpine`
|
||||
This image is based on the popular [Alpine Linux project](https://alpinelinux.org/), available in [the alpine official image][alpine]. Alpine Linux is much smaller than most distribution base images (~5MB), and thus leads to much slimmer images in general.
|
||||
|
||||
This variant is highly recommended when final image size being as small as possible is desired. The main caveat to note is that it does use `musl` libc instead of `glibc` and friends, so certain software might run into issues depending on the depth of their libc requirements. However, most software doesn't have an issue with this, so this variant is usually a very safe choice. See [this Hacker News comment thread](https://news.ycombinator.com/item?id=10782897) for more discussion of the issues that might arise and some pro/con comparisons of using Alpine-based images.
|
||||
|
||||
To minimize image size, it's uncommon for additional related tools (such as `git` or `bash`) to be included in Alpine-based images. Using this image as a base, add the things you need in your own Dockerfile (see the [alpine image description][alpine] for examples of how to install packages if you are unfamiliar).
|
||||
|
||||
### `nu:<version>-<libc-variant>`
|
||||
This image is based on [`scratch`](https://hub.docker.com/_/scratch) which doesn't create an extra layer. This variants can be handy in a project that uses multiple programming language as you need a lot of tools. By using this in [multi-stage build][], you can slim down the docker image that need to be pulled.
|
||||
|
||||
[multi-stage build]: https://docs.docker.com/develop/develop-images/multistage-build/
|
||||
|
||||
<details><summary>example</summary>
|
||||
|
||||
- using `glibc` variant
|
||||
```dockerfile
|
||||
FROM nu:0.2-glibc as shell
|
||||
FROM node:slim
|
||||
|
||||
# Build your plugins
|
||||
|
||||
COPY --from=shell /bin/nu /bin/
|
||||
# Something else
|
||||
ENTRYPOINT ["nu"]
|
||||
```
|
||||
|
||||
- using `musl` variant
|
||||
```dockerfile
|
||||
FROM nu:musl as shell
|
||||
FROM go:alpine
|
||||
|
||||
# Build your plugins
|
||||
|
||||
COPY --from=shell /bin/nu /bin/
|
||||
# Something else
|
||||
ENTRYPOINT ["nu"]
|
||||
```
|
||||
</details>
|
||||
|
||||
### `nu:<version>-<libc-variant>-distroless`
|
||||
This image is base on [Distroless](https://github.com/GoogleContainerTools/distroless) which usually to contain only your application and its runtime dependencies. This image do not contain package managers, shells or any other programs you would expect to find in a standard Linux distribution except for nushell itself. All distroless variant always contains:
|
||||
- ca-certificates
|
||||
- A /etc/passwd entry for a root user
|
||||
- A /tmp directory
|
||||
- tzdata
|
||||
|
||||
As for `glibc-distroless` variant, it **adds**:
|
||||
- glibc
|
||||
- libssl
|
||||
- openssl
|
||||
|
||||
> Most likely you want to use this in CI/CD environment for plugins that can be statically compiled.
|
||||
|
||||
<details><summary>example</summary>
|
||||
|
||||
```dockerfile
|
||||
FROM nu:musl-distroless
|
||||
|
||||
COPY target/x86_64-unknown-linux-musl/release/nu_plugin_* /bin/
|
||||
ENTRYPOINT ["nu"]
|
||||
```
|
||||
</details>
|
||||
|
||||
### `nu:<version>-<libc-variant>-busybox`
|
||||
This image is based on [Busybox](https://www.busybox.net/) which is a very good ingredient to craft space-efficient distributions. It combines tiny versions of many common UNIX utilities into a single small executable. It also provides replacements for most of the utilities you usually find in GNU fileutils, shellutils, etc. The utilities in BusyBox generally have fewer options than their full-featured GNU cousins; however, the options that are included provide the expected functionality and behave very much like their GNU counterparts. Basically, this image provides a fairly complete environment for any small or embedded system.
|
||||
|
||||
> Use this only if you need common utilities like `tar`, `awk`, and many more but don't want extra blob like nushell plugins and others.
|
||||
|
||||
<details><summary>example</summary>
|
||||
|
||||
```dockerfile
|
||||
FROM nu:0.2-glibc-busybox
|
||||
|
||||
ADD https://github.com/user/repo/releases/download/latest/nu_plugin_cowsay.tar.gz /tmp/
|
||||
RUN tar xzfv nu_plugin_cowsay.tar.gz -C /bin --strip=1 nu_plugin_cowsay
|
||||
|
||||
ENTRYPOINT ["nu"]
|
||||
```
|
||||
</details>
|
||||
|
||||
[musl]: https://www.musl-libc.org/
|
||||
[alpine]: https://hub.docker.com/_/alpine/
|
21
features.toml
Normal file
21
features.toml
Normal file
@ -0,0 +1,21 @@
|
||||
[hintsv1]
|
||||
|
||||
description = "Adding hints based upon error states in the syntax highlighter"
|
||||
enabled = false
|
||||
|
||||
[coloring_in_tokens]
|
||||
|
||||
description = "Move coloring into the TokensIterator so they can be atomic with the rest of the iterator"
|
||||
reason = """
|
||||
This is laying the groundwork for merging coloring and parsing. It also makes token_nodes.atomic() naturally
|
||||
work with coloring, which is pretty useful on its own.
|
||||
"""
|
||||
enabled = false
|
||||
|
||||
[data_processing_primitives]
|
||||
|
||||
description = "Groundwork so tables can be data processed"
|
||||
reason = """
|
||||
These will allow take tables and be able to transform, process, and explore.
|
||||
"""
|
||||
enabled = false
|
BIN
images/nushell-autocomplete.gif
Normal file
BIN
images/nushell-autocomplete.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.8 MiB |
750
src/cli.rs
750
src/cli.rs
File diff suppressed because it is too large
Load Diff
280
src/commands.rs
280
src/commands.rs
@ -1,109 +1,183 @@
|
||||
#[macro_use]
|
||||
crate mod macros;
|
||||
pub(crate) mod macros;
|
||||
|
||||
crate mod args;
|
||||
crate mod autoview;
|
||||
crate mod cd;
|
||||
crate mod classified;
|
||||
crate mod clip;
|
||||
crate mod command;
|
||||
crate mod config;
|
||||
crate mod cp;
|
||||
crate mod date;
|
||||
crate mod debug;
|
||||
crate mod enter;
|
||||
crate mod exit;
|
||||
crate mod first;
|
||||
crate mod from_array;
|
||||
crate mod from_csv;
|
||||
crate mod from_ini;
|
||||
crate mod from_json;
|
||||
crate mod from_toml;
|
||||
crate mod from_xml;
|
||||
crate mod from_yaml;
|
||||
crate mod get;
|
||||
crate mod lines;
|
||||
crate mod ls;
|
||||
crate mod mkdir;
|
||||
crate mod mv;
|
||||
crate mod next;
|
||||
crate mod nth;
|
||||
crate mod open;
|
||||
crate mod pick;
|
||||
crate mod plugin;
|
||||
crate mod prev;
|
||||
crate mod ps;
|
||||
crate mod reject;
|
||||
crate mod rm;
|
||||
crate mod save;
|
||||
crate mod shells;
|
||||
crate mod size;
|
||||
crate mod skip_while;
|
||||
crate mod sort_by;
|
||||
crate mod split_column;
|
||||
crate mod split_row;
|
||||
crate mod table;
|
||||
crate mod tags;
|
||||
crate mod to_array;
|
||||
crate mod to_csv;
|
||||
crate mod to_json;
|
||||
crate mod to_toml;
|
||||
crate mod to_yaml;
|
||||
crate mod trim;
|
||||
crate mod version;
|
||||
crate mod vtable;
|
||||
crate mod where_;
|
||||
crate mod which_;
|
||||
mod from_delimited_data;
|
||||
mod to_delimited_data;
|
||||
|
||||
crate use autoview::Autoview;
|
||||
crate use cd::CD;
|
||||
crate use command::{
|
||||
pub(crate) mod append;
|
||||
pub(crate) mod args;
|
||||
pub(crate) mod autoview;
|
||||
pub(crate) mod cd;
|
||||
pub(crate) mod classified;
|
||||
pub(crate) mod clip;
|
||||
pub(crate) mod command;
|
||||
pub(crate) mod compact;
|
||||
pub(crate) mod config;
|
||||
pub(crate) mod count;
|
||||
pub(crate) mod cp;
|
||||
pub(crate) mod date;
|
||||
pub(crate) mod debug;
|
||||
pub(crate) mod default;
|
||||
pub(crate) mod echo;
|
||||
pub(crate) mod enter;
|
||||
pub(crate) mod env;
|
||||
#[allow(unused)]
|
||||
pub(crate) mod evaluate_by;
|
||||
pub(crate) mod exit;
|
||||
pub(crate) mod fetch;
|
||||
pub(crate) mod first;
|
||||
pub(crate) mod from_bson;
|
||||
pub(crate) mod from_csv;
|
||||
pub(crate) mod from_ini;
|
||||
pub(crate) mod from_json;
|
||||
pub(crate) mod from_sqlite;
|
||||
pub(crate) mod from_ssv;
|
||||
pub(crate) mod from_toml;
|
||||
pub(crate) mod from_tsv;
|
||||
pub(crate) mod from_url;
|
||||
pub(crate) mod from_xlsx;
|
||||
pub(crate) mod from_xml;
|
||||
pub(crate) mod from_yaml;
|
||||
pub(crate) mod get;
|
||||
pub(crate) mod group_by;
|
||||
pub(crate) mod help;
|
||||
pub(crate) mod histogram;
|
||||
pub(crate) mod history;
|
||||
pub(crate) mod last;
|
||||
pub(crate) mod lines;
|
||||
pub(crate) mod ls;
|
||||
#[allow(unused)]
|
||||
pub(crate) mod map_max_by;
|
||||
pub(crate) mod mkdir;
|
||||
pub(crate) mod mv;
|
||||
pub(crate) mod next;
|
||||
pub(crate) mod nth;
|
||||
pub(crate) mod open;
|
||||
pub(crate) mod pick;
|
||||
pub(crate) mod pivot;
|
||||
pub(crate) mod plugin;
|
||||
pub(crate) mod post;
|
||||
pub(crate) mod prepend;
|
||||
pub(crate) mod prev;
|
||||
pub(crate) mod pwd;
|
||||
#[allow(unused)]
|
||||
pub(crate) mod reduce_by;
|
||||
pub(crate) mod reject;
|
||||
pub(crate) mod reverse;
|
||||
pub(crate) mod rm;
|
||||
pub(crate) mod save;
|
||||
pub(crate) mod shells;
|
||||
pub(crate) mod size;
|
||||
pub(crate) mod skip_while;
|
||||
pub(crate) mod sort_by;
|
||||
pub(crate) mod split_by;
|
||||
pub(crate) mod split_column;
|
||||
pub(crate) mod split_row;
|
||||
#[allow(unused)]
|
||||
pub(crate) mod t_sort_by;
|
||||
pub(crate) mod table;
|
||||
pub(crate) mod tags;
|
||||
pub(crate) mod to_bson;
|
||||
pub(crate) mod to_csv;
|
||||
pub(crate) mod to_json;
|
||||
pub(crate) mod to_sqlite;
|
||||
pub(crate) mod to_toml;
|
||||
pub(crate) mod to_tsv;
|
||||
pub(crate) mod to_url;
|
||||
pub(crate) mod to_yaml;
|
||||
pub(crate) mod trim;
|
||||
pub(crate) mod version;
|
||||
pub(crate) mod what;
|
||||
pub(crate) mod where_;
|
||||
pub(crate) mod which_;
|
||||
|
||||
pub(crate) use autoview::Autoview;
|
||||
pub(crate) use cd::CD;
|
||||
pub(crate) use command::{
|
||||
per_item_command, whole_stream_command, Command, PerItemCommand, RawCommandArgs,
|
||||
UnevaluatedCallInfo, WholeStreamCommand,
|
||||
};
|
||||
crate use config::Config;
|
||||
crate use cp::Cpy;
|
||||
crate use date::Date;
|
||||
crate use debug::Debug;
|
||||
crate use enter::Enter;
|
||||
crate use exit::Exit;
|
||||
crate use first::First;
|
||||
crate use from_array::FromArray;
|
||||
crate use from_csv::FromCSV;
|
||||
crate use from_ini::FromINI;
|
||||
crate use from_json::FromJSON;
|
||||
crate use from_toml::FromTOML;
|
||||
crate use from_xml::FromXML;
|
||||
crate use from_yaml::FromYAML;
|
||||
crate use get::Get;
|
||||
crate use lines::Lines;
|
||||
crate use ls::LS;
|
||||
crate use mkdir::Mkdir;
|
||||
crate use mv::Move;
|
||||
crate use next::Next;
|
||||
crate use nth::Nth;
|
||||
crate use open::Open;
|
||||
crate use pick::Pick;
|
||||
crate use prev::Previous;
|
||||
crate use ps::PS;
|
||||
crate use reject::Reject;
|
||||
crate use rm::Remove;
|
||||
crate use save::Save;
|
||||
crate use shells::Shells;
|
||||
crate use size::Size;
|
||||
crate use skip_while::SkipWhile;
|
||||
crate use sort_by::SortBy;
|
||||
crate use split_column::SplitColumn;
|
||||
crate use split_row::SplitRow;
|
||||
crate use table::Table;
|
||||
crate use tags::Tags;
|
||||
crate use to_array::ToArray;
|
||||
crate use to_csv::ToCSV;
|
||||
crate use to_json::ToJSON;
|
||||
crate use to_toml::ToTOML;
|
||||
crate use to_yaml::ToYAML;
|
||||
crate use trim::Trim;
|
||||
crate use version::Version;
|
||||
crate use vtable::VTable;
|
||||
crate use where_::Where;
|
||||
crate use which_::Which;
|
||||
|
||||
pub(crate) use append::Append;
|
||||
pub(crate) use classified::ClassifiedCommand;
|
||||
pub(crate) use compact::Compact;
|
||||
pub(crate) use config::Config;
|
||||
pub(crate) use count::Count;
|
||||
pub(crate) use cp::Cpy;
|
||||
pub(crate) use date::Date;
|
||||
pub(crate) use debug::Debug;
|
||||
pub(crate) use default::Default;
|
||||
pub(crate) use echo::Echo;
|
||||
pub(crate) use enter::Enter;
|
||||
pub(crate) use env::Env;
|
||||
#[allow(unused)]
|
||||
pub(crate) use evaluate_by::EvaluateBy;
|
||||
pub(crate) use exit::Exit;
|
||||
pub(crate) use fetch::Fetch;
|
||||
pub(crate) use first::First;
|
||||
pub(crate) use from_bson::FromBSON;
|
||||
pub(crate) use from_csv::FromCSV;
|
||||
pub(crate) use from_ini::FromINI;
|
||||
pub(crate) use from_json::FromJSON;
|
||||
pub(crate) use from_sqlite::FromDB;
|
||||
pub(crate) use from_sqlite::FromSQLite;
|
||||
pub(crate) use from_ssv::FromSSV;
|
||||
pub(crate) use from_toml::FromTOML;
|
||||
pub(crate) use from_tsv::FromTSV;
|
||||
pub(crate) use from_url::FromURL;
|
||||
pub(crate) use from_xlsx::FromXLSX;
|
||||
pub(crate) use from_xml::FromXML;
|
||||
pub(crate) use from_yaml::FromYAML;
|
||||
pub(crate) use from_yaml::FromYML;
|
||||
pub(crate) use get::Get;
|
||||
pub(crate) use group_by::GroupBy;
|
||||
pub(crate) use help::Help;
|
||||
pub(crate) use histogram::Histogram;
|
||||
pub(crate) use history::History;
|
||||
pub(crate) use last::Last;
|
||||
pub(crate) use lines::Lines;
|
||||
pub(crate) use ls::LS;
|
||||
#[allow(unused)]
|
||||
pub(crate) use map_max_by::MapMaxBy;
|
||||
pub(crate) use mkdir::Mkdir;
|
||||
pub(crate) use mv::Move;
|
||||
pub(crate) use next::Next;
|
||||
pub(crate) use nth::Nth;
|
||||
pub(crate) use open::Open;
|
||||
pub(crate) use pick::Pick;
|
||||
pub(crate) use pivot::Pivot;
|
||||
pub(crate) use post::Post;
|
||||
pub(crate) use prepend::Prepend;
|
||||
pub(crate) use prev::Previous;
|
||||
pub(crate) use pwd::PWD;
|
||||
#[allow(unused)]
|
||||
pub(crate) use reduce_by::ReduceBy;
|
||||
pub(crate) use reject::Reject;
|
||||
pub(crate) use reverse::Reverse;
|
||||
pub(crate) use rm::Remove;
|
||||
pub(crate) use save::Save;
|
||||
pub(crate) use shells::Shells;
|
||||
pub(crate) use size::Size;
|
||||
pub(crate) use skip_while::SkipWhile;
|
||||
pub(crate) use sort_by::SortBy;
|
||||
pub(crate) use split_by::SplitBy;
|
||||
pub(crate) use split_column::SplitColumn;
|
||||
pub(crate) use split_row::SplitRow;
|
||||
#[allow(unused)]
|
||||
pub(crate) use t_sort_by::TSortBy;
|
||||
pub(crate) use table::Table;
|
||||
pub(crate) use tags::Tags;
|
||||
pub(crate) use to_bson::ToBSON;
|
||||
pub(crate) use to_csv::ToCSV;
|
||||
pub(crate) use to_json::ToJSON;
|
||||
pub(crate) use to_sqlite::ToDB;
|
||||
pub(crate) use to_sqlite::ToSQLite;
|
||||
pub(crate) use to_toml::ToTOML;
|
||||
pub(crate) use to_tsv::ToTSV;
|
||||
pub(crate) use to_url::ToURL;
|
||||
pub(crate) use to_yaml::ToYAML;
|
||||
pub(crate) use trim::Trim;
|
||||
pub(crate) use version::Version;
|
||||
pub(crate) use what::What;
|
||||
pub(crate) use where_::Where;
|
||||
pub(crate) use which_::Which;
|
||||
|
47
src/commands/append.rs
Normal file
47
src/commands/append.rs
Normal file
@ -0,0 +1,47 @@
|
||||
use crate::commands::WholeStreamCommand;
|
||||
use crate::errors::ShellError;
|
||||
use crate::parser::CommandRegistry;
|
||||
use crate::prelude::*;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct AppendArgs {
|
||||
row: Value,
|
||||
}
|
||||
|
||||
pub struct Append;
|
||||
|
||||
impl WholeStreamCommand for Append {
|
||||
fn name(&self) -> &str {
|
||||
"append"
|
||||
}
|
||||
|
||||
fn signature(&self) -> Signature {
|
||||
Signature::build("append").required(
|
||||
"row value",
|
||||
SyntaxShape::Any,
|
||||
"the value of the row to append to the table",
|
||||
)
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
"Append the given row to the table"
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
args: CommandArgs,
|
||||
registry: &CommandRegistry,
|
||||
) -> Result<OutputStream, ShellError> {
|
||||
args.process(registry, append)?.run()
|
||||
}
|
||||
}
|
||||
|
||||
fn append(
|
||||
AppendArgs { row }: AppendArgs,
|
||||
RunnableContext { input, .. }: RunnableContext,
|
||||
) -> Result<OutputStream, ShellError> {
|
||||
let mut after: VecDeque<Value> = VecDeque::new();
|
||||
after.push_back(row);
|
||||
|
||||
Ok(OutputStream::from_input(input.values.chain(after)))
|
||||
}
|
@ -1,17 +1,8 @@
|
||||
use crate::object::Value;
|
||||
use crate::data::Value;
|
||||
|
||||
#[allow(unused)]
|
||||
#[derive(Debug)]
|
||||
pub enum LogLevel {
|
||||
Trace,
|
||||
Debug,
|
||||
Info,
|
||||
Warn,
|
||||
Error,
|
||||
Fatal,
|
||||
}
|
||||
pub enum LogLevel {}
|
||||
|
||||
#[allow(unused)]
|
||||
#[derive(Debug)]
|
||||
pub struct LogItem {
|
||||
level: LogLevel,
|
||||
|
@ -1,9 +1,14 @@
|
||||
use crate::commands::{RawCommandArgs, WholeStreamCommand};
|
||||
use crate::errors::ShellError;
|
||||
use crate::parser::hir::{Expression, NamedArguments};
|
||||
use crate::prelude::*;
|
||||
use futures::stream::TryStreamExt;
|
||||
use std::sync::atomic::Ordering;
|
||||
|
||||
pub struct Autoview;
|
||||
|
||||
const STREAM_PAGE_SIZE: u64 = 50;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct AutoviewArgs {}
|
||||
|
||||
@ -12,6 +17,14 @@ impl WholeStreamCommand for Autoview {
|
||||
"autoview"
|
||||
}
|
||||
|
||||
fn signature(&self) -> Signature {
|
||||
Signature::build("autoview")
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
"View the contents of the pipeline as a table or list."
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
args: CommandArgs,
|
||||
@ -19,76 +32,163 @@ impl WholeStreamCommand for Autoview {
|
||||
) -> Result<OutputStream, ShellError> {
|
||||
Ok(args.process_raw(registry, autoview)?.run())
|
||||
}
|
||||
|
||||
fn signature(&self) -> Signature {
|
||||
Signature::build("autoview")
|
||||
}
|
||||
}
|
||||
|
||||
pub fn autoview(
|
||||
AutoviewArgs {}: AutoviewArgs,
|
||||
mut context: RunnableContext,
|
||||
context: RunnableContext,
|
||||
raw: RawCommandArgs,
|
||||
) -> Result<OutputStream, ShellError> {
|
||||
Ok(OutputStream::new(async_stream_block! {
|
||||
let input = context.input.drain_vec().await;
|
||||
let binary = context.get_command("binaryview");
|
||||
let text = context.get_command("textview");
|
||||
let table = context.get_command("table");
|
||||
|
||||
if input.len() > 0 {
|
||||
if let Tagged {
|
||||
item: Value::Binary(_),
|
||||
..
|
||||
} = input[0usize]
|
||||
{
|
||||
let binary = context.expect_command("binaryview");
|
||||
let result = binary.run(raw.with_input(input), &context.commands);
|
||||
result.collect::<Vec<_>>().await;
|
||||
} else if is_single_text_value(&input) {
|
||||
let text = context.expect_command("textview");
|
||||
let result = text.run(raw.with_input(input), &context.commands);
|
||||
result.collect::<Vec<_>>().await;
|
||||
} else if equal_shapes(&input) {
|
||||
let table = context.expect_command("table");
|
||||
let result = table.run(raw.with_input(input), &context.commands);
|
||||
result.collect::<Vec<_>>().await;
|
||||
} else {
|
||||
let table = context.expect_command("table");
|
||||
let result = table.run(raw.with_input(input), &context.commands);
|
||||
result.collect::<Vec<_>>().await;
|
||||
Ok(OutputStream::new(async_stream! {
|
||||
let mut output_stream: OutputStream = context.input.into();
|
||||
|
||||
let next = output_stream.try_next().await;
|
||||
|
||||
match next {
|
||||
Ok(Some(x)) => {
|
||||
match output_stream.try_next().await {
|
||||
Ok(Some(y)) => {
|
||||
let ctrl_c = context.ctrl_c.clone();
|
||||
let stream = async_stream! {
|
||||
yield Ok(x);
|
||||
yield Ok(y);
|
||||
|
||||
loop {
|
||||
match output_stream.try_next().await {
|
||||
Ok(Some(z)) => {
|
||||
if ctrl_c.load(Ordering::SeqCst) {
|
||||
break;
|
||||
}
|
||||
yield Ok(z);
|
||||
}
|
||||
_ => break,
|
||||
}
|
||||
}
|
||||
};
|
||||
if let Some(table) = table {
|
||||
let mut new_output_stream: OutputStream = stream.to_output_stream();
|
||||
let mut finished = false;
|
||||
let mut current_idx = 0;
|
||||
loop {
|
||||
let mut new_input = VecDeque::new();
|
||||
|
||||
for _ in 0..STREAM_PAGE_SIZE {
|
||||
match new_output_stream.try_next().await {
|
||||
|
||||
Ok(Some(a)) => {
|
||||
if let ReturnSuccess::Value(v) = a {
|
||||
new_input.push_back(v);
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
finished = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let raw = raw.clone();
|
||||
|
||||
let input: Vec<Value> = new_input.into();
|
||||
|
||||
if input.len() > 0 && input.iter().all(|value| value.value.is_error()) {
|
||||
let first = &input[0];
|
||||
|
||||
let mut host = context.host.clone();
|
||||
let mut host = match host.lock() {
|
||||
Err(err) => {
|
||||
errln!("Unexpected error acquiring host lock: {:?}", err);
|
||||
return;
|
||||
}
|
||||
Ok(val) => val
|
||||
};
|
||||
|
||||
crate::cli::print_err(first.value.expect_error(), &*host, &context.source);
|
||||
return;
|
||||
}
|
||||
|
||||
let mut command_args = raw.with_input(input);
|
||||
let mut named_args = NamedArguments::new();
|
||||
named_args.insert_optional("start_number", Some(Expression::number(current_idx, Tag::unknown())));
|
||||
command_args.call_info.args.named = Some(named_args);
|
||||
|
||||
let result = table.run(command_args, &context.commands);
|
||||
result.collect::<Vec<_>>().await;
|
||||
|
||||
|
||||
if finished {
|
||||
break;
|
||||
} else {
|
||||
current_idx += STREAM_PAGE_SIZE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
if let ReturnSuccess::Value(x) = x {
|
||||
match x {
|
||||
Value {
|
||||
value: UntaggedValue::Primitive(Primitive::String(ref s)),
|
||||
tag: Tag { anchor, span },
|
||||
} if anchor.is_some() => {
|
||||
if let Some(text) = text {
|
||||
let mut stream = VecDeque::new();
|
||||
stream.push_back(UntaggedValue::string(s).into_value(Tag { anchor, span }));
|
||||
let result = text.run(raw.with_input(stream.into()), &context.commands);
|
||||
result.collect::<Vec<_>>().await;
|
||||
} else {
|
||||
outln!("{}", s);
|
||||
}
|
||||
}
|
||||
Value {
|
||||
value: UntaggedValue::Primitive(Primitive::String(s)),
|
||||
..
|
||||
} => {
|
||||
outln!("{}", s);
|
||||
}
|
||||
|
||||
Value { value: UntaggedValue::Primitive(Primitive::Binary(ref b)), .. } => {
|
||||
if let Some(binary) = binary {
|
||||
let mut stream = VecDeque::new();
|
||||
stream.push_back(x);
|
||||
let result = binary.run(raw.with_input(stream.into()), &context.commands);
|
||||
result.collect::<Vec<_>>().await;
|
||||
} else {
|
||||
use pretty_hex::*;
|
||||
outln!("{:?}", b.hex_dump());
|
||||
}
|
||||
}
|
||||
|
||||
Value { value: UntaggedValue::Error(e), .. } => {
|
||||
yield Err(e);
|
||||
}
|
||||
Value { value: ref item, .. } => {
|
||||
if let Some(table) = table {
|
||||
let mut stream = VecDeque::new();
|
||||
stream.push_back(x);
|
||||
let result = table.run(raw.with_input(stream.into()), &context.commands);
|
||||
result.collect::<Vec<_>>().await;
|
||||
} else {
|
||||
outln!("{:?}", item);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
//outln!("<no results>");
|
||||
}
|
||||
}
|
||||
|
||||
// Needed for async_stream to type check
|
||||
if false {
|
||||
yield ReturnSuccess::value(UntaggedValue::nothing().into_untagged_value());
|
||||
}
|
||||
}))
|
||||
}
|
||||
|
||||
fn equal_shapes(input: &Vec<Tagged<Value>>) -> bool {
|
||||
let mut items = input.iter();
|
||||
|
||||
let item = match items.next() {
|
||||
Some(item) => item,
|
||||
None => return false,
|
||||
};
|
||||
|
||||
let desc = item.data_descriptors();
|
||||
|
||||
for item in items {
|
||||
if desc != item.data_descriptors() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
fn is_single_text_value(input: &Vec<Tagged<Value>>) -> bool {
|
||||
if input.len() != 1 {
|
||||
return false;
|
||||
}
|
||||
if let Tagged {
|
||||
item: Value::Primitive(Primitive::String(_)),
|
||||
..
|
||||
} = input[0]
|
||||
{
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,22 @@ use crate::prelude::*;
|
||||
pub struct CD;
|
||||
|
||||
impl WholeStreamCommand for CD {
|
||||
fn name(&self) -> &str {
|
||||
"cd"
|
||||
}
|
||||
|
||||
fn signature(&self) -> Signature {
|
||||
Signature::build("cd").optional(
|
||||
"directory",
|
||||
SyntaxShape::Path,
|
||||
"the directory to change to",
|
||||
)
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
"Change to a new path."
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
args: CommandArgs,
|
||||
@ -12,14 +28,6 @@ impl WholeStreamCommand for CD {
|
||||
) -> Result<OutputStream, ShellError> {
|
||||
cd(args, registry)
|
||||
}
|
||||
|
||||
fn name(&self) -> &str {
|
||||
"cd"
|
||||
}
|
||||
|
||||
fn signature(&self) -> Signature {
|
||||
Signature::build("cd").optional("directory", SyntaxType::Path)
|
||||
}
|
||||
}
|
||||
|
||||
fn cd(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream, ShellError> {
|
||||
|
@ -1,391 +0,0 @@
|
||||
use crate::commands::Command;
|
||||
use crate::parser::{hir, TokenNode};
|
||||
use crate::prelude::*;
|
||||
use bytes::{BufMut, BytesMut};
|
||||
use futures::stream::StreamExt;
|
||||
use futures_codec::{Decoder, Encoder, Framed};
|
||||
use log::{log_enabled, trace};
|
||||
use std::io::{Error, ErrorKind};
|
||||
use std::sync::Arc;
|
||||
use subprocess::Exec;
|
||||
|
||||
/// A simple `Codec` implementation that splits up data into lines.
|
||||
pub struct LinesCodec {}
|
||||
|
||||
impl Encoder for LinesCodec {
|
||||
type Item = String;
|
||||
type Error = Error;
|
||||
|
||||
fn encode(&mut self, item: Self::Item, dst: &mut BytesMut) -> Result<(), Self::Error> {
|
||||
dst.put(item);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl Decoder for LinesCodec {
|
||||
type Item = String;
|
||||
type Error = Error;
|
||||
|
||||
fn decode(&mut self, src: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> {
|
||||
match src.iter().position(|b| b == &b'\n') {
|
||||
Some(pos) if !src.is_empty() => {
|
||||
let buf = src.split_to(pos + 1);
|
||||
String::from_utf8(buf.to_vec())
|
||||
.map(Some)
|
||||
.map_err(|e| Error::new(ErrorKind::InvalidData, e))
|
||||
}
|
||||
_ if !src.is_empty() => {
|
||||
let drained = src.take();
|
||||
String::from_utf8(drained.to_vec())
|
||||
.map(Some)
|
||||
.map_err(|e| Error::new(ErrorKind::InvalidData, e))
|
||||
}
|
||||
_ => Ok(None),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
crate struct ClassifiedInputStream {
|
||||
crate objects: InputStream,
|
||||
crate stdin: Option<std::fs::File>,
|
||||
}
|
||||
|
||||
impl ClassifiedInputStream {
|
||||
crate fn new() -> ClassifiedInputStream {
|
||||
ClassifiedInputStream {
|
||||
objects: VecDeque::new().into(),
|
||||
stdin: None,
|
||||
}
|
||||
}
|
||||
|
||||
crate fn from_input_stream(stream: impl Into<InputStream>) -> ClassifiedInputStream {
|
||||
ClassifiedInputStream {
|
||||
objects: stream.into(),
|
||||
stdin: None,
|
||||
}
|
||||
}
|
||||
|
||||
crate fn from_stdout(stdout: std::fs::File) -> ClassifiedInputStream {
|
||||
ClassifiedInputStream {
|
||||
objects: VecDeque::new().into(),
|
||||
stdin: Some(stdout),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
crate struct ClassifiedPipeline {
|
||||
crate commands: Vec<ClassifiedCommand>,
|
||||
}
|
||||
|
||||
crate enum ClassifiedCommand {
|
||||
#[allow(unused)]
|
||||
Expr(TokenNode),
|
||||
Internal(InternalCommand),
|
||||
External(ExternalCommand),
|
||||
}
|
||||
|
||||
impl ClassifiedCommand {
|
||||
#[allow(unused)]
|
||||
pub fn span(&self) -> Span {
|
||||
match self {
|
||||
ClassifiedCommand::Expr(token) => token.span(),
|
||||
ClassifiedCommand::Internal(internal) => internal.name_span.into(),
|
||||
ClassifiedCommand::External(external) => external.name_span.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
crate struct InternalCommand {
|
||||
crate command: Arc<Command>,
|
||||
crate name_span: Span,
|
||||
crate args: hir::Call,
|
||||
}
|
||||
|
||||
impl InternalCommand {
|
||||
crate async fn run(
|
||||
self,
|
||||
context: &mut Context,
|
||||
input: ClassifiedInputStream,
|
||||
source: Text,
|
||||
) -> Result<InputStream, ShellError> {
|
||||
if log_enabled!(log::Level::Trace) {
|
||||
trace!(target: "nu::run::internal", "->");
|
||||
trace!(target: "nu::run::internal", "{}", self.command.name());
|
||||
trace!(target: "nu::run::internal", "{}", self.args.debug(&source));
|
||||
}
|
||||
|
||||
let objects: InputStream =
|
||||
trace_stream!(target: "nu::trace_stream::internal", "input" = input.objects);
|
||||
|
||||
let result = context.run_command(
|
||||
self.command,
|
||||
self.name_span.clone(),
|
||||
context.source_map.clone(),
|
||||
self.args,
|
||||
source,
|
||||
objects,
|
||||
);
|
||||
|
||||
let mut result = result.values;
|
||||
|
||||
let mut stream = VecDeque::new();
|
||||
while let Some(item) = result.next().await {
|
||||
match item? {
|
||||
ReturnSuccess::Action(action) => match action {
|
||||
CommandAction::ChangePath(path) => {
|
||||
context.shell_manager.set_path(path);
|
||||
}
|
||||
CommandAction::AddSpanSource(uuid, span_source) => {
|
||||
context.add_span_source(uuid, span_source);
|
||||
}
|
||||
CommandAction::Exit => std::process::exit(0),
|
||||
CommandAction::EnterValueShell(value) => {
|
||||
context
|
||||
.shell_manager
|
||||
.insert_at_current(Box::new(ValueShell::new(value)));
|
||||
}
|
||||
CommandAction::EnterShell(location) => {
|
||||
let path = std::path::Path::new(&location);
|
||||
|
||||
if path.is_dir() {
|
||||
// If it's a directory, add a new filesystem shell
|
||||
context.shell_manager.insert_at_current(Box::new(
|
||||
FilesystemShell::with_location(
|
||||
location,
|
||||
context.registry().clone(),
|
||||
)?,
|
||||
));
|
||||
} else {
|
||||
// If it's a file, attempt to open the file as a value and enter it
|
||||
let cwd = context.shell_manager.path();
|
||||
|
||||
let full_path = std::path::PathBuf::from(cwd);
|
||||
|
||||
let (file_extension, contents, contents_tag, span_source) =
|
||||
crate::commands::open::fetch(
|
||||
&full_path,
|
||||
&location,
|
||||
Span::unknown(),
|
||||
)?;
|
||||
|
||||
if let Some(uuid) = contents_tag.origin {
|
||||
// If we have loaded something, track its source
|
||||
context.add_span_source(uuid, span_source);
|
||||
}
|
||||
|
||||
match contents {
|
||||
Value::Primitive(Primitive::String(string)) => {
|
||||
let value = crate::commands::open::parse_as_value(
|
||||
file_extension,
|
||||
string,
|
||||
contents_tag,
|
||||
Span::unknown(),
|
||||
)?;
|
||||
|
||||
context
|
||||
.shell_manager
|
||||
.insert_at_current(Box::new(ValueShell::new(value)));
|
||||
}
|
||||
value => context.shell_manager.insert_at_current(Box::new(
|
||||
ValueShell::new(value.tagged(contents_tag)),
|
||||
)),
|
||||
}
|
||||
}
|
||||
}
|
||||
CommandAction::PreviousShell => {
|
||||
context.shell_manager.prev();
|
||||
}
|
||||
CommandAction::NextShell => {
|
||||
context.shell_manager.next();
|
||||
}
|
||||
CommandAction::LeaveShell => {
|
||||
context.shell_manager.remove_at_current();
|
||||
if context.shell_manager.is_empty() {
|
||||
std::process::exit(0);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
ReturnSuccess::Value(v) => {
|
||||
stream.push_back(v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(stream.into())
|
||||
}
|
||||
}
|
||||
|
||||
crate struct ExternalCommand {
|
||||
crate name: String,
|
||||
#[allow(unused)]
|
||||
crate name_span: Span,
|
||||
crate args: Vec<Tagged<String>>,
|
||||
}
|
||||
|
||||
crate enum StreamNext {
|
||||
Last,
|
||||
External,
|
||||
Internal,
|
||||
}
|
||||
|
||||
impl ExternalCommand {
|
||||
crate async fn run(
|
||||
self,
|
||||
context: &mut Context,
|
||||
input: ClassifiedInputStream,
|
||||
stream_next: StreamNext,
|
||||
) -> Result<ClassifiedInputStream, ShellError> {
|
||||
let stdin = input.stdin;
|
||||
let inputs: Vec<Tagged<Value>> = input.objects.into_vec().await;
|
||||
let name_span = self.name_span.clone();
|
||||
|
||||
trace!(target: "nu::run::external", "-> {}", self.name);
|
||||
trace!(target: "nu::run::external", "inputs = {:?}", inputs);
|
||||
|
||||
let mut arg_string = format!("{}", self.name);
|
||||
for arg in &self.args {
|
||||
arg_string.push_str(&arg);
|
||||
}
|
||||
|
||||
let mut process;
|
||||
|
||||
#[cfg(windows)]
|
||||
{
|
||||
process = Exec::shell(&self.name);
|
||||
|
||||
if arg_string.contains("$it") {
|
||||
let mut first = true;
|
||||
|
||||
for i in &inputs {
|
||||
if i.as_string().is_err() {
|
||||
let mut span = None;
|
||||
for arg in &self.args {
|
||||
if arg.item.contains("$it") {
|
||||
span = Some(arg.span());
|
||||
}
|
||||
}
|
||||
if let Some(span) = span {
|
||||
return Err(ShellError::labeled_error(
|
||||
"External $it needs string data",
|
||||
"given object instead of string data",
|
||||
span,
|
||||
));
|
||||
} else {
|
||||
return Err(ShellError::string("Error: $it needs string data"));
|
||||
}
|
||||
}
|
||||
if !first {
|
||||
process = process.arg("&&");
|
||||
process = process.arg(&self.name);
|
||||
} else {
|
||||
first = false;
|
||||
}
|
||||
|
||||
for arg in &self.args {
|
||||
if arg.chars().all(|c| c.is_whitespace()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
process = process.arg(&arg.replace("$it", &i.as_string()?));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for arg in &self.args {
|
||||
let arg_chars: Vec<_> = arg.chars().collect();
|
||||
if arg_chars.len() > 1
|
||||
&& arg_chars[0] == '"'
|
||||
&& arg_chars[arg_chars.len() - 1] == '"'
|
||||
{
|
||||
// quoted string
|
||||
let new_arg: String = arg_chars[1..arg_chars.len() - 1].iter().collect();
|
||||
process = process.arg(new_arg);
|
||||
} else {
|
||||
process = process.arg(arg.item.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(not(windows))]
|
||||
{
|
||||
let mut new_arg_string = self.name.to_string();
|
||||
|
||||
if arg_string.contains("$it") {
|
||||
let mut first = true;
|
||||
for i in &inputs {
|
||||
if i.as_string().is_err() {
|
||||
let mut span = name_span;
|
||||
for arg in &self.args {
|
||||
if arg.item.contains("$it") {
|
||||
span = arg.span();
|
||||
}
|
||||
}
|
||||
return Err(ShellError::labeled_error(
|
||||
"External $it needs string data",
|
||||
"given object instead of string data",
|
||||
span,
|
||||
));
|
||||
}
|
||||
if !first {
|
||||
new_arg_string.push_str("&&");
|
||||
new_arg_string.push_str(&self.name);
|
||||
} else {
|
||||
first = false;
|
||||
}
|
||||
|
||||
for arg in &self.args {
|
||||
if arg.chars().all(|c| c.is_whitespace()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
new_arg_string.push_str(" ");
|
||||
new_arg_string.push_str(&arg.replace("$it", &i.as_string().unwrap()));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for arg in &self.args {
|
||||
new_arg_string.push_str(" ");
|
||||
new_arg_string.push_str(&arg);
|
||||
}
|
||||
}
|
||||
|
||||
process = Exec::shell(new_arg_string);
|
||||
}
|
||||
process = process.cwd(context.shell_manager.path());
|
||||
|
||||
let mut process = match stream_next {
|
||||
StreamNext::Last => process,
|
||||
StreamNext::External | StreamNext::Internal => {
|
||||
process.stdout(subprocess::Redirection::Pipe)
|
||||
}
|
||||
};
|
||||
|
||||
if let Some(stdin) = stdin {
|
||||
process = process.stdin(stdin);
|
||||
}
|
||||
|
||||
let mut popen = process.popen().unwrap();
|
||||
|
||||
match stream_next {
|
||||
StreamNext::Last => {
|
||||
popen.wait()?;
|
||||
Ok(ClassifiedInputStream::new())
|
||||
}
|
||||
StreamNext::External => {
|
||||
let stdout = popen.stdout.take().unwrap();
|
||||
Ok(ClassifiedInputStream::from_stdout(stdout))
|
||||
}
|
||||
StreamNext::Internal => {
|
||||
let stdout = popen.stdout.take().unwrap();
|
||||
let file = futures::io::AllowStdIo::new(stdout);
|
||||
let stream = Framed::new(file, LinesCodec {});
|
||||
let stream = stream.map(move |line| {
|
||||
Tagged::from_simple_spanned_item(Value::string(line.unwrap()), name_span)
|
||||
});
|
||||
Ok(ClassifiedInputStream::from_input_stream(
|
||||
stream.boxed() as BoxStream<'static, Tagged<Value>>
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
7
src/commands/classified/dynamic.rs
Normal file
7
src/commands/classified/dynamic.rs
Normal file
@ -0,0 +1,7 @@
|
||||
use crate::parser::hir;
|
||||
use derive_new::new;
|
||||
|
||||
#[derive(new, Debug, Eq, PartialEq)]
|
||||
pub(crate) struct Command {
|
||||
pub(crate) args: hir::Call,
|
||||
}
|
275
src/commands/classified/external.rs
Normal file
275
src/commands/classified/external.rs
Normal file
@ -0,0 +1,275 @@
|
||||
use super::ClassifiedInputStream;
|
||||
use crate::prelude::*;
|
||||
use bytes::{BufMut, BytesMut};
|
||||
use futures::stream::StreamExt;
|
||||
use futures_codec::{Decoder, Encoder, Framed};
|
||||
use log::trace;
|
||||
use std::io::{Error, ErrorKind};
|
||||
use subprocess::Exec;
|
||||
|
||||
/// A simple `Codec` implementation that splits up data into lines.
|
||||
pub struct LinesCodec {}
|
||||
|
||||
impl Encoder for LinesCodec {
|
||||
type Item = String;
|
||||
type Error = Error;
|
||||
|
||||
fn encode(&mut self, item: Self::Item, dst: &mut BytesMut) -> Result<(), Self::Error> {
|
||||
dst.put(item);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl Decoder for LinesCodec {
|
||||
type Item = String;
|
||||
type Error = Error;
|
||||
|
||||
fn decode(&mut self, src: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> {
|
||||
match src.iter().position(|b| b == &b'\n') {
|
||||
Some(pos) if !src.is_empty() => {
|
||||
let buf = src.split_to(pos + 1);
|
||||
String::from_utf8(buf.to_vec())
|
||||
.map(Some)
|
||||
.map_err(|e| Error::new(ErrorKind::InvalidData, e))
|
||||
}
|
||||
_ if !src.is_empty() => {
|
||||
let drained = src.take();
|
||||
String::from_utf8(drained.to_vec())
|
||||
.map(Some)
|
||||
.map_err(|e| Error::new(ErrorKind::InvalidData, e))
|
||||
}
|
||||
_ => Ok(None),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||
pub struct Command {
|
||||
pub(crate) name: String,
|
||||
|
||||
pub(crate) name_tag: Tag,
|
||||
pub(crate) args: ExternalArgs,
|
||||
}
|
||||
|
||||
impl HasSpan for Command {
|
||||
fn span(&self) -> Span {
|
||||
self.name_tag.span.until(self.args.span)
|
||||
}
|
||||
}
|
||||
|
||||
impl PrettyDebug for Command {
|
||||
fn pretty(&self) -> DebugDocBuilder {
|
||||
b::typed(
|
||||
"external command",
|
||||
b::description(&self.name)
|
||||
+ b::preceded(
|
||||
b::space(),
|
||||
b::intersperse(
|
||||
self.args.iter().map(|a| b::primitive(format!("{}", a.arg))),
|
||||
b::space(),
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) enum StreamNext {
|
||||
Last,
|
||||
External,
|
||||
Internal,
|
||||
}
|
||||
|
||||
impl Command {
|
||||
pub(crate) async fn run(
|
||||
self,
|
||||
context: &mut Context,
|
||||
input: ClassifiedInputStream,
|
||||
stream_next: StreamNext,
|
||||
) -> Result<ClassifiedInputStream, ShellError> {
|
||||
let stdin = input.stdin;
|
||||
let inputs: Vec<Value> = input.objects.into_vec().await;
|
||||
|
||||
trace!(target: "nu::run::external", "-> {}", self.name);
|
||||
trace!(target: "nu::run::external", "inputs = {:?}", inputs);
|
||||
|
||||
let mut arg_string = format!("{}", self.name);
|
||||
for arg in &self.args.list {
|
||||
arg_string.push_str(&arg);
|
||||
}
|
||||
|
||||
let home_dir = dirs::home_dir();
|
||||
|
||||
trace!(target: "nu::run::external", "command = {:?}", self.name);
|
||||
|
||||
let mut process;
|
||||
if arg_string.contains("$it") {
|
||||
let input_strings = inputs
|
||||
.iter()
|
||||
.map(|i| {
|
||||
i.as_string().map_err(|_| {
|
||||
let arg = self.args.iter().find(|arg| arg.arg.contains("$it"));
|
||||
if let Some(arg) = arg {
|
||||
ShellError::labeled_error(
|
||||
"External $it needs string data",
|
||||
"given row instead of string data",
|
||||
&arg.tag,
|
||||
)
|
||||
} else {
|
||||
ShellError::labeled_error(
|
||||
"$it needs string data",
|
||||
"given something else",
|
||||
self.name_tag.clone(),
|
||||
)
|
||||
}
|
||||
})
|
||||
})
|
||||
.collect::<Result<Vec<String>, ShellError>>()?;
|
||||
|
||||
let commands = input_strings.iter().map(|i| {
|
||||
let args = self.args.iter().filter_map(|arg| {
|
||||
if arg.chars().all(|c| c.is_whitespace()) {
|
||||
None
|
||||
} else {
|
||||
// Let's also replace ~ as we shell out
|
||||
let arg = if let Some(ref home_dir) = home_dir {
|
||||
arg.replace("~", home_dir.to_str().unwrap())
|
||||
} else {
|
||||
arg.replace("~", "~")
|
||||
};
|
||||
|
||||
Some(arg.replace("$it", &i))
|
||||
}
|
||||
});
|
||||
|
||||
format!("{} {}", self.name, itertools::join(args, " "))
|
||||
});
|
||||
|
||||
process = Exec::shell(itertools::join(commands, " && "))
|
||||
} else {
|
||||
process = Exec::cmd(&self.name);
|
||||
for arg in &self.args.list {
|
||||
// Let's also replace ~ as we shell out
|
||||
let arg = if let Some(ref home_dir) = home_dir {
|
||||
arg.replace("~", home_dir.to_str().unwrap())
|
||||
} else {
|
||||
arg.replace("~", "~")
|
||||
};
|
||||
|
||||
let arg_chars: Vec<_> = arg.chars().collect();
|
||||
if arg_chars.len() > 1
|
||||
&& arg_chars[0] == '"'
|
||||
&& arg_chars[arg_chars.len() - 1] == '"'
|
||||
{
|
||||
// quoted string
|
||||
let new_arg: String = arg_chars[1..arg_chars.len() - 1].iter().collect();
|
||||
process = process.arg(new_arg);
|
||||
} else {
|
||||
process = process.arg(arg.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
process = process.cwd(context.shell_manager.path());
|
||||
|
||||
trace!(target: "nu::run::external", "cwd = {:?}", context.shell_manager.path());
|
||||
|
||||
let mut process = match stream_next {
|
||||
StreamNext::Last => process,
|
||||
StreamNext::External | StreamNext::Internal => {
|
||||
process.stdout(subprocess::Redirection::Pipe)
|
||||
}
|
||||
};
|
||||
|
||||
trace!(target: "nu::run::external", "set up stdout pipe");
|
||||
|
||||
if let Some(stdin) = stdin {
|
||||
process = process.stdin(stdin);
|
||||
}
|
||||
|
||||
trace!(target: "nu::run::external", "set up stdin pipe");
|
||||
trace!(target: "nu::run::external", "built process {:?}", process);
|
||||
|
||||
let popen = process.popen();
|
||||
|
||||
trace!(target: "nu::run::external", "next = {:?}", stream_next);
|
||||
|
||||
let name_tag = self.name_tag.clone();
|
||||
if let Ok(mut popen) = popen {
|
||||
match stream_next {
|
||||
StreamNext::Last => {
|
||||
let _ = popen.detach();
|
||||
loop {
|
||||
match popen.poll() {
|
||||
None => {
|
||||
let _ = std::thread::sleep(std::time::Duration::new(0, 100000000));
|
||||
}
|
||||
_ => {
|
||||
let _ = popen.terminate();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(ClassifiedInputStream::new())
|
||||
}
|
||||
StreamNext::External => {
|
||||
let _ = popen.detach();
|
||||
let stdout = popen.stdout.take().unwrap();
|
||||
Ok(ClassifiedInputStream::from_stdout(stdout))
|
||||
}
|
||||
StreamNext::Internal => {
|
||||
let _ = popen.detach();
|
||||
let stdout = popen.stdout.take().unwrap();
|
||||
let file = futures::io::AllowStdIo::new(stdout);
|
||||
let stream = Framed::new(file, LinesCodec {});
|
||||
let stream = stream.map(move |line| {
|
||||
UntaggedValue::string(line.unwrap()).into_value(&name_tag)
|
||||
});
|
||||
Ok(ClassifiedInputStream::from_input_stream(
|
||||
stream.boxed() as BoxStream<'static, Value>
|
||||
))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return Err(ShellError::labeled_error(
|
||||
"Command not found",
|
||||
"command not found",
|
||||
name_tag,
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||
pub struct ExternalArg {
|
||||
pub arg: String,
|
||||
pub tag: Tag,
|
||||
}
|
||||
|
||||
impl std::ops::Deref for ExternalArg {
|
||||
type Target = str;
|
||||
|
||||
fn deref(&self) -> &str {
|
||||
&self.arg
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||
pub struct ExternalArgs {
|
||||
pub list: Vec<ExternalArg>,
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
impl ExternalArgs {
|
||||
pub fn iter(&self) -> impl Iterator<Item = &ExternalArg> {
|
||||
self.list.iter()
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::Deref for ExternalArgs {
|
||||
type Target = [ExternalArg];
|
||||
|
||||
fn deref(&self) -> &[ExternalArg] {
|
||||
&self.list
|
||||
}
|
||||
}
|
147
src/commands/classified/internal.rs
Normal file
147
src/commands/classified/internal.rs
Normal file
@ -0,0 +1,147 @@
|
||||
use crate::parser::hir;
|
||||
use crate::prelude::*;
|
||||
use derive_new::new;
|
||||
use log::{log_enabled, trace};
|
||||
|
||||
use super::ClassifiedInputStream;
|
||||
|
||||
#[derive(new, Debug, Clone, Eq, PartialEq)]
|
||||
pub struct Command {
|
||||
pub(crate) name: String,
|
||||
pub(crate) name_tag: Tag,
|
||||
pub(crate) args: hir::Call,
|
||||
}
|
||||
|
||||
impl HasSpan for Command {
|
||||
fn span(&self) -> Span {
|
||||
let start = self.name_tag.span;
|
||||
|
||||
start.until(self.args.span)
|
||||
}
|
||||
}
|
||||
|
||||
impl PrettyDebugWithSource for Command {
|
||||
fn pretty_debug(&self, source: &str) -> DebugDocBuilder {
|
||||
b::typed(
|
||||
"internal command",
|
||||
b::description(&self.name) + b::space() + self.args.pretty_debug(source),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl Command {
|
||||
pub(crate) fn run(
|
||||
self,
|
||||
context: &mut Context,
|
||||
input: ClassifiedInputStream,
|
||||
source: Text,
|
||||
) -> Result<InputStream, ShellError> {
|
||||
if log_enabled!(log::Level::Trace) {
|
||||
trace!(target: "nu::run::internal", "->");
|
||||
trace!(target: "nu::run::internal", "{}", self.name);
|
||||
trace!(target: "nu::run::internal", "{}", self.args.debug(&source));
|
||||
}
|
||||
|
||||
let objects: InputStream =
|
||||
trace_stream!(target: "nu::trace_stream::internal", "input" = input.objects);
|
||||
|
||||
let command = context.expect_command(&self.name);
|
||||
|
||||
let result =
|
||||
{ context.run_command(command, self.name_tag.clone(), self.args, &source, objects) };
|
||||
|
||||
let result = trace_out_stream!(target: "nu::trace_stream::internal", "output" = result);
|
||||
let mut result = result.values;
|
||||
let mut context = context.clone();
|
||||
|
||||
let stream = async_stream! {
|
||||
let mut soft_errs: Vec<ShellError> = vec![];
|
||||
let mut yielded = false;
|
||||
|
||||
while let Some(item) = result.next().await {
|
||||
match item {
|
||||
Ok(ReturnSuccess::Action(action)) => match action {
|
||||
CommandAction::ChangePath(path) => {
|
||||
context.shell_manager.set_path(path);
|
||||
}
|
||||
CommandAction::Exit => std::process::exit(0), // TODO: save history.txt
|
||||
CommandAction::Error(err) => {
|
||||
context.error(err);
|
||||
break;
|
||||
}
|
||||
CommandAction::EnterHelpShell(value) => {
|
||||
match value {
|
||||
Value {
|
||||
value: UntaggedValue::Primitive(Primitive::String(cmd)),
|
||||
tag,
|
||||
} => {
|
||||
context.shell_manager.insert_at_current(Box::new(
|
||||
HelpShell::for_command(
|
||||
UntaggedValue::string(cmd).into_value(tag),
|
||||
&context.registry(),
|
||||
).unwrap(),
|
||||
));
|
||||
}
|
||||
_ => {
|
||||
context.shell_manager.insert_at_current(Box::new(
|
||||
HelpShell::index(&context.registry()).unwrap(),
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
CommandAction::EnterValueShell(value) => {
|
||||
context
|
||||
.shell_manager
|
||||
.insert_at_current(Box::new(ValueShell::new(value)));
|
||||
}
|
||||
CommandAction::EnterShell(location) => {
|
||||
context.shell_manager.insert_at_current(Box::new(
|
||||
FilesystemShell::with_location(location, context.registry().clone()).unwrap(),
|
||||
));
|
||||
}
|
||||
CommandAction::PreviousShell => {
|
||||
context.shell_manager.prev();
|
||||
}
|
||||
CommandAction::NextShell => {
|
||||
context.shell_manager.next();
|
||||
}
|
||||
CommandAction::LeaveShell => {
|
||||
context.shell_manager.remove_at_current();
|
||||
if context.shell_manager.is_empty() {
|
||||
std::process::exit(0); // TODO: save history.txt
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
Ok(ReturnSuccess::Value(v)) => {
|
||||
yielded = true;
|
||||
yield Ok(v);
|
||||
}
|
||||
|
||||
Ok(ReturnSuccess::DebugValue(v)) => {
|
||||
yielded = true;
|
||||
|
||||
let doc = PrettyDebug::pretty_doc(&v);
|
||||
let mut buffer = termcolor::Buffer::ansi();
|
||||
|
||||
doc.render_raw(
|
||||
context.with_host(|host| host.width() - 5),
|
||||
&mut crate::parser::debug::TermColored::new(&mut buffer),
|
||||
).unwrap();
|
||||
|
||||
let value = String::from_utf8_lossy(buffer.as_slice());
|
||||
|
||||
yield Ok(UntaggedValue::string(value).into_untagged_value())
|
||||
}
|
||||
|
||||
Err(err) => {
|
||||
context.error(err);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Ok(stream.to_input_stream())
|
||||
}
|
||||
}
|
74
src/commands/classified/mod.rs
Normal file
74
src/commands/classified/mod.rs
Normal file
@ -0,0 +1,74 @@
|
||||
use crate::parser::{hir, TokenNode};
|
||||
use crate::prelude::*;
|
||||
|
||||
mod dynamic;
|
||||
mod external;
|
||||
mod internal;
|
||||
mod pipeline;
|
||||
|
||||
#[allow(unused_imports)]
|
||||
pub(crate) use dynamic::Command as DynamicCommand;
|
||||
#[allow(unused_imports)]
|
||||
pub(crate) use external::{Command as ExternalCommand, ExternalArg, ExternalArgs, StreamNext};
|
||||
pub(crate) use internal::Command as InternalCommand;
|
||||
pub(crate) use pipeline::Pipeline as ClassifiedPipeline;
|
||||
|
||||
pub(crate) struct ClassifiedInputStream {
|
||||
pub(crate) objects: InputStream,
|
||||
pub(crate) stdin: Option<std::fs::File>,
|
||||
}
|
||||
|
||||
impl ClassifiedInputStream {
|
||||
pub(crate) fn new() -> ClassifiedInputStream {
|
||||
ClassifiedInputStream {
|
||||
objects: vec![UntaggedValue::nothing().into_untagged_value()].into(),
|
||||
stdin: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn from_input_stream(stream: impl Into<InputStream>) -> ClassifiedInputStream {
|
||||
ClassifiedInputStream {
|
||||
objects: stream.into(),
|
||||
stdin: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn from_stdout(stdout: std::fs::File) -> ClassifiedInputStream {
|
||||
ClassifiedInputStream {
|
||||
objects: VecDeque::new().into(),
|
||||
stdin: Some(stdout),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||
pub enum ClassifiedCommand {
|
||||
#[allow(unused)]
|
||||
Expr(TokenNode),
|
||||
#[allow(unused)]
|
||||
Dynamic(hir::Call),
|
||||
Internal(InternalCommand),
|
||||
External(ExternalCommand),
|
||||
}
|
||||
|
||||
impl PrettyDebugWithSource for ClassifiedCommand {
|
||||
fn pretty_debug(&self, source: &str) -> DebugDocBuilder {
|
||||
match self {
|
||||
ClassifiedCommand::Expr(token) => b::typed("command", token.pretty_debug(source)),
|
||||
ClassifiedCommand::Dynamic(call) => b::typed("command", call.pretty_debug(source)),
|
||||
ClassifiedCommand::Internal(internal) => internal.pretty_debug(source),
|
||||
ClassifiedCommand::External(external) => external.pretty_debug(source),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl HasSpan for ClassifiedCommand {
|
||||
fn span(&self) -> Span {
|
||||
match self {
|
||||
ClassifiedCommand::Expr(node) => node.span(),
|
||||
ClassifiedCommand::Internal(command) => command.span(),
|
||||
ClassifiedCommand::Dynamic(call) => call.span,
|
||||
ClassifiedCommand::External(command) => command.span(),
|
||||
}
|
||||
}
|
||||
}
|
40
src/commands/classified/pipeline.rs
Normal file
40
src/commands/classified/pipeline.rs
Normal file
@ -0,0 +1,40 @@
|
||||
use super::ClassifiedCommand;
|
||||
use crate::prelude::*;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub(crate) struct Pipeline {
|
||||
pub(crate) commands: ClassifiedCommands,
|
||||
}
|
||||
|
||||
impl Pipeline {
|
||||
pub fn commands(list: Vec<ClassifiedCommand>, span: impl Into<Span>) -> Pipeline {
|
||||
Pipeline {
|
||||
commands: ClassifiedCommands {
|
||||
list,
|
||||
span: span.into(),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ClassifiedCommands {
|
||||
pub list: Vec<ClassifiedCommand>,
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
impl HasSpan for Pipeline {
|
||||
fn span(&self) -> Span {
|
||||
self.commands.span
|
||||
}
|
||||
}
|
||||
|
||||
impl PrettyDebugWithSource for Pipeline {
|
||||
fn pretty_debug(&self, source: &str) -> DebugDocBuilder {
|
||||
b::intersperse(
|
||||
self.commands.list.iter().map(|c| c.pretty_debug(source)),
|
||||
b::operator(" | "),
|
||||
)
|
||||
.or(b::delimit("<", b::description("empty pipeline"), ">"))
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user