diff --git a/Cargo.lock b/Cargo.lock index 761ce1df4e..8e8ebaf7f0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -453,10 +453,10 @@ version = "0.69.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a00dc851838a2120612785d195287475a3ac45514741da670b735818822129a0" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "cexpr", "clang-sys", - "itertools", + "itertools 0.12.1", "lazy_static", "lazycell", "log", @@ -493,9 +493,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.5.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" dependencies = [ "serde", ] @@ -649,6 +649,12 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" +[[package]] +name = "cfg_aliases" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" + [[package]] name = "chrono" version = "0.4.37" @@ -1043,7 +1049,7 @@ version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b28bfe653d79bd16c77f659305b195b82bb5ce0c0eb2a4846b82ddbd77586813" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "libloading 0.8.3", "winapi", ] @@ -1206,7 +1212,6 @@ dependencies = [ "ring", "runtimelib", "rustyline", - "rustyline-derive", "serde", "serde_json", "serde_repr", @@ -1612,7 +1617,7 @@ dependencies = [ "hyper 0.14.28", "hyper 1.4.1", "hyper-util", - "itertools", + "itertools 0.10.5", "memmem", "mime", "once_cell", @@ -3238,7 +3243,7 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fbcd2dba93594b227a1f57ee09b8b9da8892c34d55aa332e034a228d0fe6a171" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "gpu-alloc-types", ] @@ -3248,7 +3253,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "98ff03b468aa837d70984d55f5d3f846f6ec31fe34bbb97c4f85219caeee1ca4" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", ] [[package]] @@ -3257,7 +3262,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c08c1f623a8d0b722b8b99f821eb0ba672a1618f0d3b16ddbee1cedd2dd8557" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "gpu-descriptor-types", "hashbrown", ] @@ -3268,7 +3273,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fdf242682df893b86f33a73828fb09ca4b2d3bb6cc95249707fc684d27484b91" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", ] [[package]] @@ -3839,6 +3844,15 @@ dependencies = [ "either", ] +[[package]] +name = "itertools" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.11" @@ -4052,9 +4066,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.153" +version = "0.2.155" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" +checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" [[package]] name = "libffi" @@ -4092,7 +4106,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c2a198fb6b0eada2a8df47933734e6d35d350665a33a3593d7164fa52c75c19" dependencies = [ "cfg-if", - "windows-targets 0.52.4", + "windows-targets 0.48.5", ] [[package]] @@ -4107,7 +4121,7 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "libc", ] @@ -4178,9 +4192,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.21" +version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" dependencies = [ "serde", ] @@ -4312,7 +4326,7 @@ version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5637e166ea14be6063a3f8ba5ccb9a4159df7d8f6d61c02fc3d480b1f90dcfcb" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "block", "core-graphics-types", "foreign-types", @@ -4375,7 +4389,7 @@ checksum = "e536ae46fcab0876853bd4a632ede5df4b1c2527a58f6c5a4150fe86be858231" dependencies = [ "arrayvec", "bit-set", - "bitflags 2.5.0", + "bitflags 2.6.0", "codespan-reporting", "hexf-parse", "indexmap", @@ -4464,12 +4478,13 @@ dependencies = [ [[package]] name = "nix" -version = "0.27.1" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2eb04e9c688eff1c89d72b407f168cf79bb9e867a9d3323ed6c01519eb9cc053" +checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "cfg-if", + "cfg_aliases 0.2.1", "libc", ] @@ -4518,7 +4533,7 @@ version = "6.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6205bd8bb1e454ad2e27422015fb5e4f2bcc7e08fa8f27058670d208324a4d2d" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "crossbeam-channel", "filetime", "fsevent-sys", @@ -5277,7 +5292,7 @@ checksum = "119533552c9a7ffacc21e099c24a0ac8bb19c2a2a3f363de84cd9b844feab270" dependencies = [ "bytes", "heck 0.4.1", - "itertools", + "itertools 0.10.5", "lazy_static", "log", "multimap", @@ -5298,7 +5313,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5d2d8d10f3c6ded6da8b05b5fb3b8a5082514344d56c9f871412d29b4e075b4" dependencies = [ "anyhow", - "itertools", + "itertools 0.10.5", "proc-macro2", "quote", "syn 1.0.109", @@ -5348,7 +5363,7 @@ version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57206b407293d2bcd3af849ce869d52068623f19e1b5ff8e8778e3309439682b" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "memchr", "unicase", ] @@ -5704,7 +5719,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b91f7eff05f748767f183df4320a63d6936e9c6107d97c9e6bdd9784f4289c94" dependencies = [ "base64 0.21.7", - "bitflags 2.5.0", + "bitflags 2.6.0", "serde", "serde_derive", ] @@ -5772,7 +5787,7 @@ version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "549b9d036d571d42e6e85d1c1425e2ac83491075078ca9a15be021c56b1641f2" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "fallible-iterator", "fallible-streaming-iterator", "hashlink", @@ -5825,7 +5840,7 @@ version = "0.38.32" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "65e04861e65f21776e67888bfbea442b3642beaa0138fdb1dd7a84a52dffdb89" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "errno 0.3.8", "libc", "linux-raw-sys", @@ -5907,11 +5922,9 @@ checksum = "80af6f9131f277a45a3fba6ce8e2258037bb0477a67e610d3c1fe046ab31de47" [[package]] name = "rustyline" -version = "13.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02a2d683a4ac90aeef5b1013933f6d977bd37d51ff3f4dad829d4931a7e6be86" +version = "14.0.0" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "cfg-if", "clipboard-win", "fd-lock", @@ -5919,23 +5932,12 @@ dependencies = [ "libc", "log", "memchr", - "nix 0.27.1", + "nix 0.29.0", "radix_trie", "unicode-segmentation", "unicode-width", "utf8parse", - "winapi", -] - -[[package]] -name = "rustyline-derive" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "107c3d5d7f370ac09efa62a78375f94d94b8a33c61d8c278b96683fb4dbf2d8d" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", + "windows-sys 0.59.0", ] [[package]] @@ -6397,7 +6399,7 @@ version = "0.3.0+sdk-1.3.268.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eda41003dc44290527a59b13432d4a0379379fa074b70174882adfbdfd917844" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", ] [[package]] @@ -6644,7 +6646,7 @@ version = "0.117.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a5da2f0310e8cd84b8c803095e75b2cbca872c71fc7f7404d4c9c8117d894960" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "is-macro", "num-bigint", "phf 0.11.2", @@ -6730,7 +6732,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6df81c1cbb920d9c47abe6fb105363b0f78df2c8f6b0910c4fdd2ad7cbdfb23d" dependencies = [ "better_scoped_tls", - "bitflags 2.5.0", + "bitflags 2.6.0", "indexmap", "once_cell", "phf 0.11.2", @@ -7392,7 +7394,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e9cd434a998747dd2c4276bc96ee2e0c7a2eadf3cae88e52be55a05fa9053f5" dependencies = [ "async-compression", - "bitflags 2.5.0", + "bitflags 2.6.0", "bytes", "futures-core", "http 1.1.0", @@ -7799,7 +7801,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "88a710d5b95bff79a90708203cf9f74384e080d21fc6664aa4df463f2c66ac83" dependencies = [ "bindgen", - "bitflags 2.5.0", + "bitflags 2.6.0", "fslock", "gzip-header", "home", @@ -7815,7 +7817,7 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97599c400fc79925922b58303e98fcb8fa88f573379a08ddb652e72cbd2e70f6" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "encoding_rs", "indexmap", "num-bigint", @@ -8013,8 +8015,8 @@ checksum = "d50819ab545b867d8a454d1d756b90cd5f15da1f2943334ca314af10583c9d39" dependencies = [ "arrayvec", "bit-vec", - "bitflags 2.5.0", - "cfg_aliases", + "bitflags 2.6.0", + "cfg_aliases 0.1.1", "codespan-reporting", "document-features", "indexmap", @@ -8044,9 +8046,9 @@ dependencies = [ "arrayvec", "ash", "bit-set", - "bitflags 2.5.0", + "bitflags 2.6.0", "block", - "cfg_aliases", + "cfg_aliases 0.1.1", "core-graphics-types", "d3d12", "glow", @@ -8082,7 +8084,7 @@ version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1353d9a46bff7f955a680577f34c69122628cc2076e1d6f3a9be6ef00ae793ef" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "js-sys", "serde", "web-sys", @@ -8177,7 +8179,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0be" dependencies = [ "windows-core", - "windows-targets 0.52.4", + "windows-targets 0.52.6", ] [[package]] @@ -8186,7 +8188,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" dependencies = [ - "windows-targets 0.52.4", + "windows-targets 0.52.6", ] [[package]] @@ -8204,7 +8206,16 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.4", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets 0.52.6", ] [[package]] @@ -8224,17 +8235,18 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.52.4" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm 0.52.4", - "windows_aarch64_msvc 0.52.4", - "windows_i686_gnu 0.52.4", - "windows_i686_msvc 0.52.4", - "windows_x86_64_gnu 0.52.4", - "windows_x86_64_gnullvm 0.52.4", - "windows_x86_64_msvc 0.52.4", + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", ] [[package]] @@ -8245,9 +8257,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.4" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_msvc" @@ -8257,9 +8269,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" -version = "0.52.4" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_i686_gnu" @@ -8269,9 +8281,15 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_gnu" -version = "0.52.4" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_msvc" @@ -8281,9 +8299,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" -version = "0.52.4" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_x86_64_gnu" @@ -8293,9 +8311,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" -version = "0.52.4" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnullvm" @@ -8305,9 +8323,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.4" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_msvc" @@ -8317,9 +8335,9 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "windows_x86_64_msvc" -version = "0.52.4" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" diff --git a/Cargo.toml b/Cargo.toml index cbf9940ca2..dae44ef6c7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -159,7 +159,7 @@ rustls = { version = "0.23.11", default-features = false, features = ["logging", rustls-pemfile = "2" rustls-tokio-stream = "=0.3.0" rustls-webpki = "0.102" -rustyline = "=13.0.0" +rustyline = { path = "../../rustyline" } # "14.0.0" saffron = "=0.1.0" scopeguard = "1.2.0" serde = { version = "1.0.149", features = ["derive"] } diff --git a/cli/Cargo.toml b/cli/Cargo.toml index 168f2929c3..22e1e28242 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -138,7 +138,6 @@ rand = { workspace = true, features = ["small_rng"] } regex.workspace = true ring.workspace = true rustyline.workspace = true -rustyline-derive = "=0.7.0" serde.workspace = true serde_repr.workspace = true sha2.workspace = true diff --git a/cli/lsp/repl.rs b/cli/lsp/repl.rs index 2db7b1f725..ff1c92aa74 100644 --- a/cli/lsp/repl.rs +++ b/cli/lsp/repl.rs @@ -119,6 +119,7 @@ impl ReplLanguageServer { &mut self, line_text: &str, position: usize, + explicit: bool, ) -> Vec { self.did_change(line_text).await; let text_info = deno_ast::SourceTextInfo::from_string(format!( @@ -147,7 +148,11 @@ impl ReplLanguageServer { partial_result_token: None, }, context: Some(CompletionContext { - trigger_kind: CompletionTriggerKind::INVOKED, + trigger_kind: if explicit { + CompletionTriggerKind::INVOKED + } else { + CompletionTriggerKind::TRIGGER_CHARACTER + }, trigger_character: None, }), }) @@ -155,28 +160,34 @@ impl ReplLanguageServer { .ok() .unwrap_or_default(); - let mut items = match response { + let items = match response { Some(CompletionResponse::Array(items)) => items, Some(CompletionResponse::List(list)) => list.items, - None => Vec::new(), + None => return vec![], }; - items.sort_by_key(|item| { - if let Some(sort_text) = &item.sort_text { - sort_text.clone() - } else { - item.label.clone() - } - }); + items .into_iter() .filter_map(|item| { - item.text_edit.and_then(|edit| match edit { - CompletionTextEdit::Edit(edit) => Some(ReplCompletionItem { + if let Some(CompletionTextEdit::Edit(edit)) = item.text_edit { + return Some(ReplCompletionItem { new_text: edit.new_text, range: lsp_range_to_std_range(&text_info, &edit.range), - }), - CompletionTextEdit::InsertAndReplace(_) => None, + }); + } + None + /* + if let Some(text) = item.insert_text { + return Some(ReplCompletionItem { + range:line_and_column.column_index..(line_and_column.column_index + text.len()), + new_text: text, + }) + } + Some(ReplCompletionItem { + range: line_and_column.column_index..(line_and_column.column_index + item.label.len()), + new_text: item.label, }) + */ }) .filter(|item| { // filter the results to only exact matches diff --git a/cli/tools/jupyter/mod.rs b/cli/tools/jupyter/mod.rs index 7e88f92c29..f5f75166bf 100644 --- a/cli/tools/jupyter/mod.rs +++ b/cli/tools/jupyter/mod.rs @@ -407,7 +407,7 @@ impl JupyterReplSession { self .repl_session .language_server - .completions(line_text, position) + .completions(line_text, position, true) .await } @@ -485,7 +485,7 @@ impl JupyterReplSession { ) -> Result { self .repl_session - .evaluate_line_with_object_wrapping(line) + .evaluate_line_with_object_wrapping(line, false) .await } diff --git a/cli/tools/repl/channel.rs b/cli/tools/repl/channel.rs index 823a13d288..0748e9b0a2 100644 --- a/cli/tools/repl/channel.rs +++ b/cli/tools/repl/channel.rs @@ -42,12 +42,17 @@ pub enum RustylineSyncMessage { LspCompletions { line_text: String, position: usize, + explicit: bool, + }, + Preview { + line_text: String, }, } pub enum RustylineSyncResponse { PostMessage(Result), LspCompletions(Vec), + Preview(Option<(String, usize)>), } pub struct RustylineSyncMessageSender { @@ -75,7 +80,7 @@ impl RustylineSyncMessageSender { } else { match self.response_rx.borrow_mut().blocking_recv().unwrap() { RustylineSyncResponse::PostMessage(result) => result, - RustylineSyncResponse::LspCompletions(_) => unreachable!(), + _ => unreachable!(), } } } @@ -84,12 +89,14 @@ impl RustylineSyncMessageSender { &self, line_text: &str, position: usize, + explicit: bool, ) -> Vec { if self .message_tx .blocking_send(RustylineSyncMessage::LspCompletions { line_text: line_text.to_string(), position, + explicit, }) .is_err() { @@ -97,7 +104,24 @@ impl RustylineSyncMessageSender { } else { match self.response_rx.borrow_mut().blocking_recv().unwrap() { RustylineSyncResponse::LspCompletions(result) => result, - RustylineSyncResponse::PostMessage(_) => unreachable!(), + _ => unreachable!(), + } + } + } + + pub fn preview(&self, line_text: &str) -> Option<(String, usize)> { + if self + .message_tx + .blocking_send(RustylineSyncMessage::Preview { + line_text: line_text.to_string(), + }) + .is_err() + { + None + } else { + match self.response_rx.borrow_mut().blocking_recv().unwrap() { + RustylineSyncResponse::Preview(result) => result, + _ => unreachable!(), } } } diff --git a/cli/tools/repl/editor.rs b/cli/tools/repl/editor.rs index dbc9bce703..f71d574681 100644 --- a/cli/tools/repl/editor.rs +++ b/cli/tools/repl/editor.rs @@ -14,6 +14,8 @@ use deno_core::serde_json; use rustyline::completion::Completer; use rustyline::error::ReadlineError; use rustyline::highlight::Highlighter; +use rustyline::hint::Hinter; +use rustyline::preview::Previewer; use rustyline::validate::ValidationContext; use rustyline::validate::ValidationResult; use rustyline::validate::Validator; @@ -26,12 +28,11 @@ use rustyline::Editor; use rustyline::Event; use rustyline::EventContext; use rustyline::EventHandler; +use rustyline::Helper; use rustyline::KeyCode; use rustyline::KeyEvent; use rustyline::Modifiers; use rustyline::RepeatCount; -use rustyline_derive::Helper; -use rustyline_derive::Hinter; use std::borrow::Cow; use std::path::PathBuf; use std::sync::atomic::AtomicBool; @@ -43,7 +44,6 @@ use super::session::REPL_INTERNALS_NAME; // Provides helpers to the editor like validation for multi-line edits, completion candidates for // tab completion. -#[derive(Helper, Hinter)] pub struct EditorHelper { pub context_id: u64, pub sync_sender: RustylineSyncMessageSender, @@ -181,6 +181,8 @@ fn get_expr_from_line_at_pos(line: &str, cursor_pos: usize) -> &str { word } +impl Helper for EditorHelper {} + impl Completer for EditorHelper { type Candidate = String; @@ -190,7 +192,7 @@ impl Completer for EditorHelper { pos: usize, _ctx: &Context<'_>, ) -> Result<(usize, Vec), ReadlineError> { - let lsp_completions = self.sync_sender.lsp_completions(line, pos); + let lsp_completions = self.sync_sender.lsp_completions(line, pos, true); if !lsp_completions.is_empty() { // assumes all lsp completions have the same start position return Ok(( @@ -234,6 +236,51 @@ impl Completer for EditorHelper { } } +impl Hinter for EditorHelper { + type Hint = String; + + fn hint(&self, line: &str, pos: usize, ctx: &Context) -> Option { + if line.trim().is_empty() || line.ends_with(')') || line.ends_with('}') { + return None; + } + + let (p, completions) = self.complete(line, pos, ctx).ok()?; + let candidate = completions.into_iter().next()?; + // let lsp_completions = self.sync_sender.lsp_completions(line, pos, false); + //let completion = completions.into_iter().next()?; + + // let p = completion.range.start; + // let candidate = completion.new_text; + + let mut i = 0; + for (a, b) in line[p..].chars().zip(candidate.chars()) { + if a == b { + i += 1; + } else { + break; + } + } + Some(candidate[i..].to_owned()) + } +} + +impl Previewer for EditorHelper { + type Preview = String; + + fn preview( + &self, + line: &str, + _pos: usize, + _ctx: &Context, + ) -> Option { + if line.trim().is_empty() { + return None; + } + let (preview, counter) = self.sync_sender.preview(line)?; + Some(format!("Out[{counter}]: {preview}")) + } +} + impl Validator for EditorHelper { fn validate( &self, @@ -326,7 +373,11 @@ fn validate(input: &str) -> ValidationResult { impl Highlighter for EditorHelper { fn highlight_hint<'h>(&self, hint: &'h str) -> Cow<'h, str> { - hint.into() + format!("{}", colors::gray(hint)).into() + } + + fn highlight_preview<'h>(&self, hint: &'h str) -> Cow<'h, str> { + format!("{}", colors::gray(hint)).into() } fn highlight_candidate<'c>( @@ -477,8 +528,24 @@ impl ReplEditor { }) } - pub fn readline(&self) -> Result { - self.inner.lock().readline("> ") + pub fn readline(&self, counter: usize) -> Result { + let prompt = format!( + "{}{}{}", + colors::green("In ["), + colors::green_bold(counter), + colors::green("]: ") + ); + self.inner.lock().readline(&prompt) + } + + pub fn output(&self, output: String, counter: usize) { + let prompt = format!( + "{}{}{}", + colors::red("Out["), + colors::red_bold(counter), + colors::red("]: ") + ); + println!("{prompt}{output}\n"); } pub fn update_history(&self, entry: String) { diff --git a/cli/tools/repl/mod.rs b/cli/tools/repl/mod.rs index 9798a69674..14c1e48379 100644 --- a/cli/tools/repl/mod.rs +++ b/cli/tools/repl/mod.rs @@ -44,18 +44,23 @@ struct Repl { #[allow(clippy::print_stdout)] impl Repl { async fn run(&mut self) -> Result<(), AnyError> { + let mut counter = 1; loop { let line = read_line_and_poll( &mut self.session, &mut self.message_handler, self.editor.clone(), + counter, ) .await; match line { Ok(line) => { self.editor.set_should_exit_on_interrupt(false); self.editor.update_history(line.clone()); - let output = self.session.evaluate_line_and_get_output(&line).await; + let output = self + .session + .evaluate_line_and_get_output(&line, counter) + .await; // We check for close and break here instead of making it a loop condition to get // consistent behavior in when the user evaluates a call to close(). @@ -63,7 +68,15 @@ impl Repl { break; } - println!("{}", output); + match output { + EvaluationOutput::Value(s) => { + self.editor.output(s, counter); + } + EvaluationOutput::Error(s) => { + println!("{}\n", s); + } + }; + counter += 1; } Err(ReadlineError::Interrupted) => { if self.editor.should_exit_on_interrupt() { @@ -92,8 +105,9 @@ async fn read_line_and_poll( repl_session: &mut ReplSession, message_handler: &mut RustylineSyncMessageHandler, editor: ReplEditor, + counter: usize, ) -> Result { - let mut line_fut = spawn_blocking(move || editor.readline()); + let mut line_fut = spawn_blocking(move || editor.readline(counter)); let mut poll_worker = true; let notifications_rc = repl_session.notifications.clone(); let mut notifications = notifications_rc.lock().await; @@ -114,10 +128,29 @@ async fn read_line_and_poll( Some(RustylineSyncMessage::LspCompletions { line_text, position, + explicit, }) => { - let result = repl_session.language_server.completions(&line_text, position).await; + let result = repl_session.language_server.completions(&line_text, position, explicit).await; message_handler.send(RustylineSyncResponse::LspCompletions(result)).unwrap(); } + Some(RustylineSyncMessage::Preview { line_text }) => { + let result = repl_session.evaluate_line_with_object_wrapping(&line_text, true).await; + let result = match result { + Ok(evaluate_response) => { + let cdp::EvaluateResponse { + result, + exception_details, + } = evaluate_response.value; + if exception_details.is_some() { + None + } else { + repl_session.get_eval_value(&result, true).await.ok().map(|s| (s, counter)) + } + }, + _ => None, + }; + message_handler.send(RustylineSyncResponse::Preview(result)).unwrap(); + } None => {}, // channel closed } @@ -217,7 +250,7 @@ pub async fn run( Ok(eval_source) => { let output = repl .session - .evaluate_line_and_get_output(&eval_source) + .evaluate_line_and_get_output(&eval_source, 0) .await; // only output errors if let EvaluationOutput::Error(error_text) = output { @@ -232,7 +265,7 @@ pub async fn run( } if let Some(eval) = repl_flags.eval { - let output = repl.session.evaluate_line_and_get_output(&eval).await; + let output = repl.session.evaluate_line_and_get_output(&eval, 0).await; // only output errors if let EvaluationOutput::Error(error_text) = output { println!("Error in --eval flag: {error_text}"); diff --git a/cli/tools/repl/session.rs b/cli/tools/repl/session.rs index b379c3646a..0fabeda3a3 100644 --- a/cli/tools/repl/session.rs +++ b/cli/tools/repl/session.rs @@ -95,8 +95,6 @@ Object.defineProperty(globalThis, "{0}", {{ enumerable: false, writable: false, value: {{ - lastEvalResult: undefined, - lastThrownError: undefined, inspectArgs: Deno[Deno.internal].inspectArgs, noColor: Deno.noColor, get closed() {{ @@ -104,35 +102,6 @@ Object.defineProperty(globalThis, "{0}", {{ }} }}, }}); -Object.defineProperty(globalThis, "_", {{ - configurable: true, - get: () => {0}.lastEvalResult, - set: (value) => {{ - Object.defineProperty(globalThis, "_", {{ - value: value, - writable: true, - enumerable: true, - configurable: true, - }}); - console.log("Last evaluation result is no longer saved to _."); - }}, -}}); - -Object.defineProperty(globalThis, "_error", {{ - configurable: true, - get: () => {0}.lastThrownError, - set: (value) => {{ - Object.defineProperty(globalThis, "_error", {{ - value: value, - writable: true, - enumerable: true, - configurable: true, - }}); - - console.log("Last thrown error is no longer saved to _error."); - }}, -}}); - globalThis.clear = console.clear.bind(console); "#, *REPL_INTERNALS_NAME @@ -289,7 +258,9 @@ impl ReplSession { }; // inject prelude - repl_session.evaluate_expression(&get_prelude()).await?; + repl_session + .evaluate_expression(&get_prelude(), false) + .await?; Ok(repl_session) } @@ -304,7 +275,7 @@ impl ReplSession { pub async fn closing(&mut self) -> Result { let expression = format!(r#"{}.closed"#, *REPL_INTERNALS_NAME); let closed = self - .evaluate_expression(&expression) + .evaluate_expression(&expression, false) .await? .result .value @@ -343,6 +314,7 @@ impl ReplSession { pub async fn evaluate_line_and_get_output( &mut self, line: &str, + counter: usize, ) -> EvaluationOutput { fn format_diagnostic(diagnostic: &deno_ast::ParseDiagnostic) -> String { let display_position = diagnostic.display_position(); @@ -358,8 +330,12 @@ impl ReplSession { async fn inner( session: &mut ReplSession, line: &str, + counter: usize, ) -> Result { - match session.evaluate_line_with_object_wrapping(line).await { + match session + .evaluate_line_with_object_wrapping(line, false) + .await + { Ok(evaluate_response) => { let cdp::EvaluateResponse { result, @@ -390,8 +366,8 @@ impl ReplSession { .commit_text(&evaluate_response.ts_code) .await; - session.set_last_eval_result(&result).await?; - let value = session.get_eval_value(&result).await?; + session.set_last_eval_result(&result, counter).await?; + let value = session.get_eval_value(&result, false).await?; EvaluationOutput::Value(value) }) } @@ -417,13 +393,14 @@ impl ReplSession { } } - let result = inner(self, line).await; + let result = inner(self, line, counter).await; result_to_evaluation_output(result) } pub async fn evaluate_line_with_object_wrapping( &mut self, line: &str, + throw_on_side_effect: bool, ) -> Result { // Expressions like { "foo": "bar" } are interpreted as block expressions at the // statement level rather than an object literal so we interpret it as an expression statement @@ -436,7 +413,9 @@ impl ReplSession { line.to_string() }; - let evaluate_response = self.evaluate_ts_expression(&wrapped_line).await; + let evaluate_response = self + .evaluate_ts_expression(&wrapped_line, throw_on_side_effect) + .await; // If that fails, we retry it without wrapping in parens letting the error bubble up to the // user if it is still an error. @@ -449,7 +428,9 @@ impl ReplSession { .exception_details .is_some()) { - self.evaluate_ts_expression(line).await + self + .evaluate_ts_expression(line, throw_on_side_effect) + .await } else { evaluate_response }; @@ -486,10 +467,17 @@ impl ReplSession { .post_message_with_event_loop( "Runtime.callFunctionOn", Some(cdp::CallFunctionOnArgs { - function_declaration: format!( - r#"function (object) {{ {}.lastThrownError = object; }}"#, - *REPL_INTERNALS_NAME - ), + function_declaration: r#" + function (object) { + Object.defineProperty(globalThis, '_error', { + value: object, + enumerable: false, + configurable: true, + writable: true, + }); + } + "# + .to_string(), object_id: None, arguments: Some(vec![error.into()]), silent: None, @@ -509,14 +497,25 @@ impl ReplSession { async fn set_last_eval_result( &mut self, evaluate_result: &cdp::RemoteObject, + counter: usize, ) -> Result<(), AnyError> { self .post_message_with_event_loop( "Runtime.callFunctionOn", Some(cdp::CallFunctionOnArgs { function_declaration: format!( - r#"function (object) {{ {}.lastEvalResult = object; }}"#, - *REPL_INTERNALS_NAME + r#"function (object) {{ + const desc = {{ + writable: true, + configurable: true, + enumerable: false, + value: object, + }}; + Object.defineProperties(globalThis, {{ + _: desc, + "_{counter}": desc, + }}); + }}"#, ), object_id: None, arguments: Some(vec![evaluate_result.into()]), @@ -572,6 +571,7 @@ impl ReplSession { pub async fn get_eval_value( &mut self, evaluate_result: &cdp::RemoteObject, + no_color: bool, ) -> Result { // TODO(caspervonb) we should investigate using previews here but to keep things // consistent with the previous implementation we just get the preview result from @@ -581,12 +581,12 @@ impl ReplSession { format!( r#"function (object) {{ try {{ - return {0}.inspectArgs(["%o", object], {{ colors: !{0}.noColor }}); + return {0}.inspectArgs(["%o", object], {{ colors: (!{0}.noColor && !{1}) }}); }} catch (err) {{ return {0}.inspectArgs(["%o", err]); }} }}"#, - *REPL_INTERNALS_NAME + *REPL_INTERNALS_NAME, no_color ), &[evaluate_result.clone()], ) @@ -600,6 +600,7 @@ impl ReplSession { async fn evaluate_ts_expression( &mut self, expression: &str, + throw_on_side_effect: bool, ) -> Result { let parsed_source = match parse_source_as(expression.to_string(), deno_ast::MediaType::Tsx) { @@ -653,7 +654,7 @@ impl ReplSession { .text; let value = self - .evaluate_expression(&format!("'use strict'; void 0;{transpiled_src}")) + .evaluate_expression(&transpiled_src, throw_on_side_effect) .await?; Ok(TsEvaluateResponse { @@ -733,6 +734,7 @@ impl ReplSession { async fn evaluate_expression( &mut self, expression: &str, + throw_on_side_effect: bool, ) -> Result { self .post_message_with_event_loop( @@ -747,8 +749,12 @@ impl ReplSession { generate_preview: None, user_gesture: None, await_promise: None, - throw_on_side_effect: None, - timeout: None, + throw_on_side_effect: Some(throw_on_side_effect), + timeout: if throw_on_side_effect { + Some(100) + } else { + None + }, disable_breaks: None, repl_mode: Some(true), allow_unsafe_eval_blocked_by_csp: None, diff --git a/runtime/ops/tty.rs b/runtime/ops/tty.rs index be22bdd2a4..27df9948c7 100644 --- a/runtime/ops/tty.rs +++ b/runtime/ops/tty.rs @@ -412,7 +412,7 @@ pub fn op_read_line_prompt( let mut editor = Editor::<(), rustyline::history::DefaultHistory>::new() .expect("Failed to create editor."); - editor.set_keyseq_timeout(1); + editor.set_keyseq_timeout(Some(1)); editor .bind_sequence(KeyEvent(KeyCode::Esc, Modifiers::empty()), Cmd::Interrupt);