zbelial / lspce

LSP Client for Emacs implemented as a module using rust.
GNU General Public License v3.0
154 stars 11 forks source link

Clangd log in code buffer (Reason: when using Emacs + lspce in terminal, lsp servers' stderr data go to code buffer) #30

Closed alkurbatov closed 4 months ago

alkurbatov commented 4 months ago

Hi! I am trying to replace my eglot setup with lspce and so far it works quite well with Golang. However in C++ with clangd my code buffer is constantly flooded with message from clangd (see screenshot). While the messages itself are relevant, it is almost impossible to work with the code.

Снимок экрана 2024-04-12 в 10 29 15

I use OS X, lspce is the latest available, build with release. Typically I use this config for clangd but the issue could be reproduced with pure clangd without any tweaks:

 (add-to-list 'lspce-server-programs
               '("c++"
                 "clangd"
                 "-j=4"
                 "--log=error"
                 "--clang-tidy"
                 "--all-scopes-completion"
                 "--completion-style=detailed"
                 "--background-index"
                 "--pch-storage=memory"
                 "--header-insertion=never"
                 "--header-insertion-decorators=0"))
zbelial commented 4 months ago

Thanks for reporting this issue. Does it happen in all your c++ projects? Do you use flymake? If so, will this problem disappear if you disable flymake? I don't have macOS, but I tested on my Windows pc with a small c project, I couldn't reproduce this issue. I have no idea why this happened ATM.

PS. you should put all clangd's params in a single string, like the following: (add-to-list 'lspce-server-programs '("c++" "clangd" "-j=4 --log=error --clang-tidy --all-scopes-completion --completion-style=detailed --background-index --pch-storage=memory --header-insertion=never --header-insertion-decorators=0"))

alkurbatov commented 4 months ago

Does it happen in all your c++ projects?

I tested on three projects, in all cases that weird logs displayed in the buffer. The logs contain either errors regarding wrong clang-format config, or messages about background indexing and hover.

Do you use flymake? If so, will this problem disappear if you disable flymake?

I use flymake with https://github.com/mohkale/flymake-collection. Unfortunately disabling of flymake-mode doesn't help, but disabliling of lspce-mode stops the log spam.

I don't have macOS, but I tested on my Windows pc with a small c project, I couldn't reproduce this issue. I have no idea why this happened ATM.

I think macOS clangd is a bit different from e.g. Linux version (at least on my Linux setup it provides different diagnistics with eglot).

PS. you should put all clangd's params in a single string, like the following:

Ah, I see. Thank you!

alkurbatov commented 4 months ago

I think I see why it happens.

The following config doesn't produce the spam:

(setq lspce-server-programs
      `(("C"
         "clangd"
         "-j=4 --log=error --clang-tidy --all-scopes-completion --completion-style=detailed --background-index --pch-storage=memory --header-insertion=never --header-insertion-decorators=0")
        ("go" "gopls" "")))

But (add-to-list 'lspce-server-programs does. And it seems that lspce prefers "C" for C++ modes.

After some experiments I got smaller reproduction:

(setq lspce-server-programs
      `(("C" "clangd" "")))

So I see two issues:

alkurbatov commented 4 months ago

clangd without any args on macOS looks quite verbose and overflows me with messages. Might be result of --log=info set by default.

Ah, no, in fact lspce still throws errors into the buffer if clangd reports them. So this is somehow related to communication with clangd.

alkurbatov commented 4 months ago

Ah, and it seems that the problem appears only when I work in terminal (i.e. use emacs -nw).

zbelial commented 4 months ago

Thanks for digging into the problem. lspce uses lspce--lsp-type-default to determine a lsp-type (aka language-id), for c/c++, it returns "C", and then it uses this "C" to look up in lspce-server-programs to get what lsp server to use.

Ah, no, in fact lspce still throws errors into the buffer if clangd reports them. So this is somehow related to communication with clangd.

Do you enable lspce's log? I use the following to write trace logs to a file. If you enable log, could you provide it?

(lspce-set-log-file (format "/tmp/lspce/lspce_%d.log" (emacs-pid)))
(lspce-set-log-level-trace)

Ah, and it seems that the problem appears only when I work in terminal (i.e. use emacs -nw).

Lspce should only insert something into a buffer when lsp server returns textEdit(s), so I really confused. I'll test using lspce in terminal when I go back home. I've never tested/used Emacs+lspce in terminal.

alkurbatov commented 4 months ago

Here is the log, however I don't see reported errors in it (see screenshot). lspce_56466.log

Снимок экрана 2024-04-12 в 12 42 22
alkurbatov commented 4 months ago

Could it be that clangd is started in the same shell as Emacs? In this case clangd's stdout could mess with the emacs.

zbelial commented 4 months ago

Could it be that clangd is started in the same shell as Emacs? In this case clangd's stdout could mess with the emacs.

It could be! Lspce does not deal with lsp servers' stderr. I think I'll work on fixing this stderr issue then.

alkurbatov commented 4 months ago

Can confirm that this is stdout/stderr issue, as I got the same problem with pylsp when emacs is working in terminal.

zbelial commented 4 months ago

Huge thanks for your efforts to figure out the cause. I could reproduce the problem on Linux too. I just pushed a quick fix branch stderr where lsp servers' stderr is redirected to null device. It seems this fixed errors being thrown to buffer. Could you test it? Thanks.

zbelial commented 4 months ago

Implementing writing stderr to log file needs more time, so I pushed this temporary workaround.

alkurbatov commented 4 months ago

Huge thanks for your efforts to figure out the cause.

You're welcome.

I just pushed a quick fix branch stderr where lsp servers' stderr is redirected to null device. It seems this fixed errors being thrown to buffer. Could you test it? Thanks.

Checked with the stderr branch, it works well now. Thank you for swift fix!

zbelial commented 4 months ago

Checked with the stderr branch, it works well now.

Great! Then I'll merge stderr branch to master, and continue to improve it. Thanks again.

I think before I finish all stderr work, we can keep this issue open. Other people may encounter this issue as well.

zbelial commented 4 months ago

Hi @alkurbatov , I implemented writing stderr to the log file in branch stderr. But I've not tested it throughly. You can try it if you want to be aware of stderr data. Thanks.

alkurbatov commented 4 months ago

hi @zbelial I applied the changes but don't see any records regarding stderr in the log file. However, the file contains lspce tracing logs although I didn't change log level.

zbelial commented 4 months ago

I think I should test it more. Anyway, lines containing "[stderr]" are stderr message from lsp servers.

However, the file contains lspce tracing logs although I didn't change log level. It's wired. I didn't touch any code about logging. What tracing logs did you mean? Could you paste some of them here?

Maybe I can add a new module function to return the current log level to help debug.

alkurbatov commented 4 months ago

It's wired. I didn't touch any code about logging. What tracing logs did you mean? Could you paste some of them here?

I mean the logs similar to previous investigation. The log contains data regarding exchange with LSP server.
I think it could be enabled because I executed lspce-set-log-file.

Attached the log. lspce_20943.log

zbelial commented 4 months ago

Thanks, I'll try to figure out the problem.

zbelial commented 4 months ago

I just push a little new thing to stderr branch, now lspce can show current log level in the mode line.

alkurbatov commented 4 months ago

I use very customezed nano-modeline which doesn't show such info by default. But according to the value of lspce--log-level-text my default log level is INFO.