lsp-pyls.el (18918B)
1 ;;; lsp-pyls.el --- pyls configuration -*- lexical-binding: t; -*- 2 3 ;; Copyright (C) 2019 Ivan Yonchovski 4 5 ;; Author: Ivan Yonchovski <yyoncho@gmail.com> 6 ;; Keywords: 7 8 ;; This program is free software; you can redistribute it and/or modify 9 ;; it under the terms of the GNU General Public License as published by 10 ;; the Free Software Foundation, either version 3 of the License, or 11 ;; (at your option) any later version. 12 13 ;; This program is distributed in the hope that it will be useful, 14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 ;; GNU General Public License for more details. 17 18 ;; You should have received a copy of the GNU General Public License 19 ;; along with this program. If not, see <https://www.gnu.org/licenses/>. 20 21 ;;; Commentary: 22 23 ;; PYLS configuration 24 25 ;;; Code: 26 27 (require 'lsp-mode) 28 29 (defgroup lsp-pyls nil 30 "LSP support for Python, using Palantir's Python Language Server." 31 :group 'lsp-mode 32 :link '(url-link "https://github.com/palantir/python-language-server") 33 :package-version '(lsp-mode . "6.1")) 34 35 (defcustom lsp-clients-python-library-directories '("/usr/") 36 "List of directories which will be considered to be libraries." 37 :risky t 38 :type '(repeat string) 39 :group 'lsp-pyls 40 :package-version '(lsp-mode . "6.1")) 41 42 (define-obsolete-variable-alias 43 'lsp-clients-python-command 44 'lsp-pyls-server-command 45 "6.1") 46 47 (defcustom lsp-pyls-disable-warning nil 48 "Disable Palantir python-language-server deprecation warning" 49 :group 'lsp-pyls 50 :type 'boolean 51 :package-version '(lsp-mode . "8.0.0")) 52 53 (defcustom lsp-pyls-server-command '("pyls") 54 "Command to start pyls." 55 :risky t 56 :group 'lsp-pyls 57 :type '(repeat string) 58 :package-version '(lsp-mode . "6.1")) 59 60 (defcustom lsp-pyls-configuration-sources ["pycodestyle"] 61 "List of configuration sources to use." 62 :type '(repeat string) 63 :group 'lsp-pyls 64 :package-version '(lsp-mode . "6.1")) 65 66 (defcustom lsp-pyls-plugins-jedi-completion-enabled t 67 "Enable or disable the plugin." 68 :type 'boolean 69 :group 'lsp-pyls 70 :package-version '(lsp-mode . "6.1")) 71 72 (defcustom lsp-pyls-plugins-jedi-completion-include-params t 73 "Auto-completes methods and classes with tabstops for each 74 parameter." 75 :type 'boolean 76 :group 'lsp-pyls 77 :package-version '(lsp-mode . "6.1")) 78 79 (defcustom lsp-pyls-plugins-jedi-definition-enabled t 80 "Enable or disable the plugin." 81 :type 'boolean 82 :group 'lsp-pyls 83 :package-version '(lsp-mode . "6.1")) 84 85 (defcustom lsp-pyls-plugins-jedi-definition-follow-imports t 86 "The goto call will follow imports." 87 :type 'boolean 88 :group 'lsp-pyls 89 :package-version '(lsp-mode . "6.1")) 90 91 (defcustom lsp-pyls-plugins-jedi-definition-follow-builtin-imports t 92 "If follow_imports is True will decide if it follow builtin 93 imports." 94 :type 'boolean 95 :group 'lsp-pyls 96 :package-version '(lsp-mode . "6.1")) 97 98 (defcustom lsp-pyls-plugins-jedi-hover-enabled t 99 "Enable or disable the plugin." 100 :type 'boolean 101 :group 'lsp-pyls 102 :package-version '(lsp-mode . "6.1")) 103 104 (defcustom lsp-pyls-plugins-jedi-references-enabled t 105 "Enable or disable the plugin." 106 :type 'boolean 107 :group 'lsp-pyls 108 :package-version '(lsp-mode . "6.1")) 109 110 (defcustom lsp-pyls-plugins-jedi-signature-help-enabled t 111 "Enable or disable the plugin." 112 :type 'boolean 113 :group 'lsp-pyls 114 :package-version '(lsp-mode . "6.1")) 115 116 (defcustom lsp-pyls-plugins-jedi-symbols-enabled t 117 "Enable or disable the plugin." 118 :type 'boolean 119 :group 'lsp-pyls 120 :package-version '(lsp-mode . "6.1")) 121 122 (defcustom lsp-pyls-plugins-jedi-symbols-all-scopes t 123 "If True lists the names of all scopes instead of only the 124 module namespace." 125 :type 'boolean 126 :group 'lsp-pyls 127 :package-version '(lsp-mode . "6.1")) 128 129 (defcustom lsp-pyls-plugins-mccabe-enabled t 130 "Enable or disable the plugin." 131 :type 'boolean 132 :group 'lsp-pyls 133 :package-version '(lsp-mode . "6.1")) 134 135 (defcustom lsp-pyls-plugins-mccabe-threshold 15 136 "The minimum threshold that triggers warnings about cyclomatic 137 complexity." 138 :type 'number 139 :group 'lsp-pyls 140 :package-version '(lsp-mode . "6.1")) 141 142 (defcustom lsp-pyls-plugins-preload-enabled t 143 "Enable or disable the plugin." 144 :type 'boolean 145 :group 'lsp-pyls 146 :package-version '(lsp-mode . "6.1")) 147 148 (defcustom lsp-pyls-plugins-preload-modules nil 149 "List of modules to import on startup" 150 :type '(repeat string) 151 :group 'lsp-pyls 152 :package-version '(lsp-mode . "6.1")) 153 154 (defcustom lsp-pyls-plugins-pylint-enabled nil 155 "Enable or disable the plugin." 156 :type 'boolean 157 :group 'lsp-pyls 158 :package-version '(lsp-mode . "6.1")) 159 160 (defcustom lsp-pyls-plugins-pylint-args [] 161 "Arguments, passed to pylint" 162 :risky t 163 :type 'lsp-string-vector 164 :group 'lsp-pyls 165 :package-version '(lsp-mode . "6.1")) 166 167 (defcustom lsp-pyls-plugins-pycodestyle-enabled t 168 "Enable or disable the plugin." 169 :type 'boolean 170 :group 'lsp-pyls 171 :package-version '(lsp-mode . "6.1")) 172 173 (defcustom lsp-pyls-plugins-pycodestyle-exclude nil 174 "Exclude files or directories which match these patterns." 175 :type '(repeat string) 176 :group 'lsp-pyls 177 :package-version '(lsp-mode . "6.1")) 178 179 (defcustom lsp-pyls-plugins-pycodestyle-filename nil 180 "When parsing directories, only check filenames matching these 181 patterns." 182 :type '(repeat string) 183 :group 'lsp-pyls 184 :package-version '(lsp-mode . "6.1")) 185 186 (defcustom lsp-pyls-plugins-pycodestyle-select nil 187 "Select errors and warnings" 188 :type '(repeat string) 189 :group 'lsp-pyls 190 :package-version '(lsp-mode . "6.1")) 191 192 (defcustom lsp-pyls-plugins-pycodestyle-ignore nil 193 "Ignore errors and warnings" 194 :type '(repeat string) 195 :group 'lsp-pyls 196 :package-version '(lsp-mode . "6.1")) 197 198 (defcustom lsp-pyls-plugins-pycodestyle-hang-closing nil 199 "Hang closing bracket instead of matching indentation of 200 opening bracket's line." 201 :type 'boolean 202 :group 'lsp-pyls 203 :package-version '(lsp-mode . "6.1")) 204 205 (defcustom lsp-pyls-plugins-pycodestyle-max-line-length nil 206 "Set maximum allowed line length." 207 :type 'number 208 :group 'lsp-pyls 209 :package-version '(lsp-mode . "6.1")) 210 211 (defcustom lsp-pyls-plugins-pydocstyle-enabled nil 212 "Enable or disable the plugin." 213 :type 'boolean 214 :group 'lsp-pyls 215 :package-version '(lsp-mode . "6.1")) 216 217 (defcustom lsp-pyls-plugins-pydocstyle-convention nil 218 "Choose the basic list of checked errors by specifying an 219 existing convention." 220 :type '(choice (:tag "pep257" "numpy")) 221 :group 'lsp-pyls 222 :package-version '(lsp-mode . "6.1")) 223 224 (defcustom lsp-pyls-plugins-pydocstyle-add-ignore nil 225 "Ignore errors and warnings in addition to the specified 226 convention." 227 :type '(repeat string) 228 :group 'lsp-pyls 229 :package-version '(lsp-mode . "6.1")) 230 231 (defcustom lsp-pyls-plugins-pydocstyle-add-select nil 232 "Select errors and warnings in addition to the specified 233 convention." 234 :type '(repeat string) 235 :group 'lsp-pyls 236 :package-version '(lsp-mode . "6.1")) 237 238 (defcustom lsp-pyls-plugins-pydocstyle-ignore nil 239 "Ignore errors and warnings" 240 :type '(repeat string) 241 :group 'lsp-pyls 242 :package-version '(lsp-mode . "6.1")) 243 244 (defcustom lsp-pyls-plugins-pydocstyle-select nil 245 "Select errors and warnings" 246 :type '(repeat string) 247 :group 'lsp-pyls 248 :package-version '(lsp-mode . "6.1")) 249 250 (defcustom lsp-pyls-plugins-pydocstyle-match "(?!test_).*\\.py" 251 "Check only files that exactly match the given regular 252 expression; default is to match files that don't start with 253 `test_' but end with `.py'." 254 :type 'string 255 :group 'lsp-pyls 256 :package-version '(lsp-mode . "6.1")) 257 258 (defcustom lsp-pyls-plugins-pydocstyle-match-dir "[^\\.].*" 259 "Search only dirs that exactly match the given regular 260 expression; default is to match dirs which do not begin with a 261 dot." 262 :type 'string 263 :group 'lsp-pyls 264 :package-version '(lsp-mode . "6.1")) 265 266 (defcustom lsp-pyls-plugins-pyflakes-enabled t 267 "Enable or disable the plugin." 268 :type 'boolean 269 :group 'lsp-pyls 270 :package-version '(lsp-mode . "6.1")) 271 272 (defcustom lsp-pyls-plugins-rope-completion-enabled nil 273 "Enable or disable the plugin." 274 :type 'boolean 275 :group 'lsp-pyls 276 :package-version '(lsp-mode . "6.1")) 277 278 (defcustom lsp-pyls-plugins-autopep8-enabled t 279 "Enable or disable the plugin." 280 :type 'boolean 281 :group 'lsp-pyls 282 :package-version '(lsp-mode . "6.2")) 283 284 (defcustom lsp-pyls-plugins-yapf-enabled nil 285 "Enable or disable the plugin." 286 :type 'boolean 287 :group 'lsp-pyls 288 :package-version '(lsp-mode . "6.1")) 289 290 (defcustom lsp-pyls-rope-extension-modules nil 291 "Builtin and c-extension modules that are allowed to be 292 imported and inspected by rope." 293 :type 'string 294 :group 'lsp-pyls 295 :package-version '(lsp-mode . "6.1")) 296 297 (defcustom lsp-pyls-rope-rope-folder nil 298 "The name of the folder in which rope stores project 299 configurations and data. Pass `nil` for not using such a folder 300 at all." 301 :type '(repeat string) 302 :group 'lsp-pyls 303 :package-version '(lsp-mode . "6.1")) 304 305 (defcustom lsp-pyls-plugins-flake8-enabled nil 306 "Enable or disable the plugin." 307 :type 'boolean 308 :group 'lsp-pyls 309 :package-version '(lsp-mode . "6.2")) 310 311 (defcustom lsp-pyls-plugins-flake8-exclude nil 312 "List of glob patterns to exclude from checks." 313 :type '(repeat string) 314 :group 'lsp-pyls 315 :package-version '(lsp-mode . "6.2")) 316 317 (defcustom lsp-pyls-plugins-flake8-filename nil 318 "List of glob patterns to include for checks." 319 :type '(repeat string) 320 :group 'lsp-pyls 321 :package-version '(lsp-mode . "6.2")) 322 323 (defcustom lsp-pyls-plugins-flake8-hang-closing nil 324 "Toggle whether pycodestyle should enforce matching the indentation of the 325 opening bracket’s line. When you specify this, it will prefer that you hang the 326 closing bracket rather than match the indentation." 327 :type 'boolean 328 :group 'lsp-pyls 329 :package-version '(lsp-mode . "6.2")) 330 331 (defcustom lsp-pyls-plugins-flake8-ignore nil 332 "A list of codes to ignore." 333 :type '(repeat string) 334 :group 'lsp-pyls 335 :package-version '(lsp-mode . "6.2")) 336 337 (defcustom lsp-pyls-plugins-flake8-max-line-length nil 338 "Set the maximum length that any line (with some exceptions) may be. 339 Exceptions include lines that are either strings or comments which are 340 entirely URLs." 341 :type 'integer 342 :group 'lsp-pyls 343 :package-version '(lsp-mode . "6.2")) 344 345 (defcustom lsp-pyls-plugins-flake8-select nil 346 "Specify the list of error codes you wish Flake8 to report. Similarly to 347 `lsp-pyls-plugins-flake8-ignore'. You can specify a portion of an error code to 348 get all that start with that string. For example, you can use E, E4, E43, and 349 E431" 350 :type '(repeat string) 351 :group 'lsp-pyls 352 :package-version '(lsp-mode . "6.2")) 353 354 (defcustom lsp-pyls-plugins-flake8-config nil 355 "A path to a config file that will be the only config file read and used. 356 This will cause Flake8 to ignore all other config files that exist. 357 358 NOTE: other parameters as `lsp-pyls-plugins-flake8-max-line-length' take 359 precedence over parameters referenced in config." 360 :type 'string 361 :group 'lsp-pyls 362 :package-version '(lsp-mode . "6.3")) 363 364 (defcustom lsp-pyls-plugins-jedi-use-pyenv-environment nil 365 "If enabled, pass the environment got by pyenv to jedi" 366 :type 'boolean 367 :group 'lsp-pyls 368 :package-version '(lsp-mode . "6.3")) 369 370 (defcustom lsp-pyls-plugins-jedi-environment nil 371 "Specify the environment that jedi runs on where <environment>/bin/python 372 should be the python executable. This option will be prioritized over 373 `lsp-pyls-plugins-jedi-use-pyenv-environment'." 374 :type 'string 375 :group 'lsp-pyls 376 :package-version '(lsp-mode . "6.3")) 377 378 (defcustom lsp-pyls-plugins-jedi-completion-fuzzy nil 379 "If enabled, uses fuzzy completion in jedi. Requires pyls >= 0.32.0 380 Can hit performance, as well as lsp-mode implements its own fuzzy search on 381 completion items." 382 :type 'boolean 383 :group 'lsp-pyls 384 :package-version '(lsp-mode . "7.0")) 385 386 (defcustom lsp-pyls-plugins-jedi-completion-include-class-objects t 387 "If enabled, adds class objects to completion in order to avoid snippet 388 with init args. 389 390 Has no effect if `lsp-pyls-plugins-jedi-completion-include-params' is disabled. 391 Requires pyls >= 0.33.0" 392 :type 'boolean 393 :group 'lsp-pyls 394 :package-version '(lsp-mode . "7.0")) 395 396 (defcustom lsp-pyls-rename-backend 'jedi 397 "Choose renaming backend. 398 399 Jedi is preferred but only works for python >= 3.6 and pyls >= 0.32.0 400 Beware that Jedi is lazy and doesn't scan the whole project. 401 So it will rename only references it can find." 402 :type '(choice (const :tag "jedi" jedi) 403 (const :tag "rope" rope)) 404 :group 'lsp-pyls 405 :package-version '(lsp-mode . "7.0")) 406 407 408 (defun lsp-pyls-get-pyenv-environment () 409 "Get the pyenv-managed environment for current workspace, where 410 <ENV>/bin/python is the corresponding Python executable" 411 (if lsp-pyls-plugins-jedi-environment 412 lsp-pyls-plugins-jedi-environment 413 (when lsp-pyls-plugins-jedi-use-pyenv-environment 414 (let ((pyenv-version (getenv "PYENV_VERSION")) 415 (root (lsp-seq-first (lsp-find-roots-for-workspace lsp--cur-workspace (lsp-session))))) 416 (when root 417 (setenv "PYENV_VERSION" nil) 418 (let* ((pyenv-command-path (executable-find "pyenv")) 419 (python-env (when pyenv-command-path 420 (f-parent 421 (f-parent 422 (shell-command-to-string 423 (format "PYENV_DIR='%s' %s which python" 424 root pyenv-command-path))))))) 425 (if python-env (lsp--info "Configure pyls with environment: %s" python-env) 426 (lsp--warn "Can't find the python environment for 427 %s even if 428 `lsp-pyls-plugins-jedi-use-pyenv-environment` is 429 enabled") root) 430 (setenv "PYENV_VERSION" pyenv-version) 431 python-env)))))) 432 433 (lsp-register-custom-settings 434 '(("pyls.rope.ropeFolder" lsp-pyls-rope-rope-folder) 435 ("pyls.rope.extensionModules" lsp-pyls-rope-extension-modules) 436 ("pyls.plugins.rope_rename.enabled" (lambda () (eq lsp-pyls-rename-backend 'rope)) t) 437 ("pyls.plugins.autopep8.enabled" lsp-pyls-plugins-autopep8-enabled t) 438 ("pyls.plugins.yapf.enabled" lsp-pyls-plugins-yapf-enabled t) 439 ("pyls.plugins.rope_completion.enabled" lsp-pyls-plugins-rope-completion-enabled t) 440 ("pyls.plugins.pyflakes.enabled" lsp-pyls-plugins-pyflakes-enabled t) 441 ("pyls.plugins.pydocstyle.matchDir" lsp-pyls-plugins-pydocstyle-match-dir) 442 ("pyls.plugins.pydocstyle.match" lsp-pyls-plugins-pydocstyle-match) 443 ("pyls.plugins.pydocstyle.select" lsp-pyls-plugins-pydocstyle-select) 444 ("pyls.plugins.pydocstyle.ignore" lsp-pyls-plugins-pydocstyle-ignore) 445 ("pyls.plugins.pydocstyle.addSelect" lsp-pyls-plugins-pydocstyle-add-select) 446 ("pyls.plugins.pydocstyle.addIgnore" lsp-pyls-plugins-pydocstyle-add-ignore) 447 ("pyls.plugins.pydocstyle.convention" lsp-pyls-plugins-pydocstyle-convention) 448 ("pyls.plugins.pydocstyle.enabled" lsp-pyls-plugins-pydocstyle-enabled t) 449 ("pyls.plugins.pycodestyle.maxLineLength" lsp-pyls-plugins-pycodestyle-max-line-length) 450 ("pyls.plugins.pycodestyle.hangClosing" lsp-pyls-plugins-pycodestyle-hang-closing t) 451 ("pyls.plugins.pycodestyle.ignore" lsp-pyls-plugins-pycodestyle-ignore) 452 ("pyls.plugins.pycodestyle.select" lsp-pyls-plugins-pycodestyle-select) 453 ("pyls.plugins.pycodestyle.filename" lsp-pyls-plugins-pycodestyle-filename) 454 ("pyls.plugins.pycodestyle.exclude" lsp-pyls-plugins-pycodestyle-exclude) 455 ("pyls.plugins.pycodestyle.enabled" lsp-pyls-plugins-pycodestyle-enabled t) 456 ("pyls.plugins.pylint.enabled" lsp-pyls-plugins-pylint-enabled t) 457 ("pyls.plugins.pylint.args" lsp-pyls-plugins-pylint-args) 458 ("pyls.plugins.flake8.enabled" lsp-pyls-plugins-flake8-enabled) 459 ("pyls.plugins.flake8.exclude" lsp-pyls-plugins-flake8-exclude) 460 ("pyls.plugins.flake8.filename" lsp-pyls-plugins-flake8-filename) 461 ("pyls.plugins.flake8.hangClosing" lsp-pyls-plugins-flake8-hang-closing) 462 ("pyls.plugins.flake8.ignore" lsp-pyls-plugins-flake8-ignore) 463 ("pyls.plugins.flake8.maxLineLength" lsp-pyls-plugins-flake8-max-line-length) 464 ("pyls.plugins.flake8.select" lsp-pyls-plugins-flake8-select) 465 ("pyls.plugins.flake8.config" lsp-pyls-plugins-flake8-config) 466 ("pyls.plugins.preload.modules" lsp-pyls-plugins-preload-modules) 467 ("pyls.plugins.preload.enabled" lsp-pyls-plugins-preload-enabled t) 468 ("pyls.plugins.mccabe.threshold" lsp-pyls-plugins-mccabe-threshold) 469 ("pyls.plugins.mccabe.enabled" lsp-pyls-plugins-mccabe-enabled t) 470 ("pyls.plugins.jedi_symbols.all_scopes" lsp-pyls-plugins-jedi-symbols-all-scopes t) 471 ("pyls.plugins.jedi_symbols.enabled" lsp-pyls-plugins-jedi-symbols-enabled t) 472 ("pyls.plugins.jedi_signature_help.enabled" lsp-pyls-plugins-jedi-signature-help-enabled t) 473 ("pyls.plugins.jedi_references.enabled" lsp-pyls-plugins-jedi-references-enabled t) 474 ("pyls.plugins.jedi_hover.enabled" lsp-pyls-plugins-jedi-hover-enabled t) 475 ("pyls.plugins.jedi_definition.follow_builtin_imports" lsp-pyls-plugins-jedi-definition-follow-builtin-imports t) 476 ("pyls.plugins.jedi_definition.follow_imports" lsp-pyls-plugins-jedi-definition-follow-imports t) 477 ("pyls.plugins.jedi_definition.enabled" lsp-pyls-plugins-jedi-definition-enabled t) 478 ("pyls.plugins.jedi_completion.include_params" lsp-pyls-plugins-jedi-completion-include-params t) 479 ("pyls.plugins.jedi_completion.enabled" lsp-pyls-plugins-jedi-completion-enabled t) 480 ("pyls.plugins.jedi_completion.include_class_objects" lsp-pyls-plugins-jedi-completion-include-class-objects t) 481 ("pyls.plugins.jedi.environment" lsp-pyls-get-pyenv-environment) 482 ("pyls.plugins.jedi_completion.fuzzy" lsp-pyls-plugins-jedi-completion-fuzzy t) 483 ("pyls.plugins.jedi_rename.enabled" (lambda () (eq lsp-pyls-rename-backend 'jedi)) t) 484 ("pyls.configurationSources" lsp-pyls-configuration-sources))) 485 486 (lsp-register-client 487 (make-lsp-client :new-connection (lsp-stdio-connection 488 (lambda () lsp-clients-python-command)) 489 :activation-fn (lsp-activate-on "python") 490 :priority -2 491 :server-id 'pyls 492 :library-folders-fn (lambda (_workspace) lsp-clients-python-library-directories) 493 :initialized-fn (lambda (workspace) 494 (unless lsp-pyls-disable-warning 495 (warn (concat "The palantir python-language-server (pyls) is unmaintained; " 496 "a maintained fork is the python-lsp-server (pylsp) project; " 497 "you can install it with pip via: pip install python-lsp-server"))) 498 (with-lsp-workspace workspace 499 (lsp--set-configuration (lsp-configuration-section "pyls")))))) 500 501 (lsp-consistency-check lsp-pyls) 502 503 (provide 'lsp-pyls) 504 ;;; lsp-pyls.el ends here