nushell on your web browser
nushell wasm terminal

implement interrupts

ptr.pet 8fce20a8 3984b06c

verified
+214 -149
+53 -114
Cargo.lock
··· 74 75 [[package]] 76 name = "alphanumeric-sort" 77 - version = "1.5.4" 78 source = "registry+https://github.com/rust-lang/crates.io-index" 79 - checksum = "ab31f79a61d3c25cae1d6734a386662e5cf1b6ba5a9720c135b609273c058c15" 80 81 [[package]] 82 name = "android_system_properties" ··· 394 dependencies = [ 395 "alloc-no-stdlib", 396 "alloc-stdlib", 397 - ] 398 - 399 - [[package]] 400 - name = "bstr" 401 - version = "1.12.1" 402 - source = "registry+https://github.com/rust-lang/crates.io-index" 403 - checksum = "63044e1ae8e69f3b5a92c736ca6269b8d12fa7efe39bf34ddb06d102cf0e2cab" 404 - dependencies = [ 405 - "memchr", 406 - "regex-automata", 407 - "serde", 408 ] 409 410 [[package]] ··· 1348 "jacquard-repo", 1349 "js-sys", 1350 "miette", 1351 "nu-cmd-extra", 1352 "nu-cmd-lang", 1353 "nu-command", 1354 "nu-engine", 1355 "nu-parser", 1356 "nu-protocol", 1357 "rapidhash", 1358 "reqwest", ··· 2971 2972 [[package]] 2973 name = "nu-cmd-base" 2974 - version = "0.109.1" 2975 - source = "registry+https://github.com/rust-lang/crates.io-index" 2976 - checksum = "2460ee389a43b935aa18ef5ed9fa8275bdf617e8c05eba7c2b82f92effd2132b" 2977 dependencies = [ 2978 "indexmap 2.12.1", 2979 "miette", ··· 2985 2986 [[package]] 2987 name = "nu-cmd-extra" 2988 - version = "0.109.1" 2989 - source = "registry+https://github.com/rust-lang/crates.io-index" 2990 - checksum = "96f1ac416cd5182ca427a1007c9d0193feaa746aeb54b5320251faad41481cfe" 2991 dependencies = [ 2992 "fancy-regex", 2993 "heck 0.5.0", ··· 3010 3011 [[package]] 3012 name = "nu-cmd-lang" 3013 - version = "0.109.1" 3014 - source = "registry+https://github.com/rust-lang/crates.io-index" 3015 - checksum = "5b266674d87b816264f6aff8cca351e6ebb156f34faab45d7d728c2aba005495" 3016 dependencies = [ 3017 "itertools 0.14.0", 3018 "nu-cmd-base", ··· 3026 3027 [[package]] 3028 name = "nu-color-config" 3029 - version = "0.109.1" 3030 - source = "registry+https://github.com/rust-lang/crates.io-index" 3031 - checksum = "440a59265caf5468af6ff186e656bc6e6d349c08662ee959b116375597864206" 3032 dependencies = [ 3033 "nu-ansi-term", 3034 "nu-engine", ··· 3039 3040 [[package]] 3041 name = "nu-command" 3042 - version = "0.109.1" 3043 - source = "registry+https://github.com/rust-lang/crates.io-index" 3044 - checksum = "5380a9cf6ef0f482280b71d6e78fa8d4bc1b2b43aa8f0b1fa786f96087c2d500" 3045 dependencies = [ 3046 "alphanumeric-sort", 3047 "base64", ··· 3098 "pathdiff", 3099 "percent-encoding", 3100 "print-positions", 3101 - "procfs 0.17.0", 3102 "quick-xml 0.38.4", 3103 "rayon", 3104 "rmp", ··· 3129 3130 [[package]] 3131 name = "nu-derive-value" 3132 - version = "0.109.1" 3133 - source = "registry+https://github.com/rust-lang/crates.io-index" 3134 - checksum = "1465d2d3ada6004cb6689f269a08c70ba81056231e2b5392d1e0ccf5825f81cb" 3135 dependencies = [ 3136 "heck 0.5.0", 3137 "proc-macro-error2", ··· 3142 3143 [[package]] 3144 name = "nu-engine" 3145 - version = "0.109.1" 3146 - source = "registry+https://github.com/rust-lang/crates.io-index" 3147 - checksum = "b3b777faf7c5180fe5d7f67d83c44fd14138d91f2938a36494ed6ac66b7160f3" 3148 dependencies = [ 3149 "fancy-regex", 3150 "log", ··· 3157 3158 [[package]] 3159 name = "nu-experimental" 3160 - version = "0.109.1" 3161 - source = "registry+https://github.com/rust-lang/crates.io-index" 3162 - checksum = "73dd212a1afdad646a38c00579a0988264880aeb97fee820b349a28cdcc04df2" 3163 dependencies = [ 3164 "itertools 0.14.0", 3165 "thiserror 2.0.17", ··· 3167 3168 [[package]] 3169 name = "nu-glob" 3170 - version = "0.109.1" 3171 - source = "registry+https://github.com/rust-lang/crates.io-index" 3172 - checksum = "15aa2c17078926f14e393b4b708e69f228cb6fd4c81136839bde82772bdde1b5" 3173 3174 [[package]] 3175 name = "nu-json" 3176 - version = "0.109.1" 3177 - source = "registry+https://github.com/rust-lang/crates.io-index" 3178 - checksum = "7ca63927a3c1c4fb889e80dc5cfbe754daed822a7b503cc74e600627c2aa8435" 3179 dependencies = [ 3180 "linked-hash-map", 3181 "nu-utils", ··· 3186 3187 [[package]] 3188 name = "nu-parser" 3189 - version = "0.109.1" 3190 - source = "registry+https://github.com/rust-lang/crates.io-index" 3191 - checksum = "237172636312c3566272511a00c1dc355202406c376e1546a45a33c65e81babe" 3192 dependencies = [ 3193 "bytesize", 3194 "chrono", ··· 3203 3204 [[package]] 3205 name = "nu-path" 3206 - version = "0.109.1" 3207 - source = "registry+https://github.com/rust-lang/crates.io-index" 3208 - checksum = "dde9d8ba26f62c07176c0237a36f38ce964ab3a0dcfb6aab1feea7515d1c6594" 3209 dependencies = [ 3210 "dirs", 3211 "omnipath", ··· 3215 3216 [[package]] 3217 name = "nu-pretty-hex" 3218 - version = "0.109.1" 3219 - source = "registry+https://github.com/rust-lang/crates.io-index" 3220 - checksum = "02561546604ac4c443bad65d9485ab3965154cad0873340e2e9ebe72d4a18aef" 3221 dependencies = [ 3222 "nu-ansi-term", 3223 ] 3224 3225 [[package]] 3226 name = "nu-protocol" 3227 - version = "0.109.1" 3228 - source = "registry+https://github.com/rust-lang/crates.io-index" 3229 - checksum = "038943300ca9de0924fef1c795a7dd16ffc67105629477cf163e8ee6bad95ea6" 3230 dependencies = [ 3231 "bytes", 3232 "chrono", ··· 3261 3262 [[package]] 3263 name = "nu-system" 3264 - version = "0.109.1" 3265 - source = "registry+https://github.com/rust-lang/crates.io-index" 3266 - checksum = "46be734cc9b19e09a9665769e14360e13e6978490056ba5c8bfad7dd0537ea83" 3267 dependencies = [ 3268 "chrono", 3269 "itertools 0.14.0", ··· 3273 "mach2", 3274 "nix", 3275 "ntapi", 3276 - "procfs 0.17.0", 3277 "sysinfo", 3278 "web-time", 3279 "windows 0.62.2", ··· 3281 3282 [[package]] 3283 name = "nu-table" 3284 - version = "0.109.1" 3285 - source = "registry+https://github.com/rust-lang/crates.io-index" 3286 - checksum = "aa96502adbb69c838d8469715327ba2dacf2c4f5254a4cdee7536e2c6849de1d" 3287 dependencies = [ 3288 "fancy-regex", 3289 "nu-ansi-term", ··· 3296 3297 [[package]] 3298 name = "nu-term-grid" 3299 - version = "0.109.1" 3300 - source = "registry+https://github.com/rust-lang/crates.io-index" 3301 - checksum = "2b6545b361413e88bea37c4b9c7aa97a7fd7a11d84a5d330a72242367fd1d2df" 3302 dependencies = [ 3303 "nu-utils", 3304 "unicode-width 0.2.2", ··· 3306 3307 [[package]] 3308 name = "nu-utils" 3309 - version = "0.109.1" 3310 - source = "registry+https://github.com/rust-lang/crates.io-index" 3311 - checksum = "3f8eb43c29cc5bce85f87defdadc2cca964fa434d808af37036a7cb78f3c68e9" 3312 dependencies = [ 3313 "byteyarn", 3314 "crossterm_winapi", ··· 3398 ] 3399 3400 [[package]] 3401 - name = "number_prefix" 3402 - version = "0.4.0" 3403 - source = "registry+https://github.com/rust-lang/crates.io-index" 3404 - checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" 3405 - 3406 - [[package]] 3407 name = "nuon" 3408 - version = "0.109.1" 3409 - source = "registry+https://github.com/rust-lang/crates.io-index" 3410 - checksum = "f8c4f2e4460a6cf00e50cddf0840f954874d645be3af5196c5858c70c069d8c0" 3411 dependencies = [ 3412 "nu-engine", 3413 "nu-parser", ··· 3963 "chrono", 3964 "flate2", 3965 "hex", 3966 - "procfs-core 0.17.0", 3967 "rustix 0.38.44", 3968 ] 3969 3970 [[package]] 3971 - name = "procfs" 3972 - version = "0.18.0" 3973 - source = "registry+https://github.com/rust-lang/crates.io-index" 3974 - checksum = "25485360a54d6861439d60facef26de713b1e126bf015ec8f98239467a2b82f7" 3975 - dependencies = [ 3976 - "bitflags", 3977 - "chrono", 3978 - "flate2", 3979 - "procfs-core 0.18.0", 3980 - "rustix 1.1.2", 3981 - ] 3982 - 3983 - [[package]] 3984 name = "procfs-core" 3985 version = "0.17.0" 3986 source = "registry+https://github.com/rust-lang/crates.io-index" 3987 checksum = "239df02d8349b06fc07398a3a1697b06418223b1c7725085e801e7c0fc6a12ec" 3988 - dependencies = [ 3989 - "bitflags", 3990 - "chrono", 3991 - "hex", 3992 - ] 3993 - 3994 - [[package]] 3995 - name = "procfs-core" 3996 - version = "0.18.0" 3997 - source = "registry+https://github.com/rust-lang/crates.io-index" 3998 - checksum = "e6401bf7b6af22f78b563665d15a22e9aef27775b79b149a66ca022468a4e405" 3999 dependencies = [ 4000 "bitflags", 4001 "chrono", ··· 4278 4279 [[package]] 4280 name = "reqwest" 4281 - version = "0.12.25" 4282 source = "registry+https://github.com/rust-lang/crates.io-index" 4283 - checksum = "b6eff9328d40131d43bd911d42d79eb6a47312002a4daefc9e37f17e74a7701a" 4284 dependencies = [ 4285 "base64", 4286 "bytes", ··· 4471 4472 [[package]] 4473 name = "rustls" 4474 - version = "0.23.28" 4475 source = "registry+https://github.com/rust-lang/crates.io-index" 4476 - checksum = "7160e3e10bf4535308537f3c4e1641468cd0e485175d6163087c0393c7d46643" 4477 dependencies = [ 4478 "once_cell", 4479 "ring", ··· 5736 5737 [[package]] 5738 name = "uucore" 5739 - version = "0.4.0" 5740 source = "registry+https://github.com/rust-lang/crates.io-index" 5741 - checksum = "2003164a38a7f39da1de103a70fa66b745f572f0045ec261481539516c0a8a0e" 5742 dependencies = [ 5743 - "bstr", 5744 "clap", 5745 "fluent", 5746 "fluent-bundle", 5747 "fluent-syntax", 5748 "libc", 5749 "nix", 5750 - "number_prefix", 5751 "os_display", 5752 "phf 0.13.1", 5753 - "procfs 0.18.0", 5754 "thiserror 2.0.17", 5755 "unic-langid", 5756 "uucore_procs", ··· 5759 5760 [[package]] 5761 name = "uucore_procs" 5762 - version = "0.4.0" 5763 source = "registry+https://github.com/rust-lang/crates.io-index" 5764 - checksum = "c76f0308f7810d915246a39748e7f5d64e43e6bb9d6c8107224f9d741aefc375" 5765 dependencies = [ 5766 "proc-macro2", 5767 "quote",
··· 74 75 [[package]] 76 name = "alphanumeric-sort" 77 + version = "1.5.5" 78 source = "registry+https://github.com/rust-lang/crates.io-index" 79 + checksum = "774ffdfeac16e9b4d75e41225dc2545d9c2082a0634b5d7f6f70e168546eecb1" 80 81 [[package]] 82 name = "android_system_properties" ··· 394 dependencies = [ 395 "alloc-no-stdlib", 396 "alloc-stdlib", 397 ] 398 399 [[package]] ··· 1337 "jacquard-repo", 1338 "js-sys", 1339 "miette", 1340 + "nu-cmd-base", 1341 "nu-cmd-extra", 1342 "nu-cmd-lang", 1343 "nu-command", 1344 "nu-engine", 1345 "nu-parser", 1346 + "nu-path", 1347 "nu-protocol", 1348 "rapidhash", 1349 "reqwest", ··· 2962 2963 [[package]] 2964 name = "nu-cmd-base" 2965 + version = "0.109.2" 2966 + source = "git+https://github.com/90-008/nushell#db3f8b1979bc9bfc6b4b54046804db9c1709eaa0" 2967 dependencies = [ 2968 "indexmap 2.12.1", 2969 "miette", ··· 2975 2976 [[package]] 2977 name = "nu-cmd-extra" 2978 + version = "0.109.2" 2979 + source = "git+https://github.com/90-008/nushell#db3f8b1979bc9bfc6b4b54046804db9c1709eaa0" 2980 dependencies = [ 2981 "fancy-regex", 2982 "heck 0.5.0", ··· 2999 3000 [[package]] 3001 name = "nu-cmd-lang" 3002 + version = "0.109.2" 3003 + source = "git+https://github.com/90-008/nushell#db3f8b1979bc9bfc6b4b54046804db9c1709eaa0" 3004 dependencies = [ 3005 "itertools 0.14.0", 3006 "nu-cmd-base", ··· 3014 3015 [[package]] 3016 name = "nu-color-config" 3017 + version = "0.109.2" 3018 + source = "git+https://github.com/90-008/nushell#db3f8b1979bc9bfc6b4b54046804db9c1709eaa0" 3019 dependencies = [ 3020 "nu-ansi-term", 3021 "nu-engine", ··· 3026 3027 [[package]] 3028 name = "nu-command" 3029 + version = "0.109.2" 3030 + source = "git+https://github.com/90-008/nushell#db3f8b1979bc9bfc6b4b54046804db9c1709eaa0" 3031 dependencies = [ 3032 "alphanumeric-sort", 3033 "base64", ··· 3084 "pathdiff", 3085 "percent-encoding", 3086 "print-positions", 3087 + "procfs", 3088 "quick-xml 0.38.4", 3089 "rayon", 3090 "rmp", ··· 3115 3116 [[package]] 3117 name = "nu-derive-value" 3118 + version = "0.109.2" 3119 + source = "git+https://github.com/90-008/nushell#db3f8b1979bc9bfc6b4b54046804db9c1709eaa0" 3120 dependencies = [ 3121 "heck 0.5.0", 3122 "proc-macro-error2", ··· 3127 3128 [[package]] 3129 name = "nu-engine" 3130 + version = "0.109.2" 3131 + source = "git+https://github.com/90-008/nushell#db3f8b1979bc9bfc6b4b54046804db9c1709eaa0" 3132 dependencies = [ 3133 "fancy-regex", 3134 "log", ··· 3141 3142 [[package]] 3143 name = "nu-experimental" 3144 + version = "0.109.2" 3145 + source = "git+https://github.com/90-008/nushell#db3f8b1979bc9bfc6b4b54046804db9c1709eaa0" 3146 dependencies = [ 3147 "itertools 0.14.0", 3148 "thiserror 2.0.17", ··· 3150 3151 [[package]] 3152 name = "nu-glob" 3153 + version = "0.109.2" 3154 + source = "git+https://github.com/90-008/nushell#db3f8b1979bc9bfc6b4b54046804db9c1709eaa0" 3155 3156 [[package]] 3157 name = "nu-json" 3158 + version = "0.109.2" 3159 + source = "git+https://github.com/90-008/nushell#db3f8b1979bc9bfc6b4b54046804db9c1709eaa0" 3160 dependencies = [ 3161 "linked-hash-map", 3162 "nu-utils", ··· 3167 3168 [[package]] 3169 name = "nu-parser" 3170 + version = "0.109.2" 3171 + source = "git+https://github.com/90-008/nushell#db3f8b1979bc9bfc6b4b54046804db9c1709eaa0" 3172 dependencies = [ 3173 "bytesize", 3174 "chrono", ··· 3183 3184 [[package]] 3185 name = "nu-path" 3186 + version = "0.109.2" 3187 + source = "git+https://github.com/90-008/nushell#db3f8b1979bc9bfc6b4b54046804db9c1709eaa0" 3188 dependencies = [ 3189 "dirs", 3190 "omnipath", ··· 3194 3195 [[package]] 3196 name = "nu-pretty-hex" 3197 + version = "0.109.2" 3198 + source = "git+https://github.com/90-008/nushell#db3f8b1979bc9bfc6b4b54046804db9c1709eaa0" 3199 dependencies = [ 3200 "nu-ansi-term", 3201 ] 3202 3203 [[package]] 3204 name = "nu-protocol" 3205 + version = "0.109.2" 3206 + source = "git+https://github.com/90-008/nushell#db3f8b1979bc9bfc6b4b54046804db9c1709eaa0" 3207 dependencies = [ 3208 "bytes", 3209 "chrono", ··· 3238 3239 [[package]] 3240 name = "nu-system" 3241 + version = "0.109.2" 3242 + source = "git+https://github.com/90-008/nushell#db3f8b1979bc9bfc6b4b54046804db9c1709eaa0" 3243 dependencies = [ 3244 "chrono", 3245 "itertools 0.14.0", ··· 3249 "mach2", 3250 "nix", 3251 "ntapi", 3252 + "procfs", 3253 "sysinfo", 3254 "web-time", 3255 "windows 0.62.2", ··· 3257 3258 [[package]] 3259 name = "nu-table" 3260 + version = "0.109.2" 3261 + source = "git+https://github.com/90-008/nushell#db3f8b1979bc9bfc6b4b54046804db9c1709eaa0" 3262 dependencies = [ 3263 "fancy-regex", 3264 "nu-ansi-term", ··· 3271 3272 [[package]] 3273 name = "nu-term-grid" 3274 + version = "0.109.2" 3275 + source = "git+https://github.com/90-008/nushell#db3f8b1979bc9bfc6b4b54046804db9c1709eaa0" 3276 dependencies = [ 3277 "nu-utils", 3278 "unicode-width 0.2.2", ··· 3280 3281 [[package]] 3282 name = "nu-utils" 3283 + version = "0.109.2" 3284 + source = "git+https://github.com/90-008/nushell#db3f8b1979bc9bfc6b4b54046804db9c1709eaa0" 3285 dependencies = [ 3286 "byteyarn", 3287 "crossterm_winapi", ··· 3371 ] 3372 3373 [[package]] 3374 name = "nuon" 3375 + version = "0.109.2" 3376 + source = "git+https://github.com/90-008/nushell#db3f8b1979bc9bfc6b4b54046804db9c1709eaa0" 3377 dependencies = [ 3378 "nu-engine", 3379 "nu-parser", ··· 3929 "chrono", 3930 "flate2", 3931 "hex", 3932 + "procfs-core", 3933 "rustix 0.38.44", 3934 ] 3935 3936 [[package]] 3937 name = "procfs-core" 3938 version = "0.17.0" 3939 source = "registry+https://github.com/rust-lang/crates.io-index" 3940 checksum = "239df02d8349b06fc07398a3a1697b06418223b1c7725085e801e7c0fc6a12ec" 3941 dependencies = [ 3942 "bitflags", 3943 "chrono", ··· 4220 4221 [[package]] 4222 name = "reqwest" 4223 + version = "0.12.26" 4224 source = "registry+https://github.com/rust-lang/crates.io-index" 4225 + checksum = "3b4c14b2d9afca6a60277086b0cc6a6ae0b568f6f7916c943a8cdc79f8be240f" 4226 dependencies = [ 4227 "base64", 4228 "bytes", ··· 4413 4414 [[package]] 4415 name = "rustls" 4416 + version = "0.23.35" 4417 source = "registry+https://github.com/rust-lang/crates.io-index" 4418 + checksum = "533f54bc6a7d4f647e46ad909549eda97bf5afc1585190ef692b4286b198bd8f" 4419 dependencies = [ 4420 "once_cell", 4421 "ring", ··· 5678 5679 [[package]] 5680 name = "uucore" 5681 + version = "0.5.0" 5682 source = "registry+https://github.com/rust-lang/crates.io-index" 5683 + checksum = "b5eddd390f3fdef74f104a948559e6de29203f60f8f563c8c9f528cd4c88ee78" 5684 dependencies = [ 5685 "clap", 5686 "fluent", 5687 "fluent-bundle", 5688 "fluent-syntax", 5689 "libc", 5690 "nix", 5691 "os_display", 5692 "phf 0.13.1", 5693 "thiserror 2.0.17", 5694 "unic-langid", 5695 "uucore_procs", ··· 5698 5699 [[package]] 5700 name = "uucore_procs" 5701 + version = "0.5.0" 5702 source = "registry+https://github.com/rust-lang/crates.io-index" 5703 + checksum = "47148309a1f7a989d165dabbbc7f2bf156d7ff6affe7d69c1c5bfb822e663ae6" 5704 dependencies = [ 5705 "proc-macro2", 5706 "quote",
+9 -6
Cargo.toml
··· 12 getrandom = { version = "0.3", features = ["wasm_js"] } 13 web-sys = { version = "0.3", features = ["console", "Window"] } 14 vfs = { version = "0.12" } 15 - nu-cmd-lang = { version = "0.109.1", default-features = false } 16 - nu-command = { version = "0.109.1", default-features = false } 17 - nu-engine = { version = "0.109.1", default-features = false } 18 - nu-parser = { version = "0.109.1", default-features = false } 19 - nu-protocol = { version = "0.109.1", default-features = false } 20 - nu-cmd-extra = { version = "0.109.1", default-features = false } 21 serde = { version = "1.0", features = ["derive"] } 22 serde_json = "1" 23 miette = { version = "7.6", features = ["fancy"] } ··· 44 lto = true 45 codegen-units = 1 46 strip = true
··· 12 getrandom = { version = "0.3", features = ["wasm_js"] } 13 web-sys = { version = "0.3", features = ["console", "Window"] } 14 vfs = { version = "0.12" } 15 + nu-command = { git = "https://github.com/90-008/nushell", default-features = false } 16 + nu-engine = { git = "https://github.com/90-008/nushell", default-features = false } 17 + nu-parser = { git = "https://github.com/90-008/nushell", default-features = false } 18 + nu-protocol = { git = "https://github.com/90-008/nushell", default-features = false } 19 + nu-path = { git = "https://github.com/90-008/nushell", default-features = false } 20 + nu-cmd-base = { git = "https://github.com/90-008/nushell", default-features = false } 21 + nu-cmd-lang = { git = "https://github.com/90-008/nushell", default-features = false } 22 + nu-cmd-extra = { git = "https://github.com/90-008/nushell", default-features = false } 23 serde = { version = "1.0", features = ["derive"] } 24 serde_json = "1" 25 miette = { version = "7.6", features = ["fancy"] } ··· 46 lto = true 47 codegen-units = 1 48 strip = true 49 + debug-assertions = false
+7 -3
src/cmd/cd.rs
··· 1 use crate::globals::{get_pwd, get_vfs, set_pwd, to_shell_err}; 2 use nu_engine::CallExt; 3 use nu_protocol::{ 4 - Category, PipelineData, ShellError, Signature, SyntaxShape, 5 engine::{Command, EngineState, Stack}, 6 }; 7 use std::sync::Arc; ··· 28 fn run( 29 &self, 30 engine_state: &EngineState, 31 - _stack: &mut Stack, 32 call: &nu_protocol::engine::Call, 33 _input: PipelineData, 34 ) -> Result<PipelineData, ShellError> { 35 - let path_arg: Option<String> = call.opt(engine_state, _stack, 0)?; 36 let path = path_arg.unwrap_or_else(|| "/".to_string()); 37 38 let base: Arc<vfs::VfsPath> = if path.starts_with('/') { ··· 49 let metadata = target.metadata().map_err(to_shell_err(call.head))?; 50 match metadata.file_type { 51 VfsFileType::Directory => { 52 set_pwd(Arc::new(target)); 53 Ok(PipelineData::Empty) 54 }
··· 1 use crate::globals::{get_pwd, get_vfs, set_pwd, to_shell_err}; 2 use nu_engine::CallExt; 3 use nu_protocol::{ 4 + Category, IntoValue, PipelineData, ShellError, Signature, SyntaxShape, 5 engine::{Command, EngineState, Stack}, 6 }; 7 use std::sync::Arc; ··· 28 fn run( 29 &self, 30 engine_state: &EngineState, 31 + stack: &mut Stack, 32 call: &nu_protocol::engine::Call, 33 _input: PipelineData, 34 ) -> Result<PipelineData, ShellError> { 35 + let path_arg: Option<String> = call.opt(engine_state, stack, 0)?; 36 let path = path_arg.unwrap_or_else(|| "/".to_string()); 37 38 let base: Arc<vfs::VfsPath> = if path.starts_with('/') { ··· 49 let metadata = target.metadata().map_err(to_shell_err(call.head))?; 50 match metadata.file_type { 51 VfsFileType::Directory => { 52 + stack.add_env_var( 53 + "PWD".to_string(), 54 + target.as_str().into_value(call.arguments_span()), 55 + ); 56 set_pwd(Arc::new(target)); 57 Ok(PipelineData::Empty) 58 }
+1 -1
src/cmd/fetch.rs
··· 180 match result { 181 Ok(_) => {} 182 Err(e) => { 183 - print_to_console( 184 &format!("\x1b[31m✖\x1b[0m ({task_desc}) error: {e}"), 185 false, 186 );
··· 180 match result { 181 Ok(_) => {} 182 Err(e) => { 183 + let _ = print_to_console( 184 &format!("\x1b[31m✖\x1b[0m ({task_desc}) error: {e}"), 185 false, 186 );
+63 -2
src/globals.rs
··· 1 use futures::stream::AbortHandle; 2 use nu_protocol::{ 3 - ShellError, Span, 4 engine::{EngineState, StateDelta}, 5 }; 6 use std::{ ··· 171 } 172 } 173 174 - pub fn print_to_console(msg: &str, is_cmd: bool) { 175 if let Some(mutex) = CONSOLE_CALLBACK.get() { 176 if let Ok(guard) = mutex.lock() { 177 if let Some(cb) = guard.as_ref() { ··· 182 } 183 } 184 } 185 } 186 187 pub fn current_time() -> Option<SystemTime> { 188 UNIX_EPOCH.checked_add(Duration::from_millis(js_sys::Date::now() as u64)) 189 }
··· 1 use futures::stream::AbortHandle; 2 use nu_protocol::{ 3 + ShellError, Signal, Span, 4 engine::{EngineState, StateDelta}, 5 }; 6 use std::{ ··· 171 } 172 } 173 174 + pub fn print_to_console(msg: &str, is_cmd: bool) -> Result<(), ShellError> { 175 + // if is_interrupted() { 176 + // return Err(ShellError::Interrupted { 177 + // span: Span::unknown(), 178 + // }); 179 + // } 180 if let Some(mutex) = CONSOLE_CALLBACK.get() { 181 if let Ok(guard) = mutex.lock() { 182 if let Some(cb) = guard.as_ref() { ··· 187 } 188 } 189 } 190 + Ok(()) 191 } 192 193 pub fn current_time() -> Option<SystemTime> { 194 UNIX_EPOCH.checked_add(Duration::from_millis(js_sys::Date::now() as u64)) 195 } 196 + 197 + use js_sys::Int32Array; 198 + use std::cell::RefCell; 199 + 200 + // We use thread_local storage because the Wasm worker is single-threaded. 201 + // This holds the reference to the SharedArrayBuffer view passed from JS. 202 + thread_local! { 203 + pub static INTERRUPT_BUFFER: RefCell<Option<Int32Array>> = RefCell::new(None); 204 + } 205 + 206 + /// Called from JS to pass the SharedArrayBuffer view 207 + #[wasm_bindgen] 208 + pub fn set_interrupt_buffer(buffer: Int32Array) { 209 + INTERRUPT_BUFFER.with(|b| { 210 + *b.borrow_mut() = Some(buffer); 211 + }); 212 + } 213 + 214 + /// Call this function periodically in your long-running loops! 215 + /// Returns `true` if an interrupt was requested. 216 + pub fn check_interrupt() -> bool { 217 + INTERRUPT_BUFFER.with(|b| { 218 + if let Some(buffer) = b.borrow().as_ref() { 219 + // Check index 0. If it's 1, an interrupt occurred. 220 + // We use Atomics to ensure we see the value written by the main thread. 221 + match js_sys::Atomics::load(buffer, 0) { 222 + Ok(1) => true, 223 + _ => false, 224 + } 225 + } else { 226 + false 227 + } 228 + }) 229 + } 230 + 231 + pub fn set_interrupt(value: bool) { 232 + INTERRUPT_BUFFER.with(|b| { 233 + if let Some(buffer) = b.borrow().as_ref() { 234 + let _ = js_sys::Atomics::store(buffer, 0, value as i32); 235 + } 236 + }); 237 + } 238 + 239 + pub struct InterruptBool; 240 + 241 + impl Signal for InterruptBool { 242 + #[inline] 243 + fn get(&self) -> bool { 244 + check_interrupt() 245 + } 246 + #[inline] 247 + fn set(&self, value: bool) { 248 + set_interrupt(value); 249 + } 250 + }
+67 -23
src/lib.rs
··· 1 use jacquard::chrono; 2 use miette::Report; 3 use nu_cmd_extra::add_extra_command_context; 4 use nu_cmd_lang::create_default_context; 5 use nu_engine::{command_prelude::*, eval_block}; 6 use nu_parser::{FlatShape, TokenContents, flatten_block, lex, parse}; 7 use nu_protocol::{ 8 - Config, ListStream, PipelineData, Span, 9 engine::{Call, EngineState, Stack, StateWorkingSet}, 10 }; 11 use serde::Serialize; 12 use std::{ 13 io::Cursor, 14 sync::{Arc, Mutex, OnceLock}, 15 time::UNIX_EPOCH, 16 }; ··· 32 }, 33 default_context::add_shell_command_context, 34 error::format_error, 35 - globals::{apply_pending_deltas, current_time, get_pwd, print_to_console}, 36 }; 37 use error::CommandError; 38 use globals::get_vfs; 39 40 static ENGINE_STATE: OnceLock<Mutex<EngineState>> = OnceLock::new(); 41 static STACK: OnceLock<Mutex<Stack>> = OnceLock::new(); 42 ··· 110 let mut config = Config::default(); 111 config.use_ansi_coloring = true.into(); 112 config.show_banner = nu_protocol::BannerKind::Full; 113 engine_state.config = Arc::new(config); 114 115 ENGINE_STATE 116 .set(Mutex::new(engine_state)) ··· 126 127 #[wasm_bindgen] 128 pub fn init_engine() -> String { 129 - console_error_panic_hook::set_once(); 130 init_engine_internal().map_or_else(|err| format!("error: {err}"), |_| String::new()) 131 } 132 ··· 140 error: Report::new(e), 141 start_offset: 0, 142 })?; 143 - // set PWD 144 - engine_state.add_env_var( 145 - "PWD".to_string(), 146 - get_pwd_string().into_value(Span::unknown()), 147 - ); 148 149 let mut working_set = StateWorkingSet::new(engine_state); 150 let start_offset = working_set.next_span_start(); ··· 220 x => x, 221 }; 222 223 - // TODO: idk what this does i copied it from PipelineData::print_table 224 - // dunno if it matters, we can just use nu_command::Table and it works fine i think 225 - let table_command = engine_state 226 - .table_decl_id 227 - .map(|decl_id| engine_state.get_decl(decl_id)) 228 - .filter(|command| command.block_id().is_some()) 229 - .unwrap_or(&nu_command::Table); 230 - let call = Call::new(pipeline_data.span().unwrap_or_else(Span::unknown)); 231 - 232 - let res = table_command 233 - .run(engine_state, stack, &call, pipeline_data) 234 - .map_err(cmd_err)?; 235 236 match res { 237 PipelineData::Empty => {} 238 PipelineData::Value(v, _) => { 239 print_to_console(&v.to_expanded_string("\n", &engine_state.config), true) 240 } 241 PipelineData::ByteStream(s, _) => { 242 for line in s.lines().into_iter().flatten() { 243 let out = line.map_err(cmd_err)?; // TODO: do we turn this into a Value ??? or is returning err fine 244 - print_to_console(&out, true); 245 } 246 } 247 PipelineData::ListStream(s, _) => { 248 for item in s.into_iter() { 249 - let out = item.to_expanded_string("\n", &engine_state.config); 250 - print_to_console(&out, true); 251 } 252 } 253 } ··· 266 STACK.get().unwrap().lock().expect("stack initialized"), 267 ); 268 269 match run_command_internal(&mut engine_guard, &mut stack_guard, input) { 270 Ok(_) => None, 271 Err(cmd_err) => Some(format_error( ··· 286 } 287 pwd.as_str().to_string() 288 }
··· 1 use jacquard::chrono; 2 use miette::Report; 3 + use nu_cmd_base::hook::eval_hook; 4 use nu_cmd_extra::add_extra_command_context; 5 use nu_cmd_lang::create_default_context; 6 use nu_engine::{command_prelude::*, eval_block}; 7 use nu_parser::{FlatShape, TokenContents, flatten_block, lex, parse}; 8 use nu_protocol::{ 9 + Config, ListStream, PipelineData, Signals, Span, 10 engine::{Call, EngineState, Stack, StateWorkingSet}, 11 }; 12 use serde::Serialize; 13 use std::{ 14 io::Cursor, 15 + path::PathBuf, 16 sync::{Arc, Mutex, OnceLock}, 17 time::UNIX_EPOCH, 18 }; ··· 34 }, 35 default_context::add_shell_command_context, 36 error::format_error, 37 + globals::{ 38 + InterruptBool, apply_pending_deltas, current_time, get_pwd, print_to_console, set_interrupt, 39 + }, 40 }; 41 use error::CommandError; 42 use globals::get_vfs; 43 44 + #[wasm_bindgen] 45 + extern "C" { 46 + #[wasm_bindgen(js_namespace = console)] 47 + fn error(msg: String); 48 + 49 + type Error; 50 + 51 + #[wasm_bindgen(constructor)] 52 + fn new() -> Error; 53 + 54 + #[wasm_bindgen(structural, method, getter)] 55 + fn stack(error: &Error) -> String; 56 + } 57 + 58 + fn panic_hook(info: &std::panic::PanicHookInfo) { 59 + let mut msg = info.to_string(); 60 + 61 + msg.push_str("\n\nStack:\n\n"); 62 + let e = Error::new(); 63 + let stack = e.stack(); 64 + msg.push_str(&stack); 65 + msg.push_str("\n\n"); 66 + 67 + let _ = print_to_console(&msg, false); 68 + } 69 + 70 static ENGINE_STATE: OnceLock<Mutex<EngineState>> = OnceLock::new(); 71 static STACK: OnceLock<Mutex<Stack>> = OnceLock::new(); 72 ··· 140 let mut config = Config::default(); 141 config.use_ansi_coloring = true.into(); 142 config.show_banner = nu_protocol::BannerKind::Full; 143 + config.hooks.display_output = Some("table".into_value(Span::unknown())); 144 engine_state.config = Arc::new(config); 145 + 146 + engine_state.set_signals(Signals::new(Arc::new(InterruptBool))); 147 148 ENGINE_STATE 149 .set(Mutex::new(engine_state)) ··· 159 160 #[wasm_bindgen] 161 pub fn init_engine() -> String { 162 + std::panic::set_hook(Box::new(panic_hook)); 163 init_engine_internal().map_or_else(|err| format!("error: {err}"), |_| String::new()) 164 } 165 ··· 173 error: Report::new(e), 174 start_offset: 0, 175 })?; 176 + let pwd = get_pwd_string().into_value(Span::unknown()); 177 + engine_state.add_env_var("PWD".to_string(), pwd.clone()); 178 179 let mut working_set = StateWorkingSet::new(engine_state); 180 let start_offset = working_set.next_span_start(); ··· 250 x => x, 251 }; 252 253 + let conf = stack.get_config(engine_state); 254 + let hook = conf.hooks.display_output.as_ref(); 255 + let res = eval_hook( 256 + engine_state, 257 + stack, 258 + Some(pipeline_data), 259 + vec![], 260 + hook.unwrap(), 261 + "display_output", 262 + ) 263 + .map_err(cmd_err)?; 264 265 match res { 266 PipelineData::Empty => {} 267 PipelineData::Value(v, _) => { 268 print_to_console(&v.to_expanded_string("\n", &engine_state.config), true) 269 + .map_err(cmd_err)?; 270 } 271 PipelineData::ByteStream(s, _) => { 272 for line in s.lines().into_iter().flatten() { 273 let out = line.map_err(cmd_err)?; // TODO: do we turn this into a Value ??? or is returning err fine 274 + print_to_console(&out, true).map_err(cmd_err)?; 275 } 276 } 277 PipelineData::ListStream(s, _) => { 278 for item in s.into_iter() { 279 + let out = item 280 + .unwrap_error() 281 + .map_err(cmd_err)? 282 + .to_expanded_string("\n", &engine_state.config); 283 + print_to_console(&out, true).map_err(cmd_err)?; 284 } 285 } 286 } ··· 299 STACK.get().unwrap().lock().expect("stack initialized"), 300 ); 301 302 + set_interrupt(false); 303 match run_command_internal(&mut engine_guard, &mut stack_guard, input) { 304 Ok(_) => None, 305 Err(cmd_err) => Some(format_error( ··· 320 } 321 pwd.as_str().to_string() 322 } 323 + 324 + pub fn get_pwd_buf() -> PathBuf { 325 + // web_sys::console::log_1(&"before pwd".into()); 326 + let pwd = get_pwd(); 327 + // web_sys::console::log_1(&"after pwd".into()); 328 + if pwd.is_root() { 329 + return PathBuf::new().join("/"); 330 + } 331 + pwd.as_str().into() 332 + }
+5
www/src/main.ts
··· 23 type SearchState = "history" | "completion" | "none"; 24 25 async function bootstrap() { 26 // Instantiate the worker using the imported class 27 const worker = new DysnomiaWorker(); 28 ··· 448 break; 449 450 case "\u0003": // Ctrl+C 451 currentLine = ""; 452 cursorPos = 0; 453 completionCandidates = []; ··· 641 642 await readyPromise; 643 644 await callWorker("run", "open welcome.txt"); 645 646 term.write(getPrompt());
··· 23 type SearchState = "history" | "completion" | "none"; 24 25 async function bootstrap() { 26 + const sab = new SharedArrayBuffer(4); 27 + const interruptBuffer = new Int32Array(sab); 28 + 29 // Instantiate the worker using the imported class 30 const worker = new DysnomiaWorker(); 31 ··· 451 break; 452 453 case "\u0003": // Ctrl+C 454 + Atomics.store(interruptBuffer, 0, 1); 455 currentLine = ""; 456 cursorPos = 0; 457 completionCandidates = []; ··· 645 646 await readyPromise; 647 648 + await callWorker("set-interrupt-buffer", interruptBuffer); 649 await callWorker("run", "open welcome.txt"); 650 651 term.write(getPrompt());
+4
www/src/worker.ts
··· 6 get_pwd_string, 7 register_console_callback, 8 register_task_count_callback, 9 } from "../../pkg"; 10 11 // Initialize WASM ··· 30 try { 31 let result; 32 switch (type) { 33 case "run": 34 result = run_command(payload); 35 break;
··· 6 get_pwd_string, 7 register_console_callback, 8 register_task_count_callback, 9 + set_interrupt_buffer, 10 } from "../../pkg"; 11 12 // Initialize WASM ··· 31 try { 32 let result; 33 switch (type) { 34 + case "set-interrupt-buffer": 35 + set_interrupt_buffer(payload); 36 + break; 37 case "run": 38 result = run_command(payload); 39 break;
+5
www/vite.config.ts
··· 12 fs: { 13 allow: [".."], 14 }, 15 }, 16 });
··· 12 fs: { 13 allow: [".."], 14 }, 15 + cors: true, 16 + headers: { 17 + "Cross-Origin-Embedder-Policy": "require-corp", 18 + "Cross-Origin-Opener-Policy": "same-origin", 19 + }, 20 }, 21 });