Manually use rust-analyzer

Is there a tutorial somewhere on how to manually use rust-analyzer ?

I am trying to figure out how difficult it is to write a tool on top of LSP/rust-analyzer. I would prefer to not have to reverse engineer existing protocols. Is there documentation somewhere on manually talking to rust-analyzer ?

Do you want the LSP specification?



1 Like

@metreo User Manual looks really useful, but how do you actually use it? I.e. what is the command you type to rust-analyzer over stdin and what is the stdout

rust-analyzer analysis-stats

$ rust-analyzer analysis-stats
expected positional argument
$ rust-analyzer  --version
rust-analyzer 14de9e5

rust-analyzer analysis-stats requires the path to the project as argument. For example rust-analyzer analysis-stats ..

@bjorn3 : rust-analyzer analysis-stats . works. thanks!

@metreo : what does this achieve? It is not clear to me how this brings us closer to be able to issue the LSP commands / queries described in the rust-analyzer manual

rust-analyzer --help

I am starting to question at this point whether you are engaging in good faith or if you are passively aggressively saying "RTFM"

The output of rust-analyzer --help is

$ rust-analyzer  --help

    rust-analyzer [FLAGS] [COMMAND] [COMMAND_OPTIONS]

    --version         Print version
    -h, --help        Print this help

    -v,  --verbose
    -vv, --spammy
    -q,  --quiet      Set verbosity

                      Dump a LSP config JSON schema
    --log-file <PATH> Log to the specified file instead of stderr
                      Flush log records to the file immediately

    --wait-dbg        Wait until a debugger is attached to.
                      The flag is valid for debug builds only

    RA_LOG            Set log filter in env_logger format
    RA_PROFILE        Enable hierarchical profiler
    RA_WAIT_DBG       If set acts like a --wait-dbg flag


not specified         Launch LSP server

parse <       Parse tree
    --no-dump         Suppress printing

symbols <     Parse input an print the list of symbols

highlight <   Highlight input as html
    --rainbow         Enable rainbow highlighting of identifiers

analysis-stats <PATH> Batch typecheck project and print summary statistics
    <PATH>            Directory with Cargo.toml
    --randomize       Randomize order in which crates, modules, and items are processed
    --parallel        Run type inference in parallel
    --memory-usage    Collect memory usage statistics
    -o, --only <PATH> Only analyze items matching this path
    --with-deps       Also analyze all dependencies
                      Load OUT_DIR values by running `cargo check` before analysis
    --with-proc-macro Use proc-macro-srv for proc-macro expanding

analysis-bench <PATH> Benchmark specific analysis operation
    <PATH>            Directory with Cargo.toml
    --highlight <PATH>
                      Compute syntax highlighting for this file
    --complete <PATH:LINE:COLUMN>
                      Compute completions at this location
    --goto-def <PATH:LINE:COLUMN>
                      Compute goto definition at this location
    --memory-usage    Collect memory usage statistics
                      Load OUT_DIR values by running `cargo check` before analysis
    --with-proc-macro Use proc-macro-srv for proc-macro expanding

diagnostics <PATH>
    <PATH>            Directory with Cargo.toml
                      Load OUT_DIR values by running `cargo check` before analysis
    --with-proc-macro Use proc-macro-srv for proc-macro expanding

ssr [RULE...]
    <RULE>            A structured search replace rule (`$$b) ==> bar($a, $b)`)

search [PATTERN..]
    <PATTERN>         A structured search replace pattern (`$$b)`)
    --debug <snippet> Prints debug information for any nodes with source exactly
                      equal to <snippet>

It is not obvious to me at all how these commands match up with the supported featuresin User Manual ; nor how to encode these into STDIN/STDOUT queries vs LSP.

The subcommands are for development and debugging, if you want to use the language server, just run rust-analyzer and start exchanging LSP messages via stdin/stdout. If you want to use it as a library, the API documentation is hosted here, but there's no convenient interface or more detailed instructions.

To issue LSP requests, simply run rust-analyzer and send the requests to its stdin.

Hyeonu linked to the LSP specification above, which documents the format of the RPC requests that you can send over stdio. For example, here's a minimal "initialize" request.

Content-Length: 154

  "jsonrpc": "2.0",
  "method": "initialize",
    "rootUri": null,
    "capabilities": {},
    "processId": null

Note that lines must be terminated by \r\n, so you probably can't just paste this into your terminal. Also, the Content-Length header is mandatory. Rather than writing to stdin directly, I imagine you'll want to write a small program to handle at least some of the encoding details.

rust-analyzer --help &> .0
rg lsp ./.0 -i -C1
22:not specified         Launch LSP server

is the output I was pointing to