lsp-rust.el (75304B)
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-use-client-watching t 620 "Use client watching" 621 :type 'boolean 622 :group 'lsp-rust-analyzer 623 :package-version '(lsp-mode . "6.2.2")) 624 625 (defcustom lsp-rust-analyzer-exclude-globs [] 626 "Exclude globs" 627 :type 'lsp-string-vector 628 :group 'lsp-rust-analyzer 629 :package-version '(lsp-mode . "6.2.2")) 630 631 (defcustom lsp-rust-analyzer-exclude-dirs [] 632 "These directories will be ignored by rust-analyzer." 633 :type 'lsp-string-vector 634 :group 'lsp-rust-analyzer 635 :package-version '(lsp-mode . "8.0.0")) 636 637 (defcustom lsp-rust-analyzer-macro-expansion-method 'lsp-rust-analyzer-macro-expansion-default 638 "Use a different function if you want formatted macro expansion results and 639 syntax highlighting." 640 :type 'function 641 :group 'lsp-rust-analyzer 642 :package-version '(lsp-mode . "6.2.2")) 643 644 (defcustom lsp-rust-analyzer-diagnostics-enable t 645 "Whether to show native rust-analyzer diagnostics." 646 :type 'boolean 647 :group 'lsp-rust-analyzer 648 :package-version '(lsp-mode . "6.3.2")) 649 650 (defcustom lsp-rust-analyzer-diagnostics-enable-experimental nil 651 "Whether to show native rust-analyzer diagnostics that are still experimental 652 \(might have more false positives than usual)." 653 :type 'boolean 654 :group 'lsp-rust-analyzer 655 :package-version '(lsp-mode . "8.0.0")) 656 657 (defcustom lsp-rust-analyzer-diagnostics-disabled [] 658 "List of native rust-analyzer diagnostics to disable." 659 :type 'lsp-string-vector 660 :group 'lsp-rust-analyzer 661 :package-version '(lsp-mode . "8.0.0")) 662 663 (defcustom lsp-rust-analyzer-diagnostics-warnings-as-hint [] 664 "List of warnings that should be displayed with hint severity." 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-info [] 670 "List of warnings that should be displayed with info severity." 671 :type 'lsp-string-vector 672 :group 'lsp-rust-analyzer 673 :package-version '(lsp-mode . "8.0.0")) 674 675 (define-obsolete-variable-alias 676 'lsp-rust-analyzer-cargo-load-out-dirs-from-check 677 'lsp-rust-analyzer-cargo-run-build-scripts 678 "8.0.0") 679 680 (defcustom lsp-rust-analyzer-cargo-run-build-scripts t 681 "Whether to run build scripts (`build.rs`) for more precise code analysis." 682 :type 'boolean 683 :group 'lsp-rust-analyzer 684 :package-version '(lsp-mode . "8.0.0")) 685 686 (defcustom lsp-rust-analyzer-rustfmt-extra-args [] 687 "Additional arguments to rustfmt." 688 :type 'lsp-string-vector 689 :group 'lsp-rust-analyzer 690 :package-version '(lsp-mode . "6.3.2")) 691 692 (defcustom lsp-rust-analyzer-rustfmt-override-command [] 693 "Advanced option, fully override the command rust-analyzer uses 694 for formatting." 695 :type 'lsp-string-vector 696 :group 'lsp-rust-analyzer 697 :package-version '(lsp-mode . "6.3.2")) 698 699 (defcustom lsp-rust-analyzer-rustfmt-rangeformatting-enable nil 700 "Enables the use of rustfmt's unstable range formatting command for the 701 `textDocument/rangeFormatting` request. The rustfmt option is unstable and only 702 available on a nightly build." 703 :type 'boolean 704 :group 'lsp-rust-analyzer 705 :package-version '(lsp-mode . "9.0.0")) 706 707 (defcustom lsp-rust-analyzer-completion-add-call-parenthesis t 708 "Whether to add parenthesis when completing functions." 709 :type 'boolean 710 :group 'lsp-rust-analyzer 711 :package-version '(lsp-mode . "6.3.2")) 712 713 (defcustom lsp-rust-analyzer-completion-add-call-argument-snippets t 714 "Whether to add argument snippets 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-postfix-enable t 720 "Whether to show postfix snippets like `dbg`, `if`, `not`, etc." 721 :type 'boolean 722 :group 'lsp-rust-analyzer 723 :package-version '(lsp-mode . "6.3.2")) 724 725 (defcustom lsp-rust-analyzer-call-info-full t 726 "Whether to show function name and docs in parameter hints." 727 :type 'boolean 728 :group 'lsp-rust-analyzer 729 :package-version '(lsp-mode . "6.3.2")) 730 731 (defcustom lsp-rust-analyzer-proc-macro-enable t 732 "Enable Proc macro support. 733 Implies `lsp-rust-analyzer-cargo-run-build-scripts'" 734 :type 'boolean 735 :group 'lsp-rust-analyzer 736 :package-version '(lsp-mode . "6.3.2")) 737 738 (defcustom lsp-rust-analyzer-import-prefix "plain" 739 "The path structure for newly inserted paths to use. 740 Valid values are: 741 - \"plain\": Insert import paths relative to the current module, using up to 742 one `super' prefix if the parent module contains the requested item. 743 - \"by_self\": Prefix all import paths with `self' if they don't begin with 744 `self', `super', `crate' or a crate name. 745 - \"by_crate\": Force import paths to be absolute by always starting 746 them with `crate' or the crate name they refer to." 747 :type '(choice 748 (const "plain") 749 (const "by_self") 750 (const "by_crate")) 751 :group 'lsp-rust-analyzer 752 :package-version '(lsp-mode . "8.0.0")) 753 754 (defcustom lsp-rust-analyzer-import-granularity "crate" 755 "How imports should be grouped into use statements." 756 :type '(choice 757 (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.") 758 (const "module" :doc "Merge imports from the same module into a single use statement.") 759 (const "item" :doc "Don’t merge imports at all, creating one import per item.") 760 (const "preserve" :doc "Do not change the granularity of any imports. For auto-import this has the same effect as `\"item\"'")) 761 :group 'lsp-rust-analyzer 762 :package-version '(lsp-mode . "8.0.0")) 763 764 (defcustom lsp-rust-analyzer-cargo-auto-reload t 765 "Automatically refresh project info via `cargo metadata' on `Cargo.toml' changes." 766 :type 'boolean 767 :group 'lsp-rust-analyzer 768 :package-version '(lsp-mode . "8.0.0")) 769 770 (defcustom lsp-rust-analyzer-use-rustc-wrapper-for-build-scripts t 771 "Use `RUSTC_WRAPPER=rust-analyzer' when running build scripts to avoid 772 compiling unnecessary things." 773 :type 'boolean 774 :group 'lsp-rust-analyzer 775 :package-version '(lsp-mode . "8.0.0")) 776 777 (defcustom lsp-rust-analyzer-completion-auto-import-enable t 778 "Toggles the additional completions that automatically add imports when 779 completed. `lsp-completion-enable-additional-text-edit' must be non-nil 780 for this feature to be fully enabled." 781 :type 'boolean 782 :group 'lsp-rust-analyzer 783 :package-version '(lsp-mode . "8.0.0")) 784 785 (defcustom lsp-rust-analyzer-completion-auto-self-enable t 786 "Toggles the additional completions that automatically show method calls 787 and field accesses with self prefixed to them when inside a method." 788 :type 'boolean 789 :group 'lsp-rust-analyzer 790 :package-version '(lsp-mode . "8.0.0")) 791 792 (defcustom lsp-rust-analyzer-import-enforce-granularity nil 793 "Whether to enforce the import granularity setting for all files. 794 If set to nil rust-analyzer will try to keep import styles consistent per file." 795 :type 'boolean 796 :group 'lsp-rust-analyzer 797 :package-version '(lsp-mode . "8.0.0")) 798 799 (defcustom lsp-rust-analyzer-imports-merge-glob t 800 "Whether to allow import insertion to merge new imports into single path 801 glob imports like `use std::fmt::*;`." 802 :type 'boolean 803 :group 'lsp-rust-analyzer 804 :package-version '(lsp-mode . "9.0.0")) 805 806 (defcustom lsp-rust-analyzer-import-group t 807 "Group inserted imports by the following order: 808 https://rust-analyzer.github.io/manual.html#auto-import. 809 Groups are separated by newlines." 810 :type 'boolean 811 :group 'lsp-rust-analyzer 812 :package-version '(lsp-mode . "8.0.0")) 813 814 (defcustom lsp-rust-analyzer-highlighting-strings t 815 "Use semantic tokens for strings." 816 :type 'boolean 817 :group 'lsp-rust-analyzer 818 :package-version '(lsp-mode . "8.0.0")) 819 820 (defcustom lsp-rust-analyzer-rustc-source nil 821 "Path to the Cargo.toml of the rust compiler workspace." 822 :type '(choice 823 (file :tag "Path") 824 (const :tag "None" nil)) 825 :group 'lsp-rust-analyzer 826 :package-version '(lsp-mode . "8.0.0")) 827 828 (defcustom lsp-rust-analyzer-linked-projects [] 829 "Disable project auto-discovery in favor of explicitly specified set of 830 projects. Elements must be paths pointing to `Cargo.toml`, `rust-project.json`, 831 or JSON objects in `rust-project.json` format." 832 :type 'lsp-string-vector 833 :group 'lsp-rust-analyzer 834 :package-version '(lsp-mode . "9.0.0")) 835 836 (defcustom lsp-rust-analyzer-experimental-proc-attr-macros t 837 "Whether to enable experimental support for expanding proc macro attributes." 838 :type 'boolean 839 :group 'lsp-rust-analyzer 840 :package-version '(lsp-mode . "8.0.0")) 841 842 (defcustom lsp-rust-analyzer-cargo-extra-args [] 843 "Extra arguments that are passed to every cargo invocation." 844 :type 'lsp-string-vector 845 :group 'lsp-rust-analyzer 846 :package-version '(lsp-mode . "9.0.0")) 847 848 (defcustom lsp-rust-analyzer-cargo-extra-env [] 849 "Extra environment variables that will be set when running cargo, rustc or 850 other commands within the workspace. Useful for setting RUSTFLAGS." 851 :type 'lsp-string-vector 852 :group 'lsp-rust-analyzer 853 :package-version '(lsp-mode . "9.0.0")) 854 855 (defconst lsp-rust-notification-handlers 856 '(("rust-analyzer/publishDecorations" . (lambda (_w _p))))) 857 858 (defconst lsp-rust-action-handlers 859 '()) 860 861 (define-derived-mode lsp-rust-analyzer-syntax-tree-mode special-mode "Rust-Analyzer-Syntax-Tree" 862 "Mode for the rust-analyzer syntax tree buffer.") 863 864 (defun lsp-rust-analyzer-syntax-tree () 865 "Display syntax tree for current buffer." 866 (interactive) 867 (-let* ((root (lsp-workspace-root default-directory)) 868 (params (lsp-make-rust-analyzer-syntax-tree-params 869 :text-document (lsp--text-document-identifier) 870 :range? (if (use-region-p) 871 (lsp--region-to-range (region-beginning) (region-end)) 872 (lsp--region-to-range (point-min) (point-max))))) 873 (results (lsp-send-request (lsp-make-request 874 "rust-analyzer/syntaxTree" 875 params)))) 876 (let ((buf (get-buffer-create (format "*rust-analyzer syntax tree %s*" root))) 877 (inhibit-read-only t)) 878 (with-current-buffer buf 879 (lsp-rust-analyzer-syntax-tree-mode) 880 (erase-buffer) 881 (insert results) 882 (goto-char (point-min))) 883 (pop-to-buffer buf)))) 884 885 (define-derived-mode lsp-rust-analyzer-status-mode special-mode "Rust-Analyzer-Status" 886 "Mode for the rust-analyzer status buffer.") 887 888 (defun lsp-rust-analyzer-status () 889 "Displays status information for rust-analyzer." 890 (interactive) 891 (-let* ((root (lsp-workspace-root default-directory)) 892 (params (lsp-make-rust-analyzer-analyzer-status-params 893 :text-document (lsp--text-document-identifier))) 894 (results (lsp-send-request (lsp-make-request 895 "rust-analyzer/analyzerStatus" 896 params)))) 897 (let ((buf (get-buffer-create (format "*rust-analyzer status %s*" root))) 898 (inhibit-read-only t)) 899 (with-current-buffer buf 900 (lsp-rust-analyzer-status-mode) 901 (erase-buffer) 902 (insert results) 903 (pop-to-buffer buf))))) 904 905 (defun lsp-rust-analyzer-view-item-tree () 906 "Show item tree of rust file." 907 (interactive) 908 (-let* ((params (lsp-make-rust-analyzer-view-item-tree 909 :text-document (lsp--text-document-identifier))) 910 (results (lsp-send-request (lsp-make-request 911 "rust-analyzer/viewItemTree" 912 params)))) 913 (let ((buf (get-buffer-create "*rust-analyzer item tree*")) 914 (inhibit-read-only t)) 915 (with-current-buffer buf 916 (special-mode) 917 (erase-buffer) 918 (insert (lsp--render-string results "rust")) 919 (pop-to-buffer buf))))) 920 921 (defun lsp-rust-analyzer-view-hir () 922 "View Hir of function at point." 923 (interactive) 924 (-let* ((params (lsp-make-rust-analyzer-expand-macro-params 925 :text-document (lsp--text-document-identifier) 926 :position (lsp--cur-position))) 927 (results (lsp-send-request (lsp-make-request 928 "rust-analyzer/viewHir" 929 params)))) 930 (let ((buf (get-buffer-create "*rust-analyzer hir*")) 931 (inhibit-read-only t)) 932 (with-current-buffer buf 933 (special-mode) 934 (erase-buffer) 935 (insert results) 936 (pop-to-buffer buf))))) 937 938 (defun lsp-rust-analyzer-join-lines () 939 "Join selected lines into one, smartly fixing up whitespace and trailing commas." 940 (interactive) 941 (let* ((params (lsp-make-rust-analyzer-join-lines-params 942 :text-document (lsp--text-document-identifier) 943 :ranges (vector (if (use-region-p) 944 (lsp--region-to-range (region-beginning) (region-end)) 945 (lsp--region-to-range (point) (point)))))) 946 (result (lsp-send-request (lsp-make-request "experimental/joinLines" params)))) 947 (lsp--apply-text-edits result 'code-action))) 948 949 (defun lsp-rust-analyzer-reload-workspace () 950 "Reload workspace, picking up changes from Cargo.toml" 951 (interactive) 952 (lsp--cur-workspace-check) 953 (lsp-send-request (lsp-make-request "rust-analyzer/reloadWorkspace"))) 954 955 (defcustom lsp-rust-analyzer-download-url 956 (let* ((x86 (string-prefix-p "x86_64" system-configuration)) 957 (arch (if x86 "x86_64" "aarch64"))) 958 (format "https://github.com/rust-lang/rust-analyzer/releases/latest/download/%s" 959 (pcase system-type 960 ('gnu/linux (format "rust-analyzer-%s-unknown-linux-gnu.gz" arch)) 961 ('darwin (format "rust-analyzer-%s-apple-darwin.gz" arch)) 962 ('windows-nt (format "rust-analyzer-%s-pc-windows-msvc.zip" arch))))) 963 "Automatic download url for Rust Analyzer" 964 :type 'string 965 :group 'lsp-rust-analyzer 966 :package-version '(lsp-mode . "8.0.0")) 967 968 (defcustom lsp-rust-analyzer-store-path (f-join lsp-server-install-dir "rust" 969 (pcase system-type 970 ('windows-nt "rust-analyzer.exe") 971 (_ "rust-analyzer"))) 972 "The path to the file in which `rust-analyzer' will be stored." 973 :type 'file 974 :group 'lsp-rust-analyzer 975 :package-version '(lsp-mode . "8.0.0")) 976 977 (lsp-dependency 978 'rust-analyzer 979 `(:download :url lsp-rust-analyzer-download-url 980 :decompress ,(pcase system-type ('windows-nt :zip) (_ :gzip)) 981 :store-path lsp-rust-analyzer-store-path 982 :set-executable? t) 983 `(:system ,(file-name-nondirectory lsp-rust-analyzer-store-path))) 984 985 (lsp-defun lsp-rust--analyzer-run-single ((&Command :arguments?)) 986 (lsp-rust-analyzer-run (lsp-seq-first arguments?))) 987 988 (lsp-defun lsp-rust--analyzer-show-references 989 ((&Command :title :arguments? [_uri _filepos references])) 990 (lsp-show-xrefs (lsp--locations-to-xref-items references) nil 991 (s-contains-p "reference" title))) 992 993 (declare-function dap-debug "ext:dap-mode" (template) t) 994 995 (lsp-defun lsp-rust--analyzer-debug-lens ((&Command :arguments? [args])) 996 (lsp-rust-analyzer-debug args)) 997 998 ;; Semantic tokens 999 1000 ;; Modifier faces 1001 (defface lsp-rust-analyzer-documentation-modifier-face 1002 '((t nil)) 1003 "The face modification to use for documentation items." 1004 :group 'lsp-rust-analyzer-semantic-tokens) 1005 1006 (defface lsp-rust-analyzer-declaration-modifier-face 1007 '((t nil)) 1008 "The face modification to use for declaration items." 1009 :group 'lsp-rust-analyzer-semantic-tokens) 1010 1011 (defface lsp-rust-analyzer-definition-modifier-face 1012 '((t nil)) 1013 "The face modification to use for definition items." 1014 :group 'lsp-rust-analyzer-semantic-tokens) 1015 1016 (defface lsp-rust-analyzer-static-modifier-face 1017 '((t nil)) 1018 "The face modification to use for static items." 1019 :group 'lsp-rust-analyzer-semantic-tokens) 1020 1021 (defface lsp-rust-analyzer-abstract-modifier-face 1022 '((t nil)) 1023 "The face modification to use for abstract items." 1024 :group 'lsp-rust-analyzer-semantic-tokens) 1025 1026 (defface lsp-rust-analyzer-deprecated-modifier-face 1027 '((t nil)) 1028 "The face modification to use for deprecated items." 1029 :group 'lsp-rust-analyzer-semantic-tokens) 1030 1031 (defface lsp-rust-analyzer-readonly-modifier-face 1032 '((t nil)) 1033 "The face modification to use for readonly items." 1034 :group 'lsp-rust-analyzer-semantic-tokens) 1035 1036 (defface lsp-rust-analyzer-default-library-modifier-face 1037 '((t nil)) 1038 "The face modification to use for default-library items." 1039 :group 'lsp-rust-analyzer-semantic-tokens) 1040 1041 (defface lsp-rust-analyzer-async-modifier-face 1042 '((t nil)) 1043 "The face modification to use for async items." 1044 :group 'lsp-rust-analyzer-semantic-tokens) 1045 1046 (defface lsp-rust-analyzer-attribute-modifier-face 1047 '((t nil)) 1048 "The face modification to use for attribute items." 1049 :group 'lsp-rust-analyzer-semantic-tokens) 1050 1051 (defface lsp-rust-analyzer-callable-modifier-face 1052 '((t nil)) 1053 "The face modification to use for callable items." 1054 :group 'lsp-rust-analyzer-semantic-tokens) 1055 1056 (defface lsp-rust-analyzer-constant-modifier-face 1057 '((t nil)) 1058 "The face modification to use for constant items." 1059 :group 'lsp-rust-analyzer-semantic-tokens) 1060 1061 (defface lsp-rust-analyzer-consuming-modifier-face 1062 '((t nil)) 1063 "The face modification to use for consuming items." 1064 :group 'lsp-rust-analyzer-semantic-tokens) 1065 1066 (defface lsp-rust-analyzer-control-flow-modifier-face 1067 '((t nil)) 1068 "The face modification to use for control-flow items." 1069 :group 'lsp-rust-analyzer-semantic-tokens) 1070 1071 (defface lsp-rust-analyzer-crate-root-modifier-face 1072 '((t nil)) 1073 "The face modification to use for crate-root items." 1074 :group 'lsp-rust-analyzer-semantic-tokens) 1075 1076 (defface lsp-rust-analyzer-injected-modifier-face 1077 '((t nil)) 1078 "The face modification to use for injected items." 1079 :group 'lsp-rust-analyzer-semantic-tokens) 1080 1081 (defface lsp-rust-analyzer-intra-doc-link-modifier-face 1082 '((t nil)) 1083 "The face modification to use for intra-doc-link items." 1084 :group 'lsp-rust-analyzer-semantic-tokens) 1085 1086 (defface lsp-rust-analyzer-library-modifier-face 1087 '((t nil)) 1088 "The face modification to use for library items." 1089 :group 'lsp-rust-analyzer-semantic-tokens) 1090 1091 (defface lsp-rust-analyzer-mutable-modifier-face 1092 '((t :underline t)) 1093 "The face modification to use for mutable items." 1094 :group 'lsp-rust-analyzer-semantic-tokens) 1095 1096 (defface lsp-rust-analyzer-public-modifier-face 1097 '((t nil)) 1098 "The face modification to use for public items." 1099 :group 'lsp-rust-analyzer-semantic-tokens) 1100 1101 (defface lsp-rust-analyzer-reference-modifier-face 1102 '((t :bold t)) 1103 "The face modification to use for reference items." 1104 :group 'lsp-rust-analyzer-semantic-tokens) 1105 1106 (defface lsp-rust-analyzer-trait-modifier-face 1107 '((t nil)) 1108 "The face modification to use for trait items." 1109 :group 'lsp-rust-analyzer-semantic-tokens) 1110 1111 (defface lsp-rust-analyzer-unsafe-modifier-face 1112 '((t nil)) 1113 "The face modification to use for unsafe items." 1114 :group 'lsp-rust-analyzer-semantic-tokens) 1115 1116 1117 ;; --------------------------------------------------------------------- 1118 ;; Semantic token modifier face customization 1119 1120 (defcustom lsp-rust-analyzer-documentation-modifier 'lsp-rust-analyzer-documentation-modifier-face 1121 "Face for semantic token modifier for `documentation' attribute." 1122 :type 'face 1123 :group 'lsp-rust-analyzer-semantic-tokens 1124 :package-version '(lsp-mode . "9.0.0")) 1125 1126 (defcustom lsp-rust-analyzer-declaration-modifier 'lsp-rust-analyzer-declaration-modifier-face 1127 "Face for semantic token modifier for `declaration' 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-definition-modifier 'lsp-rust-analyzer-definition-modifier-face 1133 "Face for semantic token modifier for `definition' 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-static-modifier 'lsp-rust-analyzer-static-modifier-face 1139 "Face for semantic token modifier for `static' 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-abstract-modifier 'lsp-rust-analyzer-abstract-modifier-face 1145 "Face for semantic token modifier for `abstract' 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-deprecated-modifier 'lsp-rust-analyzer-deprecated-modifier-face 1151 "Face for semantic token modifier for `deprecated' 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-readonly-modifier 'lsp-rust-analyzer-readonly-modifier-face 1157 "Face for semantic token modifier for `readonly' 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-default-library-modifier 'lsp-rust-analyzer-default-library-modifier-face 1163 "Face for semantic token modifier for `default' 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-async-modifier 'lsp-rust-analyzer-async-modifier-face 1169 "Face for semantic token modifier for `async' 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-attribute-modifier 'lsp-rust-analyzer-attribute-modifier-face 1175 "Face for semantic token modifier for `attribute' 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-callable-modifier 'lsp-rust-analyzer-callable-modifier-face 1181 "Face for semantic token modifier for `callable' 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-constant-modifier 'lsp-rust-analyzer-constant-modifier-face 1187 "Face for semantic token modifier for `constant' 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-consuming-modifier 'lsp-rust-analyzer-consuming-modifier-face 1193 "Face for semantic token modifier for `consuming' 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-control-flow-modifier 'lsp-rust-analyzer-control-flow-modifier-face 1199 "Face for semantic token modifier for `control_flow' 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-crate-root-modifier 'lsp-rust-analyzer-crate-root-modifier-face 1205 "Face for semantic token modifier for `crate_root' 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-injected-modifier 'lsp-rust-analyzer-injected-modifier-face 1211 "Face for semantic token modifier for `injected' 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-intra-doc-link-modifier 'lsp-rust-analyzer-intra-doc-link-modifier-face 1217 "Face for semantic token modifier for `intra_doc_link' 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-library-modifier 'lsp-rust-analyzer-library-modifier-face 1223 "Face for semantic token modifier for `library' 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-mutable-modifier 'lsp-rust-analyzer-mutable-modifier-face 1229 "Face for semantic token modifier for `mutable' 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-public-modifier 'lsp-rust-analyzer-public-modifier-face 1235 "Face for semantic token modifier for `public' 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-reference-modifier 'lsp-rust-analyzer-reference-modifier-face 1241 "Face for semantic token modifier for `reference' 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-trait-modifier 'lsp-rust-analyzer-trait-modifier-face 1247 "Face for semantic token modifier for `trait' 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-unsafe-modifier 'lsp-rust-analyzer-unsafe-modifier-face 1253 "Face for semantic token modifier for `unsafe' attribute." 1254 :type 'face 1255 :group 'lsp-rust-analyzer-semantic-tokens 1256 :package-version '(lsp-mode . "9.0.0")) 1257 1258 ;; --------------------------------------------------------------------- 1259 1260 (defun lsp-rust-analyzer--semantic-modifiers () 1261 "Mapping between rust-analyzer keywords and fonts to apply. 1262 The keywords are sent in the initialize response, in the semantic 1263 tokens legend." 1264 `(("documentation" . ,lsp-rust-analyzer-documentation-modifier) 1265 ("declaration" . ,lsp-rust-analyzer-declaration-modifier) 1266 ("definition" . ,lsp-rust-analyzer-definition-modifier) 1267 ("static" . ,lsp-rust-analyzer-static-modifier) 1268 ("abstract" . ,lsp-rust-analyzer-abstract-modifier) 1269 ("deprecated" . ,lsp-rust-analyzer-deprecated-modifier) 1270 ("readonly" . ,lsp-rust-analyzer-readonly-modifier) 1271 ("default_library" . ,lsp-rust-analyzer-default-library-modifier) 1272 ("async" . ,lsp-rust-analyzer-async-modifier) 1273 ("attribute" . ,lsp-rust-analyzer-attribute-modifier) 1274 ("callable" . ,lsp-rust-analyzer-callable-modifier) 1275 ("constant" . ,lsp-rust-analyzer-constant-modifier) 1276 ("consuming" . ,lsp-rust-analyzer-consuming-modifier) 1277 ("control_flow" . ,lsp-rust-analyzer-control-flow-modifier) 1278 ("crate_root" . ,lsp-rust-analyzer-crate-root-modifier) 1279 ("injected" . ,lsp-rust-analyzer-injected-modifier) 1280 ("intra_doc_link" . ,lsp-rust-analyzer-intra-doc-link-modifier) 1281 ("library" . ,lsp-rust-analyzer-library-modifier) 1282 ("mutable" . ,lsp-rust-analyzer-mutable-modifier) 1283 ("public" . ,lsp-rust-analyzer-public-modifier) 1284 ("reference" . ,lsp-rust-analyzer-reference-modifier) 1285 ("trait" . ,lsp-rust-analyzer-trait-modifier) 1286 ("unsafe" . ,lsp-rust-analyzer-unsafe-modifier))) 1287 1288 (defun lsp-rust-switch-server (&optional lsp-server) 1289 "Switch priorities of lsp servers, unless LSP-SERVER is already active." 1290 (interactive) 1291 (let ((current-server (if (> (lsp--client-priority (gethash 'rls lsp-clients)) 0) 1292 'rls 1293 'rust-analyzer))) 1294 (unless (eq lsp-server current-server) 1295 (dolist (server '(rls rust-analyzer)) 1296 (when (natnump (setf (lsp--client-priority (gethash server lsp-clients)) 1297 (* (lsp--client-priority (gethash server lsp-clients)) -1))) 1298 (message (format "Switched to server %s." server))))))) 1299 1300 ;; 1301 ;;; Inlay hints 1302 1303 (defcustom lsp-rust-analyzer-debug-lens-extra-dap-args 1304 '(:MIMode "gdb" :miDebuggerPath "gdb" :stopAtEntry t :externalConsole :json-false) 1305 "Extra arguments to pass to DAP template when debugging a test from code lens. 1306 1307 As a rule of the thumb, do not add extra keys to this plist unless you exactly 1308 what you are doing, it might break the \"Debug test\" lens otherwise. 1309 1310 See dap-mode documentation and cpptools documentation for the extra variables 1311 meaning." 1312 :type 'plist 1313 :group 'lsp-rust-analyzer 1314 :package-version '(lsp-mode . "8.0.0")) 1315 1316 ;; 1317 ;;; Lenses 1318 1319 (defgroup lsp-rust-analyzer-lens nil 1320 "LSP lens support for Rust when using rust-analyzer. 1321 1322 Lenses are (depending on your configuration) clickable links to 1323 the right of function definitions and the like. These display 1324 some useful information in their own right and/or perform a 1325 shortcut action when clicked such as displaying uses of that 1326 function or running an individual test. 1327 " 1328 :prefix "lsp-rust-analyzer-lens-" 1329 :group 'lsp-rust-analyzer 1330 :link '(url-link "https://emacs-lsp.github.io/lsp-mode/") 1331 :package-version '(lsp-mode . "9.0.0")) 1332 1333 (defcustom lsp-rust-analyzer-lens-debug-enable t 1334 "Enable or disable the Debug lens." 1335 :type 'boolean 1336 :group 'lsp-rust-analyzer-lens 1337 :package-version '(lsp-mode . "9.0.0")) 1338 1339 (defcustom lsp-rust-analyzer-lens-enable t 1340 "Master-enable of lenses in Rust files." 1341 :type 'boolean 1342 :group 'lsp-rust-analyzer-lens 1343 :package-version '(lsp-mode . "9.0.0")) 1344 1345 ;; This customisation "works" in that it works as described, but the default is fine and changing it 1346 ;; from the default will either stop lenses working or do nothing. 1347 ;; 1348 ;; If this is ever uncommented to re-enable the option, don't forget to also uncomment it in defun 1349 ;; lsp-rust-analyzer--make-init-options too or it'll not do anything. 1350 1351 ;; (defcustom lsp-rust-analyzer-lens-force-custom-commands t 1352 ;; "Internal config: use custom client-side commands even when the 1353 ;; client doesn't set the corresponding capability." 1354 ;; :type 'boolean 1355 ;; :group 'lsp-rust-analyzer-lens 1356 ;; :package-version '(lsp-mode . "9.0.0")) 1357 1358 (defcustom lsp-rust-analyzer-lens-implementations-enable t 1359 "Enable or disable the Implementations lens. 1360 1361 The Implementations lens shows `NN implementations' to the right 1362 of the first line of an enum, struct, or union declaration. This 1363 is the count of impl blocks, including derived traits. Clicking 1364 on it gives a list of the impls of that type. 1365 " 1366 :type 'boolean 1367 :group 'lsp-rust-analyzer-lens 1368 :package-version '(lsp-mode . "9.0.0")) 1369 1370 ;; The valid range of values for this is documented in the rust-lang/rust-analyzer repository at the 1371 ;; path "editors/code/package.json"; the TL:DR is that it's "above_name" or "above_whole_item". 1372 ;; However, setting it to "above_whole_item" causes lenses to disappear in Emacs. I suspect this 1373 ;; feature has only ever been tested in some other IDE and it's broken in Emacs. So I've disabled it 1374 ;; for now. 1375 ;; 1376 ;; If this is ever uncommented to re-enable the option, don't forget to also uncomment it in defun 1377 ;; lsp-rust-analyzer--make-init-options too or it'll not do anything. 1378 1379 ;; (defcustom lsp-rust-analyzer-lens-location "above_name" 1380 ;; "Where to render annotations." 1381 ;; :type '(choice 1382 ;; (const :tag "Above name" "above_name") 1383 ;; (const :tag "Above whole item" "above_whole_item") 1384 ;; :group 'lsp-rust-analyzer-lens 1385 ;; :package-version '(lsp-mode . "9.0.0")) 1386 1387 (defcustom lsp-rust-analyzer-lens-references-adt-enable nil 1388 "Enable or disable the References lens on enums, structs, and traits. 1389 1390 The References lens shows `NN references` to the right of the 1391 first line of each enum, struct, or union declaration. This is 1392 the count of uses of that type. Clicking on it gives a list of 1393 where that type is used." 1394 :type 'boolean 1395 :group 'lsp-rust-analyzer-lens 1396 :package-version '(lsp-mode . "9.0.0")) 1397 1398 (defcustom lsp-rust-analyzer-lens-references-enum-variant-enable nil 1399 "Enable or disable the References lens on enum variants. 1400 1401 The References lens shows `NN references` to the right of the 1402 first (or only) line of each enum variant. This is the count of 1403 uses of that enum variant. Clicking on it gives a list of where 1404 that enum variant is used." 1405 :type 'boolean 1406 :group 'lsp-rust-analyzer-lens 1407 :package-version '(lsp-mode . "9.0.0")) 1408 1409 (defcustom lsp-rust-analyzer-lens-references-method-enable nil 1410 "Enable or disable the References lens on functions. 1411 1412 The References lens shows `NN references` to the right of the 1413 first line of each function declaration. This is the count of 1414 uses of that function. Clicking on it gives a list of where that 1415 function is used." 1416 1417 :type 'boolean 1418 :group 'lsp-rust-analyzer-lens 1419 :package-version '(lsp-mode . "9.0.0")) 1420 1421 (defcustom lsp-rust-analyzer-lens-references-trait-enable nil 1422 "Enable or disable the References lens on traits. 1423 1424 The References lens shows `NN references` to the right of the 1425 first line of each trait declaration. This is a count of uses of 1426 that trait. Clicking on it gives a list of where that trait is 1427 used. 1428 1429 There is some overlap with the Implementations lens which slows 1430 all of the trait's impl blocks, but this also shows other uses 1431 such as imports and dyn traits." 1432 :type 'boolean 1433 :group 'lsp-rust-analyzer-lens 1434 :package-version '(lsp-mode . "9.0.0")) 1435 1436 (defcustom lsp-rust-analyzer-lens-run-enable t 1437 "Enable or disable the Run lens." 1438 :type 'boolean 1439 :group 'lsp-rust-analyzer-lens 1440 :package-version '(lsp-mode . "9.0.0")) 1441 1442 (defun lsp-rust-analyzer-initialized? () 1443 (when-let ((workspace (lsp-find-workspace 'rust-analyzer (buffer-file-name)))) 1444 (eq 'initialized (lsp--workspace-status workspace)))) 1445 1446 (defun lsp-rust-analyzer-expand-macro () 1447 "Expands the macro call at point recursively." 1448 (interactive) 1449 (-if-let* ((params (lsp-make-rust-analyzer-expand-macro-params 1450 :text-document (lsp--text-document-identifier) 1451 :position (lsp--cur-position))) 1452 (response (lsp-request 1453 "rust-analyzer/expandMacro" 1454 params)) 1455 ((&rust-analyzer:ExpandedMacro :expansion) response)) 1456 (funcall lsp-rust-analyzer-macro-expansion-method expansion) 1457 (lsp--error "No macro found at point, or it could not be expanded."))) 1458 1459 (defun lsp-rust-analyzer-macro-expansion-default (result) 1460 "Default method for displaying macro expansion." 1461 (let* ((root (lsp-workspace-root default-directory)) 1462 (buf (get-buffer-create (get-buffer-create (format "*rust-analyzer macro expansion %s*" root))))) 1463 (with-current-buffer buf 1464 (let ((inhibit-read-only t)) 1465 (erase-buffer) 1466 (insert (lsp--render-string result "rust")) 1467 (special-mode))) 1468 (pop-to-buffer buf))) 1469 1470 ;; 1471 ;;; Runnables 1472 1473 (defvar lsp-rust-analyzer--last-runnable nil 1474 "Record the last runnable.") 1475 1476 (defun lsp-rust-analyzer--runnables () 1477 "Return list of runnables." 1478 (lsp-send-request (lsp-make-request 1479 "experimental/runnables" 1480 (lsp-make-rust-analyzer-runnables-params 1481 :text-document (lsp--text-document-identifier) 1482 :position? (lsp--cur-position))))) 1483 1484 (defun lsp-rust-analyzer--select-runnable () 1485 "Select runnable." 1486 (lsp--completing-read 1487 "Select runnable:" 1488 (if lsp-rust-analyzer--last-runnable 1489 (cons lsp-rust-analyzer--last-runnable 1490 (-remove (-lambda ((&rust-analyzer:Runnable :label)) 1491 (equal label (lsp-get lsp-rust-analyzer--last-runnable :label))) 1492 (lsp-rust-analyzer--runnables))) 1493 (lsp-rust-analyzer--runnables)) 1494 (-lambda ((&rust-analyzer:Runnable :label)) label))) 1495 1496 (defun lsp-rust-analyzer--common-runner (runnable) 1497 "Execute a given RUNNABLE. 1498 1499 Extract the arguments, prepare the minor mode (cargo-process-mode if possible) 1500 and run a compilation" 1501 (-let* (((&rust-analyzer:Runnable :kind :label :args) runnable) 1502 ((&rust-analyzer:RunnableArgs :cargo-args :executable-args :workspace-root? :expect-test?) args) 1503 (default-directory (or workspace-root? default-directory))) 1504 (if (not (string-equal kind "cargo")) 1505 (lsp--error "'%s' runnable is not supported" kind) 1506 (compilation-start 1507 (string-join (append (when expect-test? '("env" "UPDATE_EXPECT=1")) 1508 (list "cargo") cargo-args 1509 (when executable-args '("--")) executable-args '()) " ") 1510 1511 ;; cargo-process-mode is nice, but try to work without it... 1512 (if (functionp 'cargo-process-mode) 'cargo-process-mode nil) 1513 (lambda (_) (concat "*" label "*")))))) 1514 1515 (defun lsp-rust-analyzer-run (runnable) 1516 "Select and run a RUNNABLE action." 1517 (interactive (list (lsp-rust-analyzer--select-runnable))) 1518 (when (lsp-rust-analyzer--common-runner runnable) 1519 (setq lsp-rust-analyzer--last-runnable runnable))) 1520 1521 (defun lsp-rust-analyzer-debug (runnable) 1522 "Select and debug a RUNNABLE action." 1523 (interactive (list (lsp-rust-analyzer--select-runnable))) 1524 (unless (or (featurep 'dap-cpptools) (featurep 'dap-gdb)) 1525 (user-error "You must require `dap-cpptools' or 'dap-gdb'")) 1526 (-let (((&rust-analyzer:Runnable 1527 :args (&rust-analyzer:RunnableArgs :cargo-args :workspace-root? :executable-args) 1528 :label) runnable)) 1529 (pcase (aref cargo-args 0) 1530 ("run" (aset cargo-args 0 "build")) 1531 ("test" (when (-contains? (append cargo-args ()) "--no-run") 1532 (cl-callf append cargo-args (list "--no-run"))))) 1533 (->> (append (list (executable-find "cargo")) 1534 cargo-args 1535 (list "--message-format=json")) 1536 (s-join " ") 1537 (shell-command-to-string) 1538 (s-lines) 1539 (-keep (lambda (s) 1540 (condition-case nil 1541 (-let* ((json-object-type 'plist) 1542 ((msg &as &plist :reason :executable) (json-read-from-string s))) 1543 (when (and executable (string= "compiler-artifact" reason)) 1544 executable)) 1545 (error)))) 1546 (funcall 1547 (lambda (artifact-spec) 1548 (pcase artifact-spec 1549 (`() (user-error "No compilation artifacts or obtaining the runnable artifacts failed")) 1550 (`(,spec) spec) 1551 (_ (user-error "Multiple compilation artifacts are not supported"))))) 1552 (list :type (if (featurep 'dap-gdb) "gdb" "cppdbg") 1553 :request "launch" 1554 :name label 1555 :args executable-args 1556 :cwd workspace-root? 1557 :sourceLanguages ["rust"] 1558 :program) 1559 (append lsp-rust-analyzer-debug-lens-extra-dap-args) 1560 (dap-debug)))) 1561 1562 (defun lsp-rust-analyzer-rerun (&optional runnable) 1563 (interactive (list (or lsp-rust-analyzer--last-runnable 1564 (lsp-rust-analyzer--select-runnable)))) 1565 (lsp-rust-analyzer-run (or runnable lsp-rust-analyzer--last-runnable))) 1566 1567 ;; goto parent module 1568 (cl-defun lsp-rust-find-parent-module (&key display-action) 1569 "Find parent module of current module." 1570 (interactive) 1571 (lsp-find-locations "experimental/parentModule" nil :display-action display-action)) 1572 1573 (defun lsp-rust-analyzer-open-cargo-toml (&optional new-window) 1574 "Open the closest Cargo.toml from the current file. 1575 1576 Rust-Analyzer LSP protocol documented here and added in November 2020 1577 https://github.com/rust-lang/rust-analyzer/blob/master/docs/dev/lsp-extensions.md#open-cargotoml 1578 1579 If NEW-WINDOW (interactively the prefix argument) is non-nil, 1580 open in a new window." 1581 (interactive "P") 1582 (-if-let (workspace (lsp-find-workspace 'rust-analyzer (buffer-file-name))) 1583 (-if-let* ((response (with-lsp-workspace workspace 1584 (lsp-send-request (lsp-make-request 1585 "experimental/openCargoToml" 1586 (lsp-make-rust-analyzer-open-cargo-toml-params 1587 :text-document (lsp--text-document-identifier)))))) 1588 ((&Location :uri :range) response)) 1589 (funcall (if new-window #'find-file-other-window #'find-file) 1590 (lsp--uri-to-path uri)) 1591 (lsp--warn "Couldn't find a Cargo.toml file or your version of rust-analyzer doesn't support this extension")) 1592 (lsp--error "OpenCargoToml is an extension available only with rust-analyzer"))) 1593 1594 (defun lsp-rust-analyzer-open-external-docs () 1595 "Open a URL for documentation related to the current TextDocumentPosition. 1596 1597 Rust-Analyzer LSP protocol documented here 1598 https://github.com/rust-lang/rust-analyzer/blob/master/docs/dev/lsp-extensions.md#open-external-documentation" 1599 (interactive) 1600 (-if-let* ((params (lsp-make-rust-analyzer-open-external-docs-params 1601 :text-document (lsp--text-document-identifier) 1602 :position (lsp--cur-position))) 1603 (url (lsp-request "experimental/externalDocs" params))) 1604 (browse-url url) 1605 (lsp--warn "Couldn't find documentation URL or your version of rust-analyzer doesn't support this extension"))) 1606 1607 (defun lsp-rust-analyzer--related-tests () 1608 "Get runnable test items related to the current TextDocumentPosition. 1609 Calls a rust-analyzer LSP extension endpoint that returns a wrapper over 1610 Runnable[]." 1611 (lsp-send-request (lsp-make-request 1612 "rust-analyzer/relatedTests" 1613 (lsp--text-document-position-params)))) 1614 1615 (defun lsp-rust-analyzer--select-related-test () 1616 "Call the endpoint and ask for user selection. 1617 1618 Cannot reuse `lsp-rust-analyzer--select-runnable' because the runnables endpoint 1619 responds with Runnable[], while relatedTests responds with TestInfo[], 1620 which is a wrapper over runnable. Also, this method doesn't set 1621 the `lsp-rust-analyzer--last-runnable' variable." 1622 (-if-let* ((resp (lsp-rust-analyzer--related-tests)) 1623 (runnables (seq-map 1624 #'lsp:rust-analyzer-related-tests-runnable 1625 resp))) 1626 (lsp--completing-read 1627 "Select test: " 1628 runnables 1629 #'lsp:rust-analyzer-runnable-label))) 1630 1631 (defun lsp-rust-analyzer-related-tests (runnable) 1632 "Execute a RUNNABLE test related to the current document position. 1633 1634 Rust-Analyzer LSP protocol extension 1635 https://github.com/rust-lang/rust-analyzer/blob/master/docs/dev/lsp-extensions.md#related-tests" 1636 (interactive (list (lsp-rust-analyzer--select-related-test))) 1637 (if runnable 1638 (lsp-rust-analyzer--common-runner runnable) 1639 (lsp--info "There are no tests related to the symbol at point"))) 1640 1641 (defun lsp-rust-analyzer-move-item (direction) 1642 "Move item under cursor or selection in some DIRECTION" 1643 (let* ((params (lsp-make-rust-analyzer-move-item-params 1644 :text-document (lsp--text-document-identifier) 1645 :range (if (use-region-p) 1646 (lsp--region-to-range (region-beginning) (region-end)) 1647 (lsp--region-to-range (point) (point))) 1648 :direction direction)) 1649 (edits (lsp-request "experimental/moveItem" params))) 1650 (lsp--apply-text-edits edits 'code-action))) 1651 1652 (defun lsp-rust-analyzer-move-item-up () 1653 "Move item under cursor or selection up" 1654 (interactive) 1655 (lsp-rust-analyzer-move-item "Up")) 1656 1657 (defun lsp-rust-analyzer-move-item-down () 1658 "Move item under cursor or selection down" 1659 (interactive) 1660 (lsp-rust-analyzer-move-item "Down")) 1661 1662 (defun lsp-rust-analyzer--make-init-options () 1663 "Init options for rust-analyzer" 1664 `(:diagnostics 1665 ( :enable ,(lsp-json-bool lsp-rust-analyzer-diagnostics-enable) 1666 :enableExperimental ,(lsp-json-bool lsp-rust-analyzer-diagnostics-enable-experimental) 1667 :disabled ,lsp-rust-analyzer-diagnostics-disabled 1668 :warningsAsHint ,lsp-rust-analyzer-diagnostics-warnings-as-hint 1669 :warningsAsInfo ,lsp-rust-analyzer-diagnostics-warnings-as-info) 1670 :imports ( :granularity ( :enforce ,(lsp-json-bool lsp-rust-analyzer-import-enforce-granularity) 1671 :group ,lsp-rust-analyzer-import-granularity) 1672 :group ,(lsp-json-bool lsp-rust-analyzer-import-group) 1673 :merge (:glob ,(lsp-json-bool lsp-rust-analyzer-imports-merge-glob)) 1674 :prefix ,lsp-rust-analyzer-import-prefix) 1675 :lruCapacity ,lsp-rust-analyzer-lru-capacity 1676 ;; This `checkOnSave` is called `check` in the `rust-analyzer` docs, not 1677 ;; `checkOnSave`, but the `rust-analyzer` source code shows that both names 1678 ;; work. The `checkOnSave` name has been supported by `rust-analyzer` for a 1679 ;; long time, whereas the `check` name was introduced here in 2023: 1680 ;; https://github.com/rust-lang/rust-analyzer/commit/d2bb62b6a81d26f1e41712e04d4ac760f860d3b3 1681 :checkOnSave ( :enable ,(lsp-json-bool lsp-rust-analyzer-cargo-watch-enable) 1682 :command ,lsp-rust-analyzer-cargo-watch-command 1683 :extraArgs ,lsp-rust-analyzer-cargo-watch-args 1684 :allTargets ,(lsp-json-bool lsp-rust-analyzer-check-all-targets) 1685 ;; We need to distinguish between setting this to the empty 1686 ;; vector, and not setting it at all, which `rust-analyzer` 1687 ;; interprets as "inherit from 1688 ;; `rust-analyzer.cargo.features`". We use `nil` to mean 1689 ;; "unset". 1690 ,@(when (vectorp lsp-rust-analyzer-checkonsave-features) 1691 `(:features ,lsp-rust-analyzer-checkonsave-features)) 1692 :overrideCommand ,lsp-rust-analyzer-cargo-override-command) 1693 :highlightRelated ( :breakPoints (:enable ,(lsp-json-bool lsp-rust-analyzer-highlight-breakpoints)) 1694 :closureCaptures (:enable ,(lsp-json-bool lsp-rust-analyzer-highlight-closure-captures)) 1695 :exitPoints (:enable ,(lsp-json-bool lsp-rust-analyzer-highlight-exit-points)) 1696 :references (:enable ,(lsp-json-bool lsp-rust-analyzer-highlight-references)) 1697 :yieldPoints (:enable ,(lsp-json-bool lsp-rust-analyzer-highlight-yield-points))) 1698 :files ( :exclude ,lsp-rust-analyzer-exclude-globs 1699 :watcher ,(if lsp-rust-analyzer-use-client-watching "client" "notify") 1700 :excludeDirs ,lsp-rust-analyzer-exclude-dirs) 1701 :cargo ( :allFeatures ,(lsp-json-bool lsp-rust-all-features) 1702 :noDefaultFeatures ,(lsp-json-bool lsp-rust-no-default-features) 1703 :features ,lsp-rust-features 1704 :extraArgs ,lsp-rust-analyzer-cargo-extra-args 1705 :extraEnv ,lsp-rust-analyzer-cargo-extra-env 1706 :target ,lsp-rust-analyzer-cargo-target 1707 :runBuildScripts ,(lsp-json-bool lsp-rust-analyzer-cargo-run-build-scripts) 1708 ;; Obsolete, but used by old Rust-Analyzer versions 1709 :loadOutDirsFromCheck ,(lsp-json-bool lsp-rust-analyzer-cargo-run-build-scripts) 1710 :autoreload ,(lsp-json-bool lsp-rust-analyzer-cargo-auto-reload) 1711 :useRustcWrapperForBuildScripts ,(lsp-json-bool lsp-rust-analyzer-use-rustc-wrapper-for-build-scripts) 1712 :unsetTest ,lsp-rust-analyzer-cargo-unset-test) 1713 :rustfmt ( :extraArgs ,lsp-rust-analyzer-rustfmt-extra-args 1714 :overrideCommand ,lsp-rust-analyzer-rustfmt-override-command 1715 :rangeFormatting (:enable ,(lsp-json-bool lsp-rust-analyzer-rustfmt-rangeformatting-enable))) 1716 :lens ( :debug (:enable ,(lsp-json-bool lsp-rust-analyzer-lens-debug-enable)) 1717 :enable ,(lsp-json-bool lsp-rust-analyzer-lens-enable) 1718 ;; :forceCustomCommands ,(lsp-json-bool lsp-rust-analyzer-lens-force-custom-commands) 1719 :implementations (:enable ,(lsp-json-bool lsp-rust-analyzer-lens-implementations-enable)) 1720 ;; :location ,lsp-rust-analyzer-lens-location 1721 :references ( :adt (:enable ,(lsp-json-bool lsp-rust-analyzer-lens-references-adt-enable)) 1722 :enumVariant (:enable ,(lsp-json-bool lsp-rust-analyzer-lens-references-enum-variant-enable)) 1723 :method (:enable ,(lsp-json-bool lsp-rust-analyzer-lens-references-method-enable)) 1724 :trait (:enable ,(lsp-json-bool lsp-rust-analyzer-lens-references-trait-enable))) 1725 :run (:enable ,(lsp-json-bool lsp-rust-analyzer-lens-run-enable))) 1726 1727 :inlayHints ( :bindingModeHints (:enable ,(lsp-json-bool lsp-rust-analyzer-binding-mode-hints)) 1728 :chainingHints (:enable ,(lsp-json-bool lsp-rust-analyzer-display-chaining-hints)) 1729 :closingBraceHints ( :enable ,(lsp-json-bool lsp-rust-analyzer-closing-brace-hints) 1730 :minLines ,lsp-rust-analyzer-closing-brace-hints-min-lines) 1731 :closureCaptureHints (:enable ,(lsp-json-bool lsp-rust-analyzer-closure-capture-hints)) 1732 :closureReturnTypeHints (:enable ,lsp-rust-analyzer-closure-return-type-hints) 1733 :closureStyle ,lsp-rust-analyzer-closure-style 1734 :discriminantHints (:enable ,lsp-rust-analyzer-discriminants-hints) 1735 1736 :expressionAdjustmentHints ( :enable ,lsp-rust-analyzer-expression-adjustment-hints 1737 :hideOutsideUnsafe ,(lsp-json-bool lsp-rust-analyzer-expression-adjustment-hide-unsafe) 1738 :mode ,lsp-rust-analyzer-expression-adjustment-hints-mode) 1739 :implicitDrops (:enable ,(lsp-json-bool lsp-rust-analyzer-implicit-drops)) 1740 :lifetimeElisionHints ( :enable ,lsp-rust-analyzer-display-lifetime-elision-hints-enable 1741 :useParameterNames ,(lsp-json-bool lsp-rust-analyzer-display-lifetime-elision-hints-use-parameter-names)) 1742 :maxLength ,lsp-rust-analyzer-max-inlay-hint-length 1743 :parameterHints (:enable ,(lsp-json-bool lsp-rust-analyzer-display-parameter-hints)) 1744 :reborrowHints (:enable ,lsp-rust-analyzer-display-reborrow-hints) 1745 :renderColons ,(lsp-json-bool lsp-rust-analyzer-server-format-inlay-hints) 1746 :typeHints ( :enable ,(lsp-json-bool lsp-inlay-hint-enable) 1747 :hideClosureInitialization ,(lsp-json-bool lsp-rust-analyzer-hide-closure-initialization) 1748 :hideNamedConstructor ,(lsp-json-bool lsp-rust-analyzer-hide-named-constructor))) 1749 :completion ( :addCallParenthesis ,(lsp-json-bool lsp-rust-analyzer-completion-add-call-parenthesis) 1750 :addCallArgumentSnippets ,(lsp-json-bool lsp-rust-analyzer-completion-add-call-argument-snippets) 1751 :postfix (:enable ,(lsp-json-bool lsp-rust-analyzer-completion-postfix-enable)) 1752 :autoimport (:enable ,(lsp-json-bool lsp-rust-analyzer-completion-auto-import-enable)) 1753 :autoself (:enable ,(lsp-json-bool lsp-rust-analyzer-completion-auto-self-enable))) 1754 :callInfo (:full ,(lsp-json-bool lsp-rust-analyzer-call-info-full)) 1755 :procMacro (:enable ,(lsp-json-bool lsp-rust-analyzer-proc-macro-enable)) 1756 :rustcSource ,lsp-rust-analyzer-rustc-source 1757 :linkedProjects ,lsp-rust-analyzer-linked-projects 1758 :highlighting (:strings ,(lsp-json-bool lsp-rust-analyzer-highlighting-strings)) 1759 :experimental (:procAttrMacros ,(lsp-json-bool lsp-rust-analyzer-experimental-proc-attr-macros)))) 1760 1761 (lsp-register-client 1762 (make-lsp-client 1763 :new-connection (lsp-stdio-connection 1764 (lambda () 1765 `(,(or (executable-find 1766 (cl-first lsp-rust-analyzer-server-command)) 1767 (lsp-package-path 'rust-analyzer) 1768 "rust-analyzer") 1769 ,@(cl-rest lsp-rust-analyzer-server-command)))) 1770 :activation-fn (lsp-activate-on "rust") 1771 :priority (if (eq lsp-rust-server 'rust-analyzer) 1 -1) 1772 :initialization-options 'lsp-rust-analyzer--make-init-options 1773 :notification-handlers (ht<-alist lsp-rust-notification-handlers) 1774 :action-handlers (ht ("rust-analyzer.runSingle" #'lsp-rust--analyzer-run-single) 1775 ("rust-analyzer.debugSingle" #'lsp-rust--analyzer-debug-lens) 1776 ("rust-analyzer.showReferences" #'lsp-rust--analyzer-show-references) 1777 ("rust-analyzer.triggerParameterHints" #'lsp--action-trigger-parameter-hints)) 1778 :library-folders-fn (lambda (_workspace) lsp-rust-analyzer-library-directories) 1779 :semantic-tokens-faces-overrides `( :discard-default-modifiers t 1780 :modifiers ,(lsp-rust-analyzer--semantic-modifiers)) 1781 :server-id 'rust-analyzer 1782 :custom-capabilities `((experimental . 1783 ((snippetTextEdit . ,(and lsp-enable-snippet (fboundp 'yas-minor-mode))) 1784 (commands . ((commands . 1785 [ 1786 "rust-analyzer.runSingle" 1787 "rust-analyzer.debugSingle" 1788 "rust-analyzer.showReferences" 1789 ;; "rust-analyzer.gotoLocation" 1790 "rust-analyzer.triggerParameterHints" 1791 ;; "rust-analyzer.rename" 1792 ])))))) 1793 :download-server-fn (lambda (_client callback error-callback _update?) 1794 (lsp-package-ensure 'rust-analyzer callback error-callback)))) 1795 1796 (cl-defmethod lsp-clients-extract-signature-on-hover (contents (_server-id (eql rust-analyzer))) 1797 "Extract first non-comment line from rust-analyzer's hover CONTENTS. 1798 The first line of the hover contents is usally about memory layout or notable 1799 traits starting with //, with the actual signature follows." 1800 (let* ((lines (s-lines (s-trim (lsp--render-element contents)))) 1801 (non-comment-lines (--filter (not (s-prefix? "//" it)) lines))) 1802 (if non-comment-lines 1803 (car non-comment-lines) 1804 (car lines)))) 1805 1806 (lsp-consistency-check lsp-rust) 1807 1808 (provide 'lsp-rust) 1809 ;;; lsp-rust.el ends here