├── .gitignore ├── Cargo.lock ├── Cargo.toml ├── README.md ├── extension.toml └── src └── python_lsp.rs /.gitignore: -------------------------------------------------------------------------------- 1 | /.direnv 2 | .idea 3 | **/target 4 | **/cargo-target 5 | /zed.xcworkspace 6 | .DS_Store 7 | /plugins/bin 8 | /script/node_modules 9 | /crates/theme/schemas/theme.json 10 | /crates/collab/seed.json 11 | /crates/zed/resources/flatpak/flatpak-cargo-sources.json 12 | /dev.zed.Zed*.json 13 | /assets/*licenses.md 14 | **/venv 15 | .build 16 | *.wasm 17 | Packages 18 | *.xcodeproj 19 | xcuserdata/ 20 | DerivedData/ 21 | .swiftpm/config/registries.json 22 | .swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata 23 | .netrc 24 | .swiftpm 25 | **/*.db 26 | .pytest_cache 27 | .venv 28 | .blob_store 29 | .vscode 30 | .wrangler 31 | .flatpak-builder 32 | 33 | # Don't commit any secrets to the repo. 34 | .env.secret.toml 35 | -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "anyhow" 7 | version = "1.0.86" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" 10 | 11 | [[package]] 12 | name = "bitflags" 13 | version = "2.6.0" 14 | source = "registry+https://github.com/rust-lang/crates.io-index" 15 | checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" 16 | 17 | [[package]] 18 | name = "equivalent" 19 | version = "1.0.1" 20 | source = "registry+https://github.com/rust-lang/crates.io-index" 21 | checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" 22 | 23 | [[package]] 24 | name = "hashbrown" 25 | version = "0.14.5" 26 | source = "registry+https://github.com/rust-lang/crates.io-index" 27 | checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" 28 | 29 | [[package]] 30 | name = "heck" 31 | version = "0.4.1" 32 | source = "registry+https://github.com/rust-lang/crates.io-index" 33 | checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" 34 | dependencies = [ 35 | "unicode-segmentation", 36 | ] 37 | 38 | [[package]] 39 | name = "id-arena" 40 | version = "2.2.1" 41 | source = "registry+https://github.com/rust-lang/crates.io-index" 42 | checksum = "25a2bc672d1148e28034f176e01fffebb08b35768468cc954630da77a1449005" 43 | 44 | [[package]] 45 | name = "indexmap" 46 | version = "2.3.0" 47 | source = "registry+https://github.com/rust-lang/crates.io-index" 48 | checksum = "de3fc2e30ba82dd1b3911c8de1ffc143c74a914a14e99514d7637e3099df5ea0" 49 | dependencies = [ 50 | "equivalent", 51 | "hashbrown", 52 | "serde", 53 | ] 54 | 55 | [[package]] 56 | name = "itoa" 57 | version = "1.0.11" 58 | source = "registry+https://github.com/rust-lang/crates.io-index" 59 | checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" 60 | 61 | [[package]] 62 | name = "leb128" 63 | version = "0.2.5" 64 | source = "registry+https://github.com/rust-lang/crates.io-index" 65 | checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" 66 | 67 | [[package]] 68 | name = "log" 69 | version = "0.4.22" 70 | source = "registry+https://github.com/rust-lang/crates.io-index" 71 | checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" 72 | 73 | [[package]] 74 | name = "memchr" 75 | version = "2.7.4" 76 | source = "registry+https://github.com/rust-lang/crates.io-index" 77 | checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" 78 | 79 | [[package]] 80 | name = "proc-macro2" 81 | version = "1.0.86" 82 | source = "registry+https://github.com/rust-lang/crates.io-index" 83 | checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" 84 | dependencies = [ 85 | "unicode-ident", 86 | ] 87 | 88 | [[package]] 89 | name = "python-lsp-zed-extension" 90 | version = "0.0.1" 91 | dependencies = [ 92 | "zed_extension_api", 93 | ] 94 | 95 | [[package]] 96 | name = "quote" 97 | version = "1.0.36" 98 | source = "registry+https://github.com/rust-lang/crates.io-index" 99 | checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" 100 | dependencies = [ 101 | "proc-macro2", 102 | ] 103 | 104 | [[package]] 105 | name = "ryu" 106 | version = "1.0.18" 107 | source = "registry+https://github.com/rust-lang/crates.io-index" 108 | checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" 109 | 110 | [[package]] 111 | name = "semver" 112 | version = "1.0.23" 113 | source = "registry+https://github.com/rust-lang/crates.io-index" 114 | checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" 115 | 116 | [[package]] 117 | name = "serde" 118 | version = "1.0.206" 119 | source = "registry+https://github.com/rust-lang/crates.io-index" 120 | checksum = "5b3e4cd94123dd520a128bcd11e34d9e9e423e7e3e50425cb1b4b1e3549d0284" 121 | dependencies = [ 122 | "serde_derive", 123 | ] 124 | 125 | [[package]] 126 | name = "serde_derive" 127 | version = "1.0.206" 128 | source = "registry+https://github.com/rust-lang/crates.io-index" 129 | checksum = "fabfb6138d2383ea8208cf98ccf69cdfb1aff4088460681d84189aa259762f97" 130 | dependencies = [ 131 | "proc-macro2", 132 | "quote", 133 | "syn", 134 | ] 135 | 136 | [[package]] 137 | name = "serde_json" 138 | version = "1.0.124" 139 | source = "registry+https://github.com/rust-lang/crates.io-index" 140 | checksum = "66ad62847a56b3dba58cc891acd13884b9c61138d330c0d7b6181713d4fce38d" 141 | dependencies = [ 142 | "itoa", 143 | "memchr", 144 | "ryu", 145 | "serde", 146 | ] 147 | 148 | [[package]] 149 | name = "smallvec" 150 | version = "1.13.2" 151 | source = "registry+https://github.com/rust-lang/crates.io-index" 152 | checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" 153 | 154 | [[package]] 155 | name = "spdx" 156 | version = "0.10.6" 157 | source = "registry+https://github.com/rust-lang/crates.io-index" 158 | checksum = "47317bbaf63785b53861e1ae2d11b80d6b624211d42cb20efcd210ee6f8a14bc" 159 | dependencies = [ 160 | "smallvec", 161 | ] 162 | 163 | [[package]] 164 | name = "syn" 165 | version = "2.0.74" 166 | source = "registry+https://github.com/rust-lang/crates.io-index" 167 | checksum = "1fceb41e3d546d0bd83421d3409b1460cc7444cd389341a4c880fe7a042cb3d7" 168 | dependencies = [ 169 | "proc-macro2", 170 | "quote", 171 | "unicode-ident", 172 | ] 173 | 174 | [[package]] 175 | name = "unicode-ident" 176 | version = "1.0.12" 177 | source = "registry+https://github.com/rust-lang/crates.io-index" 178 | checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" 179 | 180 | [[package]] 181 | name = "unicode-segmentation" 182 | version = "1.11.0" 183 | source = "registry+https://github.com/rust-lang/crates.io-index" 184 | checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" 185 | 186 | [[package]] 187 | name = "unicode-xid" 188 | version = "0.2.4" 189 | source = "registry+https://github.com/rust-lang/crates.io-index" 190 | checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" 191 | 192 | [[package]] 193 | name = "wasm-encoder" 194 | version = "0.201.0" 195 | source = "registry+https://github.com/rust-lang/crates.io-index" 196 | checksum = "b9c7d2731df60006819b013f64ccc2019691deccf6e11a1804bc850cd6748f1a" 197 | dependencies = [ 198 | "leb128", 199 | ] 200 | 201 | [[package]] 202 | name = "wasm-metadata" 203 | version = "0.201.0" 204 | source = "registry+https://github.com/rust-lang/crates.io-index" 205 | checksum = "0fd83062c17b9f4985d438603cde0a5e8c5c8198201a6937f778b607924c7da2" 206 | dependencies = [ 207 | "anyhow", 208 | "indexmap", 209 | "serde", 210 | "serde_derive", 211 | "serde_json", 212 | "spdx", 213 | "wasm-encoder", 214 | "wasmparser", 215 | ] 216 | 217 | [[package]] 218 | name = "wasmparser" 219 | version = "0.201.0" 220 | source = "registry+https://github.com/rust-lang/crates.io-index" 221 | checksum = "84e5df6dba6c0d7fafc63a450f1738451ed7a0b52295d83e868218fa286bf708" 222 | dependencies = [ 223 | "bitflags", 224 | "indexmap", 225 | "semver", 226 | ] 227 | 228 | [[package]] 229 | name = "wit-bindgen" 230 | version = "0.22.0" 231 | source = "registry+https://github.com/rust-lang/crates.io-index" 232 | checksum = "288f992ea30e6b5c531b52cdd5f3be81c148554b09ea416f058d16556ba92c27" 233 | dependencies = [ 234 | "bitflags", 235 | "wit-bindgen-rt", 236 | "wit-bindgen-rust-macro", 237 | ] 238 | 239 | [[package]] 240 | name = "wit-bindgen-core" 241 | version = "0.22.0" 242 | source = "registry+https://github.com/rust-lang/crates.io-index" 243 | checksum = "e85e72719ffbccf279359ad071497e47eb0675fe22106dea4ed2d8a7fcb60ba4" 244 | dependencies = [ 245 | "anyhow", 246 | "wit-parser", 247 | ] 248 | 249 | [[package]] 250 | name = "wit-bindgen-rt" 251 | version = "0.22.0" 252 | source = "registry+https://github.com/rust-lang/crates.io-index" 253 | checksum = "fcb8738270f32a2d6739973cbbb7c1b6dd8959ce515578a6e19165853272ee64" 254 | 255 | [[package]] 256 | name = "wit-bindgen-rust" 257 | version = "0.22.0" 258 | source = "registry+https://github.com/rust-lang/crates.io-index" 259 | checksum = "d8a39a15d1ae2077688213611209849cad40e9e5cccf6e61951a425850677ff3" 260 | dependencies = [ 261 | "anyhow", 262 | "heck", 263 | "indexmap", 264 | "wasm-metadata", 265 | "wit-bindgen-core", 266 | "wit-component", 267 | ] 268 | 269 | [[package]] 270 | name = "wit-bindgen-rust-macro" 271 | version = "0.22.0" 272 | source = "registry+https://github.com/rust-lang/crates.io-index" 273 | checksum = "d376d3ae5850526dfd00d937faea0d81a06fa18f7ac1e26f386d760f241a8f4b" 274 | dependencies = [ 275 | "anyhow", 276 | "proc-macro2", 277 | "quote", 278 | "syn", 279 | "wit-bindgen-core", 280 | "wit-bindgen-rust", 281 | ] 282 | 283 | [[package]] 284 | name = "wit-component" 285 | version = "0.201.0" 286 | source = "registry+https://github.com/rust-lang/crates.io-index" 287 | checksum = "421c0c848a0660a8c22e2fd217929a0191f14476b68962afd2af89fd22e39825" 288 | dependencies = [ 289 | "anyhow", 290 | "bitflags", 291 | "indexmap", 292 | "log", 293 | "serde", 294 | "serde_derive", 295 | "serde_json", 296 | "wasm-encoder", 297 | "wasm-metadata", 298 | "wasmparser", 299 | "wit-parser", 300 | ] 301 | 302 | [[package]] 303 | name = "wit-parser" 304 | version = "0.201.0" 305 | source = "registry+https://github.com/rust-lang/crates.io-index" 306 | checksum = "196d3ecfc4b759a8573bf86a9b3f8996b304b3732e4c7de81655f875f6efdca6" 307 | dependencies = [ 308 | "anyhow", 309 | "id-arena", 310 | "indexmap", 311 | "log", 312 | "semver", 313 | "serde", 314 | "serde_derive", 315 | "serde_json", 316 | "unicode-xid", 317 | "wasmparser", 318 | ] 319 | 320 | [[package]] 321 | name = "zed_extension_api" 322 | version = "0.0.6" 323 | source = "registry+https://github.com/rust-lang/crates.io-index" 324 | checksum = "77ca8bcaea3feb2d2ce9dbeb061ee48365312a351faa7014c417b0365fe9e459" 325 | dependencies = [ 326 | "serde", 327 | "serde_json", 328 | "wit-bindgen", 329 | ] 330 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "python-lsp-zed-extension" 3 | version = "0.0.1" 4 | edition = "2021" 5 | 6 | [lib] 7 | path = "src/python_lsp.rs" 8 | crate-type = ["cdylib"] 9 | 10 | [dependencies] 11 | zed_extension_api = "0.0.6" 12 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Python LSP Server Zed Extension 2 | 3 | This extension uses the [Python Language Server](https://github.com/python-lsp/python-lsp-server) to provide language support for Python in Zed. It has providers for `jedi`, `mccabe`, `pycodestyle`, `pydocstyle`, `pyflakes`, `pylint`, `rope`, `yapf`, `mypy`, and more. 4 | 5 | ## Installation 6 | 7 | Before installing this extension, install the [Python Language Server](https://github.com/python-lsp/python-lsp-server) and ensure that it is on your `PATH`. Example, using `pipx`: 8 | 9 | ``` 10 | pipx install "python-lsp-server[all]" 11 | ``` 12 | 13 | All extensions to the `python-lsp-server` must be installed to the same virtualenv that you install the server into. 14 | 15 | 16 | ## Configuration 17 | 18 | Use any of the [configuration settings](https://github.com/python-lsp/python-lsp-server/blob/develop/CONFIGURATION.md) that pylsp supports within your zed config under `pylsp.settings`. Here's an example that disables the `E501` line length warning: 19 | 20 | ```jsonc 21 | "pylsp": { 22 | "settings": { 23 | "plugins": { 24 | "pycodestyle": { 25 | "enabled": true, 26 | "ignore": ["E501"] 27 | } 28 | } 29 | } 30 | } 31 | ``` 32 | -------------------------------------------------------------------------------- /extension.toml: -------------------------------------------------------------------------------- 1 | id = "pylsp" 2 | name = "Python LSP" 3 | version = "0.0.1" 4 | schema_version = 1 5 | authors = ["Kyle Kelley "] 6 | description = "python-lsp extension for Zed" 7 | repository = "https://github.com/rgbkrk/python-lsp-zed-extension" 8 | 9 | [language_servers.pylsp] 10 | name = "pylsp" 11 | languages = ["Python"] 12 | -------------------------------------------------------------------------------- /src/python_lsp.rs: -------------------------------------------------------------------------------- 1 | use zed::LanguageServerId; 2 | use zed_extension_api::{self as zed, serde_json::json, settings::LspSettings, Result}; 3 | 4 | struct PythonLspExtension {} 5 | 6 | impl zed::Extension for PythonLspExtension { 7 | fn new() -> Self { 8 | Self {} 9 | } 10 | 11 | fn language_server_command( 12 | &mut self, 13 | _language_server_id: &LanguageServerId, 14 | worktree: &zed::Worktree, 15 | ) -> Result { 16 | match worktree.which("pylsp") { 17 | Some(path) => Ok(zed::Command { 18 | command: path, 19 | args: vec!["-v".into()], 20 | env: vec![], 21 | }), 22 | None => Err("Unable to find pylsp from worktree".into()), 23 | } 24 | } 25 | 26 | fn language_server_initialization_options( 27 | &mut self, 28 | server_id: &LanguageServerId, 29 | worktree: &zed_extension_api::Worktree, 30 | ) -> Result> { 31 | let settings = LspSettings::for_worktree(server_id.as_ref(), worktree) 32 | .ok() 33 | .and_then(|lsp_settings| lsp_settings.initialization_options.clone()) 34 | .unwrap_or_default(); 35 | Ok(Some(settings)) 36 | } 37 | 38 | fn language_server_workspace_configuration( 39 | &mut self, 40 | server_id: &LanguageServerId, 41 | worktree: &zed_extension_api::Worktree, 42 | ) -> Result> { 43 | let settings = LspSettings::for_worktree(server_id.as_ref(), worktree) 44 | .ok() 45 | .and_then(|lsp_settings| lsp_settings.settings.clone()) 46 | .unwrap_or_default(); 47 | 48 | // pylsp expects a top level `pylsp` key, so we'll wrap the settings 49 | let settings = json!({ 50 | "pylsp": settings 51 | }); 52 | 53 | Ok(Some(settings)) 54 | } 55 | } 56 | 57 | zed::register_extension!(PythonLspExtension); 58 | --------------------------------------------------------------------------------