nushell on your web browser
nushell wasm terminal

implement interrupts

ptr.pet 8fce20a8 3984b06c

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