Index: clangd/ClangdUnit.cpp =================================================================== --- clangd/ClangdUnit.cpp +++ clangd/ClangdUnit.cpp @@ -389,6 +389,7 @@ assert(CCS && "Expected the CodeCompletionString to be non-null"); Items.push_back(ProcessCodeCompleteResult(Result, *CCS)); } + std::sort(Items.begin(), Items.end()); } GlobalCodeCompletionAllocator &getAllocator() override { return *Allocator; } Index: clangd/Protocol.h =================================================================== --- clangd/Protocol.h +++ clangd/Protocol.h @@ -545,6 +545,8 @@ static json::Expr unparse(const CompletionItem &P); }; +bool operator<(const CompletionItem &, const CompletionItem &); + /// A single parameter of a particular signature. struct ParameterInformation { Index: clangd/Protocol.cpp =================================================================== --- clangd/Protocol.cpp +++ clangd/Protocol.cpp @@ -1038,6 +1038,11 @@ return std::move(Result); } +bool clangd::operator<(const CompletionItem &L, const CompletionItem &R) { + return (L.sortText.empty() ? L.label : L.sortText) < + (R.sortText.empty() ? R.label : R.sortText); +} + json::Expr ParameterInformation::unparse(const ParameterInformation &PI) { assert(!PI.label.empty() && "parameter information label is required"); json::obj Result{{"label", PI.label}}; Index: test/clangd/completion-priorities.test =================================================================== --- test/clangd/completion-priorities.test +++ test/clangd/completion-priorities.test @@ -1,4 +1,4 @@ -# RUN: clangd -run-synchronously < %s | FileCheck %s +# RUN: clangd -pretty -run-synchronously < %s | FileCheck -strict-whitespace %s # It is absolutely vital that this file has CRLF line endings. # @@ -13,24 +13,71 @@ Content-Length: 151 {"jsonrpc":"2.0","id":2,"method":"textDocument/completion","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":12,"character":8}}} -# The order of results returned by codeComplete seems to be -# nondeterministic, so we check regardless of order. -# -# CHECK: {"id":2,"jsonrpc":"2.0","result":[ -# CHECK-DAG: {"detail":"void","filterText":"pub","insertText":"pub","insertTextFormat":1,"kind":2,"label":"pub()","sortText":"000034pub"} -# CHECK-DAG: {"detail":"void","filterText":"prot","insertText":"prot","insertTextFormat":1,"kind":2,"label":"prot()","sortText":"000034prot"} -# CHECK-DAG: {"detail":"void","filterText":"priv","insertText":"priv","insertTextFormat":1,"kind":2,"label":"priv()","sortText":"000034priv"} -# CHECK-SAME: ]} - +# CHECK: "id": 2, +# CHECK-NEXT: "jsonrpc": "2.0", +# CHECK-NEXT: "result": [ +# CHECK-NEXT: { +# CHECK-NEXT: "detail": "void", +# CHECK-NEXT: "filterText": "priv", +# CHECK-NEXT: "insertText": "priv", +# CHECK-NEXT: "insertTextFormat": 1, +# CHECK-NEXT: "kind": 2, +# CHECK-NEXT: "label": "priv()", +# CHECK-NEXT: "sortText": "000034priv" +# CHECK-NEXT: }, +# CHECK-NEXT: { +# CHECK-NEXT: "detail": "void", +# CHECK-NEXT: "filterText": "prot", +# CHECK-NEXT: "insertText": "prot", +# CHECK-NEXT: "insertTextFormat": 1, +# CHECK-NEXT: "kind": 2, +# CHECK-NEXT: "label": "prot()", +# CHECK-NEXT: "sortText": "000034prot" +# CHECK-NEXT: }, +# CHECK-NEXT: { +# CHECK-NEXT: "detail": "void", +# CHECK-NEXT: "filterText": "pub", +# CHECK-NEXT: "insertText": "pub", +# CHECK-NEXT: "insertTextFormat": 1, +# CHECK-NEXT: "kind": 2, +# CHECK-NEXT: "label": "pub()", +# CHECK-NEXT: "sortText": "000034pub" +# CHECK-NEXT: }, Content-Length: 151 {"jsonrpc":"2.0","id":3,"method":"textDocument/completion","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":17,"character":4}}} -# CHECK: {"id":3,"jsonrpc":"2.0","result":[ -# CHECK-DAG: {"detail":"void","filterText":"pub","insertText":"pub","insertTextFormat":1,"kind":2,"label":"pub()","sortText":"000034pub"} -# CHECK-DAG: {"detail":"void","filterText":"prot","insertText":"prot","insertTextFormat":1,"kind":2,"label":"prot()","sortText":"200034prot"} -# CHECK-DAG: {"detail":"void","filterText":"priv","insertText":"priv","insertTextFormat":1,"kind":2,"label":"priv()","sortText":"200034priv"} -# CHECK-SAME: ]} - +# CHECK: "id": 3, +# CHECK-NEXT: "jsonrpc": "2.0", +# CHECK-NEXT: "result": [ +# CHECK-NEXT: { +# CHECK-NEXT: "detail": "void", +# CHECK-NEXT: "filterText": "pub", +# CHECK-NEXT: "insertText": "pub", +# CHECK-NEXT: "insertTextFormat": 1, +# CHECK-NEXT: "kind": 2, +# CHECK-NEXT: "label": "pub()", +# CHECK-NEXT: "sortText": "000034pub" +# CHECK-NEXT: }, +# priv() and prot() are at the end of the list +# CHECK-NEXT: { +# CHECK: "detail": "void", +# CHECK: "filterText": "priv", +# CHECK-NEXT: "insertText": "priv", +# CHECK-NEXT: "insertTextFormat": 1, +# CHECK-NEXT: "kind": 2, +# CHECK-NEXT: "label": "priv()", +# CHECK-NEXT: "sortText": "200034priv" +# CHECK-NEXT: }, +# CHECK-NEXT: { +# CHECK-NEXT: "detail": "void", +# CHECK-NEXT: "filterText": "prot", +# CHECK-NEXT: "insertText": "prot", +# CHECK-NEXT: "insertTextFormat": 1, +# CHECK-NEXT: "kind": 2, +# CHECK-NEXT: "label": "prot()", +# CHECK-NEXT: "sortText": "200034prot" +# CHECK-NEXT: } +# CHECK-NEXT: ] Content-Length: 58 {"jsonrpc":"2.0","id":4,"method":"shutdown","params":null} Index: test/clangd/completion-qualifiers.test =================================================================== --- test/clangd/completion-qualifiers.test +++ test/clangd/completion-qualifiers.test @@ -1,4 +1,4 @@ -# RUN: clangd -run-synchronously < %s | FileCheck %s +# RUN: clangd -pretty -run-synchronously < %s | FileCheck -strict-whitespace %s Content-Length: 125 {"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}} @@ -8,11 +8,39 @@ Content-Length: 151 {"jsonrpc":"2.0","id":2,"method":"textDocument/completion","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":11,"character":8}}} -# CHECK: {"id":2,"jsonrpc":"2.0","result":[ -# CHECK-DAG: {"detail":"int","filterText":"foo","insertText":"foo","insertTextFormat":1,"kind":2,"label":"foo() const","sortText":"200035foo"} -# CHECK-DAG: {"detail":"int","filterText":"bar","insertText":"bar","insertTextFormat":1,"kind":2,"label":"bar() const","sortText":"000037bar"} -# CHECK-DAG: {"detail":"int","filterText":"foo","insertText":"foo","insertTextFormat":1,"kind":2,"label":"Foo::foo() const","sortText":"000037foo"} -# CHECK-SAME: ]} +# CHECK: "id": 2, +# CHECK-NEXT: "jsonrpc": "2.0", +# CHECK-NEXT: "result": [ +# Eligible const functions are at the top of the list. +# CHECK-NEXT: { +# CHECK-NEXT: "detail": "int", +# CHECK-NEXT: "filterText": "bar", +# CHECK-NEXT: "insertText": "bar", +# CHECK-NEXT: "insertTextFormat": 1, +# CHECK-NEXT: "kind": 2, +# CHECK-NEXT: "label": "bar() const", +# CHECK-NEXT: "sortText": "000037bar" +# CHECK-NEXT: }, +# CHECK-NEXT: { +# CHECK-NEXT: "detail": "int", +# CHECK-NEXT: "filterText": "foo", +# CHECK-NEXT: "insertText": "foo", +# CHECK-NEXT: "insertTextFormat": 1, +# CHECK-NEXT: "kind": 2, +# CHECK-NEXT: "label": "Foo::foo() const", +# CHECK-NEXT: "sortText": "000037foo" +# CHECK-NEXT: }, +# Ineligible non-const function is at the bottom of the list. +# CHECK-NEXT: { +# CHECK: "detail": "int", +# CHECK: "filterText": "foo", +# CHECK-NEXT: "insertText": "foo", +# CHECK-NEXT: "insertTextFormat": 1, +# CHECK-NEXT: "kind": 2, +# CHECK-NEXT: "label": "foo() const", +# CHECK-NEXT: "sortText": "200035foo" +# CHECK-NEXT: } +# CHECK-NEXT: ] Content-Length: 44 {"jsonrpc":"2.0","id":4,"method":"shutdown"} Index: test/clangd/completion-snippet.test =================================================================== --- test/clangd/completion-snippet.test +++ test/clangd/completion-snippet.test @@ -1,4 +1,4 @@ -# RUN: clangd -run-synchronously -enable-snippets < %s | FileCheck %s +# RUN: clangd -pretty -run-synchronously -enable-snippets < %s | FileCheck -strict-whitespace %s # It is absolutely vital that this file has CRLF line endings. # Content-Length: 125 @@ -12,30 +12,72 @@ Content-Length: 148 {"jsonrpc":"2.0","id":1,"method":"textDocument/completion","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":3,"character":5}}} -# The order of results returned by codeComplete seems to be -# nondeterministic, so we check regardless of order. -# -# CHECK: {"id":1,"jsonrpc":"2.0","result":[ -# CHECK-DAG: {"detail":"int","filterText":"a","insertText":"a","insertTextFormat":1,"kind":5,"label":"a","sortText":"000035a"} -# CHECK-DAG: {"detail":"int","filterText":"bb","insertText":"bb","insertTextFormat":1,"kind":5,"label":"bb","sortText":"000035bb"} -# CHECK-DAG: {"detail":"int","filterText":"ccc","insertText":"ccc","insertTextFormat":1,"kind":5,"label":"ccc","sortText":"000035ccc"} -# CHECK-DAG: {"detail":"fake &","filterText":"operator=","insertText":"operator=(${1:const fake &})","insertTextFormat":2,"kind":2,"label":"operator=(const fake &)","sortText":"000079operator="} -# CHECK-DAG: {"detail":"void","filterText":"~fake","insertText":"~fake()","insertTextFormat":1,"kind":4,"label":"~fake()","sortText":"000079~fake"} -# CHECK-DAG: {"detail":"int","filterText":"f","insertText":"f(${1:int i}, ${2:const float f})","insertTextFormat":2,"kind":2,"label":"f(int i, const float f) const","sortText":"000035f"} -# CHECK-SAME: ]} -Content-Length: 148 - -{"jsonrpc":"2.0","id":2,"method":"textDocument/completion","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":3,"character":5}}} -# Repeat the completion request, expect the same results. -# -# CHECK: {"id":2,"jsonrpc":"2.0","result":[ -# CHECK-DAG: {"detail":"int","filterText":"a","insertText":"a","insertTextFormat":1,"kind":5,"label":"a","sortText":"000035a"} -# CHECK-DAG: {"detail":"int","filterText":"bb","insertText":"bb","insertTextFormat":1,"kind":5,"label":"bb","sortText":"000035bb"} -# CHECK-DAG: {"detail":"int","filterText":"ccc","insertText":"ccc","insertTextFormat":1,"kind":5,"label":"ccc","sortText":"000035ccc"} -# CHECK-DAG: {"detail":"fake &","filterText":"operator=","insertText":"operator=(${1:const fake &})","insertTextFormat":2,"kind":2,"label":"operator=(const fake &)","sortText":"000079operator="} -# CHECK-DAG: {"detail":"void","filterText":"~fake","insertText":"~fake()","insertTextFormat":1,"kind":4,"label":"~fake()","sortText":"000079~fake"} -# CHECK-DAG: {"detail":"int","filterText":"f","insertText":"f(${1:int i}, ${2:const float f})","insertTextFormat":2,"kind":2,"label":"f(int i, const float f) const","sortText":"000035f"} -# CHECK-SAME: ]} +# CHECK: "id": 1, +# CHECK-NEXT: "jsonrpc": "2.0", +# CHECK-NEXT: "result": [ +# CHECK-NEXT: { +# CHECK-NEXT: "detail": "int", +# CHECK-NEXT: "filterText": "a", +# CHECK-NEXT: "insertText": "a", +# CHECK-NEXT: "insertTextFormat": 1, +# CHECK-NEXT: "kind": 5, +# CHECK-NEXT: "label": "a", +# CHECK-NEXT: "sortText": "000035a" +# CHECK-NEXT: }, +# CHECK-NEXT: { +# CHECK-NEXT: "detail": "int", +# CHECK-NEXT: "filterText": "bb", +# CHECK-NEXT: "insertText": "bb", +# CHECK-NEXT: "insertTextFormat": 1, +# CHECK-NEXT: "kind": 5, +# CHECK-NEXT: "label": "bb", +# CHECK-NEXT: "sortText": "000035bb" +# CHECK-NEXT: }, +# CHECK-NEXT: { +# CHECK-NEXT: "detail": "int", +# CHECK-NEXT: "filterText": "ccc", +# CHECK-NEXT: "insertText": "ccc", +# CHECK-NEXT: "insertTextFormat": 1, +# CHECK-NEXT: "kind": 5, +# CHECK-NEXT: "label": "ccc", +# CHECK-NEXT: "sortText": "000035ccc" +# CHECK-NEXT: }, +# CHECK-NEXT: { +# CHECK-NEXT: "detail": "int", +# CHECK-NEXT: "filterText": "f", +# CHECK-NEXT: "insertText": "f(${1:int i}, ${2:const float f})", +# CHECK-NEXT: "insertTextFormat": 2, +# CHECK-NEXT: "kind": 2, +# CHECK-NEXT: "label": "f(int i, const float f) const", +# CHECK-NEXT: "sortText": "000035f" +# CHECK-NEXT: }, +# CHECK-NEXT: { +# CHECK-NEXT: "filterText": "fake", +# CHECK-NEXT: "insertText": "fake::", +# CHECK-NEXT: "insertTextFormat": 1, +# CHECK-NEXT: "kind": 7, +# CHECK-NEXT: "label": "fake::", +# CHECK-NEXT: "sortText": "000075fake" +# CHECK-NEXT: }, +# CHECK-NEXT: { +# CHECK-NEXT: "detail": "fake &", +# CHECK-NEXT: "filterText": "operator=", +# CHECK-NEXT: "insertText": "operator=(${1:const fake &})", +# CHECK-NEXT: "insertTextFormat": 2, +# CHECK-NEXT: "kind": 2, +# CHECK-NEXT: "label": "operator=(const fake &)", +# CHECK-NEXT: "sortText": "000079operator=" +# CHECK-NEXT: }, +# CHECK-NEXT: { +# CHECK-NEXT: "detail": "void", +# CHECK-NEXT: "filterText": "~fake", +# CHECK-NEXT: "insertText": "~fake()", +# CHECK-NEXT: "insertTextFormat": 1, +# CHECK-NEXT: "kind": 4, +# CHECK-NEXT: "label": "~fake()", +# CHECK-NEXT: "sortText": "000079~fake" +# CHECK-NEXT: } +# CHECK-NEXT: ] # Update the source file and check for completions again. Content-Length: 226 @@ -44,9 +86,18 @@ Content-Length: 148 {"jsonrpc":"2.0","id":3,"method":"textDocument/completion","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":3,"character":5}}} -# CHECK: {"id":3,"jsonrpc":"2.0","result":[ -# CHECK-DAG: {"detail":"int (*)(int, int)","filterText":"func","insertText":"func()","insertTextFormat":1,"kind":2,"label":"func()","sortText":"000034func"} -# CHECK-SAME: ]} +# CHECK: "id": 3, +# CHECK-NEXT: "jsonrpc": "2.0", +# CHECK-NEXT: "result": [ +# CHECK-NEXT: { +# CHECK-NEXT: "detail": "int (*)(int, int)", +# CHECK-NEXT: "filterText": "func", +# CHECK-NEXT: "insertText": "func()", +# CHECK-NEXT: "insertTextFormat": 1, +# CHECK-NEXT: "kind": 2, +# CHECK-NEXT: "label": "func()", +# CHECK-NEXT: "sortText": "000034func" +# CHECK-NEXT: }, Content-Length: 44 {"jsonrpc":"2.0","id":4,"method":"shutdown"} Index: test/clangd/completion.test =================================================================== --- test/clangd/completion.test +++ test/clangd/completion.test @@ -1,4 +1,4 @@ -# RUN: clangd -run-synchronously < %s | FileCheck %s +# RUN: clangd -pretty -run-synchronously < %s | FileCheck -strict-whitespace %s # It is absolutely vital that this file has CRLF line endings. # Content-Length: 125 @@ -12,30 +12,141 @@ Content-Length: 148 {"jsonrpc":"2.0","id":1,"method":"textDocument/completion","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":3,"character":5}}} -# The order of results returned by codeComplete seems to be -# nondeterministic, so we check regardless of order. -# -# CHECK: {"id":1,"jsonrpc":"2.0","result":[ -# CHECK-DAG: {"detail":"int","filterText":"a","insertText":"a","insertTextFormat":1,"kind":5,"label":"a","sortText":"000035a"} -# CHECK-DAG: {"detail":"int","filterText":"bb","insertText":"bb","insertTextFormat":1,"kind":5,"label":"bb","sortText":"000035bb"} -# CHECK-DAG: {"detail":"int","filterText":"ccc","insertText":"ccc","insertTextFormat":1,"kind":5,"label":"ccc","sortText":"000035ccc"} -# CHECK-DAG: {"detail":"fake &","filterText":"operator=","insertText":"operator=","insertTextFormat":1,"kind":2,"label":"operator=(const fake &)","sortText":"000079operator="} -# CHECK-DAG: {"detail":"void","filterText":"~fake","insertText":"~fake","insertTextFormat":1,"kind":4,"label":"~fake()","sortText":"000079~fake"} -# CHECK-DAG: {"detail":"int","filterText":"f","insertText":"f","insertTextFormat":1,"kind":2,"label":"f(int i, const float f) const","sortText":"000035f"} -# CHECK-SAME: ]} +# CHECK: "id": 1 +# CHECK-NEXT: "jsonrpc": "2.0", +# CHECK-NEXT: "result": [ +# CHECK-NEXT: { +# CHECK-NEXT: "detail": "int", +# CHECK-NEXT: "filterText": "a", +# CHECK-NEXT: "insertText": "a", +# CHECK-NEXT: "insertTextFormat": 1, +# CHECK-NEXT: "kind": 5, +# CHECK-NEXT: "label": "a", +# CHECK-NEXT: "sortText": "000035a" +# CHECK-NEXT: }, +# CHECK-NEXT: { +# CHECK-NEXT: "detail": "int", +# CHECK-NEXT: "filterText": "bb", +# CHECK-NEXT: "insertText": "bb", +# CHECK-NEXT: "insertTextFormat": 1, +# CHECK-NEXT: "kind": 5, +# CHECK-NEXT: "label": "bb", +# CHECK-NEXT: "sortText": "000035bb" +# CHECK-NEXT: }, +# CHECK-NEXT: { +# CHECK-NEXT: "detail": "int", +# CHECK-NEXT: "filterText": "ccc", +# CHECK-NEXT: "insertText": "ccc", +# CHECK-NEXT: "insertTextFormat": 1, +# CHECK-NEXT: "kind": 5, +# CHECK-NEXT: "label": "ccc", +# CHECK-NEXT: "sortText": "000035ccc" +# CHECK-NEXT: }, +# CHECK-NEXT: { +# CHECK-NEXT: "detail": "int", +# CHECK-NEXT: "filterText": "f", +# CHECK-NEXT: "insertText": "f", +# CHECK-NEXT: "insertTextFormat": 1, +# CHECK-NEXT: "kind": 2, +# CHECK-NEXT: "label": "f(int i, const float f) const", +# CHECK-NEXT: "sortText": "000035f" +# CHECK-NEXT: }, +# CHECK-NEXT: { +# CHECK-NEXT: "filterText": "fake", +# CHECK-NEXT: "insertText": "fake", +# CHECK-NEXT: "insertTextFormat": 1, +# CHECK-NEXT: "kind": 7, +# CHECK-NEXT: "label": "fake::", +# CHECK-NEXT: "sortText": "000075fake" +# CHECK-NEXT: }, +# CHECK-NEXT: { +# CHECK-NEXT: "detail": "fake &", +# CHECK-NEXT: "filterText": "operator=", +# CHECK-NEXT: "insertText": "operator=", +# CHECK-NEXT: "insertTextFormat": 1, +# CHECK-NEXT: "kind": 2, +# CHECK-NEXT: "label": "operator=(const fake &)", +# CHECK-NEXT: "sortText": "000079operator=" +# CHECK-NEXT: }, +# CHECK-NEXT: { +# CHECK-NEXT: "detail": "void", +# CHECK-NEXT: "filterText": "~fake", +# CHECK-NEXT: "insertText": "~fake", +# CHECK-NEXT: "insertTextFormat": 1, +# CHECK-NEXT: "kind": 4, +# CHECK-NEXT: "label": "~fake()", +# CHECK-NEXT: "sortText": "000079~fake" +# CHECK-NEXT: } +# CHECK-NEXT: ] Content-Length: 148 {"jsonrpc":"2.0","id":2,"method":"textDocument/completion","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":3,"character":5}}} -# Repeat the completion request, expect the same results. -# -# CHECK: {"id":2,"jsonrpc":"2.0","result":[ -# CHECK-DAG: {"detail":"int","filterText":"a","insertText":"a","insertTextFormat":1,"kind":5,"label":"a","sortText":"000035a"} -# CHECK-DAG: {"detail":"int","filterText":"bb","insertText":"bb","insertTextFormat":1,"kind":5,"label":"bb","sortText":"000035bb"} -# CHECK-DAG: {"detail":"int","filterText":"ccc","insertText":"ccc","insertTextFormat":1,"kind":5,"label":"ccc","sortText":"000035ccc"} -# CHECK-DAG: {"detail":"fake &","filterText":"operator=","insertText":"operator=","insertTextFormat":1,"kind":2,"label":"operator=(const fake &)","sortText":"000079operator="} -# CHECK-DAG: {"detail":"void","filterText":"~fake","insertText":"~fake","insertTextFormat":1,"kind":4,"label":"~fake()","sortText":"000079~fake"} -# CHECK-DAG: {"detail":"int","filterText":"f","insertText":"f","insertTextFormat":1,"kind":2,"label":"f(int i, const float f) const","sortText":"000035f"} -# CHECK-SAME: ]} +# CHECK: "id": 2 +# CHECK-NEXT: "jsonrpc": "2.0", +# CHECK-NEXT: "result": [ +# CHECK-NEXT: { +# CHECK-NEXT: "detail": "int", +# CHECK-NEXT: "filterText": "a", +# CHECK-NEXT: "insertText": "a", +# CHECK-NEXT: "insertTextFormat": 1, +# CHECK-NEXT: "kind": 5, +# CHECK-NEXT: "label": "a", +# CHECK-NEXT: "sortText": "000035a" +# CHECK-NEXT: }, +# CHECK-NEXT: { +# CHECK-NEXT: "detail": "int", +# CHECK-NEXT: "filterText": "bb", +# CHECK-NEXT: "insertText": "bb", +# CHECK-NEXT: "insertTextFormat": 1, +# CHECK-NEXT: "kind": 5, +# CHECK-NEXT: "label": "bb", +# CHECK-NEXT: "sortText": "000035bb" +# CHECK-NEXT: }, +# CHECK-NEXT: { +# CHECK-NEXT: "detail": "int", +# CHECK-NEXT: "filterText": "ccc", +# CHECK-NEXT: "insertText": "ccc", +# CHECK-NEXT: "insertTextFormat": 1, +# CHECK-NEXT: "kind": 5, +# CHECK-NEXT: "label": "ccc", +# CHECK-NEXT: "sortText": "000035ccc" +# CHECK-NEXT: }, +# CHECK-NEXT: { +# CHECK-NEXT: "detail": "int", +# CHECK-NEXT: "filterText": "f", +# CHECK-NEXT: "insertText": "f", +# CHECK-NEXT: "insertTextFormat": 1, +# CHECK-NEXT: "kind": 2, +# CHECK-NEXT: "label": "f(int i, const float f) const", +# CHECK-NEXT: "sortText": "000035f" +# CHECK-NEXT: }, +# CHECK-NEXT: { +# CHECK-NEXT: "filterText": "fake", +# CHECK-NEXT: "insertText": "fake", +# CHECK-NEXT: "insertTextFormat": 1, +# CHECK-NEXT: "kind": 7, +# CHECK-NEXT: "label": "fake::", +# CHECK-NEXT: "sortText": "000075fake" +# CHECK-NEXT: }, +# CHECK-NEXT: { +# CHECK-NEXT: "detail": "fake &", +# CHECK-NEXT: "filterText": "operator=", +# CHECK-NEXT: "insertText": "operator=", +# CHECK-NEXT: "insertTextFormat": 1, +# CHECK-NEXT: "kind": 2, +# CHECK-NEXT: "label": "operator=(const fake &)", +# CHECK-NEXT: "sortText": "000079operator=" +# CHECK-NEXT: }, +# CHECK-NEXT: { +# CHECK-NEXT: "detail": "void", +# CHECK-NEXT: "filterText": "~fake", +# CHECK-NEXT: "insertText": "~fake", +# CHECK-NEXT: "insertTextFormat": 1, +# CHECK-NEXT: "kind": 4, +# CHECK-NEXT: "label": "~fake()", +# CHECK-NEXT: "sortText": "000079~fake" +# CHECK-NEXT: } +# CHECK-NEXT: ] # Update the source file and check for completions again. Content-Length: 226 @@ -44,11 +155,45 @@ Content-Length: 148 {"jsonrpc":"2.0","id":3,"method":"textDocument/completion","params":{"textDocument":{"uri":"file:///main.cpp"},"position":{"line":3,"character":5}}} -# Repeat the completion request, expect the same results. -# -# CHECK: {"id":3,"jsonrpc":"2.0","result":[ -# CHECK-DAG: {"detail":"int (*)(int, int)","filterText":"func","insertText":"func","insertTextFormat":1,"kind":2,"label":"func()","sortText":"000034func"} -# CHECK-SAME: ]} +# CHECK: "id": 3, +# CHECK-NEXT: "jsonrpc": "2.0", +# CHECK-NEXT: "result": [ +# CHECK-NEXT: { +# CHECK-NEXT: "detail": "int (*)(int, int)", +# CHECK-NEXT: "filterText": "func", +# CHECK-NEXT: "insertText": "func", +# CHECK-NEXT: "insertTextFormat": 1, +# CHECK-NEXT: "kind": 2, +# CHECK-NEXT: "label": "func()", +# CHECK-NEXT: "sortText": "000034func" +# CHECK-NEXT: }, +# CHECK-NEXT: { +# CHECK-NEXT: "filterText": "fancy", +# CHECK-NEXT: "insertText": "fancy", +# CHECK-NEXT: "insertTextFormat": 1, +# CHECK-NEXT: "kind": 7, +# CHECK-NEXT: "label": "fancy::", +# CHECK-NEXT: "sortText": "000075fancy" +# CHECK-NEXT: }, +# CHECK-NEXT: { +# CHECK-NEXT: "detail": "fancy &", +# CHECK-NEXT: "filterText": "operator=", +# CHECK-NEXT: "insertText": "operator=", +# CHECK-NEXT: "insertTextFormat": 1, +# CHECK-NEXT: "kind": 2, +# CHECK-NEXT: "label": "operator=(const fancy &)", +# CHECK-NEXT: "sortText": "000079operator=" +# CHECK-NEXT: }, +# CHECK-NEXT: { +# CHECK-NEXT: "detail": "void", +# CHECK-NEXT: "filterText": "~fancy", +# CHECK-NEXT: "insertText": "~fancy", +# CHECK-NEXT: "insertTextFormat": 1, +# CHECK-NEXT: "kind": 4, +# CHECK-NEXT: "label": "~fancy()", +# CHECK-NEXT: "sortText": "000079~fancy" +# CHECK-NEXT: } +# CHECK-NEXT: ] Content-Length: 44 {"jsonrpc":"2.0","id":4,"method":"shutdown"}