manateelazycat / lsp-bridge

A blazingly fast LSP client for Emacs
GNU General Public License v3.0
1.42k stars 205 forks source link

Question: lsp-bridge-workspace-list-symbols can find the symbol, but lsp-bridge-find-def does not #893

Closed vincentjgoh closed 6 months ago

vincentjgoh commented 6 months ago

I have this class definition:

class USpreadCalculatorBase : public UObject

If I place the cursor on UObject and invoke lsp-bridge-find-def, I get the response that no definition was found.

However, if I invoke lsp-bridge-workspace-list-symbols I get lots of results: image

And indeed, the first entry takes me to exactly the class I'm looking for.

Is this an issue with clangd, and lsp-bridge is just telling me that clangd can't do what I want? Definitely lsp-bridge-find-def works with some things with no problem.

manateelazycat commented 6 months ago

You can temporarily turn on the log through the lsp-bridge-enable-log option. The log can be seen in the *lsp-bridge* buffer.

If after the lsp-bridge-find-def command is executed, clangd returns the defined log but lsp-bridge does not jump correctly, then it is a bug of lsp-bridge. You are welcome to submit the log and I will fix it.

If clangd does not return the defined location in the log, that is a problem with clangd, lsp-bridge just obeys the information returned by the lsp server to perform the operation

vincentjgoh commented 6 months ago

I already had the logging turned on, but I noticed that it had stopped giving me any output. I closed it and it eventually started again, giving me warnings that the index might be incomplete. Is there any way to force the index to be built to completion? I don't remember having this issue before.

Anyway, I suspect that the issue might be an incomplete index. When I switched from lsp-mode to lsp-bridge, I had to delete the cache because they're using different clangd installs, and the one that lsp-bridge picks up is an older revision. Though it's still confusing that finding the symbol works and jumping to the class by finding the definition doesn't. I'll update this thread once the index has finished building.

FWIW, this is what happens when I try to look up the definition for the class AActor, a common class in the Unreal Engine:

--- [20:05:40.971285] Send textDocument/definition request (15594) to 'clangd' for project 
I[20:05:40.972] --> reply:textDocument/definition(15594) 0 ms
{
   "id": 15594,
   "method": "textDocument/definition",
   "params": {
      "position": {
         "line": 32,
         "character": 61
      },
      "textDocument": {
         "uri": "file:///d%3A/p4v/Dev/Engine/Plugins/WeaponSystem/Source/SystemRuntime/Public/Actors/WeaponVisualActor.h"
      }
   },
   "message_type": "request",
   "jsonrpc": "2.0"
}

--- [20:05:40.971285] Recv textDocument/definition response (15594) from 'clangd' for project 
Eval in Emacs: (lsp-bridge-find-def-fallback '(:line 32 :character 61))
{
   "id": 15594,
   "jsonrpc": "2.0",
   "result": []
}

I get a tremendous amount of data back from lsp-bridge-workspace-list-symbols, though. I'll just include one of the entries, but there's about 1900 lines of JSON results in the log. The duplication is in the log, it's not a copy paste error. But what's being found in this case is a constructor, so I would guess that's why this is happening?

      {
         "containerName": "AActor",
         "kind": 9,
         "location": {
            "range": {
               "end": {
                  "character": 14,
                  "line": 109
               },
               "start": {
                  "character": 8,
                  "line": 109
               }
            },
            "uri": "file:///D:/p4v/Dev/Engine/Source/Runtime/Engine/Private/Actor.cpp"
         },
         "name": "AActor",
         "score": 0.5
      },
      {
         "containerName": "AActor",
         "kind": 9,
         "location": {
            "range": {
               "end": {
                  "character": 14,
                  "line": 104
               },
               "start": {
                  "character": 8,
                  "line": 104
               }
            },
            "uri": "file:///D:/p4v/Dev/Engine/Source/Runtime/Engine/Private/Actor.cpp"
         },
         "name": "AActor",
         "score": 0.5
      },
vincentjgoh commented 6 months ago

Actually, I'll ask that question while I'm here anyway: what's the easiest way to change the path that lsp-bridge uses when it starts the language server?

I have 2 versions of clangd installed on my machine. Unreal prefers v14, and so that's the system default. I have v17 installed because it's newer, and my emacs paths are set to start that up. For lsps like lsp-mode and eglot, this is fine, since they use whatever emacs finds (or I can set the path manually).

I don't actually know python, but I looked through it quickly and I THINK what's happening is it tries to merge emacs' exec-path to the system paths, but crucially, it adds the emacs paths AFTER the system paths, so it's always going to pick up the wrong LSP for me. You can let me know if I'm right or wrong here. :)

manateelazycat commented 6 months ago

The lsp server configuration of lsp-bridge is in the langserver directory. For example, clangd is lspbridge/langserver/clangd.json

clangd.json only writes the clangd name, it will find clangd from the system directory. If you want to customize the version of clangd, you can customize lsp-bridge-get-single-lang-server-by-project, according to project- path and filename return a customized json file path. The content of the json path can be the same as lspbridge/langserver/clangd.json, except that "clangd" in clangd.json is replaced with the clangd path you specify.