config

Personal configuration.
git clone git://code.dwrz.net/config
Log | Files | Refs

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