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

[clangd] Auto complete feature is not so accurate for C/C++ struct type #2521

Open
oneWayOut opened this issue Sep 24, 2024 · 5 comments
Open

Comments

@oneWayOut
Copy link

Description

  1. There are some extra unwanted completions (which are snippets) for a struct variable as below:
    bug1

  2. Dot operator after a structure pointer would not transform to arrow (->) operator automatically as in VS Code, and the completions are all unwanted snippets too.
    bug2

Expected behavior

  1. No snippets show up if typing dot operator after a structure variable;
  2. Dot operator after a structure pointer can be transformed to arrow (->) operator automatically.

Environment

  • OS: [Windows 7]
  • Sublime Text version: [4180]
  • LSP version: [4070-2.2.0]
  • Language servers used: [clangd]
  • The code in this example is as below:
typedef struct {
	int    a;
	short  b;
	char   c;
}TEST_STRUCT;

int main()
{
	TEST_STRUCT   test1;
	TEST_STRUCT * pTest = &test1;
	test1.
	//pTest.
	return 0;
}
@jwortmann
Copy link
Member

  • No snippets show up if typing dot operator after a structure variable;

It looks like these snippets come from Sublime's builtin C++ package: https://github.com/sublimehq/Packages/tree/master/C%2B%2B/Snippets

There are a few different options to disable them:

  1. LSP setting

    LSP/LSP.sublime-settings

    Lines 150 to 151 in 9b6ecb6

    // Disable Sublime Text's snippet completions.
    "inhibit_snippet_completions": false,

  2. ST setting "ignored_snippets"

Note that LSP does also obey the following settings which would apply for snippets provided by a language server:

  1. ST setting "auto_complete_include_snippets"

  2. ST setting "auto_complete_include_snippets_when_typing"


  • Dot operator after a structure pointer can be transformed to arrow (->) operator automatically.

This should be possible if the CompletionItem provides a textEdit. You could check the payload from the LSP log panel to see if this is the case or not. In general the completions should work the same as in VSCode. But again, the "s" snippet completions from your second screenshot are most likely from Sublime Text built-in, so it obviously wouldn't work for those.

@oneWayOut
Copy link
Author

oneWayOut commented Sep 25, 2024

Thanks for your prompt reply.

  1. Setting "inhibit_snippet_completions" to true works for the first question.
  2. I still don't know how to fix the operator problem following your instruction. In the LSP log panel, I found that CompletionItem didn't provides a textEdit when a dot is after the struct pointer. It does provide a textEdit when an arrow operator is after the struct pointer. Could you please give more tips? @jwortmann

@predragnikolic
Copy link
Member

Dot operator after a structure pointer can be transformed to arrow (->) operator automatically.

Where do you get this expectation from? Do other editors(that implement the LSP spec) do that?

The editor will insert/edit text based on what the language server tells it to,
if the language server sends a text edit in which a -> replaces a dot then the editor will do that.
This means that the language server doesn't do what you expect it to do,
and we can know that if you see the LSP Logs (from the command palette type LSP: Log Panel) and copy/paste the response for the textDocument/completion request. That will answer your second expectation.

@oneWayOut
Copy link
Author

Where do you get this expectation from? Do other editors(that implement the LSP spec) do that?

Yes, I used VSCode with clangd extension, the dot to arrow feature is implemented already, which is quite convenient. There is also a link "[clangd][vscode] Enable dot-to-arrow fixes in clangd completion." about this feature.

This means that the language server doesn't do what you expect it to do,

I copy and paste the Lsp logs after I type dot after the struct pointer as below. though I don't fully understand it.

:: [23:34:10.705] <<< clangd (11) (duration: 10ms): []
clangd: I[23:34:20.887] <-- textDocument/didChange
:: [23:34:20.886]  -> clangd textDocument/didChange: {'textDocument': {'uri': 'file:///E:/MyTest/Test.cpp', 'version': 23}, 'contentChanges': [{'range': {'start': {'line': 12, 'character': 6}, 'end': {'line': 12, 'character': 6}}, 'rangeLength': 0, 'text': '.'}]}
clangd: I[23:34:20.887] <-- textDocument/completion(12)
clangd: I[23:34:20.905] <-- textDocument/documentLink(13)
clangd: I[23:34:20.905] Failed to find compilation database for E:\MyTest\Test.cpp
clangd: I[23:34:20.906] ASTWorker building file E:\MyTest\Test.cpp version 23 with command clangd fallback
clangd: [E:\MyTest]
clangd: "C:\\Program Files\\LLVM\\bin\\clang" "-resource-dir=C:\\Program Files\\LLVM\\lib\\clang\\18" -- "E:\\MyTest\\Test.cpp"
:: [23:34:20.887] --> clangd textDocument/completion (12): {'textDocument': {'uri': 'file:///E:/MyTest/Test.cpp'}, 'position': {'line': 12, 'character': 7}}
:: [23:34:20.905] --> clangd textDocument/documentLink (13): {'textDocument': {'uri': 'file:///E:/MyTest/Test.cpp'}}
clangd: I[23:34:20.956] Code complete: 0 results from Sema, 0 from Index, 0 matched, 0 from identifiers, 0 returned.
clangd: I[23:34:20.956] --> reply:textDocument/completion(12) 69 ms
clangd: I[23:34:20.982] --> textDocument/publishDiagnostics
clangd: I[23:34:20.982] --> reply:textDocument/documentLink(13) 76 ms
:: [23:34:20.974] <<< clangd (12) (duration: 86ms): {'isIncomplete': False, 'items': []}
clangd: I[23:34:21.010] <-- textDocument/codeAction(14)
clangd: I[23:34:21.010] --> reply:textDocument/codeAction(14) 0 ms
:: [23:34:20.996] <-  clangd textDocument/publishDiagnostics: {'diagnostics': [{'code': 'expected_unqualified_id', 'message': 'Expected unqualified-id', 'range': {'end': {'character': 7, 'line': 13}, 'start': {'character': 1, 'line': 13}}, 'relatedInformation': [], 'severity': 1, 'source': 'clang'}], 'uri': 'file:///E:/MyTest/Test.cpp', 'version': 23}
:: [23:34:21.009] --> clangd textDocument/codeAction (14): {'textDocument': {'uri': 'file:///E:/MyTest/Test.cpp'}, 'range': {'start': {'line': 12, 'character': 7}, 'end': {'line': 12, 'character': 7}}, 'context': {'diagnostics': [], 'triggerKind': 2}}
:: [23:34:21.012] <<< clangd (13) (duration: 106ms): []
:: [23:34:21.028] <<< clangd (14) (duration: 18ms): []
:: [23:34:21.135] --> clangd textDocument/documentHighlight (15): {'textDocument': {'uri': 'file:///E:/MyTest/Test.cpp'}, 'position': {'line': 12, 'character': 7}}
clangd: I[23:34:21.135] <-- textDocument/documentHighlight(15)
clangd: I[23:34:21.135] --> reply:textDocument/documentHighlight(15) 0 ms
:: [23:34:21.135] <<< clangd (15) (duration: 0ms): []

I think the problem is that clangd didn't give the right code complete items as it did in VSCode like below. After I select one of the complete items, the dot will convert to arrow automatically in VSCode.
VSCodeEg

@rchl
Copy link
Member

rchl commented Nov 2, 2024

Whether those completions are provided depends on client announcing support for clangd's custom textDocument.completion.editsNearCursor capability.

Per previously referenced change, for VSCode they combine it with some custom completions handler to workaround VSCode filtering issue but for us I think it would work just fine without anything like that. The only problem is that currently we don't support extending arbitrary capabilities but only adding ones in capabilities.experimental object. I've raised clangd/vscode-clangd#714 to nudge them into following the spec here which would make it easy for us to support this feature.

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

No branches or pull requests

4 participants