diff --git a/Cargo.lock b/Cargo.lock index c91a326..bd233df 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,18 +4,18 @@ version = 4 [[package]] name = "addr2line" -version = "0.22.0" +version = "0.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678" +checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" dependencies = [ "gimli", ] [[package]] -name = "adler" -version = "1.0.2" +name = "adler2" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" [[package]] name = "aho-corasick" @@ -48,23 +48,32 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.3.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] name = "backtrace" -version = "0.3.73" +version = "0.3.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cc23269a4f8976d0a4d2e7109211a419fe30e8d88d677cd60b6bc79c5732e0a" +checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" dependencies = [ "addr2line", - "cc", "cfg-if", "libc", "miniz_oxide", "object", "rustc-demangle", + "windows-targets", +] + +[[package]] +name = "basic-toml" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "823388e228f614e9558c6804262db37960ec8821856535f5c3f59913140558f8" +dependencies = [ + "serde", ] [[package]] @@ -81,9 +90,9 @@ checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "bytes" -version = "1.6.1" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a12916984aab3fa6e39d655a33e09c0071eb36d6ab3aea5c2d78551f1df6d952" +checksum = "9ac0150caa2ae65ca5bd83f25c7de183dea78d4d366469f148435e2acfbad0da" [[package]] name = "cc" @@ -169,9 +178,9 @@ dependencies = [ [[package]] name = "futures" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" +checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" dependencies = [ "futures-channel", "futures-core", @@ -184,9 +193,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" dependencies = [ "futures-core", "futures-sink", @@ -194,15 +203,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" [[package]] name = "futures-executor" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" +checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" dependencies = [ "futures-core", "futures-task", @@ -211,38 +220,38 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" [[package]] name = "futures-macro" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.85", ] [[package]] name = "futures-sink" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" [[package]] name = "futures-task" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" [[package]] name = "futures-util" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" dependencies = [ "futures-channel", "futures-core", @@ -258,9 +267,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.29.0" +version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" +checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" [[package]] name = "hard-xml" @@ -305,9 +314,9 @@ dependencies = [ [[package]] name = "insta" -version = "1.39.0" +version = "1.40.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "810ae6042d48e2c9e9215043563a58a80b877bc863228a74cf10c49d4620a6f5" +checksum = "6593a41c7a73841868772495db7dc1e8ecab43bb5c0b6da2059246c4b506ab60" dependencies = [ "console", "lazy_static", @@ -336,9 +345,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "libc" -version = "0.2.155" +version = "0.2.161" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" +checksum = "8e9489c2807c139ffd9c1794f4af0ebe86a828db53ecdc7fea2111d0fed085d1" [[package]] name = "linked-hash-map" @@ -389,22 +398,23 @@ checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "miniz_oxide" -version = "0.7.4" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" +checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" dependencies = [ - "adler", + "adler2", ] [[package]] name = "mio" -version = "0.8.11" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" +checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" dependencies = [ + "hermit-abi", "libc", "wasi", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -423,30 +433,20 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" -[[package]] -name = "num_cpus" -version = "1.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" -dependencies = [ - "hermit-abi", - "libc", -] - [[package]] name = "object" -version = "0.36.1" +version = "0.36.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "081b846d1d56ddfc18fdf1a922e4f6e07a11768ea1b92dec44e42b72712ccfce" +checksum = "aedf0a2d09c573ed1d8d85b30c119153926a2b36dce0ab28322c09a117a4683e" dependencies = [ "memchr", ] [[package]] name = "once_cell" -version = "1.19.0" +version = "1.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" [[package]] name = "overload" @@ -474,7 +474,7 @@ dependencies = [ "libc", "redox_syscall", "smallvec", - "windows-targets 0.52.6", + "windows-targets", ] [[package]] @@ -485,9 +485,9 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pin-project-lite" -version = "0.2.14" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" +checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff" [[package]] name = "pin-utils" @@ -503,18 +503,19 @@ checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" [[package]] name = "proc-macro2" -version = "1.0.86" +version = "1.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e" dependencies = [ "unicode-ident", ] [[package]] name = "protols" -version = "0.9.0" +version = "0.10.0" dependencies = [ "async-lsp", + "basic-toml", "futures", "hard-xml", "insta", @@ -533,27 +534,27 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.36" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] [[package]] name = "redox_syscall" -version = "0.5.3" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a908a6e00f1fdd0dfd9c0eb08ce85126f6d8bbda50017e74bc4a4b7d4a926a4" +checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f" dependencies = [ "bitflags 2.6.0", ] [[package]] name = "regex" -version = "1.11.0" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38200e5ee88914975b69f657f0801b6f6dccafd44fd9326302a4aaeecfacb1d8" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" dependencies = [ "aho-corasick", "memchr", @@ -586,9 +587,9 @@ checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" [[package]] name = "rustix" -version = "0.38.34" +version = "0.38.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" +checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811" dependencies = [ "bitflags 2.6.0", "errno", @@ -620,31 +621,32 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "serde" -version = "1.0.209" +version = "1.0.213" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99fce0ffe7310761ca6bf9faf5115afbc19688edd00171d81b1bb1b116c63e09" +checksum = "3ea7893ff5e2466df8d720bb615088341b295f849602c6956047f8f80f0e9bc1" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.209" +version = "1.0.213" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5831b979fd7b5439637af1752d535ff49f4860c0f341d1baeb6faf0f4242170" +checksum = "7e85ad2009c50b58e87caa8cd6dac16bdf511bbfb7af6c33df902396aa480fa5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.85", ] [[package]] name = "serde_json" -version = "1.0.120" +version = "1.0.132" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e0d21c9a8cae1235ad58a00c11cb40d4b1e5c784f1ef2c537876ed6ffd8b7c5" +checksum = "d726bfaff4b320266d395898905d0eba0345aae23b54aee3a737e260fd46db03" dependencies = [ "itoa", + "memchr", "ryu", "serde", ] @@ -657,7 +659,7 @@ checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.85", ] [[package]] @@ -734,9 +736,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.71" +version = "2.0.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b146dcf730474b4bcd16c311627b31ede9ab149045db4d6088b3becaea046462" +checksum = "5023162dfcd14ef8f32034d8bcd4cc5ddc61ef7a247c024a33e24e1f24d21b56" dependencies = [ "proc-macro2", "quote", @@ -745,9 +747,9 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.12.0" +version = "3.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04cbcdd0c794ebb0d4cf35e88edd2f7d2c4c3e9a5a6dab322839b321c6a87a64" +checksum = "f0f2c9fc62d0beef6951ccffd757e241266a2c833136efbe35af6cd2567dca5b" dependencies = [ "cfg-if", "fastrand", @@ -758,22 +760,22 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.63" +version = "1.0.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" +checksum = "5d11abd9594d9b38965ef50805c5e469ca9cc6f197f883f717e0269a3057b3d5" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.63" +version = "1.0.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" +checksum = "ae71770322cbd277e69d762a16c444af02aa0575ac0d174f0b9562d3b37f8602" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.85", ] [[package]] @@ -834,39 +836,38 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.38.1" +version = "1.41.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb2caba9f80616f438e09748d5acda951967e1ea58508ef53d9c6402485a46df" +checksum = "145f3413504347a2be84393cc8a7d2fb4d863b375909ea59f2158261aa258bbb" dependencies = [ "backtrace", "bytes", "libc", "mio", - "num_cpus", "parking_lot", "pin-project-lite", "signal-hook-registry", "socket2", "tokio-macros", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "tokio-macros" -version = "2.3.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f5ae998a069d4b5aba8ee9dad856af7d520c3699e6159b185c2acd48155d39a" +checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.85", ] [[package]] name = "tokio-util" -version = "0.7.11" +version = "0.7.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1" +checksum = "61e7c3654c13bcd040d4a03abee2c75b1d14a37b423cf5a813ceae1cc903ec6a" dependencies = [ "bytes", "futures-core", @@ -889,15 +890,15 @@ dependencies = [ [[package]] name = "tower-layer" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" +checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" [[package]] name = "tower-service" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" [[package]] name = "tracing" @@ -931,7 +932,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.85", ] [[package]] @@ -1000,21 +1001,21 @@ dependencies = [ [[package]] name = "unicode-bidi" -version = "0.3.15" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" +checksum = "5ab17db44d7388991a428b2ee655ce0c212e862eff1768a455c58f9aad6e7893" [[package]] name = "unicode-ident" -version = "1.0.12" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" [[package]] name = "unicode-normalization" -version = "0.1.23" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" +checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956" dependencies = [ "tinyvec", ] @@ -1094,22 +1095,13 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" -[[package]] -name = "windows-sys" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" -dependencies = [ - "windows-targets 0.48.5", -] - [[package]] name = "windows-sys" version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.6", + "windows-targets", ] [[package]] @@ -1118,22 +1110,7 @@ version = "0.59.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" dependencies = [ - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-targets" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" -dependencies = [ - "windows_aarch64_gnullvm 0.48.5", - "windows_aarch64_msvc 0.48.5", - "windows_i686_gnu 0.48.5", - "windows_i686_msvc 0.48.5", - "windows_x86_64_gnu 0.48.5", - "windows_x86_64_gnullvm 0.48.5", - "windows_x86_64_msvc 0.48.5", + "windows-targets", ] [[package]] @@ -1142,46 +1119,28 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm 0.52.6", - "windows_aarch64_msvc 0.52.6", - "windows_i686_gnu 0.52.6", + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", "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", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", ] -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" - [[package]] name = "windows_aarch64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" -[[package]] -name = "windows_aarch64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" - [[package]] name = "windows_aarch64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" -[[package]] -name = "windows_i686_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" - [[package]] name = "windows_i686_gnu" version = "0.52.6" @@ -1194,48 +1153,24 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" -[[package]] -name = "windows_i686_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" - [[package]] name = "windows_i686_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" -[[package]] -name = "windows_x86_64_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" - [[package]] name = "windows_x86_64_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" - [[package]] name = "windows_x86_64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" -[[package]] -name = "windows_x86_64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" - [[package]] name = "windows_x86_64_msvc" version = "0.52.6" diff --git a/Cargo.toml b/Cargo.toml index 2e8010d..44d97e0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "protols" description = "Language server for proto3 files" -version = "0.9.0" +version = "0.10.0" edition = "2021" license = "MIT" homepage = "https://github.com/coder3101/protols" @@ -26,6 +26,7 @@ walkdir = "2.5.0" hard-xml = "1.36.0" tempfile = "3.12.0" serde = { version = "1.0.209", features = ["derive"] } +basic-toml = "0.1.9" [dev-dependencies] insta = { version = "1.39.0", features = ["yaml"] } diff --git a/README.md b/README.md index 9fdf348..06e6fca 100644 --- a/README.md +++ b/README.md @@ -1,81 +1,186 @@ # Protols - Protobuf Language Server -[![Crates.io](https://img.shields.io/crates/v/protols.svg)](https://crates.io/crates/protols) +[![Crates.io](https://img.shields.io/crates/v/protols.svg)](https://crates.io/crates/protols) [![Build and Test](https://github.com/coder3101/protols/actions/workflows/ci.yml/badge.svg)](https://github.com/coder3101/protols/actions/workflows/ci.yml) -**Protols** is an open-source Language Server Protocol (LSP) for **proto** files, powered by the robust and efficient [tree-sitter](https://tree-sitter.github.io/tree-sitter/) parser. With Protols, you get powerful code assistance for protobuf files, including auto-completion, syntax diagnostics, and more. +**Protols** is an open-source, feature-rich [Language Server Protocol (LSP)](https://microsoft.github.io/language-server-protocol/) for **Protocol Buffers (proto)** files. Powered by the efficient [tree-sitter](https://tree-sitter.github.io/tree-sitter/) parser, Protols offers intelligent code assistance for protobuf development, including features like auto-completion, diagnostics, formatting, and more. -![](./assets/protols.mov) +![Protols Demo](./assets/protols.mov) ## ✨ Features -- ✅ Code Completion -- ✅ Diagnostics -- ✅ Document Symbols -- ✅ Code Formatting -- ✅ Go to Definition -- ✅ Hover Information -- ✅ Rename Symbols -- ✅ Find references +- ✅ **Code Completion**: Auto-complete messages, enums, and keywords in your `.proto` files. +- ✅ **Diagnostics**: Syntax errors detected with the tree-sitter parser. +- ✅ **Document Symbols**: Navigate and view all symbols, including messages and enums. +- ✅ **Code Formatting**: Format `.proto` files using `clang-format` for a consistent style. +- ✅ **Go to Definition**: Jump to the definition of symbols like messages or enums. +- ✅ **Hover Information**: Get detailed information and documentation on hover. +- ✅ **Rename Symbols**: Rename protobuf symbols and propagate changes across the codebase. +- ✅ **Find References**: Find where messages, enums, and fields are used throughout the codebase. -## 🚀 Getting Started +--- + +## Table of Contents + +- [Installation](#installation) + - [For Neovim](#for-neovim) + - [For Visual Studio Code](#for-visual-studio-code) +- [Configuration](#configuration) + - [Basic Configuration](#basic-configuration) + - [Experimental Configuration](#experimental-configuration) + - [Formatter Configuration](#formatter-configuration) + - [Multiple Configuration Files](#multiple-configuration-files) +- [Usage](#usage) + - [Code Completion](#code-completion) + - [Diagnostics](#diagnostics) + - [Code Formatting](#code-formatting) + - [Document Symbols](#document-symbols) + - [Go to Definition](#go-to-definition) + - [Hover Information](#hover-information) + - [Rename Symbols](#rename-symbols) + - [Find References](#find-references) +- [Contributing](#contributing) + - [Setting Up Locally](#setting-up-locally) +- [License](#license) + +--- -### Installation +## 🚀 Installation -#### For Neovim +### For Neovim -You can install [protols with mason.nvim](https://github.com/mason-org/mason-registry/blob/main/packages/protols/package.yaml) or directly from crates.io with: +You can install **Protols** via [mason.nvim](https://github.com/mason-org/mason-registry/blob/main/packages/protols/package.yaml), or install it directly from [crates.io](https://crates.io/crates/protols): ```bash cargo install protols ``` -Then, configure it with [`nvim-lspconfig`](https://github.com/neovim/nvim-lspconfig/blob/master/doc/server_configurations.md#protols): +Then, configure it in your `init.lua` using [nvim-lspconfig](https://github.com/neovim/nvim-lspconfig): ```lua require'lspconfig'.protols.setup{} ``` -#### For Visual Studio Code +### For Visual Studio Code + +If you're using Visual Studio Code, you can install the [Protobuf Language Support](https://marketplace.visualstudio.com/items?itemName=ianandhum.protobuf-support) extension, which uses this LSP under the hood. + +> **Note**: This extension is [open source](https://github.com/ianandhum/vscode-protobuf-support), but is not officially maintained by us. + +--- + +## ⚙️ Configuration + +Protols is configured using a `protols.toml` file, which you can place in any directory. **Protols** will search for the closest configuration file by recursively traversing the parent directories. + +### Sample `protols.toml` + +```toml +[config] # Base configuration; these are considered stable and should not change +include_paths = ["foobar", "bazbaaz"] # Include paths to look for protofiles during parsing +disable_parse_diagnostics = true # Disable diagnostics for parsing + +[config.experimental] # Experimental configuration; this should be considered unsafe and not fully tested +use_protoc_diagnostics = true # Use diagnostics from protoc + +[formatter] # Formatter specific configuration +clang_format_path = "/usr/bin/clang-format" # clang-format binary to execute in formatting +``` + +### Configuration Sections + +#### Basic Configuration + +The `[config]` section contains stable settings that should generally remain unchanged. + +- `include_paths`: Directories to search for `.proto` files. +- `disable_parse_diagnostics`: Set to `true` to disable diagnostics during parsing. + +#### Experimental Configuration + +The `[config.experimental]` section contains settings that are in development or not fully tested. -You can use the [Protobuf Language Support](https://marketplace.visualstudio.com/items?itemName=ianandhum.protobuf-support) extension, which leverages this LSP under the hood. +- `use_protoc_diagnostics`: Enable diagnostics from the `protoc` compiler when set to `true`. -> **Note:** This extension is [open source](https://github.com/ianandhum/vscode-protobuf-support) but is not maintained by us. +#### Formatter Configuration + +The `[formatter]` section allows configuration for code formatting. + +- `clang_format_path`: Specify the path to the `clang-format` binary. + +### Multiple Configuration Files + +You can place multiple `protols.toml` files across different directories. **Protols** will use the closest configuration file by searching up the directory tree. + +--- ## 🛠️ Usage +Protols offers a rich set of features to enhance your `.proto` file editing experience. + ### Code Completion -Protols provides intelligent autocompletion for messages, enums, and proto3 keywords within the current package. +**Protols** offers intelligent autocompletion for messages, enums, and proto3 keywords within the current package. Simply start typing, and Protols will suggest valid completions. ### Diagnostics -Diagnostics are powered by the tree-sitter parser, which catches syntax errors but does not utilize `protoc` for more advanced error reporting. +Syntax errors are caught by the tree-sitter parser, which highlights issues directly in your editor. For more advanced error reporting, the LSP can be configured to use `protoc` diagnostics. ### Code Formatting -Formatting is enabled if [clang-format](https://clang.llvm.org/docs/ClangFormat.html) is available. You can control the [formatting style](https://clang.llvm.org/docs/ClangFormatStyleOptions.html) by placing a `.clang-format` file in the root of your workspace. Both document and range formatting are supported. +Format your `.proto` files using `clang-format`. To customize the formatting style, add a `.clang-format` file to the root of your project. Both document and range formatting are supported. ### Document Symbols -Provides symbols for the entire document, including nested symbols, messages, and enums. +Protols provides a list of symbols in the current document, including nested symbols such as messages and enums. This allows for easy navigation and reference. ### Go to Definition -Jump to the definition of any custom symbol, even across package boundaries. +Jump directly to the definition of any custom symbol, including those in other files or packages. This feature works across package boundaries. ### Hover Information -Displays comments and documentation for protobuf symbols on hover. Works seamlessly across package boundaries. +Hover over any symbol to get detailed documentation and comments associated with it. This works seamlessly across different packages and namespaces. ### Rename Symbols -Allows renaming of symbols like messages and enums, along with all their usages across packages. Currently, renaming fields within symbols is not supported directly. +Rename symbols like messages or enums, and Propagate the changes throughout the codebase. Currently, field renaming within symbols is not supported. ### Find References -Allows user defined types like messages and enums can be checked for references. Nested fields are completely supported. +Find all references to user-defined types like messages or enums. Nested fields are fully supported, making it easier to track symbol usage across your project. + +--- + +## 🤝 Contributing + +We welcome contributions from developers of all experience levels! To get started: + +1. **Fork** the repository and clone it to your local machine. +2. Create a **new branch** for your feature or fix. +3. Run the tests to ensure everything works as expected. +4. **Open a pull request** with a detailed description of your changes. + +### Setting Up Locally + +1. Clone the repository: + + ```bash + git clone https://github.com/coder3101/protols.git + cd protols + ``` + +2. Build and test the project: + + ```bash + cargo build + cargo test + ``` --- -Protols is designed to supercharge your workflow with **proto** files. We welcome contributions and feedback from the community! Feel free to check out the [repository](https://github.com/coder3101/protols) and join in on improving this tool! 🎉 +## 📄 License + +This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for more details. + +--- diff --git a/src/config/input/protols-valid.toml b/src/config/input/protols-valid.toml new file mode 100644 index 0000000..e430f14 --- /dev/null +++ b/src/config/input/protols-valid.toml @@ -0,0 +1,9 @@ +[config] +include_paths = ["foobar", "bazbaaz"] +disable_parse_diagnostics = true + +[config.experimental] +use_protoc_diagnostics = true + +[formatter] +clang_format_path = "/usr/bin/clang-format" diff --git a/src/config/mod.rs b/src/config/mod.rs new file mode 100644 index 0000000..e770af8 --- /dev/null +++ b/src/config/mod.rs @@ -0,0 +1,52 @@ +use serde::{Deserialize, Serialize}; + +pub mod workspace; + +fn default_clang_format_path() -> String { + "clang-format".to_string() +} + +#[derive(Serialize, Deserialize, Debug, Clone)] +#[serde(default)] +pub struct ProtolsConfig { + pub config: Config, + pub formatter: FormatterConfig, +} + +#[derive(Serialize, Deserialize, Debug, Clone)] +pub struct FormatterConfig { + #[serde(default = "default_clang_format_path")] + pub clang_format_path: String, +} + +#[derive(Serialize, Deserialize, Debug, Clone, Default)] +#[serde(default)] +pub struct Config { + pub include_paths: Vec, + pub single_file_mode: bool, + pub disable_parse_diagnostics: bool, + pub experimental: ExperimentalConfig, +} + +#[derive(Serialize, Deserialize, Debug, Clone, Default)] +#[serde(default)] +pub struct ExperimentalConfig { + pub use_protoc_diagnostics: bool, +} + +impl Default for ProtolsConfig { + fn default() -> Self { + Self { + config: Config::default(), + formatter: FormatterConfig::default(), + } + } +} + +impl Default for FormatterConfig { + fn default() -> Self { + Self { + clang_format_path: default_clang_format_path(), + } + } +} diff --git a/src/config/snapshots/protols__config__workspace__test__get_for_workspace-2.snap b/src/config/snapshots/protols__config__workspace__test__get_for_workspace-2.snap new file mode 100644 index 0000000..a45e4b9 --- /dev/null +++ b/src/config/snapshots/protols__config__workspace__test__get_for_workspace-2.snap @@ -0,0 +1,12 @@ +--- +source: src/config/workspace.rs +expression: ws.get_config_for_uri(&inworkspace2).unwrap() +--- +config: + include_paths: [] + single_file_mode: false + disable_parse_diagnostics: false + experimental: + use_protoc_diagnostics: false +formatter: + clang_format_path: clang-format diff --git a/src/config/snapshots/protols__config__workspace__test__get_for_workspace.snap b/src/config/snapshots/protols__config__workspace__test__get_for_workspace.snap new file mode 100644 index 0000000..a922784 --- /dev/null +++ b/src/config/snapshots/protols__config__workspace__test__get_for_workspace.snap @@ -0,0 +1,14 @@ +--- +source: src/config/workspace.rs +expression: ws.get_config_for_uri(&inworkspace).unwrap() +--- +config: + include_paths: + - foobar + - bazbaaz + single_file_mode: false + disable_parse_diagnostics: true + experimental: + use_protoc_diagnostics: true +formatter: + clang_format_path: /usr/bin/clang-format diff --git a/src/config/snapshots/protols__config__workspace__test__workspace.snap b/src/config/snapshots/protols__config__workspace__test__workspace.snap new file mode 100644 index 0000000..1438bb3 --- /dev/null +++ b/src/config/snapshots/protols__config__workspace__test__workspace.snap @@ -0,0 +1,14 @@ +--- +source: src/config/workspace.rs +expression: ws.get_config_for_uri(&inworkspace) +--- +config: + include_paths: + - foobar + - bazbaaz + single_file_mode: false + disable_parse_diagnostics: true + experimental: + use_protoc_diagnostics: true +formatter: + clang_format_path: /usr/bin/clang-format diff --git a/src/config/workspace.rs b/src/config/workspace.rs new file mode 100644 index 0000000..d88193b --- /dev/null +++ b/src/config/workspace.rs @@ -0,0 +1,141 @@ +use std::{ + collections::{HashMap, HashSet}, + path::Path, +}; + +use async_lsp::lsp_types::{Url, WorkspaceFolder}; + +use crate::formatter::clang::ClangFormatter; + +use super::ProtolsConfig; + +const CONFIG_FILE_NAME: &str = "protols.toml"; + +pub struct WorkspaceProtoConfigs { + workspaces: HashSet, + configs: HashMap, + formatters: HashMap, +} + +impl WorkspaceProtoConfigs { + pub fn new() -> Self { + Self { + workspaces: Default::default(), + formatters: Default::default(), + configs: Default::default(), + } + } + + pub fn add_workspace(&mut self, w: &WorkspaceFolder) { + let Ok(wpath) = w.uri.to_file_path() else { + return; + }; + + let p = Path::new(&wpath).join(CONFIG_FILE_NAME); + let content = std::fs::read_to_string(p).unwrap_or_default(); + + let wr: ProtolsConfig = basic_toml::from_str(&content).unwrap_or_default(); + let fmt = ClangFormatter::new( + &wr.formatter.clang_format_path, + wpath.to_str().expect("non-utf8 path"), + ); + + self.workspaces.insert(w.uri.clone()); + self.configs.insert(w.uri.clone(), wr); + self.formatters.insert(w.uri.clone(), fmt); + } + + pub fn get_config_for_uri(&self, u: &Url) -> Option<&ProtolsConfig> { + self.get_workspace_for_uri(u) + .and_then(|w| self.configs.get(w)) + } + + pub fn get_formatter_for_uri(&self, u: &Url) -> Option<&ClangFormatter> { + self.get_workspace_for_uri(u) + .and_then(|w| self.formatters.get(w)) + } + + pub fn get_workspace_for_uri(&self, u: &Url) -> Option<&Url> { + let upath = u.to_file_path().ok()?; + self.workspaces + .iter() + .find(|&k| upath.starts_with(k.to_file_path().unwrap())) + } +} + +#[cfg(test)] +mod test { + use async_lsp::lsp_types::{Url, WorkspaceFolder}; + use insta::assert_yaml_snapshot; + use tempfile::tempdir; + + use super::WorkspaceProtoConfigs; + + #[test] + fn test_get_for_workspace() { + let tmpdir = tempdir().expect("failed to create temp directory"); + let tmpdir2 = tempdir().expect("failed to create temp2 directory"); + let f = tmpdir.path().join("protols.toml"); + std::fs::write(f, include_str!("input/protols-valid.toml")).unwrap(); + + let mut ws = WorkspaceProtoConfigs::new(); + ws.add_workspace(&WorkspaceFolder { + uri: Url::from_directory_path(tmpdir.path()).unwrap(), + name: "Test".to_string(), + }); + ws.add_workspace(&WorkspaceFolder { + uri: Url::from_directory_path(tmpdir2.path()).unwrap(), + name: "Test2".to_string(), + }); + + let inworkspace = Url::from_file_path(tmpdir.path().join("foobar.proto")).unwrap(); + let outworkspace = + Url::from_file_path(tempdir().unwrap().path().join("out.proto")).unwrap(); + let inworkspace2 = Url::from_file_path(tmpdir2.path().join("foobar.proto")).unwrap(); + + assert!(ws.get_config_for_uri(&inworkspace).is_some()); + assert!(ws.get_config_for_uri(&inworkspace2).is_some()); + assert!(ws.get_config_for_uri(&outworkspace).is_none()); + + assert!(ws.get_workspace_for_uri(&inworkspace).is_some()); + assert!(ws.get_workspace_for_uri(&inworkspace2).is_some()); + assert!(ws.get_workspace_for_uri(&outworkspace).is_none()); + + assert_yaml_snapshot!(ws.get_config_for_uri(&inworkspace).unwrap()); + assert_yaml_snapshot!(ws.get_config_for_uri(&inworkspace2).unwrap()); + } + + #[test] + fn test_get_formatter_for_uri() { + let tmpdir = tempdir().expect("failed to create temp directory"); + let tmpdir2 = tempdir().expect("failed to create temp2 directory"); + let f = tmpdir.path().join("protols.toml"); + std::fs::write(f, include_str!("input/protols-valid.toml")).unwrap(); + + let mut ws = WorkspaceProtoConfigs::new(); + ws.add_workspace(&WorkspaceFolder { + uri: Url::from_directory_path(tmpdir.path()).unwrap(), + name: "Test".to_string(), + }); + + ws.add_workspace(&WorkspaceFolder { + uri: Url::from_directory_path(tmpdir2.path()).unwrap(), + name: "Test2".to_string(), + }); + + let inworkspace = Url::from_file_path(tmpdir.path().join("foobar.proto")).unwrap(); + let outworkspace = + Url::from_file_path(tempdir().unwrap().path().join("out.proto")).unwrap(); + let inworkspace2 = Url::from_file_path(tmpdir2.path().join("foobar.proto")).unwrap(); + + assert!(ws.get_formatter_for_uri(&outworkspace).is_none()); + assert_eq!( + ws.get_formatter_for_uri(&inworkspace).unwrap().path, + "/usr/bin/clang-format" + ); + assert_eq!( + ws.get_formatter_for_uri(&inworkspace2).unwrap().path, + "clang-format" + ); + } +} diff --git a/src/formatter/clang.rs b/src/formatter/clang.rs index fa59344..e3fdb4f 100644 --- a/src/formatter/clang.rs +++ b/src/formatter/clang.rs @@ -1,7 +1,6 @@ #![allow(clippy::needless_late_init)] use std::{ borrow::Cow, - error::Error, fs::File, io::Write, path::{Path, PathBuf}, @@ -16,8 +15,8 @@ use tempfile::{tempdir, TempDir}; use super::ProtoFormatter; pub struct ClangFormatter { - path: String, - working_dir: Option, + pub path: String, + working_dir: String, temp_dir: TempDir, } @@ -67,15 +66,12 @@ impl Replacement<'_> { } impl ClangFormatter { - pub fn new(path: &str, workdir: Option<&str>) -> Result> { - let mut c = Command::new(path); - c.arg("--version").status()?; - - Ok(Self { - temp_dir: tempdir()?, - path: path.to_owned(), - working_dir: workdir.map(ToOwned::to_owned), - }) + pub fn new(cmd: &str, wdir: &str) -> Self { + Self { + temp_dir: tempdir().expect("faile to creat temp dir"), + path: cmd.to_owned(), + working_dir: wdir.to_owned(), + } } fn get_temp_file_path(&self, content: &str) -> Option { @@ -87,11 +83,12 @@ impl ClangFormatter { fn get_command(&self, f: &str, u: &Path) -> Option { let mut c = Command::new(self.path.as_str()); - if let Some(wd) = self.working_dir.as_ref() { - c.current_dir(wd.as_str()); - } + c.current_dir(self.working_dir.as_str()); c.stdin(File::open(u).ok()?); - c.args(["--output-replacements-xml", format!("--assume-filename={f}").as_str()]); + c.args([ + "--output-replacements-xml", + format!("--assume-filename={f}").as_str(), + ]); Some(c) } @@ -122,7 +119,12 @@ impl ProtoFormatter for ClangFormatter { self.output_to_textedit(&String::from_utf8_lossy(&output.stdout), content) } - fn format_document_range(&self, r: &Range, filename: &str, content: &str) -> Option> { + fn format_document_range( + &self, + r: &Range, + filename: &str, + content: &str, + ) -> Option> { let p = self.get_temp_file_path(content)?; let start = r.start.line + 1; let end = r.end.line + 1; diff --git a/src/formatter/mod.rs b/src/formatter/mod.rs index d5e1993..5cb3af5 100644 --- a/src/formatter/mod.rs +++ b/src/formatter/mod.rs @@ -4,5 +4,10 @@ pub mod clang; pub trait ProtoFormatter: Sized { fn format_document(&self, filename: &str, content: &str) -> Option>; - fn format_document_range(&self, r: &Range, filename: &str, content: &str) -> Option>; + fn format_document_range( + &self, + r: &Range, + filename: &str, + content: &str, + ) -> Option>; } diff --git a/src/lsp.rs b/src/lsp.rs index 0d9b59a..715825c 100644 --- a/src/lsp.rs +++ b/src/lsp.rs @@ -1,8 +1,7 @@ -use std::collections::HashMap; -use std::fs::read_to_string; use std::ops::ControlFlow; use std::sync::mpsc; use std::thread; +use std::{collections::HashMap, fs::read_to_string}; use tracing::{error, info}; use async_lsp::lsp_types::{ @@ -22,7 +21,6 @@ use async_lsp::lsp_types::{ use async_lsp::{LanguageClient, LanguageServer, ResponseError}; use futures::future::BoxFuture; -use crate::formatter::clang::ClangFormatter; use crate::formatter::ProtoFormatter; use crate::server::ProtoLanguageServer; @@ -77,20 +75,12 @@ impl LanguageServer for ProtoLanguageServer { }; let mut workspace_capabilities = None; - let mut formatter_provider = None; - let mut formatter_range_provider = None; + if let Some(folders) = params.workspace_folders { - if let Ok(f) = - ClangFormatter::new("clang-format", folders.first().map(|f| f.uri.path())) - { - self.state.add_formatter(f); - formatter_provider = Some(OneOf::Left(true)); - formatter_range_provider = Some(OneOf::Left(true)); - info!("Setting formatting server capability"); - } for workspace in folders { info!("Workspace folder: {workspace:?}"); - self.state.add_workspace_folder_async(workspace, tx.clone()) + self.configs.add_workspace(&workspace); + self.state.add_workspace_folder_async(workspace, tx.clone()); } workspace_capabilities = Some(WorkspaceServerCapabilities { workspace_folders: Some(WorkspaceFoldersServerCapabilities { @@ -134,8 +124,8 @@ impl LanguageServer for ProtoLanguageServer { document_symbol_provider: Some(OneOf::Left(true)), completion_provider: Some(CompletionOptions::default()), rename_provider: Some(rename_provider), - document_formatting_provider: formatter_provider, - document_range_formatting_provider: formatter_range_provider, + document_formatting_provider: Some(OneOf::Left(true)), + document_range_formatting_provider: Some(OneOf::Left(true)), references_provider: Some(OneOf::Left(true)), ..ServerCapabilities::default() @@ -373,8 +363,8 @@ impl LanguageServer for ProtoLanguageServer { let content = self.state.get_content(&uri); let response = self - .state - .get_formatter() + .configs + .get_formatter_for_uri(&uri) .and_then(|f| f.format_document(uri.path(), content.as_str())); Box::pin(async move { Ok(response) }) @@ -388,8 +378,8 @@ impl LanguageServer for ProtoLanguageServer { let content = self.state.get_content(&uri); let response = self - .state - .get_formatter() + .configs + .get_formatter_for_uri(&uri) .and_then(|f| f.format_document_range(¶ms.range, uri.path(), content.as_str())); Box::pin(async move { Ok(response) }) @@ -407,7 +397,15 @@ impl LanguageServer for ProtoLanguageServer { let uri = params.text_document.uri; let content = params.text_document.text; - if let Some(diagnostics) = self.state.upsert_file(&uri, content) { + let Some(diagnostics) = self.state.upsert_file(&uri, content) else { + return ControlFlow::Continue(()); + }; + + let Some(ws) = self.configs.get_config_for_uri(&uri) else { + return ControlFlow::Continue(()); + }; + + if !ws.config.disable_parse_diagnostics { if let Err(e) = self.client.publish_diagnostics(diagnostics) { error!(error=%e, "failed to publish diagnostics") } @@ -419,11 +417,20 @@ impl LanguageServer for ProtoLanguageServer { let uri = params.text_document.uri; let content = params.content_changes[0].text.clone(); - if let Some(diagnostics) = self.state.upsert_file(&uri, content) { + let Some(diagnostics) = self.state.upsert_file(&uri, content) else { + return ControlFlow::Continue(()); + }; + + let Some(ws) = self.configs.get_config_for_uri(&uri) else { + return ControlFlow::Continue(()); + }; + + if !ws.config.disable_parse_diagnostics { if let Err(e) = self.client.publish_diagnostics(diagnostics) { error!(error=%e, "failed to publish diagnostics") } } + ControlFlow::Continue(()) } diff --git a/src/main.rs b/src/main.rs index ae4e89b..8a45be5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -9,6 +9,7 @@ use server::{ProtoLanguageServer, TickEvent}; use tower::ServiceBuilder; use tracing::Level; +mod config; mod formatter; mod lsp; mod nodekind; diff --git a/src/server.rs b/src/server.rs index 37d022e..a1aa956 100644 --- a/src/server.rs +++ b/src/server.rs @@ -1,13 +1,14 @@ use async_lsp::{router::Router, ClientSocket}; use std::ops::ControlFlow; -use crate::{formatter::clang::ClangFormatter, state::ProtoLanguageState}; +use crate::{config::workspace::WorkspaceProtoConfigs, state::ProtoLanguageState}; pub struct TickEvent; pub struct ProtoLanguageServer { pub client: ClientSocket, pub counter: i32, - pub state: ProtoLanguageState, + pub state: ProtoLanguageState, + pub configs: WorkspaceProtoConfigs, } impl ProtoLanguageServer { @@ -16,6 +17,7 @@ impl ProtoLanguageServer { client, counter: 0, state: ProtoLanguageState::new(), + configs: WorkspaceProtoConfigs::new(), }); router.event(Self::on_tick); router diff --git a/src/state.rs b/src/state.rs index 901d8c4..fc20510 100644 --- a/src/state.rs +++ b/src/state.rs @@ -15,25 +15,22 @@ use tree_sitter::Node; use walkdir::WalkDir; use crate::{ - formatter::ProtoFormatter, nodekind::NodeKind, parser::{ParsedTree, ProtoParser}, }; -pub struct ProtoLanguageState { +pub struct ProtoLanguageState { documents: Arc>>, trees: Arc>>, - formatter: Option, parser: Arc>, } -impl ProtoLanguageState { +impl ProtoLanguageState { pub fn new() -> Self { ProtoLanguageState { documents: Default::default(), trees: Default::default(), parser: Arc::new(Mutex::new(ProtoParser::new())), - formatter: Default::default(), } } @@ -97,14 +94,6 @@ impl ProtoLanguageState { Self::upsert_content_impl(parser, uri, content, docs, tree) } - pub fn add_formatter(&mut self, formatter: F) { - self.formatter.replace(formatter); - } - - pub fn get_formatter(&self) -> Option<&F> { - self.formatter.as_ref() - } - pub fn add_workspace_folder_async( &mut self, workspace: WorkspaceFolder, diff --git a/src/workspace/definition.rs b/src/workspace/definition.rs index 7d425a0..2e723d4 100644 --- a/src/workspace/definition.rs +++ b/src/workspace/definition.rs @@ -1,10 +1,8 @@ use async_lsp::lsp_types::Location; -use crate::{ - formatter::ProtoFormatter, state::ProtoLanguageState, utils::split_identifier_package, -}; +use crate::{state::ProtoLanguageState, utils::split_identifier_package}; -impl ProtoLanguageState { +impl ProtoLanguageState { pub fn definition(&self, curr_package: &str, identifier: &str) -> Vec { let (mut package, identifier) = split_identifier_package(identifier); if package.is_empty() { @@ -23,7 +21,7 @@ impl ProtoLanguageState { mod test { use insta::assert_yaml_snapshot; - use crate::{formatter::clang::ClangFormatter, state::ProtoLanguageState}; + use crate::state::ProtoLanguageState; #[test] fn workspace_test_definition() { @@ -35,7 +33,7 @@ mod test { let b = include_str!("input/b.proto"); let c = include_str!("input/c.proto"); - let mut state: ProtoLanguageState = ProtoLanguageState::new(); + let mut state: ProtoLanguageState = ProtoLanguageState::new(); state.upsert_file(&a_uri, a.to_owned()); state.upsert_file(&b_uri, b.to_owned()); state.upsert_file(&c_uri, c.to_owned()); diff --git a/src/workspace/hover.rs b/src/workspace/hover.rs index 7eb0e4d..29e3b70 100644 --- a/src/workspace/hover.rs +++ b/src/workspace/hover.rs @@ -2,9 +2,7 @@ use std::{collections::HashMap, sync::LazyLock}; use async_lsp::lsp_types::{MarkupContent, MarkupKind}; -use crate::{ - formatter::ProtoFormatter, state::ProtoLanguageState, utils::split_identifier_package, -}; +use crate::{state::ProtoLanguageState, utils::split_identifier_package}; static BUITIN_DOCS: LazyLock> = LazyLock::new(|| { HashMap::from([ @@ -587,7 +585,7 @@ message Value { ]) }); -impl ProtoLanguageState { +impl ProtoLanguageState { pub fn hover(&self, curr_package: &str, identifier: &str) -> Option { if let Some(docs) = BUITIN_DOCS.get(identifier) { return Some(MarkupContent { @@ -634,7 +632,7 @@ impl ProtoLanguageState { mod test { use insta::assert_yaml_snapshot; - use crate::{formatter::clang::ClangFormatter, state::ProtoLanguageState}; + use crate::state::ProtoLanguageState; #[test] fn workspace_test_hover() { @@ -646,7 +644,7 @@ mod test { let b = include_str!("input/b.proto"); let c = include_str!("input/c.proto"); - let mut state: ProtoLanguageState = ProtoLanguageState::new(); + let mut state: ProtoLanguageState = ProtoLanguageState::new(); state.upsert_file(&a_uri, a.to_owned()); state.upsert_file(&b_uri, b.to_owned()); state.upsert_file(&c_uri, c.to_owned()); diff --git a/src/workspace/rename.rs b/src/workspace/rename.rs index 7b901d2..46bd91d 100644 --- a/src/workspace/rename.rs +++ b/src/workspace/rename.rs @@ -1,11 +1,11 @@ -use crate::{formatter::ProtoFormatter, utils::split_identifier_package}; +use crate::utils::split_identifier_package; use std::collections::HashMap; use async_lsp::lsp_types::{Location, TextEdit, Url}; use crate::state::ProtoLanguageState; -impl ProtoLanguageState { +impl ProtoLanguageState { pub fn rename_fields( &self, current_package: &str, @@ -63,7 +63,7 @@ impl ProtoLanguageState { mod test { use insta::assert_yaml_snapshot; - use crate::{formatter::clang::ClangFormatter, state::ProtoLanguageState}; + use crate::state::ProtoLanguageState; #[test] fn test_rename() { @@ -75,7 +75,7 @@ mod test { let b = include_str!("input/b.proto"); let c = include_str!("input/c.proto"); - let mut state: ProtoLanguageState = ProtoLanguageState::new(); + let mut state: ProtoLanguageState = ProtoLanguageState::new(); state.upsert_file(&a_uri, a.to_owned()); state.upsert_file(&b_uri, b.to_owned()); state.upsert_file(&c_uri, c.to_owned()); @@ -99,7 +99,7 @@ mod test { let b = include_str!("input/b.proto"); let c = include_str!("input/c.proto"); - let mut state: ProtoLanguageState = ProtoLanguageState::new(); + let mut state: ProtoLanguageState = ProtoLanguageState::new(); state.upsert_file(&a_uri, a.to_owned()); state.upsert_file(&b_uri, b.to_owned()); state.upsert_file(&c_uri, c.to_owned());