Closed ArkadiuszMichalski closed 2 months ago
Hi @ArkadiuszMichalski, thanks for the interest in this plugin. I use exactly the same version as you do
D:\>D:\ProgramData\Compiler\mingw64\bin\clangd.exe --version
(built by Brecht Sanders, r3) clangd version 18.1.8
Features: windows
Platform: x86_64-w64-windows-gnu; target=x86_64-w64-mingw32
My config is
mode = "io"
executable = 'D:\ProgramData\Compiler\mingw64\bin\clangd.exe'
args = '--offset-encoding=utf-8'
auto_start_server = true
Are you concerned about the "Language server c++ shutdown unexpectedly" in general, or did it not work for you at all? If the messages you posted are the only ones, then I'm confused as I don't see any initialization request at all.
Nothing works, it just disconnects immediately after connecting. All logs:
[1722943162747759] Some(
Config {
general: General {
diag_indicator_id: 12,
error_color: 7695584,
warning_color: 6611199,
incoming_msg_color: 8111001,
outgoing_msg_color: 16755801,
selected_text_color: 7623207,
enable_logging: false,
calltip_foreground_color: None,
calltip_background_color: None,
highlight_indicator_id: 13,
highlight_indicator_color: 6611199,
complete_always: Some(
false,
),
clear_reference_view_always: Some(
false,
),
foreground_color: 0,
background_color: 16777215,
reference_color: 15707983,
},
lspservers: {
"c++": ServerConfig {
mode: "io",
executable: "E:\\Download\\_chrome\\clang\\mingw64\\bin\\clangd.exe",
args: Some(
"--offset-encoding=utf-8 --pretty",
),
port: None,
host: None,
auto_start_server: true,
complete_always: Some(
false,
),
clear_reference_view_always: None,
explicit_shutdown: false,
},
"c": ServerConfig {
mode: "io",
executable: "E:\\Download\\_chrome\\clang\\mingw64\\bin\\clangd.exe",
args: Some(
"--offset-encoding=utf-8 --pretty",
),
port: None,
host: None,
auto_start_server: true,
complete_always: Some(
false,
),
clear_reference_view_always: None,
explicit_shutdown: false,
},
},
},
)
[1722943162749327] Logging disabled
[1722943162749804] Allocated indicator IDs start from 9
[1722943189471921] start_client - no configured server found for normal text
[1722943190530899] Enumerating workspaces
[1722943190532162] E:\Download\_chrome\npp.8.6.9.portable.x64\_test
[1722943190532971] found the following roots ["E:\\Download\\_chrome\\npp.8.6.9.portable.x64\\_test"]
[1722943190534063] start_client - "E:\\Download\\_chrome\\clang\\mingw64\\bin\\clangd.exe"
[1722943190539402] c++ language server started
[1722943190590900] stop_server - stopping "c++"
[1722943190592393] Language server c++ shutdown unexpectedly.
When I run clangd.exe
directly from the console it doesn't close.
clangd is a language server that provides IDE-like features to editors.
It should be used via an editor plugin rather than invoked directly. For more information, see:
https://clangd.llvm.org/
https://microsoft.github.io/language-server-protocol/
clangd accepts flags on the commandline, and in the CLANGD_FLAGS environment variable.
I[13:35:39.512] (built by Brecht Sanders, r3) clangd version 18.1.8
I[13:35:39.513] Features: windows
I[13:35:39.513] PID: 15056
I[13:35:39.514] Working directory: E:/Download/_chrome/clang/mingw64/bin
I[13:35:39.514] argv[0]: clangd.exe
I[13:35:39.518] Starting LSP over stdin/stdout
No additional settings for clangd
needed? Are there any entries needed in the PATH
variable for it to work properly, or is the standalone cland.exe
file sufficient and nothing needs to be added to the PATH
? I tried to simply add the entire E:\Download\_chrome\clang\mingw64\bin
but it didn't help, it still disconnects.
I'm trying this with simple C++ code in a single file but without success.
#include <iostream>
void test();
int num = 5;
int main() {
int num2 = num;
test();
}
void test(){
std::cout << "Hello World!";
}
When I switch between C/CPP files without FAW, it also tries to do something the first time, but then after subsequent switches it informs that ... is not of interest
.
[1722946046196956] start_client - no configured server found for normal text
[1722946048893952] Enumerating workspaces
[1722946048895485] found the following roots []
[1722946048896673] start_client - "E:\\Download\\_chrome\\clang\\mingw64\\bin\\clangd.exe"
[1722946048902557] c++ language server started
[1722946048949489] stop_server - stopping "c++"
[1722946048950508] Language server c++ shutdown unexpectedly.
[1722946053139193] Enumerating workspaces
[1722946053140245] found the following roots []
[1722946053141015] start_client - "E:\\Download\\_chrome\\clang\\mingw64\\bin\\clangd.exe"
[1722946053143793] c language server started
[1722946053186891] stop_server - stopping "c"
[1722946053188094] Language server c shutdown unexpectedly.
[1722946055508468] Enumerating workspaces
[1722946055509619] found the following roots []
[1722946055510386] [1753200264288] E:\Download\_chrome\npp.8.6.9.portable.x64\_test\test.cpp is not of interest
[1722946056921200] Enumerating workspaces
[1722946056922459] found the following roots []
[1722946056923353] [1753200263808] E:\Download\_chrome\npp.8.6.9.portable.x64\_test\test.c is not of interest
Can you give it a try with enable_logging = true
?
Then it should report the lsp messages in the log as well.
2024-08-06 14:21:45.367832 [INFO][ThreadId(1)] - logging initialized
2024-08-06 14:22:04.749031 [INFO][ThreadId(1)] - start_client c++
2024-08-06 14:22:04.749112 [INFO][ThreadId(1)] - process arguments provided are: "--offset-encoding=utf-8 --pretty" !!
2024-08-06 14:22:04.752532 [INFO][ThreadId(1)] - start_server c++ started.
2024-08-06 14:22:04.752897 [INFO][ThreadId(1)] - {"id":0,"jsonrpc":"2.0","method":"initialize","params":{"capabilities":{"general":{"positionEncodings":["utf-8"]},"textDocument":{"codeAction":{"codeActionLiteralSupport":{"codeActionKind":{"valueSet":["quickfix"]}}},"completion":{"completionItem":{"commitCharactersSupport":false,"deprecatedSupport":false,"documentationFormat":["plaintext"],"insertReplaceSupport":false,"preselectSupport":false,"snippetSupport":false},"completionItemKind":{},"dynamicRegistration":false,"insertTextMode":1},"formatting":{"dynamicRegistration":false},"hover":{"contentFormat":["plaintext","markdown"],"dynamicRegistration":false},"publishDiagnostics":{"codeDescriptionSupport":false,"dataSupport":false,"relatedInformation":true,"versionSupport":false},"rangeFormatting":{"dynamicRegistration":false},"signatureHelp":{"contextSupport":false,"dynamicRegistration":false,"signatureInformation":{"activeParameterSupport":false,"documentationFormat":["plaintext"],"parameterInformation":{"labelOffsetSupport":false}}},"synchronization":{"didSave":true,"dynamicRegistration":false,"willSave":true,"willSaveWaitUntil":false}},"window":{"showDocument":{"support":true},"showMessage":{"messageActionItem":{"additionalPropertiesSupport":true}},"workDoneProgress":true},"workspace":{"executeCommand":{"dynamicRegistration":true},"workspaceFolders":true}},"clientInfo":{"name":"","version":"-alpha"},"processId":1720,"rootUri":"file:///E:/Download/_chrome/npp.8.6.9.portable.x64/_test","workspaceFolders":[]}}
2024-08-06 14:22:04.753179 [INFO][ThreadId(4)] - <<< {"id":0,"jsonrpc":"2.0","method":"initialize","params":{"capabilities":{"general":{"positionEncodings":["utf-8"]},"textDocument":{"codeAction":{"codeActionLiteralSupport":{"codeActionKind":{"valueSet":["quickfix"]}}},"completion":{"completionItem":{"commitCharactersSupport":false,"deprecatedSupport":false,"documentationFormat":["plaintext"],"insertReplaceSupport":false,"preselectSupport":false,"snippetSupport":false},"completionItemKind":{},"dynamicRegistration":false,"insertTextMode":1},"formatting":{"dynamicRegistration":false},"hover":{"contentFormat":["plaintext","markdown"],"dynamicRegistration":false},"publishDiagnostics":{"codeDescriptionSupport":false,"dataSupport":false,"relatedInformation":true,"versionSupport":false},"rangeFormatting":{"dynamicRegistration":false},"signatureHelp":{"contextSupport":false,"dynamicRegistration":false,"signatureInformation":{"activeParameterSupport":false,"documentationFormat":["plaintext"],"parameterInformation":{"labelOffsetSupport":false}}},"synchronization":{"didSave":true,"dynamicRegistration":false,"willSave":true,"willSaveWaitUntil":false}},"window":{"showDocument":{"support":true},"showMessage":{"messageActionItem":{"additionalPropertiesSupport":true}},"workDoneProgress":true},"workspace":{"executeCommand":{"dynamicRegistration":true},"workspaceFolders":true}},"clientInfo":{"name":"","version":"-alpha"},"processId":1720,"rootUri":"file:///E:/Download/_chrome/npp.8.6.9.portable.x64/_test","workspaceFolders":[]}}
2024-08-06 14:22:04.754805 [INFO][ThreadId(1)] - Storing on_buffer_activated request for E:\Download\_chrome\npp.8.6.9.portable.x64\_test\test.cpp [2086357289264]
2024-08-06 14:22:04.794711 [ERROR][ThreadId(1)] - I[14:22:04.794] (built by Brecht Sanders, r3) clangd version 18.1.8
2024-08-06 14:22:04.794841 [ERROR][ThreadId(2)] - -->> stderr returned size is 0 <<--
2024-08-06 14:22:04.794897 [INFO][ThreadId(1)] - -->> exit stdout/stderr loop received
2024-08-06 14:22:04.794920 [INFO][ThreadId(1)] - stop_language_client:c++
2024-08-06 14:22:04.794959 [INFO][ThreadId(4)] - <<< {"jsonrpc":"2.0","method":"exit"}
2024-08-06 14:22:04.798535 [ERROR][ThreadId(3)] - -->> stdout returned size is 0 <<--
2024-08-06 14:22:04.798677 [INFO][ThreadId(1)] - -->> exit stdout/stderr loop received
clangd does not respond with its capabilities ...
I assume there is a test.h
next to test.cpp? Are these the only two files in the _test dir?
Regarding other parameters or path settings. Of course, clangd must be able to find all associated libraries and includes and needs a compilation database file to compile correctly. But for simple programs where no additional libraries and includes are used, it is normally able to compile the programs without a compile_commands.json file.
I assume there is a test.h next to test.cpp? Are these the only two files in the _test dir?
No I don't use .h
files here because for this simple example I don't need it.
Regarding other parameters or path settings. Of course, clangd must be able to find all associated libraries and includes and needs a compilation database file to compile correctly. But for simple programs where no additional libraries and includes are used, it is normally able to compile the programs.
But for this simple example do we need to set something in PATH
? Currently I only downloaded WinLibs and that's it, I only set in the plugin config file:
executable = 'E:\Download_chrome\clang\mingw64\bin\clangd.exe'
To be sure, I also added the entire folder 'E:\Download_chrome\clang\mingw64\bin' to the PATH
, but it didn't help.
No additional settings are required for such a simple program. I also only have the mingw bin directory in the path. Is E: a hard disk or a USB drive?
E: is hard standard disk.
Ok, thanks - I'll try a similar setup and report back on my findings.
Ok, I can replicate it
I will check it out and report back as soon as I know what is causing the problem and how to fix it.
Great because I was starting to think there was something wrong with my operating system.
It looks as if this problem has already been fixed in the next, 0.0.27, version.
I will make the new version 0.0.27 available by tomorrow at the latest.
@Ekopalypse Can you paste your current binary here, I would like to play around with this plugin today.
@ArkadiuszMichalski Here it would be, but is probably not the final 0.0.27 version.
No problem, finally something works. Any advice on how to make diagnostics not work on every keystroke? It's hard to write anything this way because the response is very slow.
Edit: Or it's a problem with autocomplete. it works very slowly, do you have the same problem?
No, normally it's fine. I don't have much experience with the clangd server, mostly I use the Python and Rust language servers and it works fine there. What does have a significant impact on performance is when logging is enabled and when the console window is open. Apart from that...?
@Ekopalypse Oh you are right, the problem was logging, I forgot that I turned it on, after turning it off it works OK.
@Ekopalypse Could you point me how autocomplete actually works? I have enabled in on NPP and I see this behavior:
Often when I test it the whole Lsp crashes and I have to start it again (because nothing works). I haven't determined exactly why this is happening yet, if so I'll give STR.
Maybe it would be worth just giving an Autocomplete command that would trigger it from Lsp? If someone would prefer to do it manually, they would have that option.
Edit: lsp not crach (I see clangd process), but the plugin commands don't work.
Edit: I don't have any easy STR, but this works:
i
).Delete
key.At this point the whole thing stops working (although the clangd
process is still open). Repair requires stopping lsp and run it again.
Next problem, code for test:
#include <iostream>
void test();
int num = 5;
int main() {
}
void test(){
std::cout << "Hello World!";
}
Write inside main
the test();
without saving and run Find references
, we got:
Other command like Goto definition/declaration
works correct.
@Ekopalypse Could you point me how autocomplete actually works?
The completion logic looks like this:
SCN_MODIFIED: if there is a single character change and no completion dialog, triggered by the lsp client is visible, send a request for completion to the LspServer
Completion response: if the lsp client has not opened a completion dialog, open one, i.e. if Npp has opened one, it will be replaced.
I have started to filter the completion list according to the text entered, but unfortunately this does not always work correctly at the moment.
Often when I test it the whole Lsp crashes and I have to start it again (because nothing works). I haven't determined exactly why this is happening yet, if so I'll give STR. Edit: lsp not crach (I see clangd process), but the plugin commands don't work. Edit: I don't have any easy STR, but this works:
Thx, I'll give it a try and see if I understand what's going on. Python and Rust server seem to be working correctly here, but it could still be a problem on the client side.
Maybe it would be worth just giving an Autocomplete command that would trigger it from Lsp? If someone would prefer to do it manually, they would have that option.
I don't understand what you mean?
Next problem, code for test:
Oh, damn, a crash, sorry ... this is serious - I'll look into it soon.
Update:
The problem is that as soon as I get the references from the lsp server, which already knows the changed content, I read the actual content of the file, which has not been updated
if let Ok(file) = File::open(file_path) {
let reader = io::BufReader::new(file);
if let Some(Ok(line)) = reader.lines().nth(location.start.line as usize) {
let pre_fix = &line[..location.start.character as usize];
let found_reference = &line[location.start.character as usize..location.end.character as usize];
let suffix = &line[location.end.character as usize..];
self.append_styled_text(format!(" - {}", pre_fix.trim_start()), DEFAULT_STYLE);
self.append_styled_text(found_reference.to_string(), REFERENCE_STYLE);
self.append_styled_text(suffix.to_string(), DEFAULT_STYLE);
}
}
and that means that
let found_reference = &line[location.start.character as usize..location.end.character as usize];
panics.
At the moment I can only see a quick solution by checking whether the length of line
>= location.end.character
.
@ArkadiuszMichalski This updated version should have fixed the problem.
NppLspClient_v.0.0.27_pre2.zip
When calling references with unsaved buffers, the output should now indicate that there is a problem.
@Ekopalypse
SCN_MODIFIED: if there is a single character change and no completion dialog, triggered by the lsp client is visible, send a request for completion to the LspServer Completion response: if the lsp client has not opened a completion dialog, open one, i.e. if Npp has opened one, it will be replaced. I have started to filter the completion list according to the text entered, but unfortunately this does not always work correctly at the moment.
Something is not working properly here, or I am understanding it wrong. Str:
double
<< nothing appears after pressing d
then o
then u
etc.
2.2. when we remove all this double
then dialog is appear and now double
is selected correctly. Well, this dialog never appears when something is typed before the current cursor.
Only now, if the dialogue is already visible, we can choose something:
Maybe it would be worth just giving an Autocomplete command that would trigger it from Lsp? If someone would prefer to do it manually, they would have that option.
I don't understand what you mean?
I mean give the command to manually send a request for completion to the LspServer, for example I wrote dou
and run this command manually then I get autocompletion for dou
, so show this list only when I ping for it. A separate command is useful because we can assign any shortcut to it. So basically it's about adding the complete option instead of autocomplete. Something similar to what we have in Notepad++, if we turn off autocompletion in the options we can still manually invoke this popup.
Btw, do you know if it's possible to expand these suggestions from clangd
somehow, because it doesn't even display my global functions/variables. Basically I only see the basic words of C/C++.
When calling references with unsaved buffers, the output should now indicate that there is a problem.
Thix, it's better than crash:)
Something is not working properly here,
That is strange, indeed. I'll check this.
I mean give the command to manually send a request for completion to the LspServer
Ok, I guess yes, a global and per language server configuration setting to do auto completions manually Something like
[general]
manual_completion = true # default setting is false
[lspservers.rust]
manual_completion = false
would mean that the client, except for rust, does not automatically send the completion request. And
[general]
manual_completion = false # default
[lspservers. "c++"]
manual_completion = true
means that the client sends the request for completion automatically, except for c++, where the user must call the command manually.
Btw, do you know if it's possible to expand these suggestions from
No, maybe something additional needs to be set for clangd. I'll have a look at what vscode is doing here. Maybe this is also related to the other problem, the initial autocomplete issue.
But now that I have disabled npp's autocomplete feature, I see that I have an issue with rust as well. I will check it out.
it's better than crash:)
For sure :-D I have to come up with a fuzzy test strategy to avoid such problems as much as possible.
@Ekopalypse I think the opposite setting would make more sense.
[general]
auto_completion = true # default
[lspservers. "c++"]
auto_completion = false
Because if we have a separate manual command, manual completion will be always available, regardless of the auto_completion
setting. If the autocompletion popup appears and we close it, we can then bring it up again with this manual command without writing to editor.
Question is whether auto_completion
should be true
or false
by default, but that's a detail.
No, maybe something additional needs to be set for clangd. I'll have a look at what vscode is doing here. Maybe this is also related to the other problem, the initial autocomplete issue.
VSCode is based on Monaco editor, and here I see that the hinting for C++ works fine. It's probably something on the cland
side that's the problem, because in the case of Lsp JavaScript the completion for my global functions/variables work.
Strange, for above simple case the suggestion works correctly, I don't have to delete anything, after each key press a dialogue is displayed. But when we enter to the scope the problem appears again.
The hint only works when we delete everything (here myv
).
Well, I'll wait with this, maybe you'll be able to determine what the problem is.
The server sends the completions, but the client somehow skips/ignores them.
Debugging session starts ...
@ArkadiuszMichalski
Remember when I said I wanted to filter the completion list? Well ... the current position is not always a valid word start position, who would have thought ;-)
Remember when I said I wanted to filter the completion list?
No, but I looked it up quickly.
The latest version finally works better, but I still wonder why something like this doesn't work:
root
file1.cpp
file2.cpp
If we have opened this two files (file1.cpp is active, file2.cpp was never active at this point, all was restored from session) then try finding definition/declaration/references from file1.cpp (when they exist in file.2cpp) not work. Only when we switch to file2.cpp
at least once it will start working. It's a bit embarrassing and easy to forget.
file1.cpp
#include <iostream>
int num = 5;
void test();
void test2();
int main() {
test();
test2();
std::cout << num;
}
void test(){
std::cout << "Hello World!";
}
file2.cpp
#include <iostream>
void test2(){
std::cout << "Hello World2!";
}
I have the same problem with LSP for JavaScript. Stop and Start server again allows us to easily reproduce this issue (without having to restart Notepad++).
Ultimately, this is a matter for the language server and what it expects. For example, a configured Cargo.toml file must exist for rust projects so that the rust-analyzer can function correctly. For clangd, I assume that it expects a compile_commands.json. E.g. with the following content
[
{
"directory": "D:/scripts/C_Scripts/tests/issue14",
"command": "clang++",
"arguments": [
"-LC:/Program Files (x86)/Windows Kits/10/Lib/10.0.22621.0/um/x64",
],
"file": "test.cpp"
},
{
"directory": "D:/scripts/C_Scripts/tests/issue14",
"command": "clang++",
"arguments": [],
"file": "test2.cpp"
}
]
As a Cpp developer, you certainly know better than me whether the content makes sense :-) . And for the TypeScript server it might be a tsconfig.json!?
The client can only help to a limited extent here. All it does is announce in the initialize request which directories are currently available. More on this in the TS issue.
OK, so some things needs to be specified in the configuration files of each server. For the simple example above, this works:
[
{
"directory": "E:/Download/_chrome/npp.8.6.9.portable.x64/_test",
"command": "clang++",
"file": "test.cpp"
},
{
"directory": "E:/Download/_chrome/npp.8.6.9.portable.x64/_test",
"command": "clang++",
"file": "test2.cpp"
}
]
And it searches for what it needs without activating all the files. We need to determine how to configure this server and do it ourselves.
OK, so some things needs to be specified in the configuration files of each server. We need to determine how to configure this server
Yes, but in most cases it is already "known" what needs to be done, because you have to "compile" it anyway, except for languages that use different build systems, like C/C++. A project could use a Visual Studio solution or project file, a make or cmake file ... but for newer languages like Rust, V, Go, Zig, Odin, Typescript, there is usually only one way ... or let's say one official way to do it. It would be nice to have a way to create/modify such "build system files" from Npp, but I don't see that this should be part of the NppLspClient.
It would be nice to have a way to create/modify such "build system files" from Npp, but I don't see that this should be part of the NppLspClient.
This is probably beyond the scope of the plugin because there can be many building systems.
fixed with v.0.0.28
@Ekopalypse I wanted to try this plugin for C++, I do everything according to the instructions and I get the message:
Can you indicate which exact version of
clangd
you are using and it works? I have this: