lsp-rust.el (75588B)
1 ;;; lsp-rust.el --- Rust Client settings -*- 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 ;; lsp-rust client 24 25 ;;; Code: 26 27 (require 'lsp-mode) 28 (require 'ht) 29 (require 'dash) 30 (require 'lsp-semantic-tokens) 31 (require 's) 32 33 (defgroup lsp-rust nil 34 "LSP support for Rust, using Rust Language Server or rust-analyzer." 35 :group 'lsp-mode 36 :link '(url-link "https://github.com/rust-lang/rls") 37 :package-version '(lsp-mode . "6.1")) 38 39 (defgroup lsp-rust-rls nil 40 "LSP support for Rust, using Rust Language Server." 41 :group 'lsp-mode 42 :link '(url-link "https://github.com/rust-lang/rls") 43 :package-version '(lsp-mode . "8.0.0")) 44 45 (defgroup lsp-rust-analyzer nil 46 "LSP support for Rust, using rust-analyzer." 47 :group 'lsp-mode 48 :link '(url-link "https://github.com/rust-lang/rust-analyzer") 49 :package-version '(lsp-mode . "8.0.0")) 50 51 (defgroup lsp-rust-analyzer-semantic-tokens nil 52 "LSP semantic tokens support for rust-analyzer." 53 :group 'lsp-rust-analyzer 54 :link '(url-link "https://github.com/rust-lang/rust-analyzer") 55 :package-version '(lsp-mode . "9.0.0")) 56 57 (defcustom lsp-rust-server 'rust-analyzer 58 "Choose LSP server." 59 :type '(choice (const :tag "rls" rls) 60 (const :tag "rust-analyzer" rust-analyzer)) 61 :group 'lsp-rust 62 :package-version '(lsp-mode . "6.2")) 63 64 ;; RLS 65 66 (defcustom lsp-rust-rls-server-command '("rls") 67 "Command to start RLS." 68 :type '(repeat string) 69 :group 'lsp-rust-rls 70 :package-version '(lsp-mode . "6.1")) 71 72 (defcustom lsp-rust-library-directories 73 '("~/.cargo/registry/src" "~/.rustup/toolchains") 74 "List of directories which will be considered to be libraries." 75 :risky t 76 :type '(repeat string) 77 :group 'lsp-rust-rls 78 :package-version '(lsp-mode . "6.1")) 79 80 (defcustom lsp-rust-sysroot nil 81 "If non-nil, use the given path as the sysroot for all rustc invocations 82 instead of trying to detect the sysroot automatically." 83 :type '(choice 84 (const :tag "None" nil) 85 (string :tag "Sysroot")) 86 :group 'lsp-rust-rls 87 :package-version '(lsp-mode . "6.1")) 88 89 (defcustom lsp-rust-target nil 90 "If non-nil, use the given target triple for all rustc invocations." 91 :type '(choice 92 (const :tag "None" nil) 93 (string :tag "Target")) 94 :group 'lsp-rust-rls 95 :package-version '(lsp-mode . "6.1")) 96 97 (defcustom lsp-rust-rustflags nil 98 "Flags added to RUSTFLAGS." 99 :type '(choice 100 (const :tag "None" nil) 101 (string :tag "Flags")) 102 :group 'lsp-rust-rls 103 :package-version '(lsp-mode . "6.1")) 104 105 (defcustom lsp-rust-clear-env-rust-log t 106 "Clear the RUST_LOG environment variable before running rustc or cargo." 107 :type 'boolean 108 :group 'lsp-rust-rls 109 :package-version '(lsp-mode . "6.1")) 110 111 (defcustom lsp-rust-build-lib nil 112 "If non-nil, checks the project as if you passed the `--lib' argument to 113 cargo. 114 115 Mutually exclusive with, and preferred over, `lsp-rust-build-bin'. (Unstable)" 116 :type 'boolean 117 :group 'lsp-rust-rls 118 :package-version '(lsp-mode . "6.1")) 119 120 (defcustom lsp-rust-build-bin nil 121 "If non-nil, checks the project as if you passed `-- bin <build_bin>' 122 argument to cargo. 123 124 Mutually exclusive with `lsp-rust-build-lib'. (Unstable)" 125 :type '(choice 126 (const :tag "None" nil) 127 (string :tag "Binary")) 128 :group 'lsp-rust-rls 129 :package-version '(lsp-mode . "6.1")) 130 131 (defcustom lsp-rust-cfg-test nil 132 "If non-nil, checks the project as if you were running `cargo test' rather 133 than cargo build. 134 135 I.e., compiles (but does not run) test code." 136 :type 'boolean 137 :group 'lsp-rust-rls 138 :package-version '(lsp-mode . "6.1")) 139 140 (defcustom lsp-rust-unstable-features nil 141 "Enable unstable features." 142 :type 'boolean 143 :group 'lsp-rust-rls 144 :package-version '(lsp-mode . "6.1")) 145 146 (defcustom lsp-rust-wait-to-build nil 147 "Time in milliseconds between receiving a change notification 148 and starting build. If not specified, automatically inferred by 149 the latest build duration." 150 :type '(choice 151 (const :tag "Auto" nil) 152 (number :tag "Time")) 153 :group 'lsp-rust-rls 154 :package-version '(lsp-mode . "6.1")) 155 156 (defcustom lsp-rust-show-warnings t 157 "Show warnings." 158 :type 'boolean 159 :group 'lsp-rust-rls 160 :package-version '(lsp-mode . "6.1")) 161 162 (defcustom lsp-rust-crate-blocklist [ 163 "cocoa" 164 "gleam" 165 "glium" 166 "idna" 167 "libc" 168 "openssl" 169 "rustc_serialize" 170 "serde" 171 "serde_json" 172 "typenum" 173 "unicode_normalization" 174 "unicode_segmentation" 175 "winapi" 176 ] 177 "A list of Cargo crates to blocklist." 178 :type 'lsp-string-vector 179 :group 'lsp-rust-rls 180 :package-version '(lsp-mode . "6.1")) 181 182 (defcustom lsp-rust-build-on-save nil 183 "Only index the project when a file is saved and not on change." 184 :type 'boolean 185 :group 'lsp-rust-rls 186 :package-version '(lsp-mode . "6.1")) 187 188 (defcustom lsp-rust-features [] 189 "List of features to activate. 190 Corresponds to the `rust-analyzer` setting `rust-analyzer.cargo.features`. 191 Set this to `\"all\"` to pass `--all-features` to cargo." 192 :type 'lsp-string-vector 193 :group 'lsp-rust-rls 194 :package-version '(lsp-mode . "6.1")) 195 196 (defcustom lsp-rust-all-features nil 197 "Enable all Cargo features." 198 :type 'boolean 199 :group 'lsp-rust-rls 200 :package-version '(lsp-mode . "6.1")) 201 202 (defcustom lsp-rust-no-default-features nil 203 "Do not enable default Cargo features." 204 :type 'boolean 205 :group 'lsp-rust-rls 206 :package-version '(lsp-mode . "6.1")) 207 208 (defcustom lsp-rust-racer-completion t 209 "Enables code completion using racer." 210 :type 'boolean 211 :group 'lsp-rust-rls 212 :package-version '(lsp-mode . "6.1")) 213 214 (defcustom lsp-rust-clippy-preference "opt-in" 215 "Controls eagerness of clippy diagnostics when available. 216 Valid values are (case-insensitive): 217 - \"off\": Disable clippy lints. 218 - \"opt-in\": Clippy lints are shown when crates specify `#![warn(clippy)]'. 219 - \"on\": Clippy lints enabled for all crates in workspace. 220 221 You need to install clippy via rustup if you haven't already." 222 :type '(choice 223 (const "on") 224 (const "opt-in") 225 (const "off")) 226 :group 'lsp-rust-rls 227 :package-version '(lsp-mode . "6.1")) 228 229 (defcustom lsp-rust-jobs nil 230 "Number of Cargo jobs to be run in parallel." 231 :type '(choice 232 (const :tag "Auto" nil) 233 (number :tag "Jobs")) 234 :group 'lsp-rust-rls 235 :package-version '(lsp-mode . "6.1")) 236 237 (defcustom lsp-rust-all-targets t 238 "Checks the project as if you were running cargo check --all-targets. 239 I.e., check all targets and integration tests too." 240 :type 'boolean 241 :group 'lsp-rust-rls 242 :package-version '(lsp-mode . "6.1")) 243 244 (defcustom lsp-rust-target-dir nil 245 "When specified, it places the generated analysis files at the 246 specified target directory. By default it is placed target/rls 247 directory." 248 :type '(choice 249 (const :tag "Default" nil) 250 (string :tag "Directory")) 251 :group 'lsp-rust-rls 252 :package-version '(lsp-mode . "6.1")) 253 254 (defcustom lsp-rust-rustfmt-path nil 255 "When specified, RLS will use the Rustfmt pointed at the path 256 instead of the bundled one" 257 :type '(choice 258 (const :tag "Bundled" nil) 259 (string :tag "Path")) 260 :group 'lsp-rust-rls 261 :package-version '(lsp-mode . "6.1")) 262 263 (defcustom lsp-rust-build-command nil 264 "EXPERIMENTAL (requires `rust.unstable_features') 265 If set, executes a given program responsible for rebuilding save-analysis to be 266 loaded by the RLS. The program given should output a list of resulting .json 267 files on stdout. 268 269 Implies `rust.build_on_save': true." 270 :type '(choice 271 (const :tag "None" nil) 272 (string :tag "Command")) 273 :group 'lsp-rust-rls 274 :package-version '(lsp-mode . "6.1")) 275 276 (defcustom lsp-rust-full-docs nil 277 "Instructs cargo to enable full documentation extraction during 278 save-analysis while building the crate." 279 :type 'boolean 280 :group 'lsp-rust-rls 281 :package-version '(lsp-mode . "6.1")) 282 283 (defcustom lsp-rust-show-hover-context t 284 "Show additional context in hover tooltips when available. This 285 is often the type local variable declaration." 286 :type 'boolean 287 :group 'lsp-rust-rls 288 :package-version '(lsp-mode . "6.1")) 289 290 (lsp-register-custom-settings 291 '(("rust.show_hover_context" lsp-rust-show-hover-context t) 292 ("rust.full_docs" lsp-rust-full-docs t) 293 ("rust.build_command" lsp-rust-build-command) 294 ("rust.rustfmt_path" lsp-rust-rustfmt-path) 295 ("rust.target_dir" lsp-rust-target-dir) 296 ("rust.all_targets" lsp-rust-all-targets t) 297 ("rust.jobs" lsp-rust-jobs) 298 ("rust.clippy_preference" lsp-rust-clippy-preference) 299 ("rust.racer_completion" lsp-rust-racer-completion t) 300 ("rust.no_default_features" lsp-rust-no-default-features t) 301 ("rust.all_features" lsp-rust-all-features t) 302 ("rust.features" lsp-rust-features) 303 ("rust.build_on_save" lsp-rust-build-on-save t) 304 ("rust.crate_blocklist" lsp-rust-crate-blocklist) 305 ("rust.show_warnings" lsp-rust-show-warnings t) 306 ("rust.wait_to_build" lsp-rust-wait-to-build) 307 ("rust.unstable_features" lsp-rust-unstable-features t) 308 ("rust.cfg_test" lsp-rust-cfg-test t) 309 ("rust.build_bin" lsp-rust-build-bin) 310 ("rust.build_lib" lsp-rust-build-lib t) 311 ("rust.clear_env_rust_log" lsp-rust-clear-env-rust-log t) 312 ("rust.rustflags" lsp-rust-rustflags) 313 ("rust.target" lsp-rust-target) 314 ("rust.sysroot" lsp-rust-sysroot))) 315 316 (defun lsp-clients--rust-window-progress (workspace params) 317 "Progress report handling. 318 PARAMS progress report notification data." 319 (-let [(&v1:ProgressParams :done? :message? :title) params] 320 (if (or done? (s-blank-str? message?)) 321 (lsp-workspace-status nil workspace) 322 (lsp-workspace-status (format "%s - %s" title (or message? "")) workspace)))) 323 324 (lsp-defun lsp-rust--rls-run ((&Command :arguments? params)) 325 (-let* (((&rls:Cmd :env :binary :args :cwd) (lsp-seq-first params)) 326 (default-directory (or cwd (lsp-workspace-root) default-directory) )) 327 (compile 328 (format "%s %s %s" 329 (s-join " " (ht-amap (format "%s=%s" key value) env)) 330 binary 331 (s-join " " args))))) 332 333 (lsp-register-client 334 (make-lsp-client :new-connection (lsp-stdio-connection (lambda () lsp-rust-rls-server-command)) 335 :activation-fn (lsp-activate-on "rust") 336 :priority (if (eq lsp-rust-server 'rls) 1 -1) 337 :initialization-options '((omitInitBuild . t) 338 (cmdRun . t)) 339 :notification-handlers (ht ("window/progress" 'lsp-clients--rust-window-progress)) 340 :action-handlers (ht ("rls.run" 'lsp-rust--rls-run)) 341 :library-folders-fn (lambda (_workspace) lsp-rust-library-directories) 342 :initialized-fn (lambda (workspace) 343 (with-lsp-workspace workspace 344 (lsp--set-configuration 345 (lsp-configuration-section "rust")))) 346 :server-id 'rls)) 347 348 349 ;; rust-analyzer 350 (defcustom lsp-rust-analyzer-server-command '("rust-analyzer") 351 "Command to start rust-analyzer." 352 :type '(repeat string) 353 :group 'lsp-rust-analyzer 354 :package-version '(lsp-mode . "6.2")) 355 356 (defcustom lsp-rust-analyzer-library-directories 357 '("~/.cargo/registry/src" "~/.rustup/toolchains") 358 "List of directories which will be considered to be libraries." 359 :risky t 360 :type '(repeat string) 361 :group 'lsp-rust-analyzer 362 :package-version '(lsp-mode . "9.0.0")) 363 364 (defcustom lsp-rust-analyzer-server-format-inlay-hints t 365 "Whether to ask rust-analyzer to format inlay hints itself. If 366 active, the various inlay format settings are not used." 367 :type 'boolean 368 :group 'lsp-rust-analyzer 369 :package-version '(lsp-mode . "9.0.0")) 370 371 (defcustom lsp-rust-analyzer-hide-closure-initialization nil 372 "Whether to hide inlay type hints for `let` statements that initialize 373 to a closure. Only applies to closures with blocks, same as 374 `#rust-analyzer.inlayHints.closureReturnTypeHints.enable#`." 375 :type 'boolean 376 :group 'lsp-rust-analyzer 377 :package-version '(lsp-mode . "9.0.0")) 378 379 (defcustom lsp-rust-analyzer-highlight-breakpoints t 380 "Enables highlighting of related references while the cursor is on 381 `break`, `loop`, `while`, or `for` keywords." 382 :type 'boolean 383 :group 'lsp-rust-analyzer 384 :package-version '(lsp-mode . "9.0.0")) 385 386 (defcustom lsp-rust-analyzer-highlight-closure-captures t 387 "Enables highlighting of all captures of a closure while the 388 cursor is on the `|` or move keyword of a closure." 389 :type 'boolean 390 :group 'lsp-rust-analyzer 391 :package-version '(lsp-mode . "9.0.0")) 392 393 (defcustom lsp-rust-analyzer-highlight-exit-points t 394 "Enables highlighting of all exit points while the cursor is on 395 any `return`, `?`, `fn`, or return type arrow (`->`)." 396 :type 'boolean 397 :group 'lsp-rust-analyzer 398 :package-version '(lsp-mode . "9.0.0")) 399 400 (defcustom lsp-rust-analyzer-highlight-references t 401 "Enables highlighting of related references while the cursor is on 402 any identifier." 403 :type 'boolean 404 :group 'lsp-rust-analyzer 405 :package-version '(lsp-mode . "9.0.0")) 406 407 (defcustom lsp-rust-analyzer-highlight-yield-points t 408 "Enables highlighting of all break points for a loop or block 409 context while the cursor is on any `async` or `await` keywords." 410 :type 'boolean 411 :group 'lsp-rust-analyzer 412 :package-version '(lsp-mode . "9.0.0")) 413 414 (defcustom lsp-rust-analyzer-closure-return-type-hints "never" 415 "Whether to show inlay type hints for return types of closures." 416 :type '(choice 417 (const "never") 418 (const "always") 419 (const "with_block")) 420 :group 'lsp-rust-analyzer 421 :package-version '(lsp-mode . "9.0.0")) 422 423 (defcustom lsp-rust-analyzer-discriminants-hints "never" 424 "Whether to show enum variant discriminant hints." 425 :type '(choice 426 (const "never") 427 (const "always") 428 (const "fieldless")) 429 :group 'lsp-rust-analyzer 430 :package-version '(lsp-mode . "9.0.0")) 431 432 (defcustom lsp-rust-analyzer-expression-adjustment-hints "never" 433 "Whether to show inlay hints for type adjustments.." 434 :type '(choice 435 (const "never") 436 (const "always") 437 (const "reborrow")) 438 :group 'lsp-rust-analyzer 439 :package-version '(lsp-mode . "9.0.0")) 440 441 (defcustom lsp-rust-analyzer-expression-adjustment-hints-mode "prefix" 442 "Whether to show inlay hints as postfix ops (`.*` instead of `*`, etc)." 443 :type '(choice 444 (const "prefix") 445 (const "postfix") 446 (const "prefer_prefix") 447 (const "prefer_postfix")) 448 :group 'lsp-rust-analyzer 449 :package-version '(lsp-mode . "9.0.0")) 450 451 (defcustom lsp-rust-analyzer-expression-adjustment-hide-unsafe nil 452 "Whether to hide inlay hints for type adjustments outside of 453 `unsafe` blocks." 454 :type 'boolean 455 :group 'lsp-rust-analyzer 456 :package-version '(lsp-mode . "9.0.0")) 457 458 (defcustom lsp-rust-analyzer-implicit-drops nil 459 "Whether to show implicit drop hints." 460 :type 'boolean 461 :group 'lsp-rust-analyzer 462 :package-version '(lsp-mode . "9.0.0")) 463 464 465 (defcustom lsp-rust-analyzer-closure-capture-hints nil 466 "Whether to show inlay hints for closure captures." 467 :type 'boolean 468 :group 'lsp-rust-analyzer 469 :package-version '(lsp-mode . "9.0.0")) 470 471 (defcustom lsp-rust-analyzer-closure-style "impl_fn" 472 "Closure notation in type and chaining inlay hints." 473 :type 'string 474 :group 'lsp-rust-analyzer 475 :package-version '(lsp-mode . "9.0.0")) 476 477 (defcustom lsp-rust-analyzer-hide-named-constructor nil 478 "Whether to hide inlay type hints for constructors." 479 :type 'boolean 480 :group 'lsp-rust-analyzer 481 :package-version '(lsp-mode . "9.0.0")) 482 483 (defcustom lsp-rust-analyzer-max-inlay-hint-length nil 484 "Max inlay hint length." 485 :type 'integer 486 :group 'lsp-rust-analyzer 487 :package-version '(lsp-mode . "6.2.2")) 488 489 (defcustom lsp-rust-analyzer-display-chaining-hints nil 490 "Whether to show inlay type hints for method chains. These 491 hints will be formatted with the type hint formatting options, if 492 the mode is not configured to ask the server to format them." 493 :type 'boolean 494 :group 'lsp-rust-analyzer 495 :package-version '(lsp-mode . "6.2.2")) 496 497 (defcustom lsp-rust-analyzer-display-lifetime-elision-hints-enable "never" 498 "Whether to show elided lifetime inlay hints." 499 :type '(choice 500 (const "never") 501 (const "always") 502 (const "skip_trivial")) 503 :group 'lsp-rust-analyzer 504 :package-version '(lsp-mode . "9.0.0")) 505 506 (defcustom lsp-rust-analyzer-display-lifetime-elision-hints-use-parameter-names nil 507 "When showing elided lifetime inlay hints, whether to use 508 parameter names or numeric placeholder names for the lifetimes." 509 :type 'boolean 510 :group 'lsp-rust-analyzer 511 :package-version '(lsp-mode . "9.0.0")) 512 513 (defcustom lsp-rust-analyzer-display-closure-return-type-hints nil 514 "Whether to show closure return type inlay hints for closures 515 with block bodies." 516 :type 'boolean 517 :group 'lsp-rust-analyzer 518 :package-version '(lsp-mode . "9.0.0")) 519 520 (defcustom lsp-rust-analyzer-display-parameter-hints nil 521 "Whether to show function parameter name inlay hints at the call site." 522 :type 'boolean 523 :group 'lsp-rust-analyzer 524 :package-version '(lsp-mode . "6.2.2")) 525 526 (defcustom lsp-rust-analyzer-display-reborrow-hints "never" 527 "Whether to show inlay type hints for compiler inserted reborrows." 528 :type '(choice 529 (const "always") 530 (const "never") 531 (const "mutable")) 532 :group 'lsp-rust-analyzer 533 :package-version '(lsp-mode . "9.0.0")) 534 535 (defcustom lsp-rust-analyzer-binding-mode-hints nil 536 "Whether to show inlay type hints for binding modes." 537 :type 'boolean 538 :group 'lsp-rust-analyzer 539 :package-version '(lsp-mode . "9.0.0")) 540 541 (defcustom lsp-rust-analyzer-closing-brace-hints t 542 "Whether to show inlay hints after a closing `}` to indicate what item it 543 belongs to." 544 :type 'boolean 545 :group 'lsp-rust-analyzer 546 :package-version '(lsp-mode . "9.0.0")) 547 548 (defcustom lsp-rust-analyzer-closing-brace-hints-min-lines 25 549 "Minimum number of lines required before the `}` until the hint is shown 550 \(set to 0 or 1 to always show them)." 551 :type 'integer 552 :group 'lsp-rust-analyzer 553 :package-version '(lsp-mode . "9.0.0")) 554 555 (defcustom lsp-rust-analyzer-lru-capacity nil 556 "Number of syntax trees rust-analyzer keeps in memory." 557 :type 'integer 558 :group 'lsp-rust-analyzer 559 :package-version '(lsp-mode . "6.2.2")) 560 561 (defcustom lsp-rust-analyzer-cargo-target nil 562 "Compilation target (target triple)." 563 :type '(choice 564 (string :tag "Target") 565 (const :tag "None" nil)) 566 :group 'lsp-rust-analyzer 567 :package-version '(lsp-mode . "8.0.0")) 568 569 (defcustom lsp-rust-analyzer-cargo-watch-enable t 570 "Enable Cargo watch." 571 :type 'boolean 572 :group 'lsp-rust-analyzer 573 :package-version '(lsp-mode . "6.2.2")) 574 575 (defcustom lsp-rust-analyzer-cargo-watch-command "check" 576 "Cargo watch command." 577 :type 'string 578 :group 'lsp-rust-analyzer 579 :package-version '(lsp-mode . "6.2.2")) 580 581 (defcustom lsp-rust-analyzer-cargo-watch-args [] 582 "Extra arguments for `cargo check`." 583 :type 'lsp-string-vector 584 :group 'lsp-rust-analyzer 585 :package-version '(lsp-mode . "6.2.2")) 586 587 (defcustom lsp-rust-analyzer-cargo-override-command [] 588 "Advanced option, fully override the command rust-analyzer uses for checking. 589 The command should include `--message=format=json` or similar option." 590 :type 'lsp-string-vector 591 :group 'lsp-rust-analyzer 592 :package-version '(lsp-mode . "6.2.2")) 593 594 (defcustom lsp-rust-analyzer-check-all-targets t 595 "Enables --all-targets for `cargo check`." 596 :type 'boolean 597 :group 'lsp-rust-analyzer 598 :package-version '(lsp-mode . "8.0.2")) 599 600 (defcustom lsp-rust-analyzer-checkonsave-features nil 601 "List of features to activate. 602 Corresponds to the `rust-analyzer` setting `rust-analyzer.check.features`. 603 When set to `nil` (default), the value of `lsp-rust-features' is inherited. 604 Set this to `\"all\"` to pass `--all-features` to cargo. 605 Note: setting this to `nil` means \"unset\", whereas setting this 606 to `[]` (empty vector) means \"set to empty list of features\", 607 which overrides any value that would otherwise be inherited from 608 `lsp-rust-features'." 609 :type 'lsp-string-vector 610 :group 'lsp-rust-rust-analyzer 611 :package-version '(lsp-mode . "8.0.2")) 612 613 (defcustom lsp-rust-analyzer-cargo-unset-test [] 614 "force rust-analyzer to unset `#[cfg(test)]` for the specified crates." 615 :type 'lsp-string-vector 616 :group 'lsp-rust-analyzer 617 :package-version '(lsp-mode . "9.0.0")) 618 619 (defcustom lsp-rust-analyzer-cfg-set-test t 620 "force rust-analyzer to set `#[cfg(test)]` for the current crate / workspace." 621 :type 'boolean 622 :group 'lsp-rust-analyzer 623 :package-version '(lsp-mode . "9.0.0")) 624 625 (defcustom lsp-rust-analyzer-use-client-watching t 626 "Use client watching" 627 :type 'boolean 628 :group 'lsp-rust-analyzer 629 :package-version '(lsp-mode . "6.2.2")) 630 631 (defcustom lsp-rust-analyzer-exclude-globs [] 632 "Exclude globs" 633 :type 'lsp-string-vector 634 :group 'lsp-rust-analyzer 635 :package-version '(lsp-mode . "6.2.2")) 636 637 (defcustom lsp-rust-analyzer-exclude-dirs [] 638 "These directories will be ignored by rust-analyzer." 639 :type 'lsp-string-vector 640 :group 'lsp-rust-analyzer 641 :package-version '(lsp-mode . "8.0.0")) 642 643 (defcustom lsp-rust-analyzer-macro-expansion-method 'lsp-rust-analyzer-macro-expansion-default 644 "Use a different function if you want formatted macro expansion results and 645 syntax highlighting." 646 :type 'function 647 :group 'lsp-rust-analyzer 648 :package-version '(lsp-mode . "6.2.2")) 649 650 (defcustom lsp-rust-analyzer-diagnostics-enable t 651 "Whether to show native rust-analyzer diagnostics." 652 :type 'boolean 653 :group 'lsp-rust-analyzer 654 :package-version '(lsp-mode . "6.3.2")) 655 656 (defcustom lsp-rust-analyzer-diagnostics-enable-experimental nil 657 "Whether to show native rust-analyzer diagnostics that are still experimental 658 \(might have more false positives than usual)." 659 :type 'boolean 660 :group 'lsp-rust-analyzer 661 :package-version '(lsp-mode . "8.0.0")) 662 663 (defcustom lsp-rust-analyzer-diagnostics-disabled [] 664 "List of native rust-analyzer diagnostics to disable." 665 :type 'lsp-string-vector 666 :group 'lsp-rust-analyzer 667 :package-version '(lsp-mode . "8.0.0")) 668 669 (defcustom lsp-rust-analyzer-diagnostics-warnings-as-hint [] 670 "List of warnings that should be displayed with hint severity." 671 :type 'lsp-string-vector 672 :group 'lsp-rust-analyzer 673 :package-version '(lsp-mode . "8.0.0")) 674 675 (defcustom lsp-rust-analyzer-diagnostics-warnings-as-info [] 676 "List of warnings that should be displayed with info severity." 677 :type 'lsp-string-vector 678 :group 'lsp-rust-analyzer 679 :package-version '(lsp-mode . "8.0.0")) 680 681 (define-obsolete-variable-alias 682 'lsp-rust-analyzer-cargo-load-out-dirs-from-check 683 'lsp-rust-analyzer-cargo-run-build-scripts 684 "8.0.0") 685 686 (defcustom lsp-rust-analyzer-cargo-run-build-scripts t 687 "Whether to run build scripts (`build.rs`) for more precise code analysis." 688 :type 'boolean 689 :group 'lsp-rust-analyzer 690 :package-version '(lsp-mode . "8.0.0")) 691 692 (defcustom lsp-rust-analyzer-rustfmt-extra-args [] 693 "Additional arguments to rustfmt." 694 :type 'lsp-string-vector 695 :group 'lsp-rust-analyzer 696 :package-version '(lsp-mode . "6.3.2")) 697 698 (defcustom lsp-rust-analyzer-rustfmt-override-command [] 699 "Advanced option, fully override the command rust-analyzer uses 700 for formatting." 701 :type 'lsp-string-vector 702 :group 'lsp-rust-analyzer 703 :package-version '(lsp-mode . "6.3.2")) 704 705 (defcustom lsp-rust-analyzer-rustfmt-rangeformatting-enable nil 706 "Enables the use of rustfmt's unstable range formatting command for the 707 `textDocument/rangeFormatting` request. The rustfmt option is unstable and only 708 available on a nightly build." 709 :type 'boolean 710 :group 'lsp-rust-analyzer 711 :package-version '(lsp-mode . "9.0.0")) 712 713 (defcustom lsp-rust-analyzer-completion-add-call-parenthesis t 714 "Whether to add parenthesis when completing functions." 715 :type 'boolean 716 :group 'lsp-rust-analyzer 717 :package-version '(lsp-mode . "6.3.2")) 718 719 (defcustom lsp-rust-analyzer-completion-add-call-argument-snippets t 720 "Whether to add argument snippets when completing functions." 721 :type 'boolean 722 :group 'lsp-rust-analyzer 723 :package-version '(lsp-mode . "6.3.2")) 724 725 (defcustom lsp-rust-analyzer-completion-postfix-enable t 726 "Whether to show postfix snippets like `dbg`, `if`, `not`, etc." 727 :type 'boolean 728 :group 'lsp-rust-analyzer 729 :package-version '(lsp-mode . "6.3.2")) 730 731 (defcustom lsp-rust-analyzer-call-info-full t 732 "Whether to show function name and docs in parameter hints." 733 :type 'boolean 734 :group 'lsp-rust-analyzer 735 :package-version '(lsp-mode . "6.3.2")) 736 737 (defcustom lsp-rust-analyzer-proc-macro-enable t 738 "Enable Proc macro support. 739 Implies `lsp-rust-analyzer-cargo-run-build-scripts'" 740 :type 'boolean 741 :group 'lsp-rust-analyzer 742 :package-version '(lsp-mode . "6.3.2")) 743 744 (defcustom lsp-rust-analyzer-import-prefix "plain" 745 "The path structure for newly inserted paths to use. 746 Valid values are: 747 - \"plain\": Insert import paths relative to the current module, using up to 748 one `super' prefix if the parent module contains the requested item. 749 - \"by_self\": Prefix all import paths with `self' if they don't begin with 750 `self', `super', `crate' or a crate name. 751 - \"by_crate\": Force import paths to be absolute by always starting 752 them with `crate' or the crate name they refer to." 753 :type '(choice 754 (const "plain") 755 (const "by_self") 756 (const "by_crate")) 757 :group 'lsp-rust-analyzer 758 :package-version '(lsp-mode . "8.0.0")) 759 760 (defcustom lsp-rust-analyzer-import-granularity "crate" 761 "How imports should be grouped into use statements." 762 :type '(choice 763 (const "crate" :doc "Merge imports from the same crate into a single use statement. This kind of nesting is only supported in Rust versions later than 1.24.") 764 (const "module" :doc "Merge imports from the same module into a single use statement.") 765 (const "item" :doc "Don’t merge imports at all, creating one import per item.") 766 (const "preserve" :doc "Do not change the granularity of any imports. For auto-import this has the same effect as `\"item\"'")) 767 :group 'lsp-rust-analyzer 768 :package-version '(lsp-mode . "8.0.0")) 769 770 (defcustom lsp-rust-analyzer-cargo-auto-reload t 771 "Automatically refresh project info via `cargo metadata' on `Cargo.toml' changes." 772 :type 'boolean 773 :group 'lsp-rust-analyzer 774 :package-version '(lsp-mode . "8.0.0")) 775 776 (defcustom lsp-rust-analyzer-use-rustc-wrapper-for-build-scripts t 777 "Use `RUSTC_WRAPPER=rust-analyzer' when running build scripts to avoid 778 compiling unnecessary things." 779 :type 'boolean 780 :group 'lsp-rust-analyzer 781 :package-version '(lsp-mode . "8.0.0")) 782 783 (defcustom lsp-rust-analyzer-completion-auto-import-enable t 784 "Toggles the additional completions that automatically add imports when 785 completed. `lsp-completion-enable-additional-text-edit' must be non-nil 786 for this feature to be fully enabled." 787 :type 'boolean 788 :group 'lsp-rust-analyzer 789 :package-version '(lsp-mode . "8.0.0")) 790 791 (defcustom lsp-rust-analyzer-completion-auto-self-enable t 792 "Toggles the additional completions that automatically show method calls 793 and field accesses with self prefixed to them when inside a method." 794 :type 'boolean 795 :group 'lsp-rust-analyzer 796 :package-version '(lsp-mode . "8.0.0")) 797 798 (defcustom lsp-rust-analyzer-import-enforce-granularity nil 799 "Whether to enforce the import granularity setting for all files. 800 If set to nil rust-analyzer will try to keep import styles consistent per file." 801 :type 'boolean 802 :group 'lsp-rust-analyzer 803 :package-version '(lsp-mode . "8.0.0")) 804 805 (defcustom lsp-rust-analyzer-imports-merge-glob t 806 "Whether to allow import insertion to merge new imports into single path 807 glob imports like `use std::fmt::*;`." 808 :type 'boolean 809 :group 'lsp-rust-analyzer 810 :package-version '(lsp-mode . "9.0.0")) 811 812 (defcustom lsp-rust-analyzer-import-group t 813 "Group inserted imports by the following order: 814 https://rust-analyzer.github.io/manual.html#auto-import. 815 Groups are separated by newlines." 816 :type 'boolean 817 :group 'lsp-rust-analyzer 818 :package-version '(lsp-mode . "8.0.0")) 819 820 (defcustom lsp-rust-analyzer-highlighting-strings t 821 "Use semantic tokens for strings." 822 :type 'boolean 823 :group 'lsp-rust-analyzer 824 :package-version '(lsp-mode . "8.0.0")) 825 826 (defcustom lsp-rust-analyzer-rustc-source nil 827 "Path to the Cargo.toml of the rust compiler workspace." 828 :type '(choice 829 (file :tag "Path") 830 (const :tag "None" nil)) 831 :group 'lsp-rust-analyzer 832 :package-version '(lsp-mode . "8.0.0")) 833 834 (defcustom lsp-rust-analyzer-linked-projects [] 835 "Disable project auto-discovery in favor of explicitly specified set of 836 projects. Elements must be paths pointing to `Cargo.toml`, `rust-project.json`, 837 or JSON objects in `rust-project.json` format." 838 :type 'lsp-string-vector 839 :group 'lsp-rust-analyzer 840 :package-version '(lsp-mode . "9.0.0")) 841 842 (defcustom lsp-rust-analyzer-experimental-proc-attr-macros t 843 "Whether to enable experimental support for expanding proc macro attributes." 844 :type 'boolean 845 :group 'lsp-rust-analyzer 846 :package-version '(lsp-mode . "8.0.0")) 847 848 (defcustom lsp-rust-analyzer-cargo-extra-args [] 849 "Extra arguments that are passed to every cargo invocation." 850 :type 'lsp-string-vector 851 :group 'lsp-rust-analyzer 852 :package-version '(lsp-mode . "9.0.0")) 853 854 (defcustom lsp-rust-analyzer-cargo-extra-env [] 855 "Extra environment variables that will be set when running cargo, rustc or 856 other commands within the workspace. Useful for setting RUSTFLAGS." 857 :type 'lsp-string-vector 858 :group 'lsp-rust-analyzer 859 :package-version '(lsp-mode . "9.0.0")) 860 861 (defconst lsp-rust-notification-handlers 862 '(("rust-analyzer/publishDecorations" . (lambda (_w _p))))) 863 864 (defconst lsp-rust-action-handlers 865 '()) 866 867 (define-derived-mode lsp-rust-analyzer-syntax-tree-mode special-mode "Rust-Analyzer-Syntax-Tree" 868 "Mode for the rust-analyzer syntax tree buffer.") 869 870 (defun lsp-rust-analyzer-syntax-tree () 871 "Display syntax tree for current buffer." 872 (interactive) 873 (-let* ((root (lsp-workspace-root default-directory)) 874 (params (lsp-make-rust-analyzer-syntax-tree-params 875 :text-document (lsp--text-document-identifier) 876 :range? (if (use-region-p) 877 (lsp--region-to-range (region-beginning) (region-end)) 878 (lsp--region-to-range (point-min) (point-max))))) 879 (results (lsp-send-request (lsp-make-request 880 "rust-analyzer/syntaxTree" 881 params)))) 882 (let ((buf (get-buffer-create (format "*rust-analyzer syntax tree %s*" root))) 883 (inhibit-read-only t)) 884 (with-current-buffer buf 885 (lsp-rust-analyzer-syntax-tree-mode) 886 (erase-buffer) 887 (insert results) 888 (goto-char (point-min))) 889 (pop-to-buffer buf)))) 890 891 (define-derived-mode lsp-rust-analyzer-status-mode special-mode "Rust-Analyzer-Status" 892 "Mode for the rust-analyzer status buffer.") 893 894 (defun lsp-rust-analyzer-status () 895 "Displays status information for rust-analyzer." 896 (interactive) 897 (-let* ((root (lsp-workspace-root default-directory)) 898 (params (lsp-make-rust-analyzer-analyzer-status-params 899 :text-document (lsp--text-document-identifier))) 900 (results (lsp-send-request (lsp-make-request 901 "rust-analyzer/analyzerStatus" 902 params)))) 903 (let ((buf (get-buffer-create (format "*rust-analyzer status %s*" root))) 904 (inhibit-read-only t)) 905 (with-current-buffer buf 906 (lsp-rust-analyzer-status-mode) 907 (erase-buffer) 908 (insert results) 909 (pop-to-buffer buf))))) 910 911 (defun lsp-rust-analyzer-view-item-tree () 912 "Show item tree of rust file." 913 (interactive) 914 (-let* ((params (lsp-make-rust-analyzer-view-item-tree 915 :text-document (lsp--text-document-identifier))) 916 (results (lsp-send-request (lsp-make-request 917 "rust-analyzer/viewItemTree" 918 params)))) 919 (let ((buf (get-buffer-create "*rust-analyzer item tree*")) 920 (inhibit-read-only t)) 921 (with-current-buffer buf 922 (special-mode) 923 (erase-buffer) 924 (insert (lsp--render-string results "rust")) 925 (pop-to-buffer buf))))) 926 927 (defun lsp-rust-analyzer-view-hir () 928 "View Hir of function at point." 929 (interactive) 930 (-let* ((params (lsp-make-rust-analyzer-expand-macro-params 931 :text-document (lsp--text-document-identifier) 932 :position (lsp--cur-position))) 933 (results (lsp-send-request (lsp-make-request 934 "rust-analyzer/viewHir" 935 params)))) 936 (let ((buf (get-buffer-create "*rust-analyzer hir*")) 937 (inhibit-read-only t)) 938 (with-current-buffer buf 939 (special-mode) 940 (erase-buffer) 941 (insert results) 942 (pop-to-buffer buf))))) 943 944 (defun lsp-rust-analyzer-join-lines () 945 "Join selected lines into one, smartly fixing up whitespace and trailing commas." 946 (interactive) 947 (let* ((params (lsp-make-rust-analyzer-join-lines-params 948 :text-document (lsp--text-document-identifier) 949 :ranges (vector (if (use-region-p) 950 (lsp--region-to-range (region-beginning) (region-end)) 951 (lsp--region-to-range (point) (point)))))) 952 (result (lsp-send-request (lsp-make-request "experimental/joinLines" params)))) 953 (lsp--apply-text-edits result 'code-action))) 954 955 (defun lsp-rust-analyzer-reload-workspace () 956 "Reload workspace, picking up changes from Cargo.toml" 957 (interactive) 958 (lsp--cur-workspace-check) 959 (lsp-send-request (lsp-make-request "rust-analyzer/reloadWorkspace"))) 960 961 (defcustom lsp-rust-analyzer-download-url 962 (let* ((x86 (string-prefix-p "x86_64" system-configuration)) 963 (arch (if x86 "x86_64" "aarch64"))) 964 (format "https://github.com/rust-lang/rust-analyzer/releases/latest/download/%s" 965 (pcase system-type 966 ('gnu/linux (format "rust-analyzer-%s-unknown-linux-gnu.gz" arch)) 967 ('darwin (format "rust-analyzer-%s-apple-darwin.gz" arch)) 968 ('windows-nt (format "rust-analyzer-%s-pc-windows-msvc.zip" arch))))) 969 "Automatic download url for Rust Analyzer" 970 :type 'string 971 :group 'lsp-rust-analyzer 972 :package-version '(lsp-mode . "8.0.0")) 973 974 (defcustom lsp-rust-analyzer-store-path (f-join lsp-server-install-dir "rust" 975 (pcase system-type 976 ('windows-nt "rust-analyzer.exe") 977 (_ "rust-analyzer"))) 978 "The path to the file in which `rust-analyzer' will be stored." 979 :type 'file 980 :group 'lsp-rust-analyzer 981 :package-version '(lsp-mode . "8.0.0")) 982 983 (lsp-dependency 984 'rust-analyzer 985 `(:download :url lsp-rust-analyzer-download-url 986 :decompress ,(pcase system-type ('windows-nt :zip) (_ :gzip)) 987 :store-path lsp-rust-analyzer-store-path 988 :set-executable? t) 989 `(:system ,(file-name-nondirectory lsp-rust-analyzer-store-path))) 990 991 (lsp-defun lsp-rust--analyzer-run-single ((&Command :arguments?)) 992 (lsp-rust-analyzer-run (lsp-seq-first arguments?))) 993 994 (lsp-defun lsp-rust--analyzer-show-references 995 ((&Command :title :arguments? [_uri _filepos references])) 996 (lsp-show-xrefs (lsp--locations-to-xref-items references) nil 997 (s-contains-p "reference" title))) 998 999 (declare-function dap-debug "ext:dap-mode" (template) t) 1000 1001 (lsp-defun lsp-rust--analyzer-debug-lens ((&Command :arguments? [args])) 1002 (lsp-rust-analyzer-debug args)) 1003 1004 ;; Semantic tokens 1005 1006 ;; Modifier faces 1007 (defface lsp-rust-analyzer-documentation-modifier-face 1008 '((t nil)) 1009 "The face modification to use for documentation items." 1010 :group 'lsp-rust-analyzer-semantic-tokens) 1011 1012 (defface lsp-rust-analyzer-declaration-modifier-face 1013 '((t nil)) 1014 "The face modification to use for declaration items." 1015 :group 'lsp-rust-analyzer-semantic-tokens) 1016 1017 (defface lsp-rust-analyzer-definition-modifier-face 1018 '((t nil)) 1019 "The face modification to use for definition items." 1020 :group 'lsp-rust-analyzer-semantic-tokens) 1021 1022 (defface lsp-rust-analyzer-static-modifier-face 1023 '((t nil)) 1024 "The face modification to use for static items." 1025 :group 'lsp-rust-analyzer-semantic-tokens) 1026 1027 (defface lsp-rust-analyzer-abstract-modifier-face 1028 '((t nil)) 1029 "The face modification to use for abstract items." 1030 :group 'lsp-rust-analyzer-semantic-tokens) 1031 1032 (defface lsp-rust-analyzer-deprecated-modifier-face 1033 '((t nil)) 1034 "The face modification to use for deprecated items." 1035 :group 'lsp-rust-analyzer-semantic-tokens) 1036 1037 (defface lsp-rust-analyzer-readonly-modifier-face 1038 '((t nil)) 1039 "The face modification to use for readonly items." 1040 :group 'lsp-rust-analyzer-semantic-tokens) 1041 1042 (defface lsp-rust-analyzer-default-library-modifier-face 1043 '((t nil)) 1044 "The face modification to use for default-library items." 1045 :group 'lsp-rust-analyzer-semantic-tokens) 1046 1047 (defface lsp-rust-analyzer-async-modifier-face 1048 '((t nil)) 1049 "The face modification to use for async items." 1050 :group 'lsp-rust-analyzer-semantic-tokens) 1051 1052 (defface lsp-rust-analyzer-attribute-modifier-face 1053 '((t nil)) 1054 "The face modification to use for attribute items." 1055 :group 'lsp-rust-analyzer-semantic-tokens) 1056 1057 (defface lsp-rust-analyzer-callable-modifier-face 1058 '((t nil)) 1059 "The face modification to use for callable items." 1060 :group 'lsp-rust-analyzer-semantic-tokens) 1061 1062 (defface lsp-rust-analyzer-constant-modifier-face 1063 '((t nil)) 1064 "The face modification to use for constant items." 1065 :group 'lsp-rust-analyzer-semantic-tokens) 1066 1067 (defface lsp-rust-analyzer-consuming-modifier-face 1068 '((t nil)) 1069 "The face modification to use for consuming items." 1070 :group 'lsp-rust-analyzer-semantic-tokens) 1071 1072 (defface lsp-rust-analyzer-control-flow-modifier-face 1073 '((t nil)) 1074 "The face modification to use for control-flow items." 1075 :group 'lsp-rust-analyzer-semantic-tokens) 1076 1077 (defface lsp-rust-analyzer-crate-root-modifier-face 1078 '((t nil)) 1079 "The face modification to use for crate-root items." 1080 :group 'lsp-rust-analyzer-semantic-tokens) 1081 1082 (defface lsp-rust-analyzer-injected-modifier-face 1083 '((t nil)) 1084 "The face modification to use for injected items." 1085 :group 'lsp-rust-analyzer-semantic-tokens) 1086 1087 (defface lsp-rust-analyzer-intra-doc-link-modifier-face 1088 '((t nil)) 1089 "The face modification to use for intra-doc-link items." 1090 :group 'lsp-rust-analyzer-semantic-tokens) 1091 1092 (defface lsp-rust-analyzer-library-modifier-face 1093 '((t nil)) 1094 "The face modification to use for library items." 1095 :group 'lsp-rust-analyzer-semantic-tokens) 1096 1097 (defface lsp-rust-analyzer-mutable-modifier-face 1098 '((t :underline t)) 1099 "The face modification to use for mutable items." 1100 :group 'lsp-rust-analyzer-semantic-tokens) 1101 1102 (defface lsp-rust-analyzer-public-modifier-face 1103 '((t nil)) 1104 "The face modification to use for public items." 1105 :group 'lsp-rust-analyzer-semantic-tokens) 1106 1107 (defface lsp-rust-analyzer-reference-modifier-face 1108 '((t :bold t)) 1109 "The face modification to use for reference items." 1110 :group 'lsp-rust-analyzer-semantic-tokens) 1111 1112 (defface lsp-rust-analyzer-trait-modifier-face 1113 '((t nil)) 1114 "The face modification to use for trait items." 1115 :group 'lsp-rust-analyzer-semantic-tokens) 1116 1117 (defface lsp-rust-analyzer-unsafe-modifier-face 1118 '((t nil)) 1119 "The face modification to use for unsafe items." 1120 :group 'lsp-rust-analyzer-semantic-tokens) 1121 1122 1123 ;; --------------------------------------------------------------------- 1124 ;; Semantic token modifier face customization 1125 1126 (defcustom lsp-rust-analyzer-documentation-modifier 'lsp-rust-analyzer-documentation-modifier-face 1127 "Face for semantic token modifier for `documentation' attribute." 1128 :type 'face 1129 :group 'lsp-rust-analyzer-semantic-tokens 1130 :package-version '(lsp-mode . "9.0.0")) 1131 1132 (defcustom lsp-rust-analyzer-declaration-modifier 'lsp-rust-analyzer-declaration-modifier-face 1133 "Face for semantic token modifier for `declaration' attribute." 1134 :type 'face 1135 :group 'lsp-rust-analyzer-semantic-tokens 1136 :package-version '(lsp-mode . "9.0.0")) 1137 1138 (defcustom lsp-rust-analyzer-definition-modifier 'lsp-rust-analyzer-definition-modifier-face 1139 "Face for semantic token modifier for `definition' attribute." 1140 :type 'face 1141 :group 'lsp-rust-analyzer-semantic-tokens 1142 :package-version '(lsp-mode . "9.0.0")) 1143 1144 (defcustom lsp-rust-analyzer-static-modifier 'lsp-rust-analyzer-static-modifier-face 1145 "Face for semantic token modifier for `static' attribute." 1146 :type 'face 1147 :group 'lsp-rust-analyzer-semantic-tokens 1148 :package-version '(lsp-mode . "9.0.0")) 1149 1150 (defcustom lsp-rust-analyzer-abstract-modifier 'lsp-rust-analyzer-abstract-modifier-face 1151 "Face for semantic token modifier for `abstract' attribute." 1152 :type 'face 1153 :group 'lsp-rust-analyzer-semantic-tokens 1154 :package-version '(lsp-mode . "9.0.0")) 1155 1156 (defcustom lsp-rust-analyzer-deprecated-modifier 'lsp-rust-analyzer-deprecated-modifier-face 1157 "Face for semantic token modifier for `deprecated' attribute." 1158 :type 'face 1159 :group 'lsp-rust-analyzer-semantic-tokens 1160 :package-version '(lsp-mode . "9.0.0")) 1161 1162 (defcustom lsp-rust-analyzer-readonly-modifier 'lsp-rust-analyzer-readonly-modifier-face 1163 "Face for semantic token modifier for `readonly' attribute." 1164 :type 'face 1165 :group 'lsp-rust-analyzer-semantic-tokens 1166 :package-version '(lsp-mode . "9.0.0")) 1167 1168 (defcustom lsp-rust-analyzer-default-library-modifier 'lsp-rust-analyzer-default-library-modifier-face 1169 "Face for semantic token modifier for `default' attribute." 1170 :type 'face 1171 :group 'lsp-rust-analyzer-semantic-tokens 1172 :package-version '(lsp-mode . "9.0.0")) 1173 1174 (defcustom lsp-rust-analyzer-async-modifier 'lsp-rust-analyzer-async-modifier-face 1175 "Face for semantic token modifier for `async' attribute." 1176 :type 'face 1177 :group 'lsp-rust-analyzer-semantic-tokens 1178 :package-version '(lsp-mode . "9.0.0")) 1179 1180 (defcustom lsp-rust-analyzer-attribute-modifier 'lsp-rust-analyzer-attribute-modifier-face 1181 "Face for semantic token modifier for `attribute' attribute." 1182 :type 'face 1183 :group 'lsp-rust-analyzer-semantic-tokens 1184 :package-version '(lsp-mode . "9.0.0")) 1185 1186 (defcustom lsp-rust-analyzer-callable-modifier 'lsp-rust-analyzer-callable-modifier-face 1187 "Face for semantic token modifier for `callable' attribute." 1188 :type 'face 1189 :group 'lsp-rust-analyzer-semantic-tokens 1190 :package-version '(lsp-mode . "9.0.0")) 1191 1192 (defcustom lsp-rust-analyzer-constant-modifier 'lsp-rust-analyzer-constant-modifier-face 1193 "Face for semantic token modifier for `constant' attribute." 1194 :type 'face 1195 :group 'lsp-rust-analyzer-semantic-tokens 1196 :package-version '(lsp-mode . "9.0.0")) 1197 1198 (defcustom lsp-rust-analyzer-consuming-modifier 'lsp-rust-analyzer-consuming-modifier-face 1199 "Face for semantic token modifier for `consuming' attribute." 1200 :type 'face 1201 :group 'lsp-rust-analyzer-semantic-tokens 1202 :package-version '(lsp-mode . "9.0.0")) 1203 1204 (defcustom lsp-rust-analyzer-control-flow-modifier 'lsp-rust-analyzer-control-flow-modifier-face 1205 "Face for semantic token modifier for `control_flow' attribute." 1206 :type 'face 1207 :group 'lsp-rust-analyzer-semantic-tokens 1208 :package-version '(lsp-mode . "9.0.0")) 1209 1210 (defcustom lsp-rust-analyzer-crate-root-modifier 'lsp-rust-analyzer-crate-root-modifier-face 1211 "Face for semantic token modifier for `crate_root' attribute." 1212 :type 'face 1213 :group 'lsp-rust-analyzer-semantic-tokens 1214 :package-version '(lsp-mode . "9.0.0")) 1215 1216 (defcustom lsp-rust-analyzer-injected-modifier 'lsp-rust-analyzer-injected-modifier-face 1217 "Face for semantic token modifier for `injected' attribute." 1218 :type 'face 1219 :group 'lsp-rust-analyzer-semantic-tokens 1220 :package-version '(lsp-mode . "9.0.0")) 1221 1222 (defcustom lsp-rust-analyzer-intra-doc-link-modifier 'lsp-rust-analyzer-intra-doc-link-modifier-face 1223 "Face for semantic token modifier for `intra_doc_link' attribute." 1224 :type 'face 1225 :group 'lsp-rust-analyzer-semantic-tokens 1226 :package-version '(lsp-mode . "9.0.0")) 1227 1228 (defcustom lsp-rust-analyzer-library-modifier 'lsp-rust-analyzer-library-modifier-face 1229 "Face for semantic token modifier for `library' attribute." 1230 :type 'face 1231 :group 'lsp-rust-analyzer-semantic-tokens 1232 :package-version '(lsp-mode . "9.0.0")) 1233 1234 (defcustom lsp-rust-analyzer-mutable-modifier 'lsp-rust-analyzer-mutable-modifier-face 1235 "Face for semantic token modifier for `mutable' attribute." 1236 :type 'face 1237 :group 'lsp-rust-analyzer-semantic-tokens 1238 :package-version '(lsp-mode . "9.0.0")) 1239 1240 (defcustom lsp-rust-analyzer-public-modifier 'lsp-rust-analyzer-public-modifier-face 1241 "Face for semantic token modifier for `public' attribute." 1242 :type 'face 1243 :group 'lsp-rust-analyzer-semantic-tokens 1244 :package-version '(lsp-mode . "9.0.0")) 1245 1246 (defcustom lsp-rust-analyzer-reference-modifier 'lsp-rust-analyzer-reference-modifier-face 1247 "Face for semantic token modifier for `reference' attribute." 1248 :type 'face 1249 :group 'lsp-rust-analyzer-semantic-tokens 1250 :package-version '(lsp-mode . "9.0.0")) 1251 1252 (defcustom lsp-rust-analyzer-trait-modifier 'lsp-rust-analyzer-trait-modifier-face 1253 "Face for semantic token modifier for `trait' attribute." 1254 :type 'face 1255 :group 'lsp-rust-analyzer-semantic-tokens 1256 :package-version '(lsp-mode . "9.0.0")) 1257 1258 (defcustom lsp-rust-analyzer-unsafe-modifier 'lsp-rust-analyzer-unsafe-modifier-face 1259 "Face for semantic token modifier for `unsafe' attribute." 1260 :type 'face 1261 :group 'lsp-rust-analyzer-semantic-tokens 1262 :package-version '(lsp-mode . "9.0.0")) 1263 1264 ;; --------------------------------------------------------------------- 1265 1266 (defun lsp-rust-analyzer--semantic-modifiers () 1267 "Mapping between rust-analyzer keywords and fonts to apply. 1268 The keywords are sent in the initialize response, in the semantic 1269 tokens legend." 1270 `(("documentation" . ,lsp-rust-analyzer-documentation-modifier) 1271 ("declaration" . ,lsp-rust-analyzer-declaration-modifier) 1272 ("definition" . ,lsp-rust-analyzer-definition-modifier) 1273 ("static" . ,lsp-rust-analyzer-static-modifier) 1274 ("abstract" . ,lsp-rust-analyzer-abstract-modifier) 1275 ("deprecated" . ,lsp-rust-analyzer-deprecated-modifier) 1276 ("readonly" . ,lsp-rust-analyzer-readonly-modifier) 1277 ("default_library" . ,lsp-rust-analyzer-default-library-modifier) 1278 ("async" . ,lsp-rust-analyzer-async-modifier) 1279 ("attribute" . ,lsp-rust-analyzer-attribute-modifier) 1280 ("callable" . ,lsp-rust-analyzer-callable-modifier) 1281 ("constant" . ,lsp-rust-analyzer-constant-modifier) 1282 ("consuming" . ,lsp-rust-analyzer-consuming-modifier) 1283 ("control_flow" . ,lsp-rust-analyzer-control-flow-modifier) 1284 ("crate_root" . ,lsp-rust-analyzer-crate-root-modifier) 1285 ("injected" . ,lsp-rust-analyzer-injected-modifier) 1286 ("intra_doc_link" . ,lsp-rust-analyzer-intra-doc-link-modifier) 1287 ("library" . ,lsp-rust-analyzer-library-modifier) 1288 ("mutable" . ,lsp-rust-analyzer-mutable-modifier) 1289 ("public" . ,lsp-rust-analyzer-public-modifier) 1290 ("reference" . ,lsp-rust-analyzer-reference-modifier) 1291 ("trait" . ,lsp-rust-analyzer-trait-modifier) 1292 ("unsafe" . ,lsp-rust-analyzer-unsafe-modifier))) 1293 1294 (defun lsp-rust-switch-server (&optional lsp-server) 1295 "Switch priorities of lsp servers, unless LSP-SERVER is already active." 1296 (interactive) 1297 (let ((current-server (if (> (lsp--client-priority (gethash 'rls lsp-clients)) 0) 1298 'rls 1299 'rust-analyzer))) 1300 (unless (eq lsp-server current-server) 1301 (dolist (server '(rls rust-analyzer)) 1302 (when (natnump (setf (lsp--client-priority (gethash server lsp-clients)) 1303 (* (lsp--client-priority (gethash server lsp-clients)) -1))) 1304 (message (format "Switched to server %s." server))))))) 1305 1306 ;; 1307 ;;; Inlay hints 1308 1309 (defcustom lsp-rust-analyzer-debug-lens-extra-dap-args 1310 '(:MIMode "gdb" :miDebuggerPath "gdb" :stopAtEntry t :externalConsole :json-false) 1311 "Extra arguments to pass to DAP template when debugging a test from code lens. 1312 1313 As a rule of the thumb, do not add extra keys to this plist unless you exactly 1314 what you are doing, it might break the \"Debug test\" lens otherwise. 1315 1316 See dap-mode documentation and cpptools documentation for the extra variables 1317 meaning." 1318 :type 'plist 1319 :group 'lsp-rust-analyzer 1320 :package-version '(lsp-mode . "8.0.0")) 1321 1322 ;; 1323 ;;; Lenses 1324 1325 (defgroup lsp-rust-analyzer-lens nil 1326 "LSP lens support for Rust when using rust-analyzer. 1327 1328 Lenses are (depending on your configuration) clickable links to 1329 the right of function definitions and the like. These display 1330 some useful information in their own right and/or perform a 1331 shortcut action when clicked such as displaying uses of that 1332 function or running an individual test. 1333 " 1334 :prefix "lsp-rust-analyzer-lens-" 1335 :group 'lsp-rust-analyzer 1336 :link '(url-link "https://emacs-lsp.github.io/lsp-mode/") 1337 :package-version '(lsp-mode . "9.0.0")) 1338 1339 (defcustom lsp-rust-analyzer-lens-debug-enable t 1340 "Enable or disable the Debug lens." 1341 :type 'boolean 1342 :group 'lsp-rust-analyzer-lens 1343 :package-version '(lsp-mode . "9.0.0")) 1344 1345 (defcustom lsp-rust-analyzer-lens-enable t 1346 "Master-enable of lenses in Rust files." 1347 :type 'boolean 1348 :group 'lsp-rust-analyzer-lens 1349 :package-version '(lsp-mode . "9.0.0")) 1350 1351 ;; This customisation "works" in that it works as described, but the default is fine and changing it 1352 ;; from the default will either stop lenses working or do nothing. 1353 ;; 1354 ;; If this is ever uncommented to re-enable the option, don't forget to also uncomment it in defun 1355 ;; lsp-rust-analyzer--make-init-options too or it'll not do anything. 1356 1357 ;; (defcustom lsp-rust-analyzer-lens-force-custom-commands t 1358 ;; "Internal config: use custom client-side commands even when the 1359 ;; client doesn't set the corresponding capability." 1360 ;; :type 'boolean 1361 ;; :group 'lsp-rust-analyzer-lens 1362 ;; :package-version '(lsp-mode . "9.0.0")) 1363 1364 (defcustom lsp-rust-analyzer-lens-implementations-enable t 1365 "Enable or disable the Implementations lens. 1366 1367 The Implementations lens shows `NN implementations' to the right 1368 of the first line of an enum, struct, or union declaration. This 1369 is the count of impl blocks, including derived traits. Clicking 1370 on it gives a list of the impls of that type. 1371 " 1372 :type 'boolean 1373 :group 'lsp-rust-analyzer-lens 1374 :package-version '(lsp-mode . "9.0.0")) 1375 1376 ;; The valid range of values for this is documented in the rust-lang/rust-analyzer repository at the 1377 ;; path "editors/code/package.json"; the TL:DR is that it's "above_name" or "above_whole_item". 1378 ;; However, setting it to "above_whole_item" causes lenses to disappear in Emacs. I suspect this 1379 ;; feature has only ever been tested in some other IDE and it's broken in Emacs. So I've disabled it 1380 ;; for now. 1381 ;; 1382 ;; If this is ever uncommented to re-enable the option, don't forget to also uncomment it in defun 1383 ;; lsp-rust-analyzer--make-init-options too or it'll not do anything. 1384 1385 ;; (defcustom lsp-rust-analyzer-lens-location "above_name" 1386 ;; "Where to render annotations." 1387 ;; :type '(choice 1388 ;; (const :tag "Above name" "above_name") 1389 ;; (const :tag "Above whole item" "above_whole_item") 1390 ;; :group 'lsp-rust-analyzer-lens 1391 ;; :package-version '(lsp-mode . "9.0.0")) 1392 1393 (defcustom lsp-rust-analyzer-lens-references-adt-enable nil 1394 "Enable or disable the References lens on enums, structs, and traits. 1395 1396 The References lens shows `NN references` to the right of the 1397 first line of each enum, struct, or union declaration. This is 1398 the count of uses of that type. Clicking on it gives a list of 1399 where that type is used." 1400 :type 'boolean 1401 :group 'lsp-rust-analyzer-lens 1402 :package-version '(lsp-mode . "9.0.0")) 1403 1404 (defcustom lsp-rust-analyzer-lens-references-enum-variant-enable nil 1405 "Enable or disable the References lens on enum variants. 1406 1407 The References lens shows `NN references` to the right of the 1408 first (or only) line of each enum variant. This is the count of 1409 uses of that enum variant. Clicking on it gives a list of where 1410 that enum variant is used." 1411 :type 'boolean 1412 :group 'lsp-rust-analyzer-lens 1413 :package-version '(lsp-mode . "9.0.0")) 1414 1415 (defcustom lsp-rust-analyzer-lens-references-method-enable nil 1416 "Enable or disable the References lens on functions. 1417 1418 The References lens shows `NN references` to the right of the 1419 first line of each function declaration. This is the count of 1420 uses of that function. Clicking on it gives a list of where that 1421 function is used." 1422 1423 :type 'boolean 1424 :group 'lsp-rust-analyzer-lens 1425 :package-version '(lsp-mode . "9.0.0")) 1426 1427 (defcustom lsp-rust-analyzer-lens-references-trait-enable nil 1428 "Enable or disable the References lens on traits. 1429 1430 The References lens shows `NN references` to the right of the 1431 first line of each trait declaration. This is a count of uses of 1432 that trait. Clicking on it gives a list of where that trait is 1433 used. 1434 1435 There is some overlap with the Implementations lens which slows 1436 all of the trait's impl blocks, but this also shows other uses 1437 such as imports and dyn traits." 1438 :type 'boolean 1439 :group 'lsp-rust-analyzer-lens 1440 :package-version '(lsp-mode . "9.0.0")) 1441 1442 (defcustom lsp-rust-analyzer-lens-run-enable t 1443 "Enable or disable the Run lens." 1444 :type 'boolean 1445 :group 'lsp-rust-analyzer-lens 1446 :package-version '(lsp-mode . "9.0.0")) 1447 1448 (defun lsp-rust-analyzer-initialized? () 1449 (when-let* ((workspace (lsp-find-workspace 'rust-analyzer (buffer-file-name)))) 1450 (eq 'initialized (lsp--workspace-status workspace)))) 1451 1452 (defun lsp-rust-analyzer-expand-macro () 1453 "Expands the macro call at point recursively." 1454 (interactive) 1455 (-if-let* ((params (lsp-make-rust-analyzer-expand-macro-params 1456 :text-document (lsp--text-document-identifier) 1457 :position (lsp--cur-position))) 1458 (response (lsp-request 1459 "rust-analyzer/expandMacro" 1460 params)) 1461 ((&rust-analyzer:ExpandedMacro :expansion) response)) 1462 (funcall lsp-rust-analyzer-macro-expansion-method expansion) 1463 (lsp--error "No macro found at point, or it could not be expanded."))) 1464 1465 (defun lsp-rust-analyzer-macro-expansion-default (result) 1466 "Default method for displaying macro expansion." 1467 (let* ((root (lsp-workspace-root default-directory)) 1468 (buf (get-buffer-create (get-buffer-create (format "*rust-analyzer macro expansion %s*" root))))) 1469 (with-current-buffer buf 1470 (let ((inhibit-read-only t)) 1471 (erase-buffer) 1472 (insert (lsp--render-string result "rust")) 1473 (special-mode))) 1474 (pop-to-buffer buf))) 1475 1476 ;; 1477 ;;; Runnables 1478 1479 (defvar lsp-rust-analyzer--last-runnable nil 1480 "Record the last runnable.") 1481 1482 (defun lsp-rust-analyzer--runnables () 1483 "Return list of runnables." 1484 (lsp-send-request (lsp-make-request 1485 "experimental/runnables" 1486 (lsp-make-rust-analyzer-runnables-params 1487 :text-document (lsp--text-document-identifier) 1488 :position? (lsp--cur-position))))) 1489 1490 (defun lsp-rust-analyzer--select-runnable () 1491 "Select runnable." 1492 (lsp--completing-read 1493 "Select runnable:" 1494 (if lsp-rust-analyzer--last-runnable 1495 (cons lsp-rust-analyzer--last-runnable 1496 (-remove (-lambda ((&rust-analyzer:Runnable :label)) 1497 (equal label (lsp-get lsp-rust-analyzer--last-runnable :label))) 1498 (lsp-rust-analyzer--runnables))) 1499 (lsp-rust-analyzer--runnables)) 1500 (-lambda ((&rust-analyzer:Runnable :label)) label))) 1501 1502 (defun lsp-rust-analyzer--common-runner (runnable) 1503 "Execute a given RUNNABLE. 1504 1505 Extract the arguments, prepare the minor mode (cargo-process-mode if possible) 1506 and run a compilation" 1507 (-let* (((&rust-analyzer:Runnable :kind :label :args) runnable) 1508 ((&rust-analyzer:RunnableArgs :cargo-args :executable-args :workspace-root? :expect-test?) args) 1509 (default-directory (or workspace-root? default-directory))) 1510 (if (not (string-equal kind "cargo")) 1511 (lsp--error "'%s' runnable is not supported" kind) 1512 (compilation-start 1513 (string-join (append (when expect-test? '("env" "UPDATE_EXPECT=1")) 1514 (list "cargo") cargo-args 1515 (when executable-args '("--")) executable-args '()) " ") 1516 1517 ;; cargo-process-mode is nice, but try to work without it... 1518 (if (functionp 'cargo-process-mode) 'cargo-process-mode nil) 1519 (lambda (_) (concat "*" label "*")))))) 1520 1521 (defun lsp-rust-analyzer-run (runnable) 1522 "Select and run a RUNNABLE action." 1523 (interactive (list (lsp-rust-analyzer--select-runnable))) 1524 (when (lsp-rust-analyzer--common-runner runnable) 1525 (setq lsp-rust-analyzer--last-runnable runnable))) 1526 1527 (defun lsp-rust-analyzer-debug (runnable) 1528 "Select and debug a RUNNABLE action." 1529 (interactive (list (lsp-rust-analyzer--select-runnable))) 1530 (unless (or (featurep 'dap-cpptools) (featurep 'dap-gdb)) 1531 (user-error "You must require `dap-cpptools' or 'dap-gdb'")) 1532 (-let (((&rust-analyzer:Runnable 1533 :args (&rust-analyzer:RunnableArgs :cargo-args :workspace-root? :executable-args) 1534 :label) runnable)) 1535 (pcase (aref cargo-args 0) 1536 ("run" (aset cargo-args 0 "build")) 1537 ("test" (when (-contains? (append cargo-args ()) "--no-run") 1538 (cl-callf append cargo-args (list "--no-run"))))) 1539 (->> (append (list (executable-find "cargo")) 1540 cargo-args 1541 (list "--message-format=json")) 1542 (s-join " ") 1543 (shell-command-to-string) 1544 (s-lines) 1545 (-keep (lambda (s) 1546 (condition-case nil 1547 (-let* ((json-object-type 'plist) 1548 ((msg &as &plist :reason :executable) (json-read-from-string s))) 1549 (when (and executable (string= "compiler-artifact" reason)) 1550 executable)) 1551 (error)))) 1552 (funcall 1553 (lambda (artifact-spec) 1554 (pcase artifact-spec 1555 (`() (user-error "No compilation artifacts or obtaining the runnable artifacts failed")) 1556 (`(,spec) spec) 1557 (_ (user-error "Multiple compilation artifacts are not supported"))))) 1558 (list :type (if (featurep 'dap-gdb) "gdb" "cppdbg") 1559 :request "launch" 1560 :name label 1561 :args executable-args 1562 :cwd workspace-root? 1563 :sourceLanguages ["rust"] 1564 :program) 1565 (append lsp-rust-analyzer-debug-lens-extra-dap-args) 1566 (dap-debug)))) 1567 1568 (defun lsp-rust-analyzer-rerun (&optional runnable) 1569 (interactive (list (or lsp-rust-analyzer--last-runnable 1570 (lsp-rust-analyzer--select-runnable)))) 1571 (lsp-rust-analyzer-run (or runnable lsp-rust-analyzer--last-runnable))) 1572 1573 ;; goto parent module 1574 (cl-defun lsp-rust-find-parent-module (&key display-action) 1575 "Find parent module of current module." 1576 (interactive) 1577 (lsp-find-locations "experimental/parentModule" nil :display-action display-action)) 1578 1579 (defun lsp-rust-analyzer-open-cargo-toml (&optional new-window) 1580 "Open the closest Cargo.toml from the current file. 1581 1582 Rust-Analyzer LSP protocol documented here and added in November 2020 1583 https://github.com/rust-lang/rust-analyzer/blob/master/docs/dev/lsp-extensions.md#open-cargotoml 1584 1585 If NEW-WINDOW (interactively the prefix argument) is non-nil, 1586 open in a new window." 1587 (interactive "P") 1588 (-if-let (workspace (lsp-find-workspace 'rust-analyzer (buffer-file-name))) 1589 (-if-let* ((response (with-lsp-workspace workspace 1590 (lsp-send-request (lsp-make-request 1591 "experimental/openCargoToml" 1592 (lsp-make-rust-analyzer-open-cargo-toml-params 1593 :text-document (lsp--text-document-identifier)))))) 1594 ((&Location :uri :range) response)) 1595 (funcall (if new-window #'find-file-other-window #'find-file) 1596 (lsp--uri-to-path uri)) 1597 (lsp--warn "Couldn't find a Cargo.toml file or your version of rust-analyzer doesn't support this extension")) 1598 (lsp--error "OpenCargoToml is an extension available only with rust-analyzer"))) 1599 1600 (defun lsp-rust-analyzer-open-external-docs () 1601 "Open a URL for documentation related to the current TextDocumentPosition. 1602 1603 Rust-Analyzer LSP protocol documented here 1604 https://github.com/rust-lang/rust-analyzer/blob/master/docs/dev/lsp-extensions.md#open-external-documentation" 1605 (interactive) 1606 (-if-let* ((params (lsp-make-rust-analyzer-open-external-docs-params 1607 :text-document (lsp--text-document-identifier) 1608 :position (lsp--cur-position))) 1609 (url (lsp-request "experimental/externalDocs" params))) 1610 (browse-url url) 1611 (lsp--warn "Couldn't find documentation URL or your version of rust-analyzer doesn't support this extension"))) 1612 1613 (defun lsp-rust-analyzer--related-tests () 1614 "Get runnable test items related to the current TextDocumentPosition. 1615 Calls a rust-analyzer LSP extension endpoint that returns a wrapper over 1616 Runnable[]." 1617 (lsp-send-request (lsp-make-request 1618 "rust-analyzer/relatedTests" 1619 (lsp--text-document-position-params)))) 1620 1621 (defun lsp-rust-analyzer--select-related-test () 1622 "Call the endpoint and ask for user selection. 1623 1624 Cannot reuse `lsp-rust-analyzer--select-runnable' because the runnables endpoint 1625 responds with Runnable[], while relatedTests responds with TestInfo[], 1626 which is a wrapper over runnable. Also, this method doesn't set 1627 the `lsp-rust-analyzer--last-runnable' variable." 1628 (-if-let* ((resp (lsp-rust-analyzer--related-tests)) 1629 (runnables (seq-map 1630 #'lsp:rust-analyzer-related-tests-runnable 1631 resp))) 1632 (lsp--completing-read 1633 "Select test: " 1634 runnables 1635 #'lsp:rust-analyzer-runnable-label))) 1636 1637 (defun lsp-rust-analyzer-related-tests (runnable) 1638 "Execute a RUNNABLE test related to the current document position. 1639 1640 Rust-Analyzer LSP protocol extension 1641 https://github.com/rust-lang/rust-analyzer/blob/master/docs/dev/lsp-extensions.md#related-tests" 1642 (interactive (list (lsp-rust-analyzer--select-related-test))) 1643 (if runnable 1644 (lsp-rust-analyzer--common-runner runnable) 1645 (lsp--info "There are no tests related to the symbol at point"))) 1646 1647 (defun lsp-rust-analyzer-move-item (direction) 1648 "Move item under cursor or selection in some DIRECTION" 1649 (let* ((params (lsp-make-rust-analyzer-move-item-params 1650 :text-document (lsp--text-document-identifier) 1651 :range (if (use-region-p) 1652 (lsp--region-to-range (region-beginning) (region-end)) 1653 (lsp--region-to-range (point) (point))) 1654 :direction direction)) 1655 (edits (lsp-request "experimental/moveItem" params))) 1656 (lsp--apply-text-edits edits 'code-action))) 1657 1658 (defun lsp-rust-analyzer-move-item-up () 1659 "Move item under cursor or selection up" 1660 (interactive) 1661 (lsp-rust-analyzer-move-item "Up")) 1662 1663 (defun lsp-rust-analyzer-move-item-down () 1664 "Move item under cursor or selection down" 1665 (interactive) 1666 (lsp-rust-analyzer-move-item "Down")) 1667 1668 (defun lsp-rust-analyzer--make-init-options () 1669 "Init options for rust-analyzer" 1670 `(:diagnostics 1671 ( :enable ,(lsp-json-bool lsp-rust-analyzer-diagnostics-enable) 1672 :enableExperimental ,(lsp-json-bool lsp-rust-analyzer-diagnostics-enable-experimental) 1673 :disabled ,lsp-rust-analyzer-diagnostics-disabled 1674 :warningsAsHint ,lsp-rust-analyzer-diagnostics-warnings-as-hint 1675 :warningsAsInfo ,lsp-rust-analyzer-diagnostics-warnings-as-info) 1676 :imports ( :granularity ( :enforce ,(lsp-json-bool lsp-rust-analyzer-import-enforce-granularity) 1677 :group ,lsp-rust-analyzer-import-granularity) 1678 :group ,(lsp-json-bool lsp-rust-analyzer-import-group) 1679 :merge (:glob ,(lsp-json-bool lsp-rust-analyzer-imports-merge-glob)) 1680 :prefix ,lsp-rust-analyzer-import-prefix) 1681 :lruCapacity ,lsp-rust-analyzer-lru-capacity 1682 ;; This `checkOnSave` is called `check` in the `rust-analyzer` docs, not 1683 ;; `checkOnSave`, but the `rust-analyzer` source code shows that both names 1684 ;; work. The `checkOnSave` name has been supported by `rust-analyzer` for a 1685 ;; long time, whereas the `check` name was introduced here in 2023: 1686 ;; https://github.com/rust-lang/rust-analyzer/commit/d2bb62b6a81d26f1e41712e04d4ac760f860d3b3 1687 :checkOnSave ( :enable ,(lsp-json-bool lsp-rust-analyzer-cargo-watch-enable) 1688 :command ,lsp-rust-analyzer-cargo-watch-command 1689 :extraArgs ,lsp-rust-analyzer-cargo-watch-args 1690 :allTargets ,(lsp-json-bool lsp-rust-analyzer-check-all-targets) 1691 ;; We need to distinguish between setting this to the empty 1692 ;; vector, and not setting it at all, which `rust-analyzer` 1693 ;; interprets as "inherit from 1694 ;; `rust-analyzer.cargo.features`". We use `nil` to mean 1695 ;; "unset". 1696 ,@(when (vectorp lsp-rust-analyzer-checkonsave-features) 1697 `(:features ,lsp-rust-analyzer-checkonsave-features)) 1698 :overrideCommand ,lsp-rust-analyzer-cargo-override-command) 1699 :highlightRelated ( :breakPoints (:enable ,(lsp-json-bool lsp-rust-analyzer-highlight-breakpoints)) 1700 :closureCaptures (:enable ,(lsp-json-bool lsp-rust-analyzer-highlight-closure-captures)) 1701 :exitPoints (:enable ,(lsp-json-bool lsp-rust-analyzer-highlight-exit-points)) 1702 :references (:enable ,(lsp-json-bool lsp-rust-analyzer-highlight-references)) 1703 :yieldPoints (:enable ,(lsp-json-bool lsp-rust-analyzer-highlight-yield-points))) 1704 :files ( :exclude ,lsp-rust-analyzer-exclude-globs 1705 :watcher ,(if lsp-rust-analyzer-use-client-watching "client" "notify") 1706 :excludeDirs ,lsp-rust-analyzer-exclude-dirs) 1707 :cfg ( :setTest ,(lsp-json-bool lsp-rust-analyzer-cfg-set-test) ) 1708 :cargo ( :allFeatures ,(lsp-json-bool lsp-rust-all-features) 1709 :noDefaultFeatures ,(lsp-json-bool lsp-rust-no-default-features) 1710 :features ,lsp-rust-features 1711 :extraArgs ,lsp-rust-analyzer-cargo-extra-args 1712 :extraEnv ,lsp-rust-analyzer-cargo-extra-env 1713 :target ,lsp-rust-analyzer-cargo-target 1714 :runBuildScripts ,(lsp-json-bool lsp-rust-analyzer-cargo-run-build-scripts) 1715 ;; Obsolete, but used by old Rust-Analyzer versions 1716 :loadOutDirsFromCheck ,(lsp-json-bool lsp-rust-analyzer-cargo-run-build-scripts) 1717 :autoreload ,(lsp-json-bool lsp-rust-analyzer-cargo-auto-reload) 1718 :useRustcWrapperForBuildScripts ,(lsp-json-bool lsp-rust-analyzer-use-rustc-wrapper-for-build-scripts) 1719 :unsetTest ,lsp-rust-analyzer-cargo-unset-test) 1720 :rustfmt ( :extraArgs ,lsp-rust-analyzer-rustfmt-extra-args 1721 :overrideCommand ,lsp-rust-analyzer-rustfmt-override-command 1722 :rangeFormatting (:enable ,(lsp-json-bool lsp-rust-analyzer-rustfmt-rangeformatting-enable))) 1723 :lens ( :debug (:enable ,(lsp-json-bool lsp-rust-analyzer-lens-debug-enable)) 1724 :enable ,(lsp-json-bool lsp-rust-analyzer-lens-enable) 1725 ;; :forceCustomCommands ,(lsp-json-bool lsp-rust-analyzer-lens-force-custom-commands) 1726 :implementations (:enable ,(lsp-json-bool lsp-rust-analyzer-lens-implementations-enable)) 1727 ;; :location ,lsp-rust-analyzer-lens-location 1728 :references ( :adt (:enable ,(lsp-json-bool lsp-rust-analyzer-lens-references-adt-enable)) 1729 :enumVariant (:enable ,(lsp-json-bool lsp-rust-analyzer-lens-references-enum-variant-enable)) 1730 :method (:enable ,(lsp-json-bool lsp-rust-analyzer-lens-references-method-enable)) 1731 :trait (:enable ,(lsp-json-bool lsp-rust-analyzer-lens-references-trait-enable))) 1732 :run (:enable ,(lsp-json-bool lsp-rust-analyzer-lens-run-enable))) 1733 1734 :inlayHints ( :bindingModeHints (:enable ,(lsp-json-bool lsp-rust-analyzer-binding-mode-hints)) 1735 :chainingHints (:enable ,(lsp-json-bool lsp-rust-analyzer-display-chaining-hints)) 1736 :closingBraceHints ( :enable ,(lsp-json-bool lsp-rust-analyzer-closing-brace-hints) 1737 :minLines ,lsp-rust-analyzer-closing-brace-hints-min-lines) 1738 :closureCaptureHints (:enable ,(lsp-json-bool lsp-rust-analyzer-closure-capture-hints)) 1739 :closureReturnTypeHints (:enable ,lsp-rust-analyzer-closure-return-type-hints) 1740 :closureStyle ,lsp-rust-analyzer-closure-style 1741 :discriminantHints (:enable ,lsp-rust-analyzer-discriminants-hints) 1742 1743 :expressionAdjustmentHints ( :enable ,lsp-rust-analyzer-expression-adjustment-hints 1744 :hideOutsideUnsafe ,(lsp-json-bool lsp-rust-analyzer-expression-adjustment-hide-unsafe) 1745 :mode ,lsp-rust-analyzer-expression-adjustment-hints-mode) 1746 :implicitDrops (:enable ,(lsp-json-bool lsp-rust-analyzer-implicit-drops)) 1747 :lifetimeElisionHints ( :enable ,lsp-rust-analyzer-display-lifetime-elision-hints-enable 1748 :useParameterNames ,(lsp-json-bool lsp-rust-analyzer-display-lifetime-elision-hints-use-parameter-names)) 1749 :maxLength ,lsp-rust-analyzer-max-inlay-hint-length 1750 :parameterHints (:enable ,(lsp-json-bool lsp-rust-analyzer-display-parameter-hints)) 1751 :reborrowHints (:enable ,lsp-rust-analyzer-display-reborrow-hints) 1752 :renderColons ,(lsp-json-bool lsp-rust-analyzer-server-format-inlay-hints) 1753 :typeHints ( :enable ,(lsp-json-bool lsp-inlay-hint-enable) 1754 :hideClosureInitialization ,(lsp-json-bool lsp-rust-analyzer-hide-closure-initialization) 1755 :hideNamedConstructor ,(lsp-json-bool lsp-rust-analyzer-hide-named-constructor))) 1756 :completion ( :addCallParenthesis ,(lsp-json-bool lsp-rust-analyzer-completion-add-call-parenthesis) 1757 :addCallArgumentSnippets ,(lsp-json-bool lsp-rust-analyzer-completion-add-call-argument-snippets) 1758 :postfix (:enable ,(lsp-json-bool lsp-rust-analyzer-completion-postfix-enable)) 1759 :autoimport (:enable ,(lsp-json-bool lsp-rust-analyzer-completion-auto-import-enable)) 1760 :autoself (:enable ,(lsp-json-bool lsp-rust-analyzer-completion-auto-self-enable))) 1761 :callInfo (:full ,(lsp-json-bool lsp-rust-analyzer-call-info-full)) 1762 :procMacro (:enable ,(lsp-json-bool lsp-rust-analyzer-proc-macro-enable)) 1763 :rustcSource ,lsp-rust-analyzer-rustc-source 1764 :linkedProjects ,lsp-rust-analyzer-linked-projects 1765 :highlighting (:strings ,(lsp-json-bool lsp-rust-analyzer-highlighting-strings)) 1766 :experimental (:procAttrMacros ,(lsp-json-bool lsp-rust-analyzer-experimental-proc-attr-macros)))) 1767 1768 (lsp-register-client 1769 (make-lsp-client 1770 :new-connection (lsp-stdio-connection 1771 (lambda () 1772 `(,(or (executable-find 1773 (cl-first lsp-rust-analyzer-server-command)) 1774 (lsp-package-path 'rust-analyzer) 1775 "rust-analyzer") 1776 ,@(cl-rest lsp-rust-analyzer-server-command)))) 1777 :activation-fn (lsp-activate-on "rust") 1778 :priority (if (eq lsp-rust-server 'rust-analyzer) 1 -1) 1779 :initialization-options 'lsp-rust-analyzer--make-init-options 1780 :notification-handlers (ht<-alist lsp-rust-notification-handlers) 1781 :action-handlers (ht ("rust-analyzer.runSingle" #'lsp-rust--analyzer-run-single) 1782 ("rust-analyzer.debugSingle" #'lsp-rust--analyzer-debug-lens) 1783 ("rust-analyzer.showReferences" #'lsp-rust--analyzer-show-references) 1784 ("rust-analyzer.triggerParameterHints" #'lsp--action-trigger-parameter-hints)) 1785 :library-folders-fn (lambda (_workspace) lsp-rust-analyzer-library-directories) 1786 :semantic-tokens-faces-overrides `( :discard-default-modifiers t 1787 :modifiers ,(lsp-rust-analyzer--semantic-modifiers)) 1788 :server-id 'rust-analyzer 1789 :custom-capabilities `((experimental . 1790 ((snippetTextEdit . ,(and lsp-enable-snippet (fboundp 'yas-minor-mode))) 1791 (commands . ((commands . 1792 [ 1793 "rust-analyzer.runSingle" 1794 "rust-analyzer.debugSingle" 1795 "rust-analyzer.showReferences" 1796 ;; "rust-analyzer.gotoLocation" 1797 "rust-analyzer.triggerParameterHints" 1798 ;; "rust-analyzer.rename" 1799 ])))))) 1800 :download-server-fn (lambda (_client callback error-callback _update?) 1801 (lsp-package-ensure 'rust-analyzer callback error-callback)))) 1802 1803 (cl-defmethod lsp-clients-extract-signature-on-hover (contents (_server-id (eql rust-analyzer))) 1804 "Extract first non-comment line from rust-analyzer's hover CONTENTS. 1805 The first line of the hover contents is usally about memory layout or notable 1806 traits starting with //, with the actual signature follows." 1807 (let* ((lines (s-lines (s-trim (lsp--render-element contents)))) 1808 (non-comment-lines (--filter (not (s-prefix? "//" it)) lines))) 1809 (if non-comment-lines 1810 (car non-comment-lines) 1811 (car lines)))) 1812 1813 (lsp-consistency-check lsp-rust) 1814 1815 (provide 'lsp-rust) 1816 ;;; lsp-rust.el ends here