diff --git a/Cargo.lock b/Cargo.lock index 58538a1e..8c8e9748 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -62,9 +62,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.83" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25bdb32cbbdce2b519a9cd7df3a678443100e265d5e25ca763b7572a5104f5f3" +checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" [[package]] name = "arc-swap" @@ -136,9 +136,9 @@ checksum = "df8670b8c7b9dae1793364eafadf7239c40d669904660c5960d74cfd80b46a53" [[package]] name = "cc" -version = "1.0.97" +version = "1.0.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "099a5357d84c4c61eb35fc8eafa9a79a902c2f76911e5747ced4e032edd8d9b4" +checksum = "96c51067fd44124faa7f870b4b1c969379ad32b2ba805aa959430ceaa384f695" [[package]] name = "cfg-if" @@ -351,6 +351,17 @@ dependencies = [ "parking_lot_core", ] +[[package]] +name = "displaydoc" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + [[package]] name = "dunce" version = "1.0.4" @@ -422,9 +433,9 @@ checksum = "a2a2b11eda1d40935b26cf18f6833c526845ae8c41e58d09af6adeb6f0269183" [[package]] name = "fastrand" -version = "2.0.1" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" +checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" [[package]] name = "fern" @@ -538,9 +549,9 @@ checksum = "b6c80984affa11d98d1b88b66ac8853f143217b399d3c74116778ff8fdb4ed2e" [[package]] name = "gix" -version = "0.62.0" +version = "0.63.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5631c64fb4cd48eee767bf98a3cbc5c9318ef3bb71074d4c099a2371510282b6" +checksum = "984c5018adfa7a4536ade67990b3ebc6e11ab57b3d6cd9968de0947ca99b4b06" dependencies = [ "gix-actor", "gix-attributes", @@ -588,9 +599,9 @@ dependencies = [ [[package]] name = "gix-actor" -version = "0.31.1" +version = "0.31.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45c3a3bde455ad2ee8ba8a195745241ce0b770a8a26faae59fcf409d01b28c46" +checksum = "d69c59d392c7e6c94385b6fd6089d6df0fe945f32b4357687989f3aee253cd7f" dependencies = [ "bstr", "gix-date", @@ -637,9 +648,9 @@ dependencies = [ [[package]] name = "gix-command" -version = "0.3.6" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f90009020dc4b3de47beed28e1334706e0a330ddd17f5cfeb097df3b15a54b77" +checksum = "6c22e086314095c43ffe5cdc5c0922d5439da4fd726f3b0438c56147c34dc225" dependencies = [ "bstr", "gix-path", @@ -663,9 +674,9 @@ dependencies = [ [[package]] name = "gix-config" -version = "0.36.1" +version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7580e05996e893347ad04e1eaceb92e1c0e6a3ffe517171af99bf6b6df0ca6e5" +checksum = "53fafe42957e11d98e354a66b6bd70aeea00faf2f62dd11164188224a507c840" dependencies = [ "bstr", "gix-config-value", @@ -697,9 +708,9 @@ dependencies = [ [[package]] name = "gix-date" -version = "0.8.5" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "180b130a4a41870edfbd36ce4169c7090bca70e195da783dea088dd973daa59c" +checksum = "367ee9093b0c2b04fd04c5c7c8b6a1082713534eab537597ae343663a518fa99" dependencies = [ "bstr", "itoa", @@ -709,9 +720,9 @@ dependencies = [ [[package]] name = "gix-diff" -version = "0.43.0" +version = "0.44.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5fbc24115b957346cd23fb0f47d830eb799c46c89cdcf2f5acc9bf2938c2d01" +checksum = "40b9bd8b2d07b6675a840b56a6c177d322d45fa082672b0dad8f063b25baf0a4" dependencies = [ "bstr", "gix-command", @@ -729,9 +740,9 @@ dependencies = [ [[package]] name = "gix-dir" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6943a1f213ad7a060a0548ece229be53f3c2151534b126446ce3533eaf5f14c" +checksum = "60c99f8c545abd63abe541d20ab6cda347de406c0a3f1c80aadc12d9b0e94974" dependencies = [ "bstr", "gix-discover", @@ -749,9 +760,9 @@ dependencies = [ [[package]] name = "gix-discover" -version = "0.31.0" +version = "0.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64bab49087ed3710caf77e473dc0efc54ca33d8ccc6441359725f121211482b1" +checksum = "fc27c699b63da66b50d50c00668bc0b7e90c3a382ef302865e891559935f3dbf" dependencies = [ "bstr", "dunce", @@ -765,9 +776,9 @@ dependencies = [ [[package]] name = "gix-features" -version = "0.38.1" +version = "0.38.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db4254037d20a247a0367aa79333750146a369719f0c6617fec4f5752cc62b37" +checksum = "ac7045ac9fe5f9c727f38799d002a7ed3583cd777e3322a7c4b43e3cf437dc69" dependencies = [ "crc32fast", "flate2", @@ -784,9 +795,9 @@ dependencies = [ [[package]] name = "gix-filter" -version = "0.11.1" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c0d1f01af62bfd2fb3dd291acc2b29d4ab3e96ad52a679174626508ce98ef12" +checksum = "00ce6ea5ac8fca7adbc63c48a1b9e0492c222c386aa15f513405f1003f2f4ab2" dependencies = [ "bstr", "encoding_rs", @@ -805,10 +816,11 @@ dependencies = [ [[package]] name = "gix-fs" -version = "0.10.2" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2184c40e7910529677831c8b481acf788ffd92427ed21fad65b6aa637e631b8" +checksum = "3f78f7d6dcda7a5809efd73a33b145e3dce7421c460df21f32126f9732736b0c" dependencies = [ + "fastrand", "gix-features", "gix-utils", ] @@ -861,9 +873,9 @@ dependencies = [ [[package]] name = "gix-index" -version = "0.32.0" +version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3383122cf18655ef4c097c0b935bba5eb56983947959aaf3b0ceb1949d4dd371" +checksum = "2d8c5a5f1c58edcbc5692b174cda2703aba82ed17d7176ff4c1752eb48b1b167" dependencies = [ "bitflags 2.5.0", "bstr", @@ -877,6 +889,7 @@ dependencies = [ "gix-object", "gix-traverse", "gix-utils", + "gix-validate", "hashbrown 0.14.5", "itoa", "libc", @@ -888,9 +901,9 @@ dependencies = [ [[package]] name = "gix-lock" -version = "13.0.0" +version = "14.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "651e46174dc5e7d18b7b809d31937b6de3681b1debd78618c99162cc30fcf3e1" +checksum = "e3bc7fe297f1f4614774989c00ec8b1add59571dc9b024b4c00acb7dedd4e19d" dependencies = [ "gix-tempfile", "gix-utils", @@ -899,9 +912,9 @@ dependencies = [ [[package]] name = "gix-macros" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dff438f14e67e7713ab9332f5fd18c8f20eb7eb249494f6c2bf170522224032" +checksum = "999ce923619f88194171a67fb3e6d613653b8d4d6078b529b15a765da0edcc17" dependencies = [ "proc-macro2", "quote", @@ -910,9 +923,9 @@ dependencies = [ [[package]] name = "gix-object" -version = "0.42.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d4f8efae72030df1c4a81d02dbe2348e748d9b9a11e108ed6efbd846326e051" +checksum = "1fe2dc4a41191c680c942e6ebd630c8107005983c4679214fdb1007dcf5ae1df" dependencies = [ "bstr", "gix-actor", @@ -929,9 +942,9 @@ dependencies = [ [[package]] name = "gix-odb" -version = "0.60.0" +version = "0.61.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8bbb43d2fefdc4701ffdf9224844d05b136ae1b9a73c2f90710c8dd27a93503" +checksum = "e92b9790e2c919166865d0825b26cc440a387c175bed1b43a2fa99c0e9d45e98" dependencies = [ "arc-swap", "gix-date", @@ -949,9 +962,9 @@ dependencies = [ [[package]] name = "gix-pack" -version = "0.50.0" +version = "0.51.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b58bad27c7677fa6b587aab3a1aca0b6c97373bd371a0a4290677c838c9bcaf1" +checksum = "7a8da51212dbff944713edb2141ed7e002eea326b8992070374ce13a6cb610b3" dependencies = [ "clru", "gix-chunk", @@ -994,9 +1007,9 @@ dependencies = [ [[package]] name = "gix-pathspec" -version = "0.7.3" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d479789f3abd10f68a709454ce04cd68b54092ee882c8622ae3aa1bb9bf8496c" +checksum = "a76cab098dc10ba2d89f634f66bf196dea4d7db4bf10b75c7a9c201c55a2ee19" dependencies = [ "bitflags 2.5.0", "bstr", @@ -1020,9 +1033,9 @@ dependencies = [ [[package]] name = "gix-ref" -version = "0.43.0" +version = "0.44.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd4aba68b925101cb45d6df328979af0681364579db889098a0de75b36c77b65" +checksum = "0b36752b448647acd59c9668fdd830b16d07db1e6d9c3b3af105c1605a6e23d9" dependencies = [ "gix-actor", "gix-date", @@ -1056,9 +1069,9 @@ dependencies = [ [[package]] name = "gix-revision" -version = "0.27.0" +version = "0.27.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e34196e1969bd5d36e2fbc4467d893999132219d503e23474a8ad2b221cb1e8" +checksum = "63e08f8107ed1f93a83bcfbb4c38084c7cb3f6cd849793f1d5eec235f9b13b2b" dependencies = [ "bstr", "gix-date", @@ -1072,9 +1085,9 @@ dependencies = [ [[package]] name = "gix-revwalk" -version = "0.13.0" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0a7d393ae814eeaae41a333c0ff684b243121cc61ccdc5bbe9897094588047d" +checksum = "4181db9cfcd6d1d0fd258e91569dbb61f94cb788b441b5294dd7f1167a3e788f" dependencies = [ "gix-commitgraph", "gix-date", @@ -1099,9 +1112,9 @@ dependencies = [ [[package]] name = "gix-status" -version = "0.9.0" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50c413bfd2952e4ee92e48438dac3c696f3555e586a34d184a427f6bedd1e4f9" +checksum = "2f4373d989713809554d136f51bc7da565adf45c91aa4d86ef6a79801621bfc8" dependencies = [ "bstr", "filetime", @@ -1121,9 +1134,9 @@ dependencies = [ [[package]] name = "gix-submodule" -version = "0.10.0" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fb7ea05666362472fecd44c1fc35fe48a5b9b841b431cc4f85b95e6f20c23ec" +checksum = "921cd49924ac14b6611b22e5fb7bbba74d8780dc7ad26153304b64d1272460ac" dependencies = [ "bstr", "gix-config", @@ -1136,9 +1149,9 @@ dependencies = [ [[package]] name = "gix-tempfile" -version = "13.0.0" +version = "14.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d337955b7af00fb87120d053d87cdfb422a80b9ff7a3aa4057a99c79422dc30" +checksum = "d3b0e276cd08eb2a22e9f286a4f13a222a01be2defafa8621367515375644b99" dependencies = [ "dashmap", "gix-fs", @@ -1156,9 +1169,9 @@ checksum = "f924267408915fddcd558e3f37295cc7d6a3e50f8bd8b606cee0808c3915157e" [[package]] name = "gix-traverse" -version = "0.39.0" +version = "0.39.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4029ec209b0cc480d209da3837a42c63801dd8548f09c1f4502c60accb62aeb" +checksum = "f20cb69b63eb3e4827939f42c05b7756e3488ef49c25c412a876691d568ee2a0" dependencies = [ "bitflags 2.5.0", "gix-commitgraph", @@ -1198,9 +1211,9 @@ dependencies = [ [[package]] name = "gix-validate" -version = "0.8.4" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e39fc6e06044985eac19dd34d474909e517307582e462b2eb4c8fa51b6241545" +checksum = "82c27dd34a49b1addf193c92070bcbf3beaf6e10f16a78544de6372e146a0acf" dependencies = [ "bstr", "thiserror", @@ -1208,9 +1221,9 @@ dependencies = [ [[package]] name = "gix-worktree" -version = "0.33.0" +version = "0.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "359a87dfef695b5f91abb9a424c947edca82768f34acfc269659f66174a510b4" +checksum = "53f6b7de83839274022aff92157d7505f23debf739d257984a300a35972ca94e" dependencies = [ "bstr", "gix-attributes", @@ -1222,6 +1235,7 @@ dependencies = [ "gix-index", "gix-object", "gix-path", + "gix-validate", ] [[package]] @@ -1570,13 +1584,133 @@ dependencies = [ ] [[package]] -name = "idna" -version = "0.5.0" +name = "icu_collections" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" dependencies = [ - "unicode-bidi", - "unicode-normalization", + "displaydoc", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locid" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_locid_transform" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_locid_transform_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_locid_transform_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e" + +[[package]] +name = "icu_normalizer" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "utf16_iter", + "utf8_iter", + "write16", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516" + +[[package]] +name = "icu_properties" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f8ac670d7422d7f76b32e17a5db556510825b29ec9154f235977c9caba61036" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_locid_transform", + "icu_properties_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569" + +[[package]] +name = "icu_provider" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_provider_macros", + "stable_deref_trait", + "tinystr", + "writeable", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_provider_macros" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "idna" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4716a3a0933a1d01c2f72450e89596eb51dd34ef3c211ccd875acdf1f8fe47ed" +dependencies = [ + "icu_normalizer", + "icu_properties", + "smallvec", + "utf8_iter", ] [[package]] @@ -1666,9 +1800,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.154" +version = "0.2.155" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae743338b92ff9146ce83992f766a31066a91a8c84a45e0e9f21e7cf6de6d346" +checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" [[package]] name = "libloading" @@ -1695,6 +1829,12 @@ version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456" +[[package]] +name = "litemap" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "643cb0b8d4fcc284004d5fd0d67ccf61dfffadb7f75e1e71bc420f4688a3a704" + [[package]] name = "lock_api" version = "0.4.9" @@ -1836,9 +1976,9 @@ checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" [[package]] name = "open" -version = "5.1.2" +version = "5.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "449f0ff855d85ddbf1edd5b646d65249ead3f5e422aaa86b7d2d0b049b103e32" +checksum = "b5ca541f22b1c46d4bb9801014f234758ab4297e7870b904b6a8415b980a7388" dependencies = [ "is-wsl", "libc", @@ -1847,9 +1987,9 @@ dependencies = [ [[package]] name = "parking_lot" -version = "0.12.2" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e4af0ca4f6caed20e900d564c242b8e5d4903fdacf31d3daf527b66fe6f42fb" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" dependencies = [ "lock_api", "parking_lot_core", @@ -1909,9 +2049,9 @@ checksum = "744a264d26b88a6a7e37cbad97953fa233b94d585236310bcbc88474b4092d79" [[package]] name = "pulldown-cmark" -version = "0.10.3" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76979bea66e7875e7509c4ec5300112b316af87fa7a252ca91c448b32dfe3993" +checksum = "8746739f11d39ce5ad5c2520a9b75285310dbfe78c541ccf832d38615765aec0" dependencies = [ "bitflags 2.5.0", "memchr", @@ -1996,9 +2136,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.10.4" +version = "1.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" +checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f" dependencies = [ "aho-corasick", "memchr", @@ -2094,18 +2234,18 @@ checksum = "1792db035ce95be60c3f8853017b3999209281c24e2ba5bc8e59bf97a0c590c1" [[package]] name = "serde" -version = "1.0.201" +version = "1.0.203" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "780f1cebed1629e4753a1a38a3c72d30b97ec044f0aef68cb26650a3c5cf363c" +checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.201" +version = "1.0.203" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5e405930b9796f1c00bee880d03fc7e0bb4b9a11afc776885ffe84320da2865" +checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" dependencies = [ "proc-macro2", "quote", @@ -2136,9 +2276,9 @@ dependencies = [ [[package]] name = "serde_spanned" -version = "0.6.5" +version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1" +checksum = "79e674e01f999af37c49f70a6ede167a8a60b2503e56c5599532a65baa5969a0" dependencies = [ "serde", ] @@ -2248,6 +2388,12 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + [[package]] name = "static_assertions" version = "1.1.0" @@ -2282,6 +2428,17 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "synstructure" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + [[package]] name = "tempfile" version = "3.10.1" @@ -2325,18 +2482,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.60" +version = "1.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "579e9083ca58dd9dcf91a9923bb9054071b9ebbd800b342194c9feb0ee89fc18" +checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.60" +version = "1.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2470041c06ec3ac1ab38d0356a6119054dedaea53e12fbefc0de730a1c08524" +checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" dependencies = [ "proc-macro2", "quote", @@ -2381,6 +2538,16 @@ dependencies = [ "time-core", ] +[[package]] +name = "tinystr" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" +dependencies = [ + "displaydoc", + "zerovec", +] + [[package]] name = "tinyvec" version = "1.6.0" @@ -2398,9 +2565,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.37.0" +version = "1.38.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1adbebffeca75fcfd058afa480fb6c0b81e165a0323f9c9d39c9697e37c46787" +checksum = "ba4f4a02a7a80d6f274636f0aa95c7e383b912d41fe721a31f29e29698585a4a" dependencies = [ "backtrace", "bytes", @@ -2417,9 +2584,9 @@ dependencies = [ [[package]] name = "tokio-macros" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" +checksum = "5f5ae998a069d4b5aba8ee9dad856af7d520c3699e6159b185c2acd48155d39a" dependencies = [ "proc-macro2", "quote", @@ -2439,9 +2606,9 @@ dependencies = [ [[package]] name = "toml" -version = "0.8.12" +version = "0.8.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9dd1545e8208b4a5af1aa9bbd0b4cf7e9ea08fabc5d0a5c67fcaafa17433aa3" +checksum = "6f49eb2ab21d2f26bd6db7bf383edc527a7ebaee412d17af4d40fdccd442f335" dependencies = [ "serde", "serde_spanned", @@ -2451,18 +2618,18 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.6.5" +version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" +checksum = "4badfd56924ae69bcc9039335b2e017639ce3f9b001c393c1b2d1ef846ce2cbf" dependencies = [ "serde", ] [[package]] name = "toml_edit" -version = "0.22.8" +version = "0.22.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c12219811e0c1ba077867254e5ad62ee2c9c190b0d957110750ac0cda1ae96cd" +checksum = "f21c7aaf97f1bd9ca9d4f9e73b0a6c74bd5afef56f2bc931943a6e1c37e04e38" dependencies = [ "indexmap", "serde", @@ -2490,12 +2657,6 @@ dependencies = [ "version_check", ] -[[package]] -name = "unicode-bidi" -version = "0.3.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" - [[package]] name = "unicode-bom" version = "2.0.2" @@ -2543,9 +2704,9 @@ checksum = "68f5e5f3158ecfd4b8ff6fe086db7c8467a2dfdac97fe420f2b7c4aa97af66d6" [[package]] name = "url" -version = "2.5.0" +version = "2.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" +checksum = "f7c25da092f0a868cdf09e8674cd3b7ef3a7d92a24253e663a2fb85e2496de56" dependencies = [ "form_urlencoded", "idna", @@ -2553,6 +2714,18 @@ dependencies = [ "serde", ] +[[package]] +name = "utf16_iter" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" + +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + [[package]] name = "version_check" version = "0.9.4" @@ -2894,6 +3067,18 @@ version = "0.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d135d17ab770252ad95e9a872d365cf3090e3be864a34ab46f48555993efc904" +[[package]] +name = "write16" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" + +[[package]] +name = "writeable" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" + [[package]] name = "xtask" version = "24.3.0" @@ -2905,6 +3090,30 @@ dependencies = [ "toml", ] +[[package]] +name = "yoke" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c5b1314b079b0930c31e3af543d8ee1757b1951ae1e1565ec704403a7240ca5" +dependencies = [ + "serde", + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28cc31741b18cb6f1d5ff12f5b7523e3d6eb0852bbbad19d73905511d9849b95" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", + "synstructure", +] + [[package]] name = "zerocopy" version = "0.7.31" @@ -2924,3 +3133,46 @@ dependencies = [ "quote", "syn 2.0.48", ] + +[[package]] +name = "zerofrom" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91ec111ce797d0e0784a1116d0ddcdbea84322cd79e5d5ad173daeba4f93ab55" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ea7b4a3637ea8669cedf0f1fd5c286a17f3de97b8dd5a70a6c167a1730e63a5" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", + "synstructure", +] + +[[package]] +name = "zerovec" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb2cc8827d6c0994478a15c53f374f46fbd41bea663d809b14744bc42e6b109c" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97cf56601ee5052b4417d90c8755c6683473c926039908196cf35d99f893ebe7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] diff --git a/book/src/editor.md b/book/src/editor.md index 88541a7b..ba03e90e 100644 --- a/book/src/editor.md +++ b/book/src/editor.md @@ -32,7 +32,6 @@ ### `[editor]` Section | `gutters` | Gutters to display: Available are `diagnostics` and `diff` and `line-numbers` and `spacer`, note that `diagnostics` also includes other features like breakpoints, 1-width padding will be inserted if gutters is non-empty | `["diagnostics", "spacer", "line-numbers", "spacer", "diff"]` | | `auto-completion` | Enable automatic pop up of auto-completion | `true` | | `auto-format` | Enable automatic formatting on save | `true` | -| `auto-save` | Enable automatic saving on the focus moving away from Helix. Requires [focus event support](https://github.com/helix-editor/helix/wiki/Terminal-Support) from your terminal | `false` | | `idle-timeout` | Time in milliseconds since last keypress before idle timers trigger. | `250` | | `completion-timeout` | Time in milliseconds after typing a word character before completions are shown, set to 5 for instant. | `250` | | `preview-completion-insert` | Whether to apply completion item instantly when selected | `true` | @@ -222,6 +221,16 @@ ### `[editor.auto-pairs]` Section '<' = '>' ``` +### `[editor.auto-save]` Section + +Control auto save behavior. + +| Key | Description | Default | +|--|--|---------| +| `focus-lost` | Enable automatic saving on the focus moving away from Helix. Requires [focus event support](https://github.com/helix-editor/helix/wiki/Terminal-Support) from your terminal | `false` | +| `after-delay.enable` | Enable automatic saving after `auto-save.after-delay.timeout` milliseconds have passed since last edit. | `false` | +| `after-delay.timeout` | Time in milliseconds since last edit before auto save timer triggers. | `3000` | + ### `[editor.search]` Section Search specific options. diff --git a/book/src/generated/lang-support.md b/book/src/generated/lang-support.md index d013f201..5afde097 100644 --- a/book/src/generated/lang-support.md +++ b/book/src/generated/lang-support.md @@ -42,6 +42,7 @@ | edoc | ✓ | | | | | eex | ✓ | | | | | ejs | ✓ | | | | +| elisp | ✓ | | | | | elixir | ✓ | ✓ | ✓ | `elixir-ls` | | elm | ✓ | ✓ | | `elm-language-server` | | elvish | ✓ | | | `elvish` | @@ -189,7 +190,7 @@ | supercollider | ✓ | | | | | svelte | ✓ | | ✓ | `svelteserver` | | sway | ✓ | ✓ | ✓ | `forc` | -| swift | ✓ | | | `sourcekit-lsp` | +| swift | ✓ | ✓ | | `sourcekit-lsp` | | t32 | ✓ | | | | | tablegen | ✓ | ✓ | ✓ | | | tact | ✓ | ✓ | ✓ | | diff --git a/flake.nix b/flake.nix index e113d94b..c230dc31 100644 --- a/flake.nix +++ b/flake.nix @@ -114,10 +114,7 @@ if pkgs.stdenv.isLinux then pkgs.stdenv else pkgs.clangStdenv; - rustFlagsEnv = - if stdenv.isLinux - then ''$RUSTFLAGS -C link-arg=-fuse-ld=lld -C target-cpu=native -Clink-arg=-Wl,--no-rosegment'' - else "$RUSTFLAGS"; + rustFlagsEnv = pkgs.lib.optionalString stdenv.isLinux "-C link-arg=-fuse-ld=lld -C target-cpu=native -Clink-arg=-Wl,--no-rosegment"; rustToolchain = pkgs.pkgsBuildHost.rust-bin.fromRustupToolchainFile ./rust-toolchain.toml; craneLibMSRV = (crane.mkLib pkgs).overrideToolchain rustToolchain; craneLibStable = (crane.mkLib pkgs).overrideToolchain pkgs.pkgsBuildHost.rust-bin.stable.latest.default; @@ -183,7 +180,7 @@ shellHook = '' export HELIX_RUNTIME="$PWD/runtime" export RUST_BACKTRACE="1" - export RUSTFLAGS="${rustFlagsEnv}" + export RUSTFLAGS="''${RUSTFLAGS:-""} ${rustFlagsEnv}" ''; }; }) diff --git a/helix-dap/src/types.rs b/helix-dap/src/types.rs index bbaf53a6..9cec05e6 100644 --- a/helix-dap/src/types.rs +++ b/helix-dap/src/types.rs @@ -1,4 +1,4 @@ -use serde::{Deserialize, Serialize}; +use serde::{Deserialize, Deserializer, Serialize}; use serde_json::Value; use std::collections::HashMap; use std::path::PathBuf; @@ -311,7 +311,8 @@ pub struct Variable { #[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)] #[serde(rename_all = "camelCase")] pub struct Module { - pub id: String, // TODO: || number + #[serde(deserialize_with = "from_number")] + pub id: String, pub name: String, #[serde(skip_serializing_if = "Option::is_none")] pub path: Option, @@ -331,6 +332,23 @@ pub struct Module { pub address_range: Option, } +fn from_number<'de, D>(deserializer: D) -> Result +where + D: Deserializer<'de>, +{ + #[derive(Deserialize)] + #[serde(untagged)] + enum NumberOrString { + Number(i64), + String(String), + } + + match NumberOrString::deserialize(deserializer)? { + NumberOrString::Number(n) => Ok(n.to_string()), + NumberOrString::String(s) => Ok(s), + } +} + pub mod requests { use super::*; #[derive(Debug, Default, PartialEq, Eq, Clone, Deserialize, Serialize)] @@ -887,4 +905,18 @@ pub struct Memory { pub offset: usize, pub count: usize, } + + #[test] + fn test_deserialize_module_id_from_number() { + let raw = r#"{"id": 0, "name": "Name"}"#; + let module: super::Module = serde_json::from_str(raw).expect("Error!"); + assert_eq!(module.id, "0"); + } + + #[test] + fn test_deserialize_module_id_from_string() { + let raw = r#"{"id": "0", "name": "Name"}"#; + let module: super::Module = serde_json::from_str(raw).expect("Error!"); + assert_eq!(module.id, "0"); + } } diff --git a/helix-loader/build.rs b/helix-loader/build.rs index a4562c00..ea068983 100644 --- a/helix-loader/build.rs +++ b/helix-loader/build.rs @@ -50,6 +50,7 @@ fn main() { .ok() .filter(|output| output.status.success()) .and_then(|x| String::from_utf8(x.stdout).ok()) + .map(|x| x.trim().to_string()) else { return; }; @@ -67,6 +68,7 @@ fn main() { .ok() .filter(|output| output.status.success()) .and_then(|x| String::from_utf8(x.stdout).ok()) + .map(|x| x.trim().to_string()) else { return; }; diff --git a/helix-lsp/Cargo.toml b/helix-lsp/Cargo.toml index b1b26734..c6c94b84 100644 --- a/helix-lsp/Cargo.toml +++ b/helix-lsp/Cargo.toml @@ -27,8 +27,8 @@ lsp-types = { version = "0.95" } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" thiserror = "1.0" -tokio = { version = "1.37", features = ["rt", "rt-multi-thread", "io-util", "io-std", "time", "process", "macros", "fs", "parking_lot", "sync"] } +tokio = { version = "1.38", features = ["rt", "rt-multi-thread", "io-util", "io-std", "time", "process", "macros", "fs", "parking_lot", "sync"] } tokio-stream = "0.1.15" -parking_lot = "0.12.2" +parking_lot = "0.12.3" arc-swap = "1" slotmap.workspace = true diff --git a/helix-term/Cargo.toml b/helix-term/Cargo.toml index e67a0389..2bad11b8 100644 --- a/helix-term/Cargo.toml +++ b/helix-term/Cargo.toml @@ -53,13 +53,13 @@ log = "0.4" nucleo.workspace = true ignore = "0.4" # markdown doc rendering -pulldown-cmark = { version = "0.10", default-features = false } +pulldown-cmark = { version = "0.11", default-features = false } # file type detection content_inspector = "0.2.4" # opening URLs -open = "5.1.2" -url = "2.5.0" +open = "5.1.4" +url = "2.5.1" # config toml = "0.8" @@ -73,7 +73,7 @@ grep-searcher = "0.1.13" [target.'cfg(not(windows))'.dependencies] # https://github.com/vorner/signal-hook/issues/100 signal-hook-tokio = { version = "0.3", features = ["futures-v0_3"] } -libc = "0.2.154" +libc = "0.2.155" [target.'cfg(target_os = "macos")'.dependencies] crossterm = { version = "0.27", features = ["event-stream", "use-dev-tty"] } diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index 3dacb5c8..b647b760 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -26,7 +26,7 @@ history::UndoKind, increment, indent, indent::IndentStyle, - line_ending::{get_line_ending_of_str, line_end_char_index, str_is_line_ending}, + line_ending::{get_line_ending_of_str, line_end_char_index}, match_brackets, movement::{self, move_vertically_visual, Direction}, object, pos_at_coords, @@ -142,6 +142,17 @@ pub fn callback( pub fn count(&self) -> usize { self.count.map_or(1, |v| v.get()) } + + /// Waits on all pending jobs, and then tries to flush all pending write + /// operations for all documents. + pub fn block_try_flush_writes(&mut self) -> anyhow::Result<()> { + compositor::Context { + editor: self.editor, + jobs: self.jobs, + scroll: None, + } + .block_try_flush_writes() + } } #[inline] @@ -326,7 +337,7 @@ pub fn doc(&self) -> &str { append_mode, "Append after selection", command_mode, "Enter command mode", file_picker, "Open file picker", - file_picker_in_current_buffer_directory, "Open file picker at current buffers's directory", + file_picker_in_current_buffer_directory, "Open file picker at current buffer's directory", file_picker_in_current_directory, "Open file picker at current working directory", code_action, "Perform code action", buffer_picker, "Open buffer picker", @@ -1594,19 +1605,11 @@ fn replace(cx: &mut Context) { if let Some(ch) = ch { let transaction = Transaction::change_by_selection(doc.text(), selection, |range| { if !range.is_empty() { - let text: String = + let text: Tendril = RopeGraphemes::new(doc.text().slice(range.from()..range.to())) - .map(|g| { - let cow: Cow = g.into(); - if str_is_line_ending(&cow) { - cow - } else { - ch.into() - } - }) + .map(|_g| ch) .collect(); - - (range.from(), range.to(), Some(text.into())) + (range.from(), range.to(), Some(text)) } else { // No change. (range.from(), range.to(), None) @@ -5832,7 +5835,10 @@ fn shell_prompt(cx: &mut Context, prompt: Cow<'static, str>, behavior: ShellBeha fn suspend(_cx: &mut Context) { #[cfg(not(windows))] - signal_hook::low_level::raise(signal_hook::consts::signal::SIGTSTP).unwrap(); + { + _cx.block_try_flush_writes().ok(); + signal_hook::low_level::raise(signal_hook::consts::signal::SIGTSTP).unwrap(); + } } fn add_newline_above(cx: &mut Context) { diff --git a/helix-term/src/commands/lsp.rs b/helix-term/src/commands/lsp.rs index e7ba9f0f..d585e1be 100644 --- a/helix-term/src/commands/lsp.rs +++ b/helix-term/src/commands/lsp.rs @@ -1029,11 +1029,12 @@ fn get_prefill_from_lsp_response( fn create_rename_prompt( editor: &Editor, prefill: String, + history_register: Option, language_server_id: Option, ) -> Box { let prompt = ui::Prompt::new( "rename-to:".into(), - None, + history_register, ui::completers::none, move |cx: &mut compositor::Context, input: &str, event: PromptEvent| { if event != PromptEvent::Validate { @@ -1070,6 +1071,7 @@ fn create_rename_prompt( } let (view, doc) = current_ref!(cx.editor); + let history_register = cx.register; if doc .language_servers_with_feature(LanguageServerFeature::RenameSymbol) @@ -1112,14 +1114,14 @@ fn create_rename_prompt( } }; - let prompt = create_rename_prompt(editor, prefill, Some(ls_id)); + let prompt = create_rename_prompt(editor, prefill, history_register, Some(ls_id)); compositor.push(prompt); }, ); } else { let prefill = get_prefill_from_word_boundary(cx.editor); - let prompt = create_rename_prompt(cx.editor, prefill, None); + let prompt = create_rename_prompt(cx.editor, prefill, history_register, None); cx.push_layer(prompt); } } diff --git a/helix-term/src/commands/typed.rs b/helix-term/src/commands/typed.rs index b6182f8a..652106bd 100644 --- a/helix-term/src/commands/typed.rs +++ b/helix-term/src/commands/typed.rs @@ -1495,6 +1495,8 @@ fn lsp_stop( for doc in cx.editor.documents_mut() { if let Some(client) = doc.remove_language_server_by_name(ls_name) { doc.clear_diagnostics(Some(client.id())); + doc.reset_all_inlay_hints(); + doc.inlay_hints_oudated = true; } } } diff --git a/helix-term/src/handlers.rs b/helix-term/src/handlers.rs index d45809d3..fc927313 100644 --- a/helix-term/src/handlers.rs +++ b/helix-term/src/handlers.rs @@ -5,12 +5,14 @@ use crate::config::Config; use crate::events; +use crate::handlers::auto_save::AutoSaveHandler; use crate::handlers::completion::CompletionHandler; use crate::handlers::signature_help::SignatureHelpHandler; pub use completion::trigger_auto_completion; pub use helix_view::handlers::Handlers; +mod auto_save; pub mod completion; mod signature_help; @@ -19,11 +21,16 @@ pub fn setup(config: Arc>) -> Handlers { let completions = CompletionHandler::new(config).spawn(); let signature_hints = SignatureHelpHandler::new().spawn(); + let auto_save = AutoSaveHandler::new().spawn(); + let handlers = Handlers { completions, signature_hints, + auto_save, }; + completion::register_hooks(&handlers); signature_help::register_hooks(&handlers); + auto_save::register_hooks(&handlers); handlers } diff --git a/helix-term/src/handlers/auto_save.rs b/helix-term/src/handlers/auto_save.rs new file mode 100644 index 00000000..d3f7f6fc --- /dev/null +++ b/helix-term/src/handlers/auto_save.rs @@ -0,0 +1,61 @@ +use std::time::Duration; + +use anyhow::Ok; +use arc_swap::access::Access; + +use helix_event::{register_hook, send_blocking}; +use helix_view::{events::DocumentDidChange, handlers::Handlers, Editor}; +use tokio::time::Instant; + +use crate::{ + commands, compositor, + job::{self, Jobs}, +}; + +#[derive(Debug)] +pub(super) struct AutoSaveHandler; + +impl AutoSaveHandler { + pub fn new() -> AutoSaveHandler { + AutoSaveHandler + } +} + +impl helix_event::AsyncHook for AutoSaveHandler { + type Event = u64; + + fn handle_event( + &mut self, + timeout: Self::Event, + _: Option, + ) -> Option { + Some(Instant::now() + Duration::from_millis(timeout)) + } + + fn finish_debounce(&mut self) { + job::dispatch_blocking(move |editor, _| request_auto_save(editor)) + } +} + +fn request_auto_save(editor: &mut Editor) { + let context = &mut compositor::Context { + editor, + scroll: Some(0), + jobs: &mut Jobs::new(), + }; + + if let Err(e) = commands::typed::write_all_impl(context, false, false) { + context.editor.set_error(format!("{}", e)); + } +} + +pub(super) fn register_hooks(handlers: &Handlers) { + let tx = handlers.auto_save.clone(); + register_hook!(move |event: &mut DocumentDidChange<'_>| { + let config = event.doc.config.load(); + if config.auto_save.after_delay.enable { + send_blocking(&tx, config.auto_save.after_delay.timeout); + } + Ok(()) + }); +} diff --git a/helix-term/src/handlers/completion/resolve.rs b/helix-term/src/handlers/completion/resolve.rs index 6b70e52c..0b2c9067 100644 --- a/helix-term/src/handlers/completion/resolve.rs +++ b/helix-term/src/handlers/completion/resolve.rs @@ -42,10 +42,30 @@ pub fn ensure_item_resolved(&mut self, editor: &mut Editor, item: &mut Completio if item.resolved { return; } - let needs_resolve = item.item.documentation.is_none() - || item.item.detail.is_none() - || item.item.additional_text_edits.is_none(); - if !needs_resolve { + // We consider an item to be fully resolved if it has non-empty, none-`None` details, + // docs and additional text-edits. Ideally we could use `is_some` instead of this + // check but some language servers send values like `Some([])` for additional text + // edits although the items need to be resolved. This is probably a consequence of + // how `null` works in the JavaScript world. + let is_resolved = item + .item + .documentation + .as_ref() + .is_some_and(|docs| match docs { + lsp::Documentation::String(text) => !text.is_empty(), + lsp::Documentation::MarkupContent(markup) => !markup.value.is_empty(), + }) + && item + .item + .detail + .as_ref() + .is_some_and(|detail| !detail.is_empty()) + && item + .item + .additional_text_edits + .as_ref() + .is_some_and(|edits| !edits.is_empty()); + if is_resolved { item.resolved = true; return; } diff --git a/helix-term/src/ui/editor.rs b/helix-term/src/ui/editor.rs index 97f90f62..a071bfaa 100644 --- a/helix-term/src/ui/editor.rs +++ b/helix-term/src/ui/editor.rs @@ -938,7 +938,11 @@ fn command_mode(&mut self, mode: Mode, cxt: &mut commands::Context, event: KeyEv // If the count is already started and the input is a number, always continue the count. (key!(i @ '0'..='9'), Some(count)) => { let i = i.to_digit(10).unwrap() as usize; - cxt.editor.count = NonZeroUsize::new(count.get() * 10 + i); + let count = count.get() * 10 + i; + if count > 100_000_000 { + return; + } + cxt.editor.count = NonZeroUsize::new(count); } // A non-zero digit will start the count if that number isn't used by a keymap. (key!(i @ '1'..='9'), None) if !self.keymaps.contains_key(mode, event) => { @@ -1451,7 +1455,7 @@ fn handle_event( EventResult::Consumed(None) } Event::FocusLost => { - if context.editor.config().auto_save { + if context.editor.config().auto_save.focus_lost { if let Err(e) = commands::typed::write_all_impl(context, false, false) { context.editor.set_error(format!("{}", e)); } diff --git a/helix-term/tests/test/commands.rs b/helix-term/tests/test/commands.rs index 1c5c6196..7f41a221 100644 --- a/helix-term/tests/test/commands.rs +++ b/helix-term/tests/test/commands.rs @@ -722,5 +722,19 @@ fn foo() { )) .await?; + test(( + indoc! {"\ + #[a + b + c + d + e|]# + f + "}, + "s\\nr,", + "a#[,|]#b#(,|)#c#(,|)#d#(,|)#e\nf\n", + )) + .await?; + Ok(()) } diff --git a/helix-tui/src/backend/crossterm.rs b/helix-tui/src/backend/crossterm.rs index c5c95bff..0e60e386 100644 --- a/helix-tui/src/backend/crossterm.rs +++ b/helix-tui/src/backend/crossterm.rs @@ -23,13 +23,33 @@ fmt, io::{self, Write}, }; +use termini::TermInfo; fn term_program() -> Option { - std::env::var("TERM_PROGRAM").ok() + // Some terminals don't set $TERM_PROGRAM + match std::env::var("TERM_PROGRAM") { + Err(_) => std::env::var("TERM").ok(), + Ok(term_program) => Some(term_program), + } } fn vte_version() -> Option { std::env::var("VTE_VERSION").ok()?.parse().ok() } +fn reset_cursor_approach(terminfo: TermInfo) -> String { + let mut reset_str = "\x1B[0 q".to_string(); + + if let Some(termini::Value::Utf8String(se_str)) = terminfo.extended_cap("Se") { + reset_str.push_str(se_str); + }; + + reset_str.push_str( + terminfo + .utf8_string_cap(termini::StringCapability::CursorNormal) + .unwrap_or(""), + ); + + reset_str +} /// Describes terminal capabilities like extended underline, truecolor, etc. #[derive(Clone, Debug)] @@ -63,16 +83,13 @@ pub fn from_env_or_default(config: &EditorConfig) -> Self { Ok(t) => Capabilities { // Smulx, VTE: https://unix.stackexchange.com/a/696253/246284 // Su (used by kitty): https://sw.kovidgoyal.net/kitty/underlines - // WezTerm supports underlines but a lot of distros don't properly install it's terminfo + // WezTerm supports underlines but a lot of distros don't properly install its terminfo has_extended_underlines: config.undercurl || t.extended_cap("Smulx").is_some() || t.extended_cap("Su").is_some() || vte_version() >= Some(5102) || matches!(term_program().as_deref(), Some("WezTerm")), - reset_cursor_command: t - .utf8_string_cap(termini::StringCapability::CursorNormal) - .unwrap_or("\x1B[0 q") - .to_string(), + reset_cursor_command: reset_cursor_approach(t), }, } } diff --git a/helix-tui/src/buffer.rs b/helix-tui/src/buffer.rs index 6126c249..d28c32fc 100644 --- a/helix-tui/src/buffer.rs +++ b/helix-tui/src/buffer.rs @@ -734,13 +734,16 @@ fn buffer_set_string_zero_width() { let area = Rect::new(0, 0, 1, 1); let mut buffer = Buffer::empty(area); + // U+200B is the zero-width space codepoint + assert_eq!("\u{200B}".width(), 0); + // Leading grapheme with zero width - let s = "\u{1}a"; + let s = "\u{200B}a"; buffer.set_stringn(0, 0, s, 1, Style::default()); assert_eq!(buffer, Buffer::with_lines(vec!["a"])); - // Trailing grapheme with zero with - let s = "a\u{1}"; + // Trailing grapheme with zero width + let s = "a\u{200B}"; buffer.set_stringn(0, 0, s, 1, Style::default()); assert_eq!(buffer, Buffer::with_lines(vec!["a"])); } diff --git a/helix-vcs/Cargo.toml b/helix-vcs/Cargo.toml index a9529cea..9d6c9a73 100644 --- a/helix-vcs/Cargo.toml +++ b/helix-vcs/Cargo.toml @@ -19,7 +19,7 @@ tokio = { version = "1", features = ["rt", "rt-multi-thread", "time", "sync", "p parking_lot = "0.12" arc-swap = { version = "1.7.1" } -gix = { version = "0.62.0", features = ["attributes", "status"], default-features = false, optional = true } +gix = { version = "0.63.0", features = ["attributes", "status"], default-features = false, optional = true } imara-diff = "0.1.5" anyhow = "1" diff --git a/helix-view/Cargo.toml b/helix-view/Cargo.toml index 41ac6f52..987746a2 100644 --- a/helix-view/Cargo.toml +++ b/helix-view/Cargo.toml @@ -32,7 +32,7 @@ tempfile = "3.9" # Conversion traits once_cell = "1.19" -url = "2.5.0" +url = "2.5.1" arc-swap = { version = "1.7.1" } @@ -49,7 +49,7 @@ serde_json = "1.0" toml = "0.8" log = "~0.4" -parking_lot = "0.12.2" +parking_lot = "0.12.3" [target.'cfg(windows)'.dependencies] diff --git a/helix-view/src/editor.rs b/helix-view/src/editor.rs index 5540c518..635f7261 100644 --- a/helix-view/src/editor.rs +++ b/helix-view/src/editor.rs @@ -55,6 +55,8 @@ ArcSwap, }; +pub const DEFAULT_AUTO_SAVE_DELAY: u64 = 3000; + fn deserialize_duration_millis<'de, D>(deserializer: D) -> Result where D: serde::Deserializer<'de>, @@ -266,8 +268,11 @@ pub struct Config { pub auto_completion: bool, /// Automatic formatting on save. Defaults to true. pub auto_format: bool, - /// Automatic save on focus lost. Defaults to false. - pub auto_save: bool, + /// Automatic save on focus lost and/or after delay. + /// Time delay in milliseconds since last edit after which auto save timer triggers. + /// Time delay defaults to false with 3000ms delay. Focus lost defaults to false. + #[serde(deserialize_with = "deserialize_auto_save")] + pub auto_save: AutoSave, /// Set a global text_width pub text_width: usize, /// Time in milliseconds since last keypress before idle timers trigger. @@ -771,6 +776,61 @@ pub fn newline(&self) -> WhitespaceRenderValue { } } +#[derive(Debug, Default, Clone, PartialEq, Eq, Deserialize, Serialize)] +#[serde(rename_all = "kebab-case")] +pub struct AutoSave { + /// Auto save after a delay in milliseconds. Defaults to disabled. + #[serde(default)] + pub after_delay: AutoSaveAfterDelay, + /// Auto save on focus lost. Defaults to false. + #[serde(default)] + pub focus_lost: bool, +} + +#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)] +#[serde(deny_unknown_fields)] +pub struct AutoSaveAfterDelay { + #[serde(default)] + /// Enable auto save after delay. Defaults to false. + pub enable: bool, + #[serde(default = "default_auto_save_delay")] + /// Time delay in milliseconds. Defaults to [DEFAULT_AUTO_SAVE_DELAY]. + pub timeout: u64, +} + +impl Default for AutoSaveAfterDelay { + fn default() -> Self { + Self { + enable: false, + timeout: DEFAULT_AUTO_SAVE_DELAY, + } + } +} + +fn default_auto_save_delay() -> u64 { + DEFAULT_AUTO_SAVE_DELAY +} + +fn deserialize_auto_save<'de, D>(deserializer: D) -> Result +where + D: serde::Deserializer<'de>, +{ + #[derive(Deserialize, Serialize)] + #[serde(untagged, deny_unknown_fields, rename_all = "kebab-case")] + enum AutoSaveToml { + EnableFocusLost(bool), + AutoSave(AutoSave), + } + + match AutoSaveToml::deserialize(deserializer)? { + AutoSaveToml::EnableFocusLost(focus_lost) => Ok(AutoSave { + focus_lost, + ..Default::default() + }), + AutoSaveToml::AutoSave(auto_save) => Ok(auto_save), + } +} + #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] #[serde(default)] pub struct WhitespaceCharacters { @@ -881,7 +941,7 @@ fn default() -> Self { auto_pairs: AutoPairConfig::default(), auto_completion: true, auto_format: true, - auto_save: false, + auto_save: AutoSave::default(), idle_timeout: Duration::from_millis(250), completion_timeout: Duration::from_millis(250), preview_completion_insert: true, @@ -1356,6 +1416,7 @@ pub fn refresh_doc_language(&mut self, doc_id: DocumentId) { let doc = doc_mut!(self, &doc_id); let diagnostics = Editor::doc_diagnostics(&self.language_servers, &self.diagnostics, doc); doc.replace_diagnostics(diagnostics, &[], None); + doc.reset_all_inlay_hints(); } /// Launch a language server for a given document diff --git a/helix-view/src/handlers.rs b/helix-view/src/handlers.rs index 724e7b19..352abb88 100644 --- a/helix-view/src/handlers.rs +++ b/helix-view/src/handlers.rs @@ -11,6 +11,7 @@ pub struct Handlers { // only public because most of the actual implementation is in helix-term right now :/ pub completions: Sender, pub signature_hints: Sender, + pub auto_save: Sender, } impl Handlers { diff --git a/languages.toml b/languages.toml index 8776947a..436937cd 100644 --- a/languages.toml +++ b/languages.toml @@ -223,7 +223,7 @@ mode = "location" [[language]] name = "rust" scope = "source.rust" -injection-regex = "rust" +injection-regex = "rs|rust" file-types = ["rs"] roots = ["Cargo.toml", "Cargo.lock"] shebangs = ["rust-script", "cargo"] @@ -824,7 +824,7 @@ source = { git = "https://github.com/tree-sitter/tree-sitter-html", rev = "29f53 [[language]] name = "python" scope = "source.python" -injection-regex = "python" +injection-regex = "py(thon)?" file-types = ["py", "pyi", "py3", "pyw", "ptl", "rpy", "cpy", "ipy", "pyt", { glob = ".python_history" }, { glob = ".pythonstartup" }, { glob = ".pythonrc" }, { glob = "SConstruct" }, { glob = "SConscript" }] shebangs = ["python"] roots = ["pyproject.toml", "setup.py", "poetry.lock", "pyrightconfig.json"] @@ -1265,7 +1265,7 @@ source = { git = "https://github.com/ikatyang/tree-sitter-yaml", rev = "0e36bed1 [[language]] name = "haskell" scope = "source.haskell" -injection-regex = "haskell" +injection-regex = "hs|haskell" file-types = ["hs", "hs-boot"] roots = ["Setup.hs", "stack.yaml", "cabal.project"] comment-token = "--" @@ -1908,16 +1908,17 @@ language-servers = [ "r" ] name = "swift" scope = "source.swift" injection-regex = "swift" -file-types = ["swift"] +file-types = ["swift", "swiftinterface"] roots = [ "Package.swift" ] comment-token = "//" block-comment-tokens = { start = "/*", end = "*/" } +formatter = { command = "swift-format", args = [ "--configuration", ".swift-format"] } auto-format = true language-servers = [ "sourcekit-lsp" ] [[grammar]] name = "swift" -source = { git = "https://github.com/alex-pinkus/tree-sitter-swift", rev = "b1b66955d420d5cf5ff268ae552f0d6e43ff66e1" } +source = { git = "https://github.com/alex-pinkus/tree-sitter-swift", rev = "57c1c6d6ffa1c44b330182d41717e6fe37430704" } [[language]] name = "erb" @@ -2073,9 +2074,12 @@ file-types = ["cairo"] comment-token = "//" indent = { tab-width = 4, unit = " " } # auto-format = true -grammar = "rust" language-servers = [ "cairo-language-server" ] +[[grammar]] +name = "cairo" +source = { git = "https://github.com/starkware-libs/tree-sitter-cairo", rev = "0596baab741ffacdc65c761d5d5ffbbeae97f033" } + [[language]] name = "cpon" scope = "scope.cpon" @@ -2721,7 +2725,7 @@ formatter = { command = "inko", args = ["fmt", "-"] } [[grammar]] name = "inko" -source = { git = "https://github.com/inko-lang/tree-sitter-inko", rev = "6983354c13a14bc621d7a3619f1790149e901187" } +source = { git = "https://github.com/inko-lang/tree-sitter-inko", rev = "7860637ce1b43f5f79cfb7cc3311bf3234e9479f" } [[language]] name = "bicep" @@ -3155,7 +3159,7 @@ grammar = "html" [[language]] name = "typst" scope = "source.typst" -injection-regex = "typst" +injection-regex = "typ(st)?" file-types = ["typst", "typ"] comment-token = "//" language-servers = ["tinymist", "typst-lsp"] @@ -3565,7 +3569,7 @@ language-servers = ["earthlyls"] [[grammar]] name = "earthfile" -source = { git = "https://github.com/glehmann/tree-sitter-earthfile", rev = "a079e6c472eeedd6b9a1e03ca0b6c82cd6a112a4" } +source = { git = "https://github.com/glehmann/tree-sitter-earthfile", rev = "dbfb970a59cd87b628d087eb8e3fbe19c8e20601" } [[language]] name = "adl" @@ -3641,6 +3645,20 @@ language-servers = ["pest-language-server"] name = "pest" source = { git = "https://github.com/pest-parser/tree-sitter-pest", rev = "a8a98a824452b1ec4da7f508386a187a2f234b85" } +[[language]] +name = "elisp" +scope = "source.elisp" +file-types = ["el"] +comment-tokens = [";"] + +[language.auto-pairs] +'(' = ')' +'"' = '"' + +[[grammar]] +name = "elisp" +source = { git = "https://github.com/Wilfred/tree-sitter-elisp", rev = "e5524fdccf8c22fc726474a910e4ade976dfc7bb" } + [[language]] name = "gjs" scope = "source.gjs" diff --git a/runtime/queries/cairo/highlights.scm b/runtime/queries/cairo/highlights.scm index ae55c7fa..d2cabd1c 100644 --- a/runtime/queries/cairo/highlights.scm +++ b/runtime/queries/cairo/highlights.scm @@ -1 +1,362 @@ -; inherits: rust +; ------- +; Tree-Sitter doesn't allow overrides in regards to captures, +; though it is possible to affect the child node of a captured +; node. Thus, the approach here is to flip the order so that +; overrides are unnecessary. +; ------- + +; ------- +; Types +; ------- + +(type_parameters + (type_identifier) @type.parameter) +(constrained_type_parameter + left: (type_identifier) @type.parameter) + +; --- +; Primitives +; --- + +(primitive_type) @type.builtin +(boolean_literal) @constant.builtin.boolean +(numeric_literal) @constant.numeric.integer +[ + (string_literal) + (shortstring_literal) +] @string +[ + (line_comment) +] @comment + +; --- +; Extraneous +; --- + +(enum_variant (identifier) @type.enum.variant) + +(field_initializer + (field_identifier) @variable.other.member) +(shorthand_field_initializer + (identifier) @variable.other.member) +(shorthand_field_identifier) @variable.other.member + + +; --- +; Punctuation +; --- + +[ + "::" + "." + ";" + "," +] @punctuation.delimiter + +[ + "(" + ")" + "[" + "]" + "{" + "}" +] @punctuation.bracket +(type_arguments + [ + "<" + ">" + ] @punctuation.bracket) +(type_parameters + [ + "<" + ">" + ] @punctuation.bracket) + +; --- +; Variables +; --- + +(let_declaration + pattern: [ + ((identifier) @variable) + ((tuple_pattern + (identifier) @variable)) + ]) + +; It needs to be anonymous to not conflict with `call_expression` further below. +(_ + value: (field_expression + value: (identifier)? @variable + field: (field_identifier) @variable.other.member)) + +(parameter + pattern: (identifier) @variable.parameter) + +; ------- +; Keywords +; ------- +[ + "match" + "if" + "else" +] @keyword.control.conditional + +[ + "while" + "loop" +] @keyword.control.repeat + +[ + "break" + "continue" + "return" +] @keyword.control.return + +"use" @keyword.control.import +(mod_item "mod" @keyword.control.import !body) +(use_as_clause "as" @keyword.control.import) + + +[ + (crate) + (super) + "as" + "pub" + "mod" + (extern) + (nopanic) + + "impl" + "trait" + "of" + + "default" +] @keyword + +[ + "struct" + "enum" + "type" +] @keyword.storage.type + +"let" @keyword.storage +"fn" @keyword.function + +(mutable_specifier) @keyword.storage.modifier.mut +(ref_specifier) @keyword.storage.modifier.ref + +(snapshot_type "@" @keyword.storage.modifier.ref) + +[ + "const" + "ref" +] @keyword.storage.modifier + +; TODO: variable.mut to highlight mutable identifiers via locals.scm + +; ------- +; Constructors +; ------- +; TODO: this is largely guesswork, remove it once we get actual info from locals.scm or r-a + +(struct_expression + name: (type_identifier) @constructor) + +(tuple_enum_pattern + type: [ + (identifier) @constructor + (scoped_identifier + name: (identifier) @constructor) + ]) +(struct_pattern + type: [ + ((type_identifier) @constructor) + (scoped_type_identifier + name: (type_identifier) @constructor) + ]) +(match_pattern + ((identifier) @constructor) (#match? @constructor "^[A-Z]")) +(or_pattern + ((identifier) @constructor) + ((identifier) @constructor) + (#match? @constructor "^[A-Z]")) + +; ------- +; Guess Other Types +; ------- + +((identifier) @constant + (#match? @constant "^[A-Z][A-Z\\d_]*$")) + +; --- +; PascalCase identifiers in call_expressions (e.g. `Ok()`) +; are assumed to be enum constructors. +; --- + +(call_expression + function: [ + ((identifier) @constructor + (#match? @constructor "^[A-Z]")) + (scoped_identifier + name: ((identifier) @constructor + (#match? @constructor "^[A-Z]"))) + ]) + +; --- +; PascalCase identifiers under a path which is also PascalCase +; are assumed to be constructors if they have methods or fields. +; --- + +(field_expression + value: (scoped_identifier + path: [ + (identifier) @type + (scoped_identifier + name: (identifier) @type) + ] + name: (identifier) @constructor + (#match? @type "^[A-Z]") + (#match? @constructor "^[A-Z]"))) + +; --- +; Other PascalCase identifiers are assumed to be structs. +; --- + +((identifier) @type + (#match? @type "^[A-Z]")) + +; ------- +; Functions +; ------- + +(call_expression + function: [ + ((identifier) @function) + (scoped_identifier + name: (identifier) @function) + (field_expression + field: (field_identifier) @function) + ]) +(generic_function + function: [ + ((identifier) @function) + (scoped_identifier + name: (identifier) @function) + (field_expression + field: (field_identifier) @function.method) + ]) +(function_item + (function + name: (identifier) @function)) + +(function_signature_item + (function + name: (identifier) @function)) + +(external_function_item + (function + name: (identifier) @function)) + +; --- +; Macros +; --- + +(attribute + (identifier) @special + arguments: (token_tree (identifier) @type) + (#eq? @special "derive") +) + +(attribute + (identifier) @function.macro) +(attribute + [ + (identifier) @function.macro + (scoped_identifier + name: (identifier) @function.macro) + ] + (token_tree (identifier) @function.macro)?) + +(inner_attribute_item) @attribute + +(macro_invocation + macro: [ + ((identifier) @function.macro) + (scoped_identifier + name: (identifier) @function.macro) + ] + "!" @function.macro) + + +; ------- +; Operators +; ------- + +[ + "*" + "->" + "=>" + "<=" + "=" + "==" + "!" + "!=" + "%" + "%=" + "@" + "&&" + "|" + "||" + "^" + "*" + "*=" + "-" + "-=" + "+" + "+=" + "/" + "/=" + ">" + "<" + ">=" + ">>" + "<<" +] @operator + +; ------- +; Paths +; ------- + +(use_declaration + argument: (identifier) @namespace) +(use_wildcard + (identifier) @namespace) +(mod_item + name: (identifier) @namespace) +(scoped_use_list + path: (identifier)? @namespace) +(use_list + (identifier) @namespace) +(use_as_clause + path: (identifier)? @namespace + alias: (identifier) @namespace) + +; --- +; Remaining Paths +; --- + +(scoped_identifier + path: (identifier)? @namespace + name: (identifier) @namespace) +(scoped_type_identifier + path: (identifier) @namespace) + +; ------- +; Remaining Identifiers +; ------- + +"?" @special + +(type_identifier) @type +(identifier) @variable +(field_identifier) @variable.other.member diff --git a/runtime/queries/cairo/indents.scm b/runtime/queries/cairo/indents.scm index ae55c7fa..35c16242 100644 --- a/runtime/queries/cairo/indents.scm +++ b/runtime/queries/cairo/indents.scm @@ -1 +1,118 @@ -; inherits: rust +[ + (use_list) + (block) + (match_block) + (arguments) + (parameters) + (declaration_list) + (field_declaration_list) + (field_initializer_list) + (struct_pattern) + (tuple_pattern) + (unit_expression) + (enum_variant_list) + (call_expression) + (binary_expression) + (field_expression) + (tuple_expression) + (array_expression) + + (token_tree) +] @indent + +[ + "}" + "]" + ")" +] @outdent + +; Indent the right side of assignments. +; The #not-same-line? predicate is required to prevent an extra indent for e.g. +; an else-clause where the previous if-clause starts on the same line as the assignment. +(assignment_expression + . + (_) @expr-start + right: (_) @indent + (#not-same-line? @indent @expr-start) + (#set! "scope" "all") +) +(compound_assignment_expr + . + (_) @expr-start + right: (_) @indent + (#not-same-line? @indent @expr-start) + (#set! "scope" "all") +) +(let_declaration + "let" @expr-start + value: (_) @indent + alternative: (_)? @indent + (#not-same-line? @indent @expr-start) + (#set! "scope" "all") +) +(let_condition + . + (_) @expr-start + value: (_) @indent + (#not-same-line? @indent @expr-start) + (#set! "scope" "all") +) +(if_expression + . + (_) @expr-start + condition: (_) @indent + (#not-same-line? @indent @expr-start) + (#set! "scope" "all") +) +(field_pattern + . + (_) @expr-start + pattern: (_) @indent + (#not-same-line? @indent @expr-start) + (#set! "scope" "all") +) +; Indent type aliases that span multiple lines, similar to +; regular assignment expressions +(type_item + . + (_) @expr-start + type: (_) @indent + (#not-same-line? @indent @expr-start) + (#set! "scope" "all") +) + +; Some field expressions where the left part is a multiline expression are not +; indented by cargo fmt. +; Because this multiline expression might be nested in an arbitrary number of +; field expressions, this can only be matched using a Regex. +(field_expression + value: (_) @val + "." @outdent + ; Check whether the first line ends with `(`, `{` or `[` (up to whitespace). + (#match? @val "(\\A[^\\n\\r]+(\\(|\\{|\\[)[\\t ]*(\\n|\\r))") +) +; Same as above, but with an additional `call_expression`. This is required since otherwise +; the arguments of the function call won't be outdented. +(call_expression + function: (field_expression + value: (_) @val + "." @outdent + (#match? @val "(\\A[^\\n\\r]+(\\(|\\{|\\[)[\\t ]*(\\n|\\r))") + ) + arguments: (_) @outdent +) + + +; Indent if guards in patterns. +; Since the tree-sitter grammar doesn't create a node for the if expression, +; it's not possible to do this correctly in all cases. Indenting the tail of the +; whole pattern whenever it contains an `if` only fails if the `if` appears after +; the second line of the pattern (which should only rarely be the case) +(match_pattern + . + (_) @expr-start + "if" @pattern-guard + (#not-same-line? @expr-start @pattern-guard) +) @indent + + diff --git a/runtime/queries/cairo/injections.scm b/runtime/queries/cairo/injections.scm index a2358b1c..e07c83b4 100644 --- a/runtime/queries/cairo/injections.scm +++ b/runtime/queries/cairo/injections.scm @@ -1,3 +1,3 @@ -([(line_comment) (block_comment)] @injection.content +([(line_comment)] @injection.content (#set! injection.language "comment")) diff --git a/runtime/queries/cairo/locals.scm b/runtime/queries/cairo/locals.scm index ae55c7fa..35acb55c 100644 --- a/runtime/queries/cairo/locals.scm +++ b/runtime/queries/cairo/locals.scm @@ -1 +1,25 @@ -; inherits: rust +; Scopes + +[ + (function_item) + (struct_item) + (enum_item) + (type_item) + (trait_item) + (impl_item) + (block) +] @local.scope + +; Definitions + +(parameter + (identifier) @local.definition) + +(type_parameters + (type_identifier) @local.definition) +(constrained_type_parameter + left: (type_identifier) @local.definition) + +; References +(identifier) @local.reference +(type_identifier) @local.reference diff --git a/runtime/queries/cairo/textobjects.scm b/runtime/queries/cairo/textobjects.scm index ae55c7fa..4031873d 100644 --- a/runtime/queries/cairo/textobjects.scm +++ b/runtime/queries/cairo/textobjects.scm @@ -1 +1,73 @@ -; inherits: rust +(function_item + body: (_) @function.inside) @function.around + +(struct_item + body: (_) @class.inside) @class.around + +(enum_item + body: (_) @class.inside) @class.around + +(trait_item + body: (_) @class.inside) @class.around + +(impl_item + body: (_) @class.inside) @class.around + +(parameters + ((_) @parameter.inside . ","? @parameter.around) @parameter.around) + +(type_parameters + ((_) @parameter.inside . ","? @parameter.around) @parameter.around) + +(type_arguments + ((_) @parameter.inside . ","? @parameter.around) @parameter.around) + +(arguments + ((_) @parameter.inside . ","? @parameter.around) @parameter.around) + +(field_initializer_list + ((_) @parameter.inside . ","? @parameter.around) @parameter.around) + +[ + (line_comment) +] @comment.inside + +(line_comment)+ @comment.around + +(; #[test] + (attribute_item + (attribute + (identifier) @_test_attribute)) + ; allow other attributes like #[should_panic] and comments + [ + (attribute_item) + (line_comment) + ]* + ; the test function + (function_item + body: (_) @test.inside) @test.around + (#eq? @_test_attribute "test")) + +(array_expression + (_) @entry.around) + +(tuple_expression + (_) @entry.around) + +(tuple_pattern + (_) @entry.around) + +; Commonly used vec macro intializer is special cased +(macro_invocation + (identifier) @_id (token_tree (_) @entry.around) + (#eq? @_id "array")) + +(enum_variant) @entry.around + +(field_declaration + (_) @entry.inside) @entry.around + +(field_initializer + (_) @entry.inside) @entry.around + +(shorthand_field_initializer) @entry.around diff --git a/runtime/queries/elisp/highlights.scm b/runtime/queries/elisp/highlights.scm new file mode 100644 index 00000000..1639168b --- /dev/null +++ b/runtime/queries/elisp/highlights.scm @@ -0,0 +1,72 @@ +;; Special forms +[ + "and" + "catch" + "cond" + "condition-case" + "defconst" + "defvar" + "function" + "if" + "interactive" + "lambda" + "let" + "let*" + "or" + "prog1" + "prog2" + "progn" + "quote" + "save-current-buffer" + "save-excursion" + "save-restriction" + "setq" + "setq-default" + "unwind-protect" + "while" +] @keyword + +;; Function definitions +[ + "defun" + "defsubst" + ] @keyword +(function_definition name: (symbol) @function) +(function_definition parameters: (list (symbol) @variable.parameter)) +(function_definition docstring: (string) @comment) + +;; Highlight macro definitions the same way as function definitions. +"defmacro" @keyword +(macro_definition name: (symbol) @function) +(macro_definition parameters: (list (symbol) @variable.parameter)) +(macro_definition docstring: (string) @comment) + +(comment) @comment + +(integer) @constant.numeric.integer +(float) @constant.numeric.float +(char) @constant.character + +(string) @string + +[ + "(" + ")" + "#[" + "[" + "]" +] @punctuation.bracket + +[ + "`" + "#'" + "'" + "," + ",@" +] @operator + +;; Highlight nil and t as constants, unlike other symbols +[ + "nil" + "t" +] @constant.builtin diff --git a/runtime/queries/elisp/tags.scm b/runtime/queries/elisp/tags.scm new file mode 100644 index 00000000..7abcb9a4 --- /dev/null +++ b/runtime/queries/elisp/tags.scm @@ -0,0 +1,5 @@ +;; defun/defsubst +(function_definition name: (symbol) @name) @definition.function + +;; Treat macros as function definitions for the sake of TAGS. +(macro_definition name: (symbol) @name) @definition.function diff --git a/runtime/queries/swift/highlights.scm b/runtime/queries/swift/highlights.scm index e7610e38..42411d90 100644 --- a/runtime/queries/swift/highlights.scm +++ b/runtime/queries/swift/highlights.scm @@ -1,4 +1,4 @@ -; Upstream: https://github.com/alex-pinkus/tree-sitter-swift/blob/1c586339fb00014b23d6933f2cc32b588a226f3b/queries/highlights.scm +; Upstream: https://github.com/alex-pinkus/tree-sitter-swift/blob/57c1c6d6ffa1c44b330182d41717e6fe37430704/queries/highlights.scm (line_string_literal ["\\(" ")"] @punctuation.special) @@ -10,6 +10,7 @@ (attribute) @variable (type_identifier) @type (self_expression) @variable.builtin +(user_type (type_identifier) @variable.builtin (#eq? @variable.builtin "Self")) ; Declarations "func" @keyword.function @@ -23,7 +24,9 @@ ] @keyword (function_declaration (simple_identifier) @function.method) -(function_declaration "init" @constructor) +(init_declaration ["init" @constructor]) +(deinit_declaration ["deinit" @constructor]) + (throws) @keyword "async" @keyword "await" @keyword @@ -48,10 +51,23 @@ "override" "convenience" "required" - "some" + "mutating" + "associatedtype" + "package" "any" ] @keyword +(opaque_type ["some" @keyword]) +(existential_type ["any" @keyword]) + +(precedence_group_declaration + ["precedencegroup" @keyword] + (simple_identifier) @type) +(precedence_group_attribute + (simple_identifier) @keyword + [(simple_identifier) @type + (boolean_literal) @constant.builtin.boolean]) + [ (getter_specifier) (setter_specifier) @@ -73,6 +89,10 @@ ((navigation_expression (simple_identifier) @type) ; SomeType.method(): highlight SomeType as a type (#match? @type "^[A-Z]")) +(call_expression (simple_identifier) @keyword (#eq? @keyword "defer")) ; defer { ... } + +(try_operator) @operator +(try_operator ["try" @keyword]) (directive) @function.macro (diagnostic) @function.macro @@ -136,10 +156,8 @@ ; Operators [ - "try" - "try?" - "try!" "!" + "?" "+" "-" "*" @@ -171,3 +189,8 @@ "..." (custom_operator) ] @operator + +(value_parameter_pack ["each" @keyword]) +(value_pack_expansion ["repeat" @keyword]) +(type_parameter_pack ["each" @keyword]) +(type_pack_expansion ["repeat" @keyword]) diff --git a/runtime/queries/swift/injections.scm b/runtime/queries/swift/injections.scm new file mode 100644 index 00000000..0ac6cddf --- /dev/null +++ b/runtime/queries/swift/injections.scm @@ -0,0 +1,6 @@ +; Upstream: https://github.com/alex-pinkus/tree-sitter-swift/blob/57c1c6d6ffa1c44b330182d41717e6fe37430704/queries/injections.scm + +; Parse regex syntax within regex literals + +((regex_literal) @injection.content + (#set! injection.language "regex")) diff --git a/runtime/queries/swift/locals.scm b/runtime/queries/swift/locals.scm index 59cd4c00..31bc9abf 100644 --- a/runtime/queries/swift/locals.scm +++ b/runtime/queries/swift/locals.scm @@ -1,7 +1,19 @@ +; Upstream: https://github.com/alex-pinkus/tree-sitter-swift/blob/57c1c6d6ffa1c44b330182d41717e6fe37430704/queries/locals.scm +(import_declaration (identifier) @definition.import) +(function_declaration name: (simple_identifier) @definition.function) + +; Scopes [ + (for_statement) + (while_statement) + (repeat_while_statement) + (do_statement) + (if_statement) + (guard_statement) + (switch_statement) + (property_declaration) (function_declaration) + (class_declaration) + (protocol_declaration) + (lambda_literal) ] @local.scope - -(parameter name: (simple_identifier) @local.definition) - -(simple_identifier) @local.reference diff --git a/runtime/queries/swift/textobjects.scm b/runtime/queries/swift/textobjects.scm new file mode 100644 index 00000000..2a9938bf --- /dev/null +++ b/runtime/queries/swift/textobjects.scm @@ -0,0 +1,23 @@ +(class_declaration + body: (_) @class.inside) @class.around + +(protocol_declaration + body: (_) @class.inside) @class.around + +(function_declaration + body: (_) @function.inside) @function.around + +(parameter + (_) @parameter.inside) @parameter.around + +(lambda_parameter + (_) @parameter.inside) @parameter.around + +[ + (comment) + (multiline_comment) +] @comment.inside + +(comment)+ @comment.around + +(multiline_comment) @comment.around diff --git a/runtime/themes/catppuccin_frappe.toml b/runtime/themes/catppuccin_frappe.toml index b63e5270..2ac76ee7 100644 --- a/runtime/themes/catppuccin_frappe.toml +++ b/runtime/themes/catppuccin_frappe.toml @@ -1,7 +1,6 @@ inherits = "catppuccin_mocha" [palette] -# catppuccin palette colors rosewater = "#f2d5cf" flamingo = "#eebebe" pink = "#f4b8e4" @@ -16,7 +15,6 @@ sky = "#99d1db" sapphire = "#85c1dc" blue = "#8caaee" lavender = "#babbf1" - text = "#c6d0f5" subtext1 = "#b5bfe2" subtext0 = "#a5adce" @@ -26,13 +24,11 @@ overlay0 = "#737994" surface2 = "#626880" surface1 = "#51576d" surface0 = "#414559" - base = "#303446" mantle = "#292c3c" crust = "#232634" -# derived colors by blending existing palette colors cursorline = "#3b3f52" secondary_cursor = "#b8a5a6" -secondary_cursor_normal = "#9193be" +secondary_cursor_normal = "#9192be" secondary_cursor_insert = "#83a275" diff --git a/runtime/themes/catppuccin_latte.toml b/runtime/themes/catppuccin_latte.toml index 7a015168..1686f576 100644 --- a/runtime/themes/catppuccin_latte.toml +++ b/runtime/themes/catppuccin_latte.toml @@ -1,7 +1,6 @@ inherits = "catppuccin_mocha" [palette] -# catppuccin palette colors rosewater = "#dc8a78" flamingo = "#dd7878" pink = "#ea76cb" @@ -16,7 +15,6 @@ sky = "#04a5e5" sapphire = "#209fb5" blue = "#1e66f5" lavender = "#7287fd" - text = "#4c4f69" subtext1 = "#5c5f77" subtext0 = "#6c6f85" @@ -26,13 +24,11 @@ overlay0 = "#9ca0b0" surface2 = "#acb0be" surface1 = "#bcc0cc" surface0 = "#ccd0da" - base = "#eff1f5" mantle = "#e6e9ef" crust = "#dce0e8" -# derived colors by blending existing palette colors -cursorline = "#e9ebf1" -secondary_cursor = "#e2a99e" -secondary_cursor_normal = "#98a7fb" -secondary_cursor_insert = "#75b868" +cursorline = "#e8ecf1" +secondary_cursor = "#e1a99d" +secondary_cursor_normal = "#97a7fb" +secondary_cursor_insert = "#74b867" diff --git a/runtime/themes/catppuccin_macchiato.toml b/runtime/themes/catppuccin_macchiato.toml index 6203eaad..581eb613 100644 --- a/runtime/themes/catppuccin_macchiato.toml +++ b/runtime/themes/catppuccin_macchiato.toml @@ -1,7 +1,6 @@ inherits = "catppuccin_mocha" [palette] -# catppuccin palette colors rosewater = "#f4dbd6" flamingo = "#f0c6c6" pink = "#f5bde6" @@ -16,7 +15,6 @@ sky = "#91d7e3" sapphire = "#7dc4e4" blue = "#8aadf4" lavender = "#b7bdf8" - text = "#cad3f5" subtext1 = "#b8c0e0" subtext0 = "#a5adcb" @@ -26,13 +24,11 @@ overlay0 = "#6e738d" surface2 = "#5b6078" surface1 = "#494d64" surface0 = "#363a4f" - base = "#24273a" mantle = "#1e2030" crust = "#181926" -# derived colors by blending existing palette colors cursorline = "#303347" -secondary_cursor = "#b6a5a7" -secondary_cursor_normal = "#8b90bf" -secondary_cursor_insert = "#7fa47a" +secondary_cursor = "#b6a6a7" +secondary_cursor_normal = "#8b91bf" +secondary_cursor_insert = "#80a57a" diff --git a/runtime/themes/catppuccin_mocha.toml b/runtime/themes/catppuccin_mocha.toml index 58173dab..3c030762 100644 --- a/runtime/themes/catppuccin_mocha.toml +++ b/runtime/themes/catppuccin_mocha.toml @@ -1,19 +1,22 @@ # Syntax highlighting # ------------------- +"attribute" = "yellow" + "type" = "yellow" +"type.enum.variant" = "teal" "constructor" = "sapphire" "constant" = "peach" -"constant.builtin" = "peach" "constant.character" = "teal" "constant.character.escape" = "pink" "string" = "green" -"string.regexp" = "peach" +"string.regexp" = "pink" "string.special" = "blue" +"string.special.symbol" = "red" -"comment" = { fg = "overlay1", modifiers = ["italic"] } +"comment" = { fg = "overlay2", modifiers = ["italic"] } "variable" = "text" "variable.parameter" = { fg = "maroon", modifiers = ["italic"] } @@ -26,7 +29,6 @@ "punctuation.special" = "sky" "keyword" = "mauve" -"keyword.storage.modifier.ref" = "teal" "keyword.control.conditional" = { fg = "mauve", modifiers = ["italic"] } "operator" = "sky" @@ -34,10 +36,9 @@ "function" = "blue" "function.macro" = "mauve" -"tag" = "mauve" -"attribute" = "blue" +"tag" = "blue" -"namespace" = { fg = "blue", modifiers = ["italic"] } +"namespace" = { fg = "yellow", modifiers = ["italic"] } "special" = "blue" # fuzzy highlight @@ -51,8 +52,7 @@ "markup.list" = "mauve" "markup.bold" = { modifiers = ["bold"] } "markup.italic" = { modifiers = ["italic"] } -"markup.strikethrough" = { modifiers = ["crossed_out"] } -"markup.link.url" = { fg = "rosewater", modifiers = ["underlined"] } +"markup.link.url" = { fg = "blue", modifiers = ["italic", "underlined"] } "markup.link.text" = "blue" "markup.raw" = "flamingo" @@ -70,8 +70,8 @@ "ui.statusline" = { fg = "subtext1", bg = "mantle" } "ui.statusline.inactive" = { fg = "surface2", bg = "mantle" } "ui.statusline.normal" = { fg = "base", bg = "lavender", modifiers = ["bold"] } -"ui.statusline.insert" = { fg = "base", bg = "green", modifiers = ["bold"] } -"ui.statusline.select" = { fg = "base", bg = "flamingo", modifiers = ["bold"] } +"ui.statusline.insert" = { fg = "base", bg = "green", modifiers = ["bold"] } +"ui.statusline.select" = { fg = "base", bg = "flamingo", modifiers = ["bold"] } "ui.popup" = { fg = "text", bg = "surface0" } "ui.window" = { fg = "crust" } @@ -88,7 +88,7 @@ "ui.virtual" = "overlay0" "ui.virtual.ruler" = { bg = "surface0" } "ui.virtual.indent-guide" = "surface0" -"ui.virtual.inlay-hint" = { fg = "overlay0", bg = "base" } +"ui.virtual.inlay-hint" = { fg = "surface1", bg = "mantle" } "ui.virtual.jump-label" = { fg = "rosewater", modifiers = ["bold"] } "ui.selection" = { bg = "surface1" } @@ -116,8 +116,6 @@ "diagnostic.warning" = { underline = { color = "yellow", style = "curl" } } "diagnostic.info" = { underline = { color = "sky", style = "curl" } } "diagnostic.hint" = { underline = { color = "teal", style = "curl" } } -"diagnostic.unnecessary" = { modifiers = ["dim"] } -"diagnostic.deprecated" = { modifiers = ["crossed_out"] } error = "red" warning = "yellow" @@ -125,7 +123,6 @@ info = "sky" hint = "teal" [palette] -# catppuccin palette colors rosewater = "#f5e0dc" flamingo = "#f2cdcd" pink = "#f5c2e7" @@ -140,7 +137,6 @@ sky = "#89dceb" sapphire = "#74c7ec" blue = "#89b4fa" lavender = "#b4befe" - text = "#cdd6f4" subtext1 = "#bac2de" subtext0 = "#a6adc8" @@ -150,13 +146,11 @@ overlay0 = "#6c7086" surface2 = "#585b70" surface1 = "#45475a" surface0 = "#313244" - base = "#1e1e2e" mantle = "#181825" crust = "#11111b" -# derived colors by blending existing palette colors cursorline = "#2a2b3c" secondary_cursor = "#b5a6a8" secondary_cursor_normal = "#878ec0" -secondary_cursor_insert = "#7da87e" +secondary_cursor_insert = "#7ea87f" diff --git a/runtime/themes/noctis.toml b/runtime/themes/noctis.toml index db127229..5846576e 100644 --- a/runtime/themes/noctis.toml +++ b/runtime/themes/noctis.toml @@ -45,10 +45,13 @@ 'ui.linenr' = { fg = "gray" } # Line numbers. 'ui.linenr.selected' = { fg = "light-green", modifiers = [ "bold" ] } # Current line number. -'ui.virtual' = { fg = "mid-green" } # Namespace for additions to the editing area. +'ui.virtual' = { fg = "autocomp-green" } # Namespace for additions to the editing area. 'ui.virtual.ruler' = { bg = "mid-green" } # Vertical rulers (colored columns in editing area). -'ui.virtual.whitespace' = { fg = "light-gray"} # Whitespace markers in editing area. -'ui.virtual.indent-guide' = { fg = "light-gray" } # Indentation guides. +'ui.virtual.whitespace' = { fg = "mid-green"} # Whitespace markers in editing area. +'ui.virtual.inlay-hint' = { fg = "autocomp-green" } # LSP inlay hints +'ui.virtual.indent-guide' = { fg = "mid-green" } # Indentation guides. +'ui.virtual.wrap' = { fg = "mid-green"} # Soft-wrap indicators +'ui.virtual.jump-label' = { fg = "autocomp-green", modifiers = [ "bold" ] } # Word-jump labels 'ui.statusline' = { fg = "light-green", bg = "autocomp-green"} # Status line. 'ui.statusline.inactive' = { fg = "white", bg = "mid-green"} # Status line in unfocused windows.