Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a variable for customizing rust-analyzer.cargo.targetDir #4506

Open
fitzgen opened this issue Jul 26, 2024 · 2 comments
Open

Add a variable for customizing rust-analyzer.cargo.targetDir #4506

fitzgen opened this issue Jul 26, 2024 · 2 comments

Comments

@fitzgen
Copy link

fitzgen commented Jul 26, 2024

The rust-analyzer.cargo.targetDir setting allows controlling the directory that rust-analyzer will use for build artifacts. It is useful to set this to something other than the default project's target directory because only one of cargo and rust-analyzer can use the directory at a time, they each exclusively lock it. This means that running tests and rust-analyzer running in the background can contend, which results in a poor user experience. Therefore, it would be nice if lsp-mode allowed configuring this setting via a custom variable or something.

More details: https://rust-analyzer.github.io/manual.html#rust-analyzer.cargo.targetDir

Thanks for all your work on lsp-mode!

@apodolsk
Copy link

apodolsk commented Aug 22, 2024

Edit: well, no. The below does not work. I can see a didChangeConfiguration message getting logged, and its param JSON is identical to what I see with a known-working eglot-workspace-configuration, but rust-analyzer is not actually creating a subdirectory as it does with the eglot variant. I don't know enough about lsp-mode or the protocol to guess why, atm.

Based on #167, it seems that lsp-mode does support passing/overriding LSP config options generically after initialization, via didChangeConfiguration LSP protocol messages. Here's my init.el snippet to set that up, including setting targetDir:

  (add-hook 'lsp-after-initialize-hook
            (lambda ()
              (lsp--set-configuration
               '(:rust-analyzer (:check (:ignore ["dead_code"
                                                  "unused_variables"
                                                  "unused_imports"])
                                        :cargo (:targetDir t
                                                    :features "all"))))))

I can see/debug the resulting didChangeConfiguration message via lsp-workspace-show-log.

As someone with 0 elisp knowledge, I found discussion of the similar eglot option to be useful for understanding the format of this thing: joaotavora/eglot#363.

It's definitely nice to have prepacked per-LSP-server customize vars for common options, but I do also wish that we had this
generic fallback as a first class documented and customizable setting.

@apodolsk
Copy link

apodolsk commented Sep 1, 2024

I looked at this a bit more, though unfortunately the result is that I'm convinced that there's no way to set "override" options for rust-analyzer without changing lsp-mode sources.

The issue with lsp--set-configuration is that apparently the workspace/didChangeConfiguration protocol (where the LSP client notifies the server of config value changes) is at least "semi" deprecated in favor of workspace/configuration messages (where the server instead queries the client for config values). Rust analyzer still responds to didChangeConfiguration, but the response is apparently to ignore the config value payload and simply trigger a workspace/configuration message in reply to re-query the same values: https://github.com/rust-lang/rust-analyzer/blob/64c538f9fb3d490dd0c987df494d802977a5b9f0/crates/rust-analyzer/src/handlers/notification.rs#L201. I can again see in logs that both eglot and lsp-mode send the same didChangeConfiguration message, but only eglot actually responds to the resulting workspace/configuration request. lsp-mode leaves that message on read.

According to #3686, there's an alternate mechanism to generically set options, via lsp-register-custom-settings. However, I couldn't get it to work, and I think that there's just a bug in the lsp-mode rust-analyzer integration which makes this method impossible. Namely, the issue is that, while the rls integration queries the "custom settings" via (lsp-configuration-section "rust") when setting up the language server (

:initialized-fn (lambda (workspace)
), the rust-analyzer integration skips that and just produces a config object in a more hardcoded way - it looks at pre-registered custom variables, but doesn't seem to integrate at all with the lsp-register-custom-settings system (
(defun lsp-rust-analyzer--make-init-options ()
).

Since it seems like post-startup configuration via workspace/configuration is basically unimplemented, and startup-time configuration respects only a hardcoded set of options, I don't think there's a way to provide "extra" options to rust analyzer. Though the latter seems like it could be a straightforward bugfix (ideally for someone who actually knows elisp...).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants